diff --git a/lib/pem.js b/lib/pem.js index 6237c2f0..aa4c7462 100644 --- a/lib/pem.js +++ b/lib/pem.js @@ -868,27 +868,41 @@ function checkPkcs12 (bufferOrPath, passphrase, callback) { * Verifies the signing chain of the passed certificate * @static * @param {String|Array} PEM encoded certificate include intermediate certificates - * @param {String|Array} List of CA certificates + * @param {String|Array} [List] of CA certificates * @param {Function} callback Callback function with an error object and a boolean valid */ function verifySigningChain (certificate, ca, callback) { + if (!callback && typeof ca === 'function') { + callback = ca + ca = undefined + } if (!Array.isArray(certificate)) { certificate = [certificate] } - if (!Array.isArray(ca)) { - ca = [ca] + if (!Array.isArray(ca) && ca !== undefined) { + if (ca !== '') { + ca = [ca] + } } - var files = [ - ca.join('\n'), - certificate.join('\n') - ] + var files = [] - var params = ['verify', - '-CAfile', - '--TMPFILE--', - '--TMPFILE--' - ] + if (ca !== undefined) { + // ca certificates + files.push(ca.join('\n')) + } + // certificate incl. intermediate certificates + files.push(certificate.join('\n')) + + var params = ['verify'] + + if (ca !== undefined) { + // ca certificates + params.push('-CAfile') + params.push('--TMPFILE--') + } + // certificate incl. intermediate certificates + params.push('--TMPFILE--') openssl.spawnWrapper(params, files, function (err, code, stdout) { if (err) { diff --git a/test/fixtures/google.com.pem b/test/fixtures/google.com.pem new file mode 100644 index 00000000..0d3c0955 --- /dev/null +++ b/test/fixtures/google.com.pem @@ -0,0 +1,68 @@ +-----BEGIN CERTIFICATE----- +MIIDwjCCAqqgAwIBAgIIMPfmgdxQ04QwDQYJKoZIhvcNAQELBQAwSTELMAkGA1UE +BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2dsZSBJbnRl +cm5ldCBBdXRob3JpdHkgRzIwHhcNMTcwOTI2MTA1OTAwWhcNMTcxMjE5MTA1OTAw +WjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwN +TW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UEAwwOd3d3 +Lmdvb2dsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQptqSsDzHdgCpE +2bLsaN1aKT/np0r/I2bQ2QZueQvOWKwaJD5Kt6s6HE1LUZ/omxTwacgT7HDWmj8f +bhMEZ45No4IBWDCCAVQwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAsG +A1UdDwQEAwIHgDAZBgNVHREEEjAQgg53d3cuZ29vZ2xlLmNvbTBoBggrBgEFBQcB +AQRcMFowKwYIKwYBBQUHMAKGH2h0dHA6Ly9wa2kuZ29vZ2xlLmNvbS9HSUFHMi5j +cnQwKwYIKwYBBQUHMAGGH2h0dHA6Ly9jbGllbnRzMS5nb29nbGUuY29tL29jc3Aw +HQYDVR0OBBYEFD1fAbfuUfW5VEUWBvJeq8hsdnzlMAwGA1UdEwEB/wQCMAAwHwYD +VR0jBBgwFoAUSt0GFhu89mi1dvWBtrtiGrpagS8wIQYDVR0gBBowGDAMBgorBgEE +AdZ5AgUBMAgGBmeBDAECAjAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdv +b2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQBEd6FLPzPDnVVS +HLBtKfb5Gv3rkLku4wy13QORTK1yU+c2cbWCiVXyU8rXUqWLeFfjNw5Z6/2vvNRF +SQ2G/isM+GdT42UI0cPxYV+oLfxcQU9pu2FnsIaq1mSu0ckIe7gFSXRnUZWOHMur +WkSP+4EwUZlXgK/h06fy3Ran1NmBglwWGF3MXAGgNeFeKSRtszn8pClOaWOmjNt8 +pzp6KfJIaZV0y1ss1I8x1XnR7EFbG+9vPQpsB2xhEPqyC78QoazaCS3y9AyFrpzb +Ig2jZRLdtq9bLhsEb1jSM3qIECCiPu0AwNLU+508PVyYXlvRTfwMVo1PfllWhiMP +Ub8Y7gCe +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEKDCCAxCgAwIBAgIQAQAhJYiw+lmnd+8Fe2Yn3zANBgkqhkiG9w0BAQsFADBC +MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMS +R2VvVHJ1c3QgR2xvYmFsIENBMB4XDTE3MDUyMjExMzIzN1oXDTE4MTIzMTIzNTk1 +OVowSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMT +HEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCcKgR3XNhQkToGo4Lg2FBIvIk/8RlwGohGfuCPxfGJziHu +Wv5hDbcyRImgdAtTT1WkzoJile7rWV/G4QWAEsRelD+8W0g49FP3JOb7kekVxM/0 +Uw30SvyfVN59vqBrb4fA0FAfKDADQNoIc1Fsf/86PKc3Bo69SxEE630k3ub5/DFx ++5TVYPMuSq9C0svqxGoassxT3RVLix/IGWEfzZ2oPmMrhDVpZYTIGcVGIvhTlb7j +gEoQxirsupcgEcc5mRAEoPBhepUljE5SdeK27QjKFPzOImqzTs9GA5eXA37Asd57 +r0Uzz7o+cbfe9CUlwg01iZ2d+w4ReYkeN8WvjnJpAgMBAAGjggERMIIBDTAfBgNV +HSMEGDAWgBTAephojYn7qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1 +dvWBtrtiGrpagS8wDgYDVR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggr +BgEFBQcwAYYSaHR0cDovL2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAw +NQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9i +YWwuY3JsMCEGA1UdIAQaMBgwDAYKKwYBBAHWeQIFATAIBgZngQwBAgIwHQYDVR0l +BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQDKSeWs +12Rkd1u+cfrP9B4jx5ppY1Rf60zWGSgjZGaOHMeHgGRfBIsmr5jfCnC8vBk97nsz +qX+99AXUcLsFJnnqmseYuQcZZTTMPOk/xQH6bwx+23pwXEz+LQDwyr4tjrSogPsB +E4jLnD/lu3fKOmc2887VJwJyQ6C9bgLxRwVxPgFZ6RGeGvOED4Cmong1L7bHon8X +fOGLVq7uZ4hRJzBgpWJSwzfVO+qFKgE4h6LPcK2kesnE58rF2rwjMvL+GMJ74N87 +L9TQEOaWTPtEtyFkDbkAlDASJodYmDkFOA/MgkgMCkdm7r+0X8T/cKjhf4t5K7hl +MqO5tzHpCvX2HzLc +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg +R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 +9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq +fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv +iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU +1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ +bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW +MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA +ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l +uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn +Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS +tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF +PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un +hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV +5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== +-----END CERTIFICATE----- diff --git a/test/pem.spec.js b/test/pem.spec.js index 15beea16..13e08f05 100644 --- a/test/pem.spec.js +++ b/test/pem.spec.js @@ -581,6 +581,14 @@ describe('General Tests', function () { }) }) }) + it('Verify google.com certificate without provided CA certificates', function (done) { + var certificate = fs.readFileSync('./test/fixtures/google.com.pem').toString() + pem.verifySigningChain(certificate, function (error, valid) { + hlp.checkError(error) + expect(valid).to.be.false() + done() + }) + }) it('Verify deep sigining chain', function (done) { pem.createCertificate({ commonName: 'Intermediate CA Certificate',