Add support for unusal 'othername' subjectAltNames
authorDirk-Willem van Gulik <dirkx@webweaving.org>
Tue, 21 Apr 2020 21:06:38 +0000 (23:06 +0200)
committerDmitry Belyavskiy <beldmit@gmail.com>
Sat, 25 Apr 2020 15:52:30 +0000 (18:52 +0300)
Increasingly certificates seem to have special things in the subjectAltName that have arbitrary strings in them.

E.g. some (now) common in EU export certificates and, for a few years now, certificates issued to medical doctors (in for example the netherlands, the full spec is https://www.uziregister.nl/Media/Default/PDF/20200325%20CA%20model%20pasmodel%20certificaatprofielen%20v10_0.pdf, section 4.8, page 16 for an example of one country).

Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/11599)

crypto/x509/v3_alt.c
test/certs/fake-gp.pem [new file with mode: 0644]
test/recipes/25-test_x509.t

index 67d8acc81bb6be3e6acabe59f6e842731c4fcfbb..f15bbdbd21b2d2ac5a38851e583b8b513b67c3c4 100644 (file)
@@ -82,6 +82,7 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
                                        STACK_OF(CONF_VALUE) *ret)
 {
     unsigned char *p;
+    char othername[256];
     char oline[256], htmp[5];
     int i;
 
@@ -124,7 +125,25 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
                 return NULL;
             break;
         default:
-            if (!X509V3_add_value("othername", "<unsupported>", &ret))
+            if (OBJ_obj2txt(oline, sizeof(oline), gen->d.otherName->type_id, 0) > 0) 
+                snprintf(othername, sizeof(othername), "othername: %s:", oline);
+            else
+                strncpy(othername, "othername:", sizeof(othername));
+
+            /* check if the value is something printable */
+            if (gen->d.otherName->value->type == V_ASN1_IA5STRING) {
+                if (X509V3_add_value_uchar(othername,
+                             gen->d.otherName->value->value.ia5string->data,
+                             &ret)) 
+                    return ret;
+            }
+            if (gen->d.otherName->value->type == V_ASN1_UTF8STRING) {
+                if (X509V3_add_value_uchar(othername,
+                             gen->d.otherName->value->value.utf8string->data,
+                             &ret)) 
+                    return ret;
+            }
+            if (!X509V3_add_value(othername, "<unsupported>", &ret))
                 return NULL;
             break;
         }
