Skip Menu |

This queue is for tickets about the Crypt-PKCS10 CPAN distribution.

Report information
The Basics
Id: 110820
Status: resolved
Priority: 0/
Queue: Crypt-PKCS10

People
Owner: tlhackque [...] yahoo.com
Requestors: tlhackque [...] yahoo.com
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in:
  • 1.3
  • 1.0
  • 1.1
  • 1.2
Fixed in: 1.401-TRIAL



Subject: Fails to parse PEM. Other issues. With patch.
Thank you for creating this. I found & fixed several issues while exploring. I also removed trailing whitespace and did a small amount of code cleanup in the attached patch. I didn't bump the version. 1) PEM CSR's output by openssl start with the PUBLIC KEY block. There can be other data before (or after) the CSR in a file. new() doesn't expect this. The test for PEM input needs /ms rather than /s. 2) The access methods don't support repeated attributes. E.g. in the first test certificate below, the subject is /C=AU/ST=Some-State/L=my city/O=Internet Widgits Pty Ltd/OU=Big org/OU=Smaller org/CN=My Name/emailAddress=none@no-email.com Note that /OU occurs twice. Fix: if called in array context, return an array instead of the first item parsed. This should be compatible with most uses; however existing calls in array context may need to do one of: (scalar $decoded->functionName) or join( ', ', $decoded->functionName) 3) extensionValue crashes if given a certificate with no extensions, e.g. test 1 below. Fix: return undef in that case. Also, document extensionValue For these items, see the second CSR 4) the OID for serialNumber is 2.5.4.5; you have it as 2.5.4.12 Fix: change the hash entry 5) _convert_rdn doesn't handle multiple items. Here, unstructuredName is missed. Also doesn't handle multiple values. Fix: loop over the array and include all items. Also, simplify the code (push will autovivify the value array) 6) It is not possible to obtain the actual subject of the CSR. The order of components is lost by converting them to a hash. The order is significant: "/C=AU/CN=Fred" is NOT the same as "/CN=Fred/C=AU". Fix: Add the 'subject' access method. This returns a string of the form /countryName=AU/organizationalUnitName=Big org ... in scalar context, or an array of (name, [values]) pairs in array context. 7) A few useful OIDs were missing. Fix: Added. 8) domainComponent can crash if called when none are present. Fix: Return empty list in this case. 9) There is no way to determine if an extension is marked 'critical'. Fix: Add extensionPresent(name). Returns 1 if present, 2 if present and marked 'critical', undef otherwise. 10) attributes() can crash if none are present. Fix: Return empty list. 11) The module has no exports; it is not necessary to use Exporter. Fix: Remove dependency. 12) There are no access methods for many subject name components. Fix: Automatically generate them when present. (To see if a component name has a method, use $decoded->can('localityName') ). This approach avoids the hassle of creating a new patch every time some strange OID is encountered in a subject name. Use a similar approach to create the documented 'always present' subject access method. Test data: ====Example 1 Show quoted text
-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDO8GrRcQnEVSQkQzFLLl5Y/qIE 7bhXpuQaC0vvqBXHM5ALpdrl87JVwpwfSeeIEZDuJNTkiseKOJdtLMVWEIUP2ISy tUFxf3irt4QsrU9Xd2VG99NKq73GrEn0HwGCPBa/CHpLicqIgk2C0B1ns9CXwNKA YxVR1MMhWDJSFfz31QIDAQAB -----END PUBLIC KEY----- -----BEGIN CERTIFICATE REQUEST----- MIIB9DCCAV0CAQAwgbMxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRl MRAwDgYDVQQHDAdteSBjaXR5MSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0 eSBMdGQxEDAOBgNVBAsMB0JpZyBvcmcxFDASBgNVBAsMC1NtYWxsZXIgb3JnMRAw DgYDVQQDDAdNeSBOYW1lMSAwHgYJKoZIhvcNAQkBFhFub25lQG5vLWVtYWlsLmNv bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzvBq0XEJxFUkJEMxSy5eWP6i BO24V6bkGgtL76gVxzOQC6Xa5fOyVcKcH0nniBGQ7iTU5IrHijiXbSzFVhCFD9iE srVBcX94q7eELK1PV3dlRvfTSqu9xqxJ9B8BgjwWvwh6S4nKiIJNgtAdZ7PQl8DS gGMVUdTDIVgyUhX899UCAwEAAaAAMA0GCSqGSIb3DQEBBQUAA4GBAF0ulFJ0XAq2 +L2Y559GRB99G6OJHZG51Ze/MDN+ZKqrSw1CBV2qCxrspdhgtmzutIZliUClzaex s7NlOgbMnrPt6TVyi5Alsw0kb6ALbIjhkFOd6rzZqSZFekTgGu+PtUkZC5ogo8O4 E+Ob8iHsm6kgbmE2sxfCURxDMVn4FlCa -----END CERTIFICATE REQUEST----- ===Example 2
-----BEGIN CERTIFICATE REQUEST----- MIIDJzCCAg8CAQAwgcAxITAfBgkqhkiG9w0BCQEWEnNlY3VyaXR5QGxpdHRzLm5l dDEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czELMAkGA1UEBhMCVVMxGjAYBgNVBAMT EXBpY28uc2IubGl0dHMubmV0MRAwDgYDVQQLEwdSb3V0ZXJzMRIwEAYDVQQKEwls aXR0cy5uZXQxNDASBgNVBAUTC0ZUWDE1NTI4MFFYMB4GCSqGSIb3DQEJAhYRcGlj by5zYi5saXR0cy5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV r5YvIb2n1+jws8ntmeMRtC/ZjxMke2G4moIWioj/Cxhy9bj7fieNyEGfg712CBmh btxBTuTZvVbFZK66W3NlugbHnbGH0LvfrIjgHIkEovwd2v34XJgFE3ETM8AZb79+ NqUr2m+uy+ukL97WctOlgW+RcE/CSHDp+S2YBlM/K8tdOQWJ4d7RB/wCaQp+Ad4c fpWDrOZPawYEu6Saxc7Q3WxjXpUdj+qyY3t2ELcxwkgZy1PALH0KddqMQkLQfH+0 v4aIFGc23egJutDm+6PBVZQ+ShDPbkS7RSs4IXtbZvu7bHaf7pOqQt/QS0fWwBn5 zYvGaX+1+OJRrbb4t+aVAgMBAAGgITAfBgkqhkiG9w0BCQ4xEjAQMA4GA1UdDwEB /wQEAwIFoDANBgkqhkiG9w0BAQQFAAOCAQEAJV/s65GMJkhN40dNU4cm7Gx8fD/l +xyatoIcrFVafiSmCNnwiLqyxhFWGesx5vBiKVJNR0Mn7rWC/aBZp/jifI7sLMxW +AeYtULI3TYTs5Q1QOcap4tlQMsxExMmSAADfn/zZUomNnHLt8/ctGtGLyTm9pyq rI8exr1e8fYxica569Zd1d0A3i1YtUPMvYpFCQaT4WUi3EKTHE14zqKH/4eMnK6g iJaMVNtdzH5KaBhNK8Ua6vlcBRAMKY+ynH3APK28QnUu/x+4WrCFFs95UhslmFBn b5jb9VDmLCqcbwagLhCXLwQfDr5JhCcLMGESJ9omWpA3XWWdhdsVcig5Pg== -----END CERTIFICATE REQUEST----- Test program (use perl -d <test.csr) #!/usr/bin/perl use warnings; use strict; use Crypt::PKCS10; use Data::Dumper; $Data::Dumper::Sortkeys = 1; my $pem; { local $/; $pem = <>; } my $csr = Crypt::PKCS10->new($pem); print Dumper($csr->subject, $csr->organizationalUnitName, (scalar $csr->organizationalUnitName )); print scalar $csr->subject, "\n"; print (scalar $csr->serialNumber, "\n") if( $csr->can('serialNumber'); Testing done under perl 5.8.8.
Subject: PKCS10_patch_1.patch

