diff --git a/src/node_crypto.cc b/src/node_crypto.cc index d0fcfc9a2a..d0d30964d1 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -54,8 +54,11 @@ return ThrowException(Exception::TypeError(String::New("Not a string or buffer"))); \ } -static const char *PUBLIC_KEY_PFX = "-----BEGIN PUBLIC KEY-----"; -static const int PUBLIC_KEY_PFX_LEN = strlen(PUBLIC_KEY_PFX); +static const char PUBLIC_KEY_PFX[] = "-----BEGIN PUBLIC KEY-----"; +static const int PUBLIC_KEY_PFX_LEN = sizeof(PUBLIC_KEY_PFX) - 1; + +static const char PUBRSA_KEY_PFX[] = "-----BEGIN RSA PUBLIC KEY-----"; +static const int PUBRSA_KEY_PFX_LEN = sizeof(PUBRSA_KEY_PFX) - 1; static const int X509_NAME_FLAGS = ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_ESC_MSB @@ -3304,13 +3307,26 @@ class Verify : public ObjectWrap { return 0; } - // Check if this is a PKCS#8 public key before trying as X.509 + // Check if this is a PKCS#8 or RSA public key before trying as X.509. + // Split this out into a separate function once we have more than one + // consumer of public keys. if (strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) { pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL); if (pkey == NULL) { ERR_print_errors_fp(stderr); return 0; } + } else if (strncmp(key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0) { + RSA* rsa = PEM_read_bio_RSAPublicKey(bp, NULL, NULL, NULL); + if (rsa) { + pkey = EVP_PKEY_new(); + if (pkey) EVP_PKEY_set1_RSA(pkey, rsa); + RSA_free(rsa); + } + if (pkey == NULL) { + ERR_print_errors_fp(stderr); + return 0; + } } else { // X.509 fallback x509 = PEM_read_bio_X509(bp, NULL, NULL, NULL); diff --git a/test/fixtures/test_rsa_privkey_2.pem b/test/fixtures/test_rsa_privkey_2.pem new file mode 100644 index 0000000000..092bd85b6b --- /dev/null +++ b/test/fixtures/test_rsa_privkey_2.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWQIBAAKBgQCsMgRdxxEeeXscPvqFzp/6/IIdoeKSlBn7361FWZwMQUG0qCbr +XYtdXPyqp2B4GThviIqiaJZITCTY87CiV7bFvH2lmUMJLsCc3BaQ4XFQbEU5D5jN +FfP7g78MEKbCb9rEfYMI2EGwbfKRUZUrYeBadzIMHEMEHDyiBXrCohTXMQIBIwKB +gHEoLsFITRQGr/yeah1qhmMa9ms+fvKb1o+S/NXNLAgNoDTjh0o2KGHspgm+cpgQ +kszzU8nPszbS86SC4cnEnKy/g3uw3Lf55a2P8vgh1P386/PzI+Im8s6E/EpDwn/P +R2E5gqTfePl8m7r9oeIARZXysmHHgBtEm5pTUav6QvOLAkEA2arx2R/3Yb6yZ5oO +3ldZEzCBNmB6mCoczrH6jjBosb4Gj7TK+asNlbinw1gj8sgdkzAw6jGnJ2IUfftm +QMykwQJBAMqFDclCf2b9cwi82+Xg+mjlT8BEf+l5xdRrweOyjB6DmUhgeqDISJUK +JgxGr4TxIQ6DGeEWxChGzzU6utlRnnECQDf4wdi/E7oMdwSylhvqkz9y32XBCZTX +oQHzQG20rTUE+l93oeht0EsSOcSEYQPqUL9yyr/g4dbtVbn+0SabBcsCQEs4u/pL +5i2RVpzYbu77yrk/OuEDf/eiQipT6O4sX+4Tn1VlqePynp3B8N/8/11DnpBclJVu +2yTnGcNQVAeTWBsCQFMekiY/KbwAgTopqpCUg5CLNph91FVW5PIntLmd5gSj8ZJS +uNuro8CURrOe8iiI3pG9m4KkbDdOBSOMADXJojE= +-----END RSA PRIVATE KEY----- diff --git a/test/fixtures/test_rsa_pubkey_2.pem b/test/fixtures/test_rsa_pubkey_2.pem new file mode 100644 index 0000000000..eafcf73e19 --- /dev/null +++ b/test/fixtures/test_rsa_pubkey_2.pem @@ -0,0 +1,5 @@ +-----BEGIN RSA PUBLIC KEY----- +MIGHAoGBAKwyBF3HER55exw++oXOn/r8gh2h4pKUGfvfrUVZnAxBQbSoJutdi11c +/KqnYHgZOG+IiqJolkhMJNjzsKJXtsW8faWZQwkuwJzcFpDhcVBsRTkPmM0V8/uD +vwwQpsJv2sR9gwjYQbBt8pFRlSth4Fp3MgwcQwQcPKIFesKiFNcxAgEj +-----END RSA PUBLIC KEY----- diff --git a/test/simple/test-crypto.js b/test/simple/test-crypto.js index 6b1c6ca020..621a8d10ca 100644 --- a/test/simple/test-crypto.js +++ b/test/simple/test-crypto.js @@ -394,6 +394,29 @@ assert.equal(rsaSignature, '5c50e3145c4e2497aadb0eabc83b342d0b0021ece0d4c4a064b7 rsaVerify.update(rsaPubPem); assert.strictEqual(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), true); +(function() { + var privateKey = fs.readFileSync( + common.fixturesDir + '/test_rsa_privkey_2.pem'); + + var publicKey = fs.readFileSync( + common.fixturesDir + '/test_rsa_pubkey_2.pem'); + + var input = 'I AM THE WALRUS'; + + var signature = '79d59d34f56d0e94aa6a3e306882b52ed4191f07521f25f505a078dc2f89396e0c8ac89e996fde5717f4cb89199d8fec249961fcb07b74cd3d2a4ffa235417b69618e4bcd76b97e29975b7ce862299410e1b522a328e44ac9bb28195e0268da7eda23d9825ac43c724e86ceeee0d0d4465678652ccaf65010ddfb299bedeb1ad'; + + var sign = crypto.createSign('RSA-SHA256'); + sign.update(input); + + var output = sign.sign(privateKey, 'hex'); + assert.equal(output, signature); + + var verify = crypto.createVerify('RSA-SHA256'); + verify.update(input); + + assert.strictEqual(verify.verify(publicKey, signature, 'hex'), true); +})(); + // Test PBKDF2 with RFC 6070 test vectors (except #4) crypto.pbkdf2('password', 'salt', 1, 20, function(err, result) {