26 DISABLE_GCC_WARNING(
"-Wstrict-prototypes")
30 ENABLE_GCC_WARNING(
"-Wstrict-prototypes")
33 #include <openssl/rsa.h>
34 #include <openssl/evp.h>
40 SECKEYPrivateKey *seckey;
41 SECKEYPublicKey *pubkey;
49 return key && key->seckey;
55 crypto_pk_new_from_nss_pubkey(
struct SECKEYPublicKeyStr *pub)
63 const SECKEYPublicKey *
72 const SECKEYPrivateKey *
83 crypto_new_pk_from_openssl_rsa_(RSA *rsa)
86 unsigned char *buf = NULL;
87 int len = i2d_RSAPublicKey(rsa, &buf);
90 if (len < 0 || buf == NULL)
107 unsigned char *buf = tor_malloc_zero(buflen);
108 const unsigned char *cp = buf;
114 rsa = d2i_RSAPrivateKey(NULL, &cp, used);
126 crypto_pk_get_openssl_evp_pkey_,(
crypto_pk_t *pk,
int private))
129 unsigned char *buf = tor_malloc_zero(buflen);
130 const unsigned char *cp = buf;
132 EVP_PKEY *result = NULL;
138 rsa = d2i_RSAPrivateKey(NULL, &cp, len);
143 rsa = d2i_RSAPublicKey(NULL, &cp, len);
148 if (!(result = EVP_PKEY_new()))
150 if (!(EVP_PKEY_assign_RSA(result, rsa))) {
151 EVP_PKEY_free(result);
178 SECKEY_DestroyPublicKey(key->pubkey);
180 SECKEY_DestroyPrivateKey(key->seckey);
193 crypto_pk_clear(key);
206 PK11RSAGenParams params = {
207 .keySizeInBits = bits,
212 PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS_KEY_PAIR_GEN, NULL);
213 SECKEYPrivateKey *seckey = NULL;
214 SECKEYPublicKey *pubkey = NULL;
217 crypto_nss_log_errors(
LOG_WARN,
"getting slot for RSA keygen");
221 seckey = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, ¶ms,
226 if (seckey == NULL || pubkey == NULL) {
227 crypto_nss_log_errors(
LOG_WARN,
"generating an RSA key");
231 crypto_pk_clear(key);
232 key->seckey = seckey;
233 key->pubkey = pubkey;
242 SECKEY_DestroyPublicKey(pubkey);
244 SECKEY_DestroyPrivateKey(seckey);
256 return key && key->seckey;
267 key->pubkey->keyType == rsaKey &&
274 secitem_uint_cmp(
const SECItem *a,
const SECItem *b)
276 const unsigned abits = SECKEY_BigIntegerBitLength(a);
277 const unsigned bbits = SECKEY_BigIntegerBitLength(b);
281 else if (abits > bbits)
286 const unsigned nbytes = CEIL_DIV(abits, 8);
290 const unsigned char *aptr = a->data + (a->len - nbytes);
291 const unsigned char *bptr = b->data + (b->len - nbytes);
307 char a_is_non_null = (a != NULL) && (a->pubkey != NULL);
308 char b_is_non_null = (b != NULL) && (b->pubkey != NULL);
309 char an_argument_is_null = !a_is_non_null | !b_is_non_null;
311 result =
tor_memcmp(&a_is_non_null, &b_is_non_null,
sizeof(a_is_non_null));
312 if (an_argument_is_null)
319 const SECItem *a_n, *a_e, *b_n, *b_e;
320 a_n = &a->pubkey->u.rsa.modulus;
321 b_n = &b->pubkey->u.rsa.modulus;
322 a_e = &a->pubkey->u.rsa.publicExponent;
323 b_e = &b->pubkey->u.rsa.publicExponent;
325 result = secitem_uint_cmp(a_n, b_n);
328 return secitem_uint_cmp(a_e, b_e);
337 return SECKEY_PublicKeyStrength(key->pubkey);
346 return SECKEY_PublicKeyStrengthInBits(key->pubkey);
357 result->pubkey = SECKEY_CopyPublicKey(key->pubkey);
359 result->seckey = SECKEY_CopyPrivateKey(key->seckey);
368 crypto_pk_clear(dest);
370 dest->pubkey = SECKEY_CopyPublicKey(src->pubkey);
378 crypto_pk_clear(dest);
380 dest->pubkey = SECKEY_CopyPublicKey(src->pubkey);
382 dest->seckey = SECKEY_CopyPrivateKey(src->seckey);
395 static const CK_RSA_PKCS_OAEP_PARAMS oaep_params = {
396 .hashAlg = CKM_SHA_1,
397 .mgf = CKG_MGF1_SHA1,
398 .source = CKZ_DATA_SPECIFIED,
402 static const SECItem oaep_item = {
404 .data = (
unsigned char *) &oaep_params,
405 .len =
sizeof(oaep_params)
410 static CK_MECHANISM_TYPE
411 padding_to_mechanism(
int padding, SECItem **item_out)
415 *item_out = (SECItem *)&oaep_item;
416 return CKM_RSA_PKCS_OAEP;
418 tor_assert_unreached();
420 return CKM_INVALID_MECHANISM;
434 const char *from,
size_t fromlen,
int padding)
442 if (BUG(! env->pubkey))
445 unsigned int result_len = 0;
446 SECItem *item = NULL;
447 CK_MECHANISM_TYPE m = padding_to_mechanism(padding, &item);
449 SECStatus s = PK11_PubEncrypt(env->pubkey, m, item,
450 (
unsigned char *)to, &result_len,
452 (
const unsigned char *)from,
453 (
unsigned int)fromlen,
455 if (s != SECSuccess) {
456 crypto_nss_log_errors(
LOG_WARN,
"encrypting to an RSA key");
460 return (
int)result_len;
474 const char *from,
size_t fromlen,
475 int padding,
int warnOnFailure)
486 unsigned int result_len = 0;
487 SECItem *item = NULL;
488 CK_MECHANISM_TYPE m = padding_to_mechanism(padding, &item);
489 SECStatus s = PK11_PrivDecrypt(key->seckey, m, item,
490 (
unsigned char *)to, &result_len,
492 (
const unsigned char *)from,
493 (
unsigned int)fromlen);
495 if (s != SECSuccess) {
497 crypto_nss_log_errors(severity,
"decrypting with an RSA key");
501 return (
int)result_len;
515 const char *from,
size_t fromlen))
526 .data = (
unsigned char *) from,
527 .len = (
unsigned int) fromlen,
531 .data = (
unsigned char *) to,
532 .len = (
unsigned int) tolen
535 s = PK11_VerifyRecover(key->pubkey, &sig, &dsig, NULL);
539 return (
int)dsig.len;
552 const char *from,
size_t fromlen)
565 .data = (
unsigned char *)to,
566 .len = (
unsigned int) tolen
570 .data = (
unsigned char *)from,
571 .len = (
unsigned int) fromlen
573 CK_MECHANISM_TYPE m = CKM_RSA_PKCS;
574 SECStatus s = PK11_SignWithMechanism(key->seckey, m, NULL,
577 if (s != SECSuccess) {
578 crypto_nss_log_errors(
LOG_WARN,
"signing with an RSA key");
587 static const unsigned char RSA_OID[] = {
588 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
600 if (pk->pubkey == NULL)
603 CERTSubjectPublicKeyInfo *info;
604 info = SECKEY_CreateSubjectPublicKeyInfo(pk->pubkey);
608 const SECItem *item = &info->subjectPublicKey;
609 size_t actual_len = (item->len) >> 3;
610 size_t n_used = MIN(actual_len, dest_len);
611 memcpy(dest, item->data, n_used);
613 SECKEY_DestroySubjectPublicKeyInfo(info);
626 CERTSubjectPublicKeyInfo info = {
630 .data = (
unsigned char *)RSA_OID,
631 .len =
sizeof(RSA_OID)
634 .subjectPublicKey = {
636 .data = (
unsigned char *)str,
637 .len = (
unsigned int)(len << 3)
641 SECKEYPublicKey *pub = SECKEY_ExtractPublicKey(&info);
646 result->pubkey = pub;
650 DISABLE_GCC_WARNING(
"-Wunused-parameter")
659 char *dest,
size_t destlen)
665 SECKEYPrivateKeyInfo *info = PK11_ExportPrivKeyInfo(pk->seckey, NULL);
668 SECItem *item = &info->privateKey;
670 if (destlen < item->len) {
671 SECKEY_DestroyPrivateKeyInfo(info, PR_TRUE);
674 int result = (int)item->len;
675 memcpy(dest, item->data, item->len);
676 SECKEY_DestroyPrivateKeyInfo(info, PR_TRUE);
693 PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS, NULL);
697 SECKEYPrivateKeyInfo info = {
701 .data = (
unsigned char *)RSA_OID,
702 .len =
sizeof(RSA_OID)
707 .data = (
unsigned char *)str,
713 SECKEYPrivateKey *seckey = NULL;
715 s = PK11_ImportPrivateKeyInfoAndReturnKey(slot, &info,
725 if (s == SECSuccess && seckey) {
727 output->seckey = seckey;
728 output->pubkey = SECKEY_ConvertToPublicKey(seckey);
731 crypto_nss_log_errors(
LOG_WARN,
"decoding an RSA private key");
735 crypto_pk_free(output);
740 const int bits = SECKEY_PublicKeyStrengthInBits(output->pubkey);
741 if (max_bits >= 0 && bits > max_bits) {
742 log_info(
LD_CRYPTO,
"Private key longer than expected.");
743 crypto_pk_free(output);
Macro definitions for MIN, MAX, and CLAMP.
Headers for crypto_nss_mgt.c.
Headers for crypto_rsa.c.
crypto_pk_t * crypto_pk_dup_key(crypto_pk_t *orig)
void crypto_pk_assign_private(crypto_pk_t *dest, const crypto_pk_t *src)
crypto_pk_t * crypto_pk_asn1_decode_private(const char *str, size_t len, int max_bits)
int crypto_pk_cmp_keys(const crypto_pk_t *a, const crypto_pk_t *b)
int crypto_pk_generate_key_with_bits(crypto_pk_t *env, int bits)
size_t crypto_pk_keysize(const crypto_pk_t *env)
crypto_pk_t * crypto_pk_new(void)
int crypto_pk_private_sign(const crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen)
int crypto_pk_is_valid_private_key(const crypto_pk_t *env)
crypto_pk_t * crypto_pk_asn1_decode(const char *str, size_t len)
int crypto_pk_private_decrypt(crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen, int padding, int warnOnFailure)
#define PK_PKCS1_OAEP_PADDING
int crypto_pk_asn1_encode(const crypto_pk_t *pk, char *dest, size_t dest_len)
int crypto_pk_public_encrypt(crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen, int padding)
void crypto_pk_assign_public(crypto_pk_t *dest, const crypto_pk_t *src)
int crypto_pk_num_bits(crypto_pk_t *env)
int crypto_pk_key_is_private(const crypto_pk_t *key)
int crypto_pk_asn1_encode_private(const crypto_pk_t *pk, char *dest, size_t dest_len)
crypto_pk_t * crypto_pk_copy_full(crypto_pk_t *orig)
int crypto_pk_public_checksig(const crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen)
int crypto_pk_public_exponent_ok(const crypto_pk_t *env)
void crypto_pk_free_(crypto_pk_t *env)
void memwipe(void *mem, uint8_t byte, size_t sz)
Common functions for cryptographic routines.
int tor_memcmp(const void *a, const void *b, size_t len)
#define fast_memcmp(a, b, c)
Wrappers for reading and writing data to files on disk.
#define MOCK_IMPL(rv, funcname, arglist)
Macros to manage assertions, fatal and non-fatal.