diff --git a/test/certs/fake-gp.pem b/test/certs/fake-gp.pem
new file mode 100644 (file)
index 0000000..c25f172
--- /dev/null
@@ -0,0 +1,36 @@
+-----BEGIN CERTIFICATE-----
+MIIGTzCCBTegAwIBAgIEAJiW+zANBgkqhkiG9w0BAQsFADBpMQswCQYDVQQGEwJO
+TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMTowOAYDVQQDDDFTdGFh
+dCBkZXIgTmVkZXJsYW5kZW4gT3JnYW5pc2F0aWUgUGVyc29vbiBDQSAtIEczMB4X
+DTIwMDQxNjE0MDUyMFoXDTIwMDUxNjE0MDUyMFowbDERMA8GA1UEDAwISHVpc2Fy
+dHMxEjAQBgNVBAUTCTAwMDA2NjYwMDEaMBgGA1UEAwwRSGVybWFudXMgQm9lcmhh
+dmUxGjAYBgNVBAoMEUhlcm1hbnVzIEJvZXJoYXZlMQswCQYDVQQGEwJOTDCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALs6G9LEt9nOBxjdyjD8nRH3mkDp
+oltjjMB9USuY2jHy5TTEzCwQW6ohJuN6s+TbwQYvJns+keJKWB5d2u7EtEuiND1O
+4QIkH2j044DYdeomcuZ3Tt56rptA9oJ2OGDvT0/PZOQlFzXcNkf+3Bo40Ppr372X
+dam/6eOZ928b+pfTmUDOyMPU40hyJimi+hxnLuPPYhQipIpkpGXtyA9r9qBuXqja
+I0Ramdi/+WuBch2NkvjWw36tMO4MREdF2cOxLXtiMMD5404bI68ugH6sJeg3pTWd
+9fMzmoD4TH0eR2u5Ayn70fGiYY9xCdLckRas2R4txC4BvUHVYimrhsc/yekCAwEA
+AaOCAvowggL2MAkGA1UdEwQCMAAwMQYDVR0lBCowKAYIKwYBBQUHAwEGCCsGAQUF
+BwMCBggrBgEFBQcDAwYIKwYBBQUHAwQwHQYDVR0OBBYEFJRP8jB2vCG/hWC52q3r
+wU7AIkbQMG0GA1UdIwRmMGShXqRcMFoxKzApBgNVBAMMIlN0YWF0IGRlciBOZWRl
+cmxhbmRlbiBSb290IENBIC0gRzMxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxh
+bmRlbjELMAkGA1UEBhMCTkyCAgPyMDcGCCsGAQUFBwEBBCswKTAnBggrBgEFBQcw
+AYYbaHR0cDovL29jc3AudXppLXJlZ2lzdGVyLm5sMFAGA1UdHwRJMEcwRaBDoEGG
+P2h0dHA6Ly93d3cudXppLXJlZ2lzdGVyLm5sL2NkcC91emktcmVnaXN0ZXJfem9y
+Z3ZlcmxlbmVyX2NhLmNybDCCASoGA1UdIASCASEwggEdMIIBGQYKYIQQAYdrAQIC
+AjCCAQkwNAYIKwYBBQUHAgEWKGh0dHBzOi8vd3d3LnV6aS1yZWdpc3Rlci5ubC9j
+cHMvY3BzLmh0bWwwgdAGCCsGAQUFBwICMIHDGoHASGV0IHRvZXBhc3NpbmdzZ2Vi
+aWVkIHZhbiBkaXQgY2VydGlmaWNhYXQgaXMgYmVwZXJrdCB0b3QgY29tbXVuaWNh
+dGllIGJpbm5lbiBoZXQgZG9tZWluIE92ZXJoZWlkIHpvYWxzIGFhbmdlZ2V2ZW4g
+aW4gaGV0IFByb2dyYW1tYSB2YW4gRWlzZW4gdmFuIGRlIFBLSSB2b29yIGRlIE92
+ZXJoZWlkLiBaaWUgd3d3LnBraW92ZXJoZWlkLm5sMFUGA1UdEQROMEygSgYDVQUF
+oEMWQTIuMTYuNTI4LjEuMTAwMy4xLjMuNS41LjItMS0wMDAwMDA2NjY2LVotMTIz
+NDU2NzgtMDEuMDE1LTEyMzQ1Njc4MBgGCCsGAQUFBwEDBAwwCjAIBgYEAI5GAQEw
+DQYJKoZIhvcNAQELBQADggEBACqw60ermDQAmqra5eaJS6RC6WPNzm28V1/CaBYd
+7TD6s+hdmjrxCXsXjQNBea4+f6Ig1usJOF/G1GR4znfBIWeB73ve5lZ19qwoJf2P
+OgajStG2qgWMGPuCbsDQVQDIDWVd99C1/iTq9te3Ljp9A8baWQMcDLGifkzRFnWU
+k+toRfZE5K4WmD+8GL7gp1We1egMuBvCO4z3uACcKWK5FKFSvLdhuOXf3jIe9T6+
+xo4RbfzLaF9EjgcGeXdZvDYfu6TZv/ZW6yh3vAtRlxhhymHsA19Bl70k1Im1Xkuy
+Um0W+wwXjUcRfiuXarWwbSZxOZZcSFjYQuiQlvUgWSEeiR0=
+-----END CERTIFICATE-----
index 145844013c553e49d305bf57223a3597386ec8b2..427c6b7fea1279b71a42650ff9b8330a53fbb56b 100644 (file)
@@ -16,7 +16,7 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/;
 
 setup("test_x509");
 
-plan tests => 10;
+plan tests => 11;
 
 require_ok(srctop_file('test','recipes','tconversion.pl'));
 
@@ -68,4 +68,20 @@ subtest 'x509 -- second x.509 v3 certificate' => sub {
 
 subtest 'x509 -- pathlen' => sub {
     ok(run(test(["v3ext", srctop_file("test/certs", "pathlen.pem")])));
+};
+
+subtest 'x500 -- subjectAltName' => sub {
+     my $fp = srctop_file("test/certs", "fake-gp.pem");
+     my $out = "ext.out";
+     ok(run(app(["openssl", "x509", "-text", "-in", $fp, "-out", $out])));
+     ok(has_doctor_id($out));
+     unlink $out;
+};
+
+sub has_doctor_id { 
+    $_ = shift @_;
+    open(DATA,$_) or return 0;
+    $_= join('',<DATA>); 
+    close(DATA);
+    return m/2.16.528.1.1003.1.3.5.5.2-1-0000006666-Z-12345678-01.015-12345678/;
 }