Re: Parsing X509 certificate subjectAltName
On 9/12/2012 9:36 AM, Dr. Stephen Henson wrote: You check each value of the returned GENERAL_NAMES structure until you find the one you are interested in. It looks like in your case it is the type GEN_DIRNAME which means the X509_NAME field directoryName of the union is relevant. You can then analyse that X509_NAME field e.g. like a certificate subject name. Here's the code I came up with - error checking, etc. removed for brevity. It works. Would anyone care to critique it? To review, here's what I'm trying to parse: X509v3 Subject Alternative Name: critical DirName:/2.23.133.2.1=id:xx00/2.23.133.2.2=Partname/2.23.133.2.3=id:version int GetExtensions(X509 *x509Certificate) { STACK_OF(X509_EXTENSION) *exts; int numExtensions; GENERAL_NAMES *subjectAltNames = (GENERAL_NAMES*) X509_get_ext_d2i(x509Certificate, NID_subject_alt_name, NULL, NULL); int numberOfAlts = sk_GENERAL_NAME_num (subjectAltNames); for ( i = 0; i < numberOfAlts ; i++) { const GENERAL_NAME *pName = sk_GENERAL_NAME_value (subjectAltNames, i); if (pName->type == GEN_DIRNAME) { X509_NAME *directoryName = (X509_NAME *)pName->d.dirn; int entryCount = X509_NAME_entry_count(directoryName); for (i = 0 ; i < entryCount ; i++) { char asn1Object[256]; unsigned char *asn1ObjectValue = NULL; X509_NAME_ENTRY *ent = X509_NAME_get_entry(directoryName, i); /* get the name, the OID */ ASN1_OBJECT *fn = X509_NAME_ENTRY_get_object(ent); OBJ_obj2txt(asn1Object, sizeof asn1Object, fn, 1); /* get the value, the text associated with OID name */ ASN1_STRING *val = X509_NAME_ENTRY_get_data(ent); int length = ASN1_STRING_to_UTF8(&asn1ObjectValue, val); } } } } __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: Parsing X509 certificate subjectAltName
On Wed, Sep 12, 2012, Kenneth Goldman wrote: > If I shouldn't use GEN_IPADD, what should I use? > > The goal is to extract the text value associated with several OIDs. > dumpasn1 says the values are PrintableString. > You check each value of the returned GENERAL_NAMES structure until you find the one you are interested in. It looks like in your case it is the type GEN_DIRNAME which means the X509_NAME field directoryName of the union is relevant. You can then analyse that X509_NAME field e.g. like a certificate subject name. Steve. -- Dr Stephen N. Henson. OpenSSL project core developer. Commercial tech support now available see: http://www.openssl.org __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: Parsing X509 certificate subjectAltName
If I shouldn't use GEN_IPADD, what should I use? The goal is to extract the text value associated with several OIDs. dumpasn1 says the values are PrintableString. -- Ken Goldman kgold...@us.ibm.com 914-945-2415 (862-2415) From: "Dr. Stephen Henson" To: openssl-users@openssl.org, Date: 09/11/2012 06:49 PM Subject: Re: Parsing X509 certificate subjectAltName Sent by:owner-openssl-us...@openssl.org On Tue, Sep 11, 2012, Charles Mills wrote: > > { > > case GEN_DNS: > > case GEN_URI: > > case GEN_IPADD: > > > ASN1_STRING_to_UTF8(&pBuffer, pName->d.ia5); > > b = > isWildcardedCNcompare(reinterpret_cast(pBuffer), nodeName); > > Don't do that with the GEN_IPADD: it isn't an IA5String it is an OCTETSTRING representing the IP address in a format described by RFC3280 et al. Steve. -- Dr Stephen N. Henson. OpenSSL project core developer. Commercial tech support now available see: http://www.openssl.org __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
RE: Parsing X509 certificate subjectAltName
Thanks! Charles -Original Message- From: owner-openssl-us...@openssl.org [mailto:owner-openssl-us...@openssl.org] On Behalf Of Dr. Stephen Henson Sent: Tuesday, September 11, 2012 3:46 PM To: openssl-users@openssl.org Subject: Re: Parsing X509 certificate subjectAltName On Tue, Sep 11, 2012, Charles Mills wrote: > > { > > case GEN_DNS: > > case GEN_URI: > > case GEN_IPADD: > > > ASN1_STRING_to_UTF8(&pBuffer, pName->d.ia5); > > b = > isWildcardedCNcompare(reinterpret_cast(pBuffer), nodeName); > > Don't do that with the GEN_IPADD: it isn't an IA5String it is an OCTETSTRING representing the IP address in a format described by RFC3280 et al. Steve. -- Dr Stephen N. Henson. OpenSSL project core developer. Commercial tech support now available see: http://www.openssl.org __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: Parsing X509 certificate subjectAltName
On Tue, Sep 11, 2012, Charles Mills wrote: > > { > > case GEN_DNS: > > case GEN_URI: > > case GEN_IPADD: > > > ASN1_STRING_to_UTF8(&pBuffer, pName->d.ia5); > > b = > isWildcardedCNcompare(reinterpret_cast(pBuffer), nodeName); > > Don't do that with the GEN_IPADD: it isn't an IA5String it is an OCTETSTRING representing the IP address in a format described by RFC3280 et al. Steve. -- Dr Stephen N. Henson. OpenSSL project core developer. Commercial tech support now available see: http://www.openssl.org __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
RE: Parsing X509 certificate subjectAltName
bool Comm::isAltNameMatch(X509 *certificate, const char *nodeName) { // there is alternative code on page 136 of O'Reilly OpenSSL unsigned char *pBuffer = NULL; int length = 0; GENERAL_NAMES *subjectAltNames; bool b; subjectAltNames = (GENERAL_NAMES*) X509_get_ext_d2i(certificate, NID_subject_alt_name, NULL, NULL); if ( subjectAltNames ) { int numberOfAlts; int i; // get number of names. Supposed to be at least one, but don't count on it numberOfAlts = sk_GENERAL_NAME_num (subjectAltNames); // loop through all of the alternate names for ( i = 0; i < numberOfAlts; i++) { // get a handle to alternative name i const GENERAL_NAME *pName = sk_GENERAL_NAME_value (subjectAltNames, i); // what did we get? switch (pName->type) { case GEN_DNS: case GEN_URI: case GEN_IPADD: ASN1_STRING_to_UTF8(&pBuffer, pName->d.ia5); b = isWildcardedCNcompare(reinterpret_cast(pBuffer), nodeName); OPENSSL_free(pBuffer); if ( b ) return true; break; case GEN_OTHERNAME: case GEN_EMAIL: case GEN_X400: case GEN_DIRNAME: case GEN_EDIPARTY: case GEN_RID: default: break; } } } // fall through or no alt names return false; } Charles From: owner-openssl-us...@openssl.org [mailto:owner-openssl-us...@openssl.org] On Behalf Of Kenneth Goldman Sent: Tuesday, September 11, 2012 2:14 PM To: openssl-users@openssl.org Subject: Parsing X509 certificate subjectAltName I'm 90% deep into parsing an X509 certificate, but I can't find sample code for the last piece. I found the extension, and located the ASN1_OBJECT with nid 85, OID 2.5.29.17, the subjectAltName. From the dumpasn output, I see that this is an octet string of a sequence, etc. I have to pull out the three OIDs '2.23.133.2. [1, 2, and 3]' which are presumably in the ASN1_OBJECT. Can anyone point me to sample code or a hint? ~~ 515 3: . . . . . OBJECT IDENTIFIER subjectAltName (2 5 29 17) : . . . . . . (X.509 extension) <01 01 FF> 520 1: . . . . . BOOLEAN TRUE <04 4A 30 48 A4 46 30 44 31 42 30 14 06 05 67 81 05 02 01 13 0B 69 64 3A> 523 74: . . . . . OCTET STRING, encapsulates { <30 48 A4 46 30 44 31 42 30 14 06 05 67 81 05 02 01 13 0B 69 64 3A 35 37> 525 72: . . . . . . SEQUENCE { 527 70: . . . . . . . [4] { <30 44 31 42 30 14 06 05 67 81 05 02 01 13 0B 69 64 3A 35 37 34 35 34 33> 529 68: . . . . . . . . SEQUENCE { <31 42 30 14 06 05 67 81 05 02 01 13 0B 69 64 3A 35 37 34 35 34 33 30 30> 531 66: . . . . . . . . . SET { <30 14 06 05 67 81 05 02 01 13 0B 69 64 3A 35 37 34 35 34 33 30 30> 533 20: . . . . . . . . . . SEQUENCE { <06 05 67 81 05 02 01> 535 5: . . . . . . . . . . . OBJECT IDENTIFIER '2 23 133 2 1' <13 0B 69 64 3A 35 37 34 35 34 33 30 30> 542 11: . . . . . . . . . . . PrintableString 'id:57454300' : . . . . . . . . . . . } <30 18 06 05 67 81 05 02 02 13 0F 4E 50 43 54 34 32 78 2F 4E 50 43 54 35> 555 24: . . . . . . . . . . SEQUENCE { <06 05 67 81 05 02 02> 557 5: . . . . . . . . . . . OBJECT IDENTIFIER '2 23 133 2 2' <13 0F 4E 50 43 54 34 32 78 2F 4E 50 43 54 35 30 78> 564 15: . . . . . . . . . . . PrintableString 'NPCT42x/NPCT50x' : . . . . . . . . . . . } <30 10 06 05 67 81 05 02 03 13 07 69 64 3A 30 33 39 31> 581 16: . . . . . . . . . . SEQUENCE { <06 05 67 81 05 02 0
Parsing X509 certificate subjectAltName
I'm 90% deep into parsing an X509 certificate, but I can't find sample code for the last piece. I found the extension, and located the ASN1_OBJECT with nid 85, OID 2.5.29.17, the subjectAltName. From the dumpasn output, I see that this is an octet string of a sequence, etc. I have to pull out the three OIDs '2.23.133.2. [1, 2, and 3]' which are presumably in the ASN1_OBJECT. Can anyone point me to sample code or a hint? ~~ 515 3: . . . . . OBJECT IDENTIFIER subjectAltName (2 5 29 17) : . . . . . . (X.509 extension) <01 01 FF> 520 1: . . . . . BOOLEAN TRUE <04 4A 30 48 A4 46 30 44 31 42 30 14 06 05 67 81 05 02 01 13 0B 69 64 3A> 523 74: . . . . . OCTET STRING, encapsulates { <30 48 A4 46 30 44 31 42 30 14 06 05 67 81 05 02 01 13 0B 69 64 3A 35 37> 525 72: . . . . . . SEQUENCE { 527 70: . . . . . . . [4] { <30 44 31 42 30 14 06 05 67 81 05 02 01 13 0B 69 64 3A 35 37 34 35 34 33> 529 68: . . . . . . . . SEQUENCE { <31 42 30 14 06 05 67 81 05 02 01 13 0B 69 64 3A 35 37 34 35 34 33 30 30> 531 66: . . . . . . . . . SET { <30 14 06 05 67 81 05 02 01 13 0B 69 64 3A 35 37 34 35 34 33 30 30> 533 20: . . . . . . . . . . SEQUENCE { <06 05 67 81 05 02 01> 535 5: . . . . . . . . . . . OBJECT IDENTIFIER '2 23 133 2 1' <13 0B 69 64 3A 35 37 34 35 34 33 30 30> 542 11: . . . . . . . . . . . PrintableString 'id:57454300' : . . . . . . . . . . . } <30 18 06 05 67 81 05 02 02 13 0F 4E 50 43 54 34 32 78 2F 4E 50 43 54 35> 555 24: . . . . . . . . . . SEQUENCE { <06 05 67 81 05 02 02> 557 5: . . . . . . . . . . . OBJECT IDENTIFIER '2 23 133 2 2' <13 0F 4E 50 43 54 34 32 78 2F 4E 50 43 54 35 30 78> 564 15: . . . . . . . . . . . PrintableString 'NPCT42x/NPCT50x' : . . . . . . . . . . . } <30 10 06 05 67 81 05 02 03 13 07 69 64 3A 30 33 39 31> 581 16: . . . . . . . . . . SEQUENCE { <06 05 67 81 05 02 03> 583 5: . . . . . . . . . . . OBJECT IDENTIFIER '2 23 133 2 3' <13 07 69 64 3A 30 33 39 31> 590 7: . . . . . . . . . . . PrintableString 'id:0391' : . . . . . . . . . . . } : . . . . . . . . . . } : . . . . . . . . . } : . . . . . . . . } : . . . . . . . } : . . . . . . } : . . . . . } -- Ken Goldman kgold...@us.ibm.com 914-945-2415 (862-2415)