diff --git a/X509.pm b/X509.pm index 2c17577..e12241e 100644 --- a/X509.pm +++ b/X509.pm @@ -114,7 +114,7 @@ sub Crypt::OpenSSL::X509::subjectaltname { my $ok = $asn->prepare(q< AnotherName ::= SEQUENCE { type OBJECT IDENTIFIER, - value [0] EXPLICIT ANY } --DEFINED BY type-id } + value [0] EXPLICIT ANY DEFINED BY type } EDIPartyName ::= SEQUENCE { nameAssigner [0] DirectoryString OPTIONAL, @@ -158,6 +158,7 @@ sub Crypt::OpenSSL::X509::subjectaltname { GeneralNames ::= SEQUENCE OF GeneralName GeneralName ::= CHOICE { + otherName [0] AnotherName, rfc822Name [1] IA5String, dNSName [2] IA5String, x400Address [3] ANY, --ORAddress, @@ -172,6 +173,16 @@ sub Crypt::OpenSSL::X509::subjectaltname { die '*** Could not prepare definition: '.$asn->error() if !$ok; + # Microsoft's User Principal Name (Smart Card Logon) + my $upn = Convert::ASN1->new or die( "New UPN" ); + $upn->prepare(q(UPN UTF8String)) or die ( "Prepare UPN" ); + $asn->registeroid( '1.3.6.1.4.1.311.20.2.3', $upn ); + + # RFC 4985 Service name + my $srv = Convert::ASN1->new or die( "New SRV" ); + $srv->prepare(q(SRVName IA5String)) or die ( "Prepare SRV" ); + $asn->registeroid( '1.3.6.1.5.5.7.8.7', $srv ); + # This is an important bit - if you don't do the find the decode # will randomly fail/succeed. This is required to work my $asn_node = $asn->find('SubjectAltName') @@ -180,6 +191,31 @@ sub Crypt::OpenSSL::X509::subjectaltname { my $san = $asn_node->decode($bin_data) or die 'Unable to decode SubjectAltName: '.$asn_node->error; + foreach my $name ( @$san ) { + foreach my $item (keys %$name) { + if( $item eq 'iPAddress' ) { + my $ip = $name->{$item}; + if( length $ip == 4 ) { + $name->{iPAddress} = sprintf( '%d.%d.%d.%d', unpack( 'C4', $ip ) ); + } elsif( length $ip == 16 ) { + $name->{iPAddress} = sprintf( '%x:%x:%x:%x:%x:%x:%x:%x', unpack( 'n8', $ip ) ); + } else { + $name->{iPAddress} = unpack( 'H*', $ip ); + } + } elsif ( $item eq 'otherName' ) { + my $otherName = $name->{otherName}; + if ( $otherName->{type} eq '1.3.6.1.4.1.311.20.2.3' || + $otherName->{type} eq '1.3.6.1.5.5.7.8.7' ) { + my $value; + foreach my $val (keys %{$otherName->{value}}) { + $value .= $val . "::" . $otherName->{value}{$val}; + } + $name->{otherName} = $value; + } + } + } + } + return $san; } diff --git a/certs/ipacert.pem b/certs/ipacert.pem new file mode 100644 index 0000000..c3612db --- /dev/null +++ b/certs/ipacert.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDAzCCAeugAwIBAgICA+gwDQYJKoZIhvcNAQELBQAwFjEUMBIGA1UEAwwLZXhh +bXBsZS5uZXQwHhcNMjQwNTE4MjI1NzM5WhcNMzQwNTE2MjI1NzM5WjAWMRQwEgYD +VQQDDAtleGFtcGxlLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ALMEHPyELA3raG9/ATjFGhl3iFX1no+Iko7TxW68O7PX083+g+jOPVLY7lDSExkz +y3ka2Y/lldRPdi0HoEDl1kTYXsC25zNrRIgePSNF4gsFqHKtJCxIf40M7o3Ic/i6 +ginVAi8pVDEXkag4i1Lna6ERA9ExU68M31klB1Dm9ZimodN3wC5hMlMS4jjM7hhc +SEXsxmTgBs57yBNIkUVgbOBpDJZs7ZZPlVPjyafQtJebiDfi/HUbFELA/KTWgSrn +s5WYPf5/Pjt30j0Hx5C+Po8g5C6z9Jk+aOe+SXt+S1XUa6bvLu0DvG964sjWtYqN +qI5MFJSpZrAzJt+5vHu/XRECAwEAAaNbMFkwDwYDVR0TBAgwBgEB/wIBADBGBgNV +HREEPzA9ggtleGFtcGxlLm5ldIcEwAAAAYcEwAAAAocQIAENuAEjAAAAAAAAAAAA +BIcQIAECuAEjAAAAAAAAAAAABTANBgkqhkiG9w0BAQsFAAOCAQEAYlbJosKKRi1E +m0As7w+LsZeOsFBvUuH62FJLMet3S/nbtXbqvjaiCcH+KOknwJ7dVby2OToEtmb9 +t5SuhuZuADNbjPM+QOO6E5Ti1pIz+3gluqhfumGbmLRSf1IaDaQg0u2JnRiEICP0 +w6q43ln6+0A+i92n/CfTiSwtWQi4QJC/V31S33t+fvZ5yHZpA+U7PjNjLUvGPOQ9 +jl4SM42jDQ/Ob46EeDPhS8CEG2SsgCtFuvn4EwOdoZ1VedJA4q2VfJUpew5KJton +8PkTA8407DhuwAXXzoGnczm8VNuxTEL11QrRKZe/t9v9sOjLIb4dmvmz665nzcPE +PFYLjo3fJQ== +-----END CERTIFICATE----- + diff --git a/certs/srvname.pem b/certs/srvname.pem new file mode 100644 index 0000000..d90cf34 --- /dev/null +++ b/certs/srvname.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDLTCCAhWgAwIBAgIUWCot9rNObq8LrwCy3zqVKM5LZNswDQYJKoZIhvcNAQEL +BQAwUzELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVRleGFzMQ8wDQYDVQQHDAZBdXN0 +aW4xEzARBgNVBAoMCk15IENvbXBhbnkxDjAMBgNVBAMMBU15IENBMB4XDTIxMDIy +MzExMjk0N1oXDTIxMDMyNTExMjk0N1owETEPMA0GA1UEAwwGZm9vYmFyMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0xNcCng0SCct0v53G0wUaH07augd +1CT/GDdvX53VNVsni4bFRu039vhD8JIx9ohhmbs2EhgoUsdH7PmX1i8wOuF9NbGr +HVCMd/gvwX03O8ecLHlwDFc4Do4rU84fi9c8PHiB9jaqmY7Mnn9xsoGi8trVyK6e +s9d7y8rD1Depgl3UkXuMUaNz3oLLcsj8ck2UPrtUa2kVn1Pqczs3PZKMO+R0+9BX +bv1MpFEK8SWVbMBmJZXc0qwrRrbzOlUFXtSTJW7C6UgrmdBSd8ll5d4V7RXiVsNm +tr2YcIGHDsjgOeyRaNLIm0C1K/VDh83AJGfoMUPx9JQPEFfA0rGhBxtKsQIDAQAB +ozswOTA3BgNVHREEMDAuggpkb21haW4ub3JnoCAGCCsGAQUFBwgHoBQWEl93ZWJh +cHAuZG9tYWluLm9yZzANBgkqhkiG9w0BAQsFAAOCAQEAHDWrfRtsYdO6r++MPMr9 +ECEWazsIhFz6vRKaifgnzymC3/U1tRilpKH1aJWB8x5JHMvHkwhaP/GsQI/AYYq/ +opznPvEbjnVTIF5NALXBi0HqT7xBVlColfFHZ/OQ9cs190kWWzHQZXzWevbgLMd6 +QFZMHF0Z575OA6jOROhpt3n+p94dYpnCXSZtZ9Su62OyFddGrGEnisTvDHuBlhmr +00/pPhu6Jt6Kk1zVeWp3AHtPT20iihQIbH+GZHkEmpRH3YcNikePefwnYHILsnpP +2+q8VbAFXsY8VbKisoU3g+sKc1E3dXkg509VAxjxRuAU0xdSJONvMyUL6zn544w5 +bQ== +-----END CERTIFICATE----- diff --git a/certs/upn-cert.pem b/certs/upn-cert.pem new file mode 100644 index 0000000..61e1d7d --- /dev/null +++ b/certs/upn-cert.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBoTCCAUagAwIBAgIRAIPqMfAzi3GkNeRTRJLFkkswCgYIKoZIzj0EAwIwHjEc +MBoGA1UEAwwTam9obkRvZUBleGFtcGxlLmNvbTAeFw0yNDA1MTcxODU3MDBaFw0y +NTA1MTcxODU3MDBaMB4xHDAaBgNVBAMME2pvaG5Eb2VAZXhhbXBsZS5jb20wWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAAT1L7LWhF85IOFgdxvSVqVhwypneowwJq+c +XR80zUhLJbAsd+EA6GZwhFmjNts3L9Vhpw7WfN6p5DCyQHyQa61ho2UwYzAOBgNV +HQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAu +BgNVHREEJzAloCMGCisGAQQBgjcUAgOgFQwTam9obkRvZUBleGFtcGxlLmNvbTAK +BggqhkjOPQQDAgNJADBGAiEAqUejaH3IJznnb/zLPoz0IzBcI380UEDP/EyGuKDg +o/0CIQDZgr6tAF/GAjCw7z/qzWpS0YfwlBAcoY4XLa0Yl2R0ag== +-----END CERTIFICATE----- diff --git a/t/san.t b/t/san.t index 2987d5c..c4c76d3 100644 --- a/t/san.t +++ b/t/san.t @@ -1,4 +1,4 @@ -use Test::More tests => 17; +use Test::More tests => 23; BEGIN { use_ok('Crypt::OpenSSL::X509') };