Add some Node compatibility functions.

This doesn't cover all the functions used by Node, but it's the easy
bits. (EVP_PKEY_paramgen will be done separately as its a non-trivial
bit of machinery.)

Change-Id: I6501e99f9239ffcdcc57b961ebe85d0ad3965549
Reviewed-on: https://boringssl-review.googlesource.com/c/34544
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
This commit is contained in:
David Benjamin 2019-01-25 04:44:22 +00:00 committed by CQ bot account: commit-bot@chromium.org
parent 6c1b376e1d
commit 23dcf88e18
7 changed files with 94 additions and 0 deletions

View File

@ -460,3 +460,11 @@ BIGNUM *BN_mpi2bn(const uint8_t *in, size_t len, BIGNUM *out) {
} }
return out; return out;
} }
int BN_bn2binpad(const BIGNUM *in, uint8_t *out, int len) {
if (len < 0 ||
!BN_bn2bin_padded(out, (size_t)len, in)) {
return -1;
}
return len;
}

View File

@ -344,3 +344,44 @@ int i2d_PublicKey(const EVP_PKEY *key, uint8_t **outp) {
return -1; return -1;
} }
} }
EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **out, const uint8_t **inp,
long len) {
EVP_PKEY *ret = EVP_PKEY_new();
if (ret == NULL) {
return NULL;
}
CBS cbs;
CBS_init(&cbs, *inp, len < 0 ? 0 : (size_t)len);
switch (type) {
case EVP_PKEY_RSA: {
RSA *rsa = RSA_parse_public_key(&cbs);
if (rsa == NULL || !EVP_PKEY_assign_RSA(ret, rsa)) {
RSA_free(rsa);
goto err;
}
break;
}
// Unlike OpenSSL, we do not support EC keys with this API. The raw EC
// public key serialization requires knowing the group. In OpenSSL, calling
// this function with |EVP_PKEY_EC| and setting |out| to NULL does not work.
// It requires |*out| to include a partially-initiazed |EVP_PKEY| to extract
// the group.
default:
OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
goto err;
}
*inp = CBS_data(&cbs);
if (out != NULL) {
EVP_PKEY_free(*out);
*out = ret;
}
return ret;
err:
EVP_PKEY_free(ret);
return NULL;
}

View File

@ -660,6 +660,22 @@ const char *EC_curve_nid2nist(int nid) {
return NULL; return NULL;
} }
int EC_curve_nist2nid(const char *name) {
if (strcmp(name, "P-224") == 0) {
return NID_secp224r1;
}
if (strcmp(name, "P-256") == 0) {
return NID_X9_62_prime256v1;
}
if (strcmp(name, "P-384") == 0) {
return NID_secp384r1;
}
if (strcmp(name, "P-521") == 0) {
return NID_secp521r1;
}
return NID_undef;
}
EC_POINT *EC_POINT_new(const EC_GROUP *group) { EC_POINT *EC_POINT_new(const EC_GROUP *group) {
if (group == NULL) { if (group == NULL) {
OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);

View File

@ -932,6 +932,12 @@ OPENSSL_EXPORT BN_MONT_CTX *BN_MONT_CTX_new(void);
OPENSSL_EXPORT int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, OPENSSL_EXPORT int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod,
BN_CTX *ctx); BN_CTX *ctx);
// BN_bn2binpad behaves like |BN_bn2bin_padded|, but it returns |len| on success
// and -1 on error.
//
// Use |BN_bn2bin_padded| instead. It is |size_t|-clean.
OPENSSL_EXPORT int BN_bn2binpad(const BIGNUM *in, uint8_t *out, int len);
// Private functions // Private functions

View File

@ -162,6 +162,11 @@ OPENSSL_EXPORT unsigned EC_GROUP_get_degree(const EC_GROUP *group);
// for |NID_X9_62_prime256v1|. // for |NID_X9_62_prime256v1|.
OPENSSL_EXPORT const char *EC_curve_nid2nist(int nid); OPENSSL_EXPORT const char *EC_curve_nid2nist(int nid);
// EC_curve_nist2nid returns the NID of the elliptic curve specified by the NIST
// name |name|, or |NID_undef| if |name| is not a recognized name. For example,
// it returns |NID_X9_62_prime256v1| for "P-256".
OPENSSL_EXPORT int EC_curve_nist2nid(const char *name);
// Points on elliptic curves. // Points on elliptic curves.

View File

@ -826,6 +826,20 @@ OPENSSL_EXPORT EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out,
OPENSSL_EXPORT EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, OPENSSL_EXPORT EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp,
long len); long len);
// d2i_PublicKey parse a public key from |len| bytes at |*inp| in a type-
// specific format specified by |type|. If |out| is not NULL then, on exit, a
// pointer to the result is in |*out|. Note that, even if |*out| is already non-
// NULL on entry, it will not be written to. Rather, a fresh |EVP_PKEY| is
// allocated and the previous one is freed. On successful exit, |*inp| is
// advanced past the decoded key. It returns the result or NULL on error.
//
// RSA keys are parsed as a DER-encoded RSAPublicKey (RFC 3447) structure.
// Parsing EC keys is not supported by this function.
//
// Use |RSA_parse_public_key| instead.
OPENSSL_EXPORT EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **out,
const uint8_t **inp, long len);
// EVP_PKEY_get0_DH returns NULL. // EVP_PKEY_get0_DH returns NULL.
OPENSSL_EXPORT DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey); OPENSSL_EXPORT DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey);

View File

@ -136,6 +136,10 @@ OPENSSL_EXPORT int BIO_vsnprintf(char *buf, size_t n, const char *format,
#define CRYPTO_realloc OPENSSL_realloc #define CRYPTO_realloc OPENSSL_realloc
#define CRYPTO_free OPENSSL_free #define CRYPTO_free OPENSSL_free
// OPENSSL_clear_free calls |OPENSSL_free|. BoringSSL automatically clears all
// allocations on free, but we define |OPENSSL_clear_free| for compatibility.
#define OPENSSL_clear_free(ptr, len) OPENSSL_free(ptr)
#if defined(__cplusplus) #if defined(__cplusplus)
} // extern C } // extern C