Archived

This forum has been archived. Please start a new discussion on GitHub.

IceSSL: getSubjectAlternativeNames() doesn't work

I have a self signed certificate that has subject alternative names in it. Example:

Certificate:
Data:
Version: 3 (0x2)
Serial Number: 699767278 (0x29b599ee)
Signature Algorithm: sha256WithRSAEncryption
Issuer: O = HP ZCentral Remote Boost, CN = test
Validity
Not Before: Mar 25 20:07:26 2021 GMT
Not After : Mar 25 20:07:26 2022 GMT
Subject: O = HP ZCentral Remote Boost, CN = test
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
...
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:host1,DNS:host2
...

The cert is loaded in an IceSSL::Certificate. When I call getSubjectAlternativeNames(), nothing is returned.
If I use the approach of getX509Extension(oid) followed by getData(), it works, but the data is in raw format and not nicely parsed into a vector of values.

Why doesn't getSubjectAlternativeNames() work? Is it indended for a different type of format in the certificate?

Thanks!

Comments

  • xdm
    xdm La Coruña, Spain

    Hi Jeremy,

    I was doing some testing trying to reproduce this issue but getSubjectAlternativeNames seems to be working fine, you can see my tests in https://github.com/zeroc-ice/ice/compare/3.7...pepone:getsubjectalternativenames?expand=1

    Maybe you can provide a certificate that we can use to reproduce the issue? what platform are you using for your tests?

    Cheers,
    Jose

  • HI Jose,
    We are using Windows 10.
    I've attached a self-signed cert that we are using. I'm wondering if it's not formatted as expected?
    Thanks
    Jeremy

  • xdm
    xdm La Coruña, Spain

    Hi Jeremy,

    I took a look at your certificate and seems to me there is something wrong with the encoding of the subject alt names.

    Checking your certificate with ASN.1 decoder I see something like

          SEQUENCE (1 elem)
            SEQUENCE (2 elem)
              OBJECT IDENTIFIER 2.5.29.17 subjectAltName (X.509 extension)
              OCTET STRING (15 byte) DNS:z2rgssender
    

    This doesn't seem correct, alt names should contain a sequence of GeneralName entries each with a type-id and value see for example. If you inspect the certificates used with Ice testing you will see something like:

            SEQUENCE (2 elem)
              OBJECT IDENTIFIER 2.5.29.17 subjectAltName (X.509 extension)
              OCTET STRING (19 byte) 301187047F00000182096C6F63616C686F7374
                SEQUENCE (2 elem)
                  [7] (4 byte) 7F000001
                  [2] (9 byte) localhost
    

    Where 7 correspond to the IPAddress type-id, and 2 to the DNSName type-id.

    How are you generating the certificate?

    I also find it odd that your certificate only include the alt names extension, if you check the test certificates provided with Ice there are a few other extensions that seems missing from your certificate

    X509v3 extensions:
        X509v3 Subject Key Identifier: 
            7D:C7:82:1C:3A:BA:C2:00:7C:84:AD:DF:EA:10:A2:E4:AB:81:4A:F1
        X509v3 Authority Key Identifier: 
            keyid:EC:EE:9B:CD:E6:30:20:18:79:95:BB:01:D8:54:AC:F0:3B:9D:3E:AF
            DirName:/CN=Ice Tests CA/OU=Ice/O=ZeroC, Inc./L=Jupiter/ST=Florida/C=US/emailAddress=info@zeroc.com
            serial:B3:98:0A:EB:6B:F0:4B:D4
    
        X509v3 Key Usage: 
            Digital Signature, Non Repudiation, Key Encipherment
        X509v3 Subject Alternative Name: 
            IP Address:127.0.0.1, DNS:localhost
        X509v3 Extended Key Usage: 
            TLS Web Server Authentication, TLS Web Client Authentication
    
  • Hi Jose,

    We are using OpenSSL C++ libraries to create our own self signed certs. I struggled to find example code to add SAN to our cert. I found a code sample online, and it sounds like it might be incorrect:

    if ( !subjectAltName.empty( ) )
    {
        X509_EXTENSION *extensionSAN = nullptr;
        ASN1_OCTET_STRING *subjectAltNameAsn1 = nullptr;
        subjectAltNameAsn1 = ASN1_OCTET_STRING_new( );
        if ( !subjectAltNameAsn1 )
        {
            LOG_ERROR( " generateCertificate: failed during SAN extension creation" );
            return false;
        }
        ASN1_OCTET_STRING_set( subjectAltNameAsn1, (const unsigned char *) (subjectAltName.c_str( )), static_cast<int>(subjectAltName.length( )) );
        if ( !X509_EXTENSION_create_by_NID( &extensionSAN, NID_subject_alt_name, 0, subjectAltNameAsn1 ) )
        {
            LOG_ERROR( " generateCertificate: failed during SAN extension creation" );
            return false;
        }
    
        ASN1_OCTET_STRING_free( subjectAltNameAsn1 );
        if ( !X509_add_ext( x509.get( ), extensionSAN, -1 ) )
        {
            LOG_ERROR( " generateCertificate: failed to add SAN extension to cert" );
            return false;
        }
    
        // The certificate can be signed with different algorithms. EVP_md5 and EVP_sha256
        // have been used. The default when creating a certificate with openssl is sha256.
        if ( X509_sign( x509.get( ), evpKey.get( ), EVP_sha256( ) ) == 0 )
        {
            LOG_ERROR( "generateCertificate: failed to sign certificate" );
            return false;
        }
    }
    

    I can certainly experiment with this some more, unless you had a suggestion.

    As to the other fields you mentioned, we don't need them. The self signed cert is something we create on one end of our connect (the host system), and then is presented to the client system when a connection is made. We then have a custom certificate verifier that will parse the fields that we need. The reason us adding the SAN information to this cert was to provide more options than just what's in the CN.

    Thanks
    Jeremy

  • xdm
    xdm La Coruña, Spain

    Hi Jeremy,

    I'm not very familiar with the OpenSSL API for creating the certificates, I found this comment that might point you in the right direction

    https://github.com/openssl/openssl/issues/11706#issuecomment-633180151

  • Hi Jose,
    That code helped me fix it!! Thanks so much. All is good now, much appreciated.
    -Jeremy