Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
crypto: add support for RSA public key signing/verification
Browse files Browse the repository at this point in the history
  • Loading branch information
bnoordhuis committed Nov 17, 2011
1 parent 3ac5f11 commit 9d3faf4
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 3 deletions.
22 changes: 19 additions & 3 deletions src/node_crypto.cc
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
15 changes: 15 additions & 0 deletions 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-----
5 changes: 5 additions & 0 deletions 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-----
23 changes: 23 additions & 0 deletions test/simple/test-crypto.js
Expand Up @@ -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) {
Expand Down

0 comments on commit 9d3faf4

Please sign in to comment.