src: accept passphrase when crypto signing with private key
Previous behaviour was to drop to an openssl prompt ("Enter PEM pass phrase:") when supplying a private key with a passphrase. This change adds a fourth, optional, paramter that will be used as the passphrase. To include this parameter in a backwards compatible way it was necessary to expose the previously undocumented (and unexposed) feature of being able to explitly setting the output encoding.
This commit is contained in:
parent
8130744044
commit
f755ecf484
@ -290,8 +290,15 @@ with new data as it is streamed.
|
|||||||
### sign.sign(private_key, [output_format])
|
### sign.sign(private_key, [output_format])
|
||||||
|
|
||||||
Calculates the signature on all the updated data passed through the
|
Calculates the signature on all the updated data passed through the
|
||||||
sign. `private_key` is a string containing the PEM encoded private
|
sign.
|
||||||
key for signing.
|
|
||||||
|
`private_key` can be an object or a string. If `private_key` is a string, it is
|
||||||
|
treated as the key with no passphrase.
|
||||||
|
|
||||||
|
`private_key`:
|
||||||
|
|
||||||
|
* `key` : A string holding the PEM encoded private key
|
||||||
|
* `passphrase` : A string of passphrase for the private key
|
||||||
|
|
||||||
Returns the signature in `output_format` which can be `'binary'`,
|
Returns the signature in `output_format` which can be `'binary'`,
|
||||||
`'hex'` or `'base64'`. If no encoding is provided, then a buffer is
|
`'hex'` or `'base64'`. If no encoding is provided, then a buffer is
|
||||||
|
@ -382,10 +382,15 @@ Sign.prototype._write = function(chunk, encoding, callback) {
|
|||||||
|
|
||||||
Sign.prototype.update = Hash.prototype.update;
|
Sign.prototype.update = Hash.prototype.update;
|
||||||
|
|
||||||
Sign.prototype.sign = function(key, encoding) {
|
Sign.prototype.sign = function(options, encoding) {
|
||||||
encoding = encoding || exports.DEFAULT_ENCODING;
|
if (!options)
|
||||||
var ret = this._binding.sign(toBuf(key));
|
throw new Error('No key provided to sign');
|
||||||
|
|
||||||
|
var key = options.key || options;
|
||||||
|
var passphrase = options.passphrase || null;
|
||||||
|
var ret = this._binding.sign(toBuf(key), null, passphrase);
|
||||||
|
|
||||||
|
encoding = encoding || exports.DEFAULT_ENCODING;
|
||||||
if (encoding && encoding !== 'buffer')
|
if (encoding && encoding !== 'buffer')
|
||||||
ret = ret.toString(encoding);
|
ret = ret.toString(encoding);
|
||||||
|
|
||||||
|
@ -164,6 +164,19 @@ static void crypto_lock_cb(int mode, int n, const char* file, int line) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int CryptoPemCallback(char *buf, int size, int rwflag, void *u) {
|
||||||
|
if (u) {
|
||||||
|
size_t buflen = static_cast<size_t>(size);
|
||||||
|
size_t len = strlen(static_cast<const char*>(u));
|
||||||
|
len = len > buflen ? buflen : len;
|
||||||
|
memcpy(buf, u, len);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ThrowCryptoErrorHelper(unsigned long err, bool is_type_error) {
|
void ThrowCryptoErrorHelper(unsigned long err, bool is_type_error) {
|
||||||
HandleScope scope(node_isolate);
|
HandleScope scope(node_isolate);
|
||||||
char errmsg[128];
|
char errmsg[128];
|
||||||
@ -342,7 +355,7 @@ static X509* LoadX509(Handle<Value> v) {
|
|||||||
if (!bio)
|
if (!bio)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
X509 * x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
|
X509 * x509 = PEM_read_bio_X509(bio, NULL, CryptoPemCallback, NULL);
|
||||||
if (!x509) {
|
if (!x509) {
|
||||||
BIO_free_all(bio);
|
BIO_free_all(bio);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -372,7 +385,9 @@ void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
String::Utf8Value passphrase(args[1]);
|
String::Utf8Value passphrase(args[1]);
|
||||||
|
|
||||||
EVP_PKEY* key = PEM_read_bio_PrivateKey(bio, NULL, NULL,
|
EVP_PKEY* key = PEM_read_bio_PrivateKey(bio,
|
||||||
|
NULL,
|
||||||
|
CryptoPemCallback,
|
||||||
len == 1 ? NULL : *passphrase);
|
len == 1 ? NULL : *passphrase);
|
||||||
|
|
||||||
if (!key) {
|
if (!key) {
|
||||||
@ -399,7 +414,7 @@ int SSL_CTX_use_certificate_chain(SSL_CTX *ctx, BIO *in) {
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
X509 *x = NULL;
|
X509 *x = NULL;
|
||||||
|
|
||||||
x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
|
x = PEM_read_bio_X509_AUX(in, NULL, CryptoPemCallback, NULL);
|
||||||
|
|
||||||
if (x == NULL) {
|
if (x == NULL) {
|
||||||
SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
|
SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
|
||||||
@ -425,7 +440,7 @@ int SSL_CTX_use_certificate_chain(SSL_CTX *ctx, BIO *in) {
|
|||||||
ctx->extra_certs = NULL;
|
ctx->extra_certs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
|
while ((ca = PEM_read_bio_X509(in, NULL, CryptoPemCallback, NULL))) {
|
||||||
r = SSL_CTX_add_extra_chain_cert(ctx, ca);
|
r = SSL_CTX_add_extra_chain_cert(ctx, ca);
|
||||||
|
|
||||||
if (!r) {
|
if (!r) {
|
||||||
@ -530,7 +545,7 @@ void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) {
|
|||||||
if (!bio)
|
if (!bio)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
X509_CRL *x509 = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
|
X509_CRL *x509 = PEM_read_bio_X509_CRL(bio, NULL, CryptoPemCallback, NULL);
|
||||||
|
|
||||||
if (x509 == NULL) {
|
if (x509 == NULL) {
|
||||||
BIO_free_all(bio);
|
BIO_free_all(bio);
|
||||||
@ -564,7 +579,7 @@ void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
X509 *x509 = PEM_read_bio_X509(bp, NULL, NULL, NULL);
|
X509 *x509 = PEM_read_bio_X509(bp, NULL, CryptoPemCallback, NULL);
|
||||||
|
|
||||||
if (x509 == NULL) {
|
if (x509 == NULL) {
|
||||||
BIO_free_all(bp);
|
BIO_free_all(bp);
|
||||||
@ -2634,28 +2649,57 @@ void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Sign::SignFinal(unsigned char** md_value,
|
bool Sign::SignFinal(const char* key_pem,
|
||||||
unsigned int *md_len,
|
int key_pem_len,
|
||||||
const char* key_pem,
|
const char* passphrase,
|
||||||
int key_pem_len) {
|
unsigned char** sig,
|
||||||
if (!initialised_)
|
unsigned int *sig_len) {
|
||||||
|
if (!initialised_) {
|
||||||
|
ThrowError("Sign not initalised");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
BIO* bp = NULL;
|
BIO* bp = NULL;
|
||||||
EVP_PKEY* pkey = NULL;
|
EVP_PKEY* pkey = NULL;
|
||||||
|
bool fatal = true;
|
||||||
|
|
||||||
bp = BIO_new(BIO_s_mem());
|
bp = BIO_new(BIO_s_mem());
|
||||||
|
if (bp == NULL)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
if (!BIO_write(bp, key_pem, key_pem_len))
|
if (!BIO_write(bp, key_pem, key_pem_len))
|
||||||
return false;
|
goto exit;
|
||||||
|
|
||||||
pkey = PEM_read_bio_PrivateKey(bp, NULL, NULL, NULL);
|
pkey = PEM_read_bio_PrivateKey(bp,
|
||||||
|
NULL,
|
||||||
|
CryptoPemCallback,
|
||||||
|
const_cast<char*>(passphrase));
|
||||||
if (pkey == NULL)
|
if (pkey == NULL)
|
||||||
return 0;
|
goto exit;
|
||||||
|
|
||||||
|
if (EVP_SignFinal(&mdctx_, *sig, sig_len, pkey))
|
||||||
|
fatal = false;
|
||||||
|
|
||||||
EVP_SignFinal(&mdctx_, *md_value, md_len, pkey);
|
|
||||||
EVP_MD_CTX_cleanup(&mdctx_);
|
|
||||||
initialised_ = false;
|
initialised_ = false;
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
BIO_free_all(bp);
|
exit:
|
||||||
|
if (pkey != NULL)
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
|
if (bp != NULL)
|
||||||
|
BIO_free_all(bp);
|
||||||
|
|
||||||
|
EVP_MD_CTX_cleanup(&mdctx_);
|
||||||
|
|
||||||
|
if (fatal) {
|
||||||
|
unsigned long err = ERR_get_error();
|
||||||
|
if (err) {
|
||||||
|
ThrowCryptoError(err);
|
||||||
|
} else {
|
||||||
|
ThrowError("PEM_read_bio_PrivateKey");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2668,19 +2712,26 @@ void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
|
|||||||
unsigned char* md_value;
|
unsigned char* md_value;
|
||||||
unsigned int md_len;
|
unsigned int md_len;
|
||||||
|
|
||||||
|
unsigned int len = args.Length();
|
||||||
enum encoding encoding = BUFFER;
|
enum encoding encoding = BUFFER;
|
||||||
if (args.Length() >= 2) {
|
if (len >= 2 && args[1]->IsString()) {
|
||||||
encoding = ParseEncoding(args[1]->ToString(), BUFFER);
|
encoding = ParseEncoding(args[1]->ToString(), BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String::Utf8Value passphrase(args[2]);
|
||||||
|
|
||||||
ASSERT_IS_BUFFER(args[0]);
|
ASSERT_IS_BUFFER(args[0]);
|
||||||
ssize_t len = Buffer::Length(args[0]);
|
size_t buf_len = Buffer::Length(args[0]);
|
||||||
char* buf = Buffer::Data(args[0]);
|
char* buf = Buffer::Data(args[0]);
|
||||||
|
|
||||||
md_len = 8192; // Maximum key size is 8192 bits
|
md_len = 8192; // Maximum key size is 8192 bits
|
||||||
md_value = new unsigned char[md_len];
|
md_value = new unsigned char[md_len];
|
||||||
|
|
||||||
bool r = sign->SignFinal(&md_value, &md_len, buf, len);
|
bool r = sign->SignFinal(buf,
|
||||||
|
buf_len,
|
||||||
|
len >= 3 && !args[2]->IsNull() ? *passphrase : NULL,
|
||||||
|
&md_value,
|
||||||
|
&md_len);
|
||||||
if (!r) {
|
if (!r) {
|
||||||
delete[] md_value;
|
delete[] md_value;
|
||||||
md_value = NULL;
|
md_value = NULL;
|
||||||
@ -2811,11 +2862,11 @@ bool Verify::VerifyFinal(const char* key_pem,
|
|||||||
// Split this out into a separate function once we have more than one
|
// Split this out into a separate function once we have more than one
|
||||||
// consumer of public keys.
|
// consumer of public keys.
|
||||||
if (strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) {
|
if (strncmp(key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0) {
|
||||||
pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL);
|
pkey = PEM_read_bio_PUBKEY(bp, NULL, CryptoPemCallback, NULL);
|
||||||
if (pkey == NULL)
|
if (pkey == NULL)
|
||||||
goto exit;
|
goto exit;
|
||||||
} else if (strncmp(key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0) {
|
} else if (strncmp(key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0) {
|
||||||
RSA* rsa = PEM_read_bio_RSAPublicKey(bp, NULL, NULL, NULL);
|
RSA* rsa = PEM_read_bio_RSAPublicKey(bp, NULL, CryptoPemCallback, NULL);
|
||||||
if (rsa) {
|
if (rsa) {
|
||||||
pkey = EVP_PKEY_new();
|
pkey = EVP_PKEY_new();
|
||||||
if (pkey)
|
if (pkey)
|
||||||
@ -2826,7 +2877,7 @@ bool Verify::VerifyFinal(const char* key_pem,
|
|||||||
goto exit;
|
goto exit;
|
||||||
} else {
|
} else {
|
||||||
// X.509 fallback
|
// X.509 fallback
|
||||||
x509 = PEM_read_bio_X509(bp, NULL, NULL, NULL);
|
x509 = PEM_read_bio_X509(bp, NULL, CryptoPemCallback, NULL);
|
||||||
if (x509 == NULL)
|
if (x509 == NULL)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
@ -434,10 +434,11 @@ class Sign : public WeakObject {
|
|||||||
|
|
||||||
void SignInit(const char* sign_type);
|
void SignInit(const char* sign_type);
|
||||||
bool SignUpdate(const char* data, int len);
|
bool SignUpdate(const char* data, int len);
|
||||||
bool SignFinal(unsigned char** md_value,
|
bool SignFinal(const char* key_pem,
|
||||||
unsigned int *md_len,
|
int key_pem_len,
|
||||||
const char* key_pem,
|
const char* passphrase,
|
||||||
int key_pem_len);
|
unsigned char** sig,
|
||||||
|
unsigned int *sig_len);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
|
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
|
23
test/fixtures/test_dsa_privkey_encrypted.pem
vendored
Normal file
23
test/fixtures/test_dsa_privkey_encrypted.pem
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
-----BEGIN DSA PRIVATE KEY-----
|
||||||
|
Proc-Type: 4,ENCRYPTED
|
||||||
|
DEK-Info: AES-128-CBC,2E8DE7F5BD338C4118488E8D640FC695
|
||||||
|
|
||||||
|
7jnL7kBITpnfjHc4DiRF+9d0M9QKdQmiL9N7Bj52XC+L0jZTwfNld3xi6fQ1GNle
|
||||||
|
RKrrgSgEYXxf+RJ9Nz/BOttYWnIyAWSswFIjm1vGjpoYTH6H/wFg1QSoZUfINO2I
|
||||||
|
3p4Y+cYVWOgSAYegzT5sdWTKDJrRUUfYFThmdQk0uO3s8B7urQuVlEtHr02OuPAj
|
||||||
|
hRiWaBtxkttBWA+x8dgpgAbjHlZIWv1fj0EAKaaVehaNzEyK+nyS1a816ssDV3t8
|
||||||
|
YMOZdCdKgzbBr5T3Zf83hdzpmhagBNZve1P0kJEgGdydiRWSyTxotOt5AGsRSvza
|
||||||
|
A9PVk8V/U6U1B18hACxGV4wiKCMQDAsHfo+BrVoZBvVBlpW4dfcsIEtQqwu18x2b
|
||||||
|
wIW5Qc2zXFFL6P+eqfdZ0ZRdfsClX6/GYOO5Z4oy8iAQSuD1UdaG6Psy84U7LU8g
|
||||||
|
++OcbEcw8UnKjKVJU+zBC4QmhxUSUiOQwcgeFQuMIEMtprUKztgm/oPClAMTY/pm
|
||||||
|
FGxLZS59owVWkrN9Oc4ccw+6Zt6mDxH9cnHv+nkGlcK9pcD+gU1MVXUfuby+DNbI
|
||||||
|
4iYqUoYZdb9gpWQ/VrXMX63NydXzE+vMB9BxOlgfw3b6BrFCUAuyH1FiIAlGeAjP
|
||||||
|
LZa06WiOayeu6Lm8rzeu/Cjbe1pYzK9cyX3JxSGJxipPeO4URZ5+hyqBMyCCCUq8
|
||||||
|
EVFcfwgkdQaeVeBUdxJyRXfuBQmlgJF0Ixlkw29StpI2dAbNrtcSAIwbsxDInK4b
|
||||||
|
6ItdadW+0nCRAxdVbGt6oQIPqpjbmtVkqj+m1yAic1xYc7Kd2xngGdtOMefKefcw
|
||||||
|
+7d7E82ljPycHDG2SNENsFV9TNENdNlaP1A1HQy+f/1YkLZHfNLQrUf1+BRR7oHI
|
||||||
|
N0ACLF6jgZ9MFelB64774veUTLvcrmYKIX7TnV25kw28ZIQ8StmIt9YJ+Mq+x6DC
|
||||||
|
32JbRBbwbHm598fCrfr471xw/SM1/OnPefVhJSQ6223IfjuSWG0Snvjo7mHbaduz
|
||||||
|
xWW6ApT7/iilanZs8uKBuPaEtwu3CmJcdgj0tTUuXb5ivY3M0dD/ZLSQliqb49iU
|
||||||
|
64LX0/kRvkUZ6nJqPA4nlKPfGebo6H0V4oX7XF/gm74=
|
||||||
|
-----END DSA PRIVATE KEY-----
|
18
test/fixtures/test_rsa_privkey_encrypted.pem
vendored
Normal file
18
test/fixtures/test_rsa_privkey_encrypted.pem
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
Proc-Type: 4,ENCRYPTED
|
||||||
|
DEK-Info: AES-128-CBC,9D916E00476DFF9E70FA4BA9E3A6CB0E
|
||||||
|
|
||||||
|
oj0VC35ShSEqlfJ0rLGgkqJCyIK+mXSsa/X/xAur+lI/RVOVTWd7oQQGTdI/0rLX
|
||||||
|
PdQR02Na3X9Rptezh6J04PfMGeFysxdT6RpC+rkHRPVbN0F4TqxSNNXzkwK70+EF
|
||||||
|
dSuDMyVKv9YN4wWDf0g6VKe4ShAH/sqICQBrVyzWyYLvH/hwZmZZ1QEab6ylIKtb
|
||||||
|
EJunwu9BxVVA04bbuATKkKjJOqDn0fG8hb4bYbyD02dJwgLePzzn36F31kcBCEHI
|
||||||
|
tESlD3RsS+EtfpfgPkplXNOhqYzkD9auDb7Zy+ZwL20fjnJb75OSGu8gOg3KTljt
|
||||||
|
mApZOg0nJ5Jk9ATAdyzyVSFOM1Hhcw12ws06Dq9KRnXgO6bbuadLTFRDdvSYDFvD
|
||||||
|
ijUb+97UolQfYIXQMqXli3EIvHr7CTWe/3mpoDgK1mtr0+923Bm97XgE7KSr0L46
|
||||||
|
n5QpNjCZf1vbXldNmW+TRifiJMgtVdS7x0N4vqDPNEe+FelVv3U4Pz3HIOtFuWLr
|
||||||
|
ZCxlgVxJY4IsyYlV0ItQjIv8fJiAyemZdO2lA9K6h0eEF+9Apr3i79JGWUi74p5D
|
||||||
|
Ooak4le0Va9O34f6FxCGn/a54A6bhKu24Ub/0gr/e4WRa7693euEdgIAZXhtMu2Z
|
||||||
|
taU5SKjjXPzjmRCM2kINHTCENlaU4oFzTmj3TYY/jdKyNP1bHa07NhlomladkIHK
|
||||||
|
GD6HaYkcbuwvh8hOPsopSwuS+NqjnGPq9Vv4ecBC+9veDEmpIE1iR6FK9Hjrre88
|
||||||
|
kLoMQNmA+vuc8jG4/FIHM3SauQiR1ZJ6+zkz97kcmOf+X7LRaS4j6lfFR6qHiJ6y
|
||||||
|
-----END RSA PRIVATE KEY-----
|
@ -46,6 +46,15 @@ var rsaPubPem = fs.readFileSync(common.fixturesDir + '/test_rsa_pubkey.pem',
|
|||||||
'ascii');
|
'ascii');
|
||||||
var rsaKeyPem = fs.readFileSync(common.fixturesDir + '/test_rsa_privkey.pem',
|
var rsaKeyPem = fs.readFileSync(common.fixturesDir + '/test_rsa_privkey.pem',
|
||||||
'ascii');
|
'ascii');
|
||||||
|
var rsaKeyPemEncrypted = fs.readFileSync(
|
||||||
|
common.fixturesDir + '/test_rsa_privkey_encrypted.pem', 'ascii');
|
||||||
|
var dsaPubPem = fs.readFileSync(common.fixturesDir + '/test_dsa_pubkey.pem',
|
||||||
|
'ascii');
|
||||||
|
var dsaKeyPem = fs.readFileSync(common.fixturesDir + '/test_dsa_privkey.pem',
|
||||||
|
'ascii');
|
||||||
|
var dsaKeyPemEncrypted = fs.readFileSync(
|
||||||
|
common.fixturesDir + '/test_dsa_privkey_encrypted.pem', 'ascii');
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var credentials = crypto.createCredentials(
|
var credentials = crypto.createCredentials(
|
||||||
@ -761,6 +770,30 @@ assert.equal(rsaSignature,
|
|||||||
rsaVerify.update(rsaPubPem);
|
rsaVerify.update(rsaPubPem);
|
||||||
assert.strictEqual(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), true);
|
assert.strictEqual(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), true);
|
||||||
|
|
||||||
|
// Test RSA key signing/verification with encrypted key
|
||||||
|
rsaSign = crypto.createSign('RSA-SHA1');
|
||||||
|
rsaSign.update(rsaPubPem);
|
||||||
|
assert.doesNotThrow(function() {
|
||||||
|
var signOptions = { key: rsaKeyPemEncrypted, passphrase: 'password' };
|
||||||
|
rsaSignature = rsaSign.sign(signOptions, 'hex');
|
||||||
|
});
|
||||||
|
assert.equal(rsaSignature,
|
||||||
|
'5c50e3145c4e2497aadb0eabc83b342d0b0021ece0d4c4a064b7c' +
|
||||||
|
'8f020d7e2688b122bfb54c724ac9ee169f83f66d2fe90abeb95e8' +
|
||||||
|
'e1290e7e177152a4de3d944cf7d4883114a20ed0f78e70e25ef0f' +
|
||||||
|
'60f06b858e6af42a2f276ede95bbc6bc9a9bbdda15bd663186a6f' +
|
||||||
|
'40819a7af19e577bb2efa5e579a1f5ce8a0d4ca8b8f6');
|
||||||
|
|
||||||
|
rsaVerify = crypto.createVerify('RSA-SHA1');
|
||||||
|
rsaVerify.update(rsaPubPem);
|
||||||
|
assert.strictEqual(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), true);
|
||||||
|
|
||||||
|
rsaSign = crypto.createSign('RSA-SHA1');
|
||||||
|
rsaSign.update(rsaPubPem);
|
||||||
|
assert.throws(function() {
|
||||||
|
var signOptions = { key: rsaKeyPemEncrypted, passphrase: 'wrong' };
|
||||||
|
rsaSign.sign(signOptions, 'hex');
|
||||||
|
});
|
||||||
|
|
||||||
//
|
//
|
||||||
// Test RSA signing and verification
|
// Test RSA signing and verification
|
||||||
@ -798,24 +831,48 @@ assert.strictEqual(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), true);
|
|||||||
// Test DSA signing and verification
|
// Test DSA signing and verification
|
||||||
//
|
//
|
||||||
(function() {
|
(function() {
|
||||||
var privateKey = fs.readFileSync(
|
|
||||||
common.fixturesDir + '/test_dsa_privkey.pem');
|
|
||||||
|
|
||||||
var publicKey = fs.readFileSync(
|
|
||||||
common.fixturesDir + '/test_dsa_pubkey.pem');
|
|
||||||
|
|
||||||
var input = 'I AM THE WALRUS';
|
var input = 'I AM THE WALRUS';
|
||||||
|
|
||||||
// DSA signatures vary across runs so there is no static string to verify
|
// DSA signatures vary across runs so there is no static string to verify
|
||||||
// against
|
// against
|
||||||
var sign = crypto.createSign('DSS1');
|
var sign = crypto.createSign('DSS1');
|
||||||
sign.update(input);
|
sign.update(input);
|
||||||
var signature = sign.sign(privateKey, 'hex');
|
var signature = sign.sign(dsaKeyPem, 'hex');
|
||||||
|
|
||||||
var verify = crypto.createVerify('DSS1');
|
var verify = crypto.createVerify('DSS1');
|
||||||
verify.update(input);
|
verify.update(input);
|
||||||
|
|
||||||
assert.strictEqual(verify.verify(publicKey, signature, 'hex'), true);
|
assert.strictEqual(verify.verify(dsaPubPem, signature, 'hex'), true);
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Test DSA signing and verification with encrypted key
|
||||||
|
//
|
||||||
|
(function() {
|
||||||
|
var input = 'I AM THE WALRUS';
|
||||||
|
|
||||||
|
var sign = crypto.createSign('DSS1');
|
||||||
|
sign.update(input);
|
||||||
|
assert.throws(function() {
|
||||||
|
sign.sign({ key: dsaKeyPemEncrypted, passphrase: 'wrong' }, 'hex');
|
||||||
|
});
|
||||||
|
|
||||||
|
// DSA signatures vary across runs so there is no static string to verify
|
||||||
|
// against
|
||||||
|
var sign = crypto.createSign('DSS1');
|
||||||
|
sign.update(input);
|
||||||
|
|
||||||
|
var signature;
|
||||||
|
assert.doesNotThrow(function() {
|
||||||
|
var signOptions = { key: dsaKeyPemEncrypted, passphrase: 'password' };
|
||||||
|
signature = sign.sign(signOptions, 'hex');
|
||||||
|
});
|
||||||
|
|
||||||
|
var verify = crypto.createVerify('DSS1');
|
||||||
|
verify.update(input);
|
||||||
|
|
||||||
|
assert.strictEqual(verify.verify(dsaPubPem, signature, 'hex'), true);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user