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.