golang subject dn from x509 cert

匿名 (未验证) 提交于 2019-12-03 03:10:03

问题:

Is there any easy way to get the complete subject DN (or issuer DN) from an x509 certificate in go as a string?

I was not able to find any methods like ".String()" in pkix.Name

回答1:

Solution (thanks to a colleague):

var oid = map[string]string{     "2.5.4.3":                    "CN",     "2.5.4.4":                    "SN",     "2.5.4.5":                    "serialNumber",     "2.5.4.6":                    "C",     "2.5.4.7":                    "L",     "2.5.4.8":                    "ST",     "2.5.4.9":                    "streetAddress",     "2.5.4.10":                   "O",     "2.5.4.11":                   "OU",     "2.5.4.12":                   "title",     "2.5.4.17":                   "postalCode",     "2.5.4.42":                   "GN",     "2.5.4.43":                   "initials",     "2.5.4.44":                   "generationQualifier",     "2.5.4.46":                   "dnQualifier",     "2.5.4.65":                   "pseudonym",     "0.9.2342.19200300.100.1.25": "DC",     "1.2.840.113549.1.9.1":       "emailAddress",     "0.9.2342.19200300.100.1.1":  "userid", }  func getDNFromCert(namespace pkix.Name, sep string) (string, error) {     subject := []string{}     for _, s := range namespace.ToRDNSequence() {         for _, i := range s {             if v, ok := i.Value.(string); ok {                 if name, ok := oid[i.Type.String()]; ok {                     // <oid name>=<value>                     subject = append(subject, fmt.Sprintf("%s=%s", name, v))                 } else {                     // <oid>=<value> if no <oid name> is found                     subject = append(subject, fmt.Sprintf("%s=%s", i.Type.String(), v))                 }             } else {                 // <oid>=<value in default format> if value is not string                 subject = append(subject, fmt.Sprintf("%s=%v", i.Type.String, v))             }         }     }     return sep + strings.Join(subject, sep), nil } 

calling the function:

subj, err := getDNFromCert(x509Cert.Subject, "/") if err != nil {    // do error handling } fmt.Println(subj) 

output (example):

/C=US/O=some organization/OU=unit/CN=common name 

this seems to be the only "easy" solution



回答2:

In order to get complete subject DN (or issuer DN) from an x509 certificate, you may use next code:

cert, err := x509.ParseCertificate(certData) if err != nil {     return err }  var subject pkix.RDNSequence if _, err := asn1.Unmarshal(cert.RawSubject, &subject); err != nil {     return err }  fmt.Plrintln(subject.String() 

Similarly, if you need to get only some specific object value from the subject (or issuer) you may use next approach. Example below retrieves UID from subject (which is not defined in the stdlib https://github.com/golang/go/issues/25667)

// http://www.alvestrand.no/objectid/0.9.2342.19200300.100.1.1.html const oidUserID = "0.9.2342.19200300.100.1.1" var UID string  cert, err := x509.ParseCertificate(certData) if err != nil {     return err }  // manually parsing the Certificate subject to get the // UID field, which is being ignored by the stdlib // https://github.com/golang/go/issues/25667 var subject pkix.RDNSequence if _, err := asn1.Unmarshal(cert.RawSubject, &subject); err != nil {     return err }  for _, s := range subject {     for _, i := range s {         if i.Type.String() == oidUserID {             if v, ok := i.Value.(string); ok {                 UID = v             }         }     } }  fmt.Println(UID) 

UPDATE: Simplified way to get the UID, thanks to @FiloSottile:

// http://www.alvestrand.no/objectid/0.9.2342.19200300.100.1.1.html var oidUserID = []int{0, 9, 2342, 19200300, 100, 1, 1} var UID string  cert, err := x509.ParseCertificate(certData) if err != nil {     return err }  // reading the UID from list of unprased  // objects from Subject for _, n := range cert.Subject.Names {     if n.Type.Equal(oidUserID) {         if v, ok := n.Value.(string); ok {             UID = v         }     } }  fmt.Println(UID) 


回答3:

I faced the same task today. You could get subject from certificate this way:

// d is []byte with your certificate cert, err := x509.ParseCertificate(d) fmt.Printf("%+v\n", cert.Subject.ToRDNSequence())  // Output: CN=client1,OU=MyClients,O=MongoDB-Cluster,L=Austin,ST=TX,C=US 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!