Message body is not shown because it is too large.

Subject: Updated patch: add ability to extract CSR
From: tlhackque [...] yahoo.com
I've also found it useful to be able to extract the binary CSR. For example, Crypt::PKCS10 will (now) find the PEM anywhere in a text file. And it also will remove any bits in the binary that extend beyond the ASN.1 structure. It's useful to be able to put that into OpenSSL for debugging, or to archive the bits. The attached updated patch adds the csrRequest method, which supports extracting the CSR as either PEM or binary.
Subject: PKCS10_patch_2.patch

Message body is not shown because it is too large.

Subject: Add extract public key for other tools
From: tlhackque [...] yahoo.com
Sorry about the string of changes, but here's one more version of the patch (includes all previous). It's useful to be able to extract the public key as a PEM string, which other tools expect. So this version of the patch adds a $format parameter to subjectPublicKey() to do that. With this change, it's possible to parse a CSR with Crypt::PKCS10 and generate a signed certificate using Crypt::OpenSSL::CA. Here's a simple example: #!/usr/bin/perl use warnings; use strict; use Crypt::PKCS10; use Crypt::OpenSSL::CA; use MIME::Base64; my $pem; { local $/; $pem = <>; } my $csr = Crypt::PKCS10->new($pem); # Validate the signature on the CSR & get the public key eval { my $crt = Crypt::OpenSSL::CA::PublicKey->validate_PKCS10( $csr->csrRequest(1) ); }; if( $@ ) { print "CSR validation failed: $@\n"; exit; } # If you don't want to validate, just get the public key: # $crt = Crypt::OpenSSL::CA::X509->new( Crypt::OpenSSL::CA::PublicKey->parse_RSA( $csr->subjectPublicKey(1) ) ); # Add the necessary stuff to the certificate. # Reformat the subject's DN to suit the CA my @dn = $csr->subject; my @subj = (); while( @dn ) { push @subj, shift @dn; push @subj, join( ",", @{shift @dn} ); } my $dn = Crypt::OpenSSL::CA::X509_NAME->new( @subj ); $crt->set_serial( "0x1"); $crt->set_subject_DN( $dn ); $crt->set_issuer_DN( $dn ); # self-signed $crt->set_extension("basicConstraints", "CA:FALSE", -critical => 1 ); my $privkey = Crypt::OpenSSL::CA::PrivateKey->parse( << "_KEY" ); Show quoted text
-----BEGIN PRIVATE KEY----- MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAMkWdxqw1pd+Jakt 6oyZASeXF+k6ysCRilPHDJjXZNalinIHMzU82RYepYN1h03OX1qaypc5+jtEHEQ2 f0LlOJ/BIDSjEqlKaYxgdGarbsSqVYAnVdb8TWBhyDxD4DBpZXFiIvZnKo7ggEIf eqOwHaUUD4p8+BWI0T0ucbkQFChHAgMBAAECgYAaQvvVGYk9CbWDbcK3D/htojb2 N75o/djx7goAIAlEWyRElhoi9spnMCNvkrbT+4LKg3K341OBz/hdFDz0kJkfUHVe a3xPV6txwV9ww85gWqdDBJGym5xOx3b1gB911k/XgL1THEnnN6Levg9kAcd/NGZ8 /Dw38lQwdQnLyVxWEQJBAPu0Xmg+xgV8BhBA8mUaj2qydGFhjB2CEnkWgRILp2ZI gQCIK9XBjF/7fkZLzQ7mpSxTc4RC95oXYeP+SPMezskCQQDMhPcD+xM3NJusrU22 m2ObtiNv6V64qVCbkGmY/bj2+qrpq6o/L+V5INMDzQArcadYPE1yKoIlCd9SZkC7 HnaPAkB7/8malYI8ZXMfQr+na0RIDg4jg0jhqJitKpb/atpXG1TiDDN8JNOg3WbB /snQk3O/uITqHYuZT/ebuEP78atxAkA6jM5Su2xS36K5mpum7XFkwI4AmeTeJMrI 3lz8yZZMTpLjdpu0nzeop7cBXYzw4wavggQB7R15EQx4AIIDj8MNAkBMq5LvocI2 5XKAKB77uscP/Haocx2dnd1ZGZNyGqvRun/3Xzj3s4ryUGx1SytadPFSO7vMQh8h xx6iORYrEee5 -----END PRIVATE KEY----- _KEY my $signed = $crt->sign( $privkey, "sha1" ); print $signed;
Subject: PKCS10_patch_3.patch

Message body is not shown because it is too large.

Subject: See git pull request for latest patch
From: tlhackque [...] yahoo.com
I noticed that you have a git repo, so I generated a pull request there. 4th change is minor correction. Thanks. @@ -123,7 +123,7 @@ sub new { my $substr = substr( $der, 0, unpack("n*", substr($der, 2, 2)) + 4 ); no bytes; - my $self = { _der => $der }; + my $self = { _der => $substr }; bless( $self, $class ); my $top =
Subject: Allow users to register OIDs
From: tlhackque [...] yahoo.com
Another pull request on github implements the ability for users to register custom OIDs (or those not yet added to this module). Cleaned up implementation of domainComponent(). Not bothering to duplicate the patch here. Thanks for the support.
Subject: /UID missing in subject
From: tlhackque [...] yahoo.com
UID is not recognized in an RDN. Interestingly, the CSR used by the tests includes /UID=123456: /DC=org/DC=OpenSSL/DC=users/CN=test/UID=123456/emailAddress=test@test.com But it was never accessible or verified. Fix: Add the OID to the known OIDs hash. As usual, an accessor for UID will materialize if UID is present in an RDN. Add a test for the full subject to the tests. Code is in current pull request.
Subject: Fixed in the next release
These will be fixed in the next release.
Incorporated/fixed in V1.4_01.