31 #include <openssl/rsa.h>
32 #include <openssl/evp.h>
38 SECKEYPrivateKey *seckey;
39 SECKEYPublicKey *pubkey;
47 return key && key->seckey;
53 crypto_pk_new_from_nss_pubkey(
struct SECKEYPublicKeyStr *pub)
61 const SECKEYPublicKey *
70 const SECKEYPrivateKey *
81 crypto_new_pk_from_openssl_rsa_(RSA *rsa)
84 unsigned char *buf = NULL;
85 int len = i2d_RSAPublicKey(rsa, &buf);
88 if (len < 0 || buf == NULL)
105 unsigned char *buf = tor_malloc_zero(buflen);
106 const unsigned char *cp = buf;
112 rsa = d2i_RSAPrivateKey(NULL, &cp, used);
124 crypto_pk_get_openssl_evp_pkey_,(
crypto_pk_t *pk,
int private))
127 unsigned char *buf = tor_malloc_zero(buflen);
128 const unsigned char *cp = buf;
130 EVP_PKEY *result = NULL;
136 rsa = d2i_RSAPrivateKey(NULL, &cp, len);
141 rsa = d2i_RSAPublicKey(NULL, &cp, len);
146 if (!(result = EVP_PKEY_new()))
148 if (!(EVP_PKEY_assign_RSA(result, rsa))) {
149 EVP_PKEY_free(result);
176 SECKEY_DestroyPublicKey(key->pubkey);
178 SECKEY_DestroyPrivateKey(key->seckey);
191 crypto_pk_clear(key);
204 PK11RSAGenParams params = {
205 .keySizeInBits = bits,
210 PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS_KEY_PAIR_GEN, NULL);
211 SECKEYPrivateKey *seckey = NULL;
212 SECKEYPublicKey *pubkey = NULL;
215 crypto_nss_log_errors(
LOG_WARN,
"getting slot for RSA keygen");
219 seckey = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, ¶ms,
224 if (seckey == NULL || pubkey == NULL) {
225 crypto_nss_log_errors(
LOG_WARN,
"generating an RSA key");
229 crypto_pk_clear(key);
230 key->seckey = seckey;
231 key->pubkey = pubkey;
240 SECKEY_DestroyPublicKey(pubkey);
242 SECKEY_DestroyPrivateKey(seckey);
254 return key && key->seckey;
265 key->pubkey->keyType == rsaKey &&
272 secitem_uint_cmp(
const SECItem *a,
const SECItem *b)
274 const unsigned abits = SECKEY_BigIntegerBitLength(a);
275 const unsigned bbits = SECKEY_BigIntegerBitLength(b);
279 else if (abits > bbits)
284 const unsigned nbytes = CEIL_DIV(abits, 8);
288 const unsigned char *aptr = a->data + (a->len - nbytes);
289 const unsigned char *bptr = b->data + (b->len - nbytes);
305 char a_is_non_null = (a != NULL) && (a->pubkey != NULL);
306 char b_is_non_null = (b != NULL) && (b->pubkey != NULL);
307 char an_argument_is_null = !a_is_non_null | !b_is_non_null;
309 result =
tor_memcmp(&a_is_non_null, &b_is_non_null,
sizeof(a_is_non_null));
310 if (an_argument_is_null)
317 const SECItem *a_n, *a_e, *b_n, *b_e;
318 a_n = &a->pubkey->u.rsa.modulus;
319 b_n = &b->pubkey->u.rsa.modulus;
320 a_e = &a->pubkey->u.rsa.publicExponent;
321 b_e = &b->pubkey->u.rsa.publicExponent;
323 result = secitem_uint_cmp(a_n, b_n);
326 return secitem_uint_cmp(a_e, b_e);
335 return SECKEY_PublicKeyStrength(key->pubkey);
344 return SECKEY_PublicKeyStrengthInBits(key->pubkey);
355 result->pubkey = SECKEY_CopyPublicKey(key->pubkey);
357 result->seckey = SECKEY_CopyPrivateKey(key->seckey);
366 crypto_pk_clear(dest);
368 dest->pubkey = SECKEY_CopyPublicKey(src->pubkey);
376 crypto_pk_clear(dest);
378 dest->pubkey = SECKEY_CopyPublicKey(src->pubkey);
380 dest->seckey = SECKEY_CopyPrivateKey(src->seckey);
393 static const CK_RSA_PKCS_OAEP_PARAMS oaep_params = {
394 .hashAlg = CKM_SHA_1,
395 .mgf = CKG_MGF1_SHA1,
396 .source = CKZ_DATA_SPECIFIED,
400 static const SECItem oaep_item = {
402 .data = (
unsigned char *) &oaep_params,
403 .len =
sizeof(oaep_params)
408 static CK_MECHANISM_TYPE
409 padding_to_mechanism(
int padding, SECItem **item_out)
413 *item_out = (SECItem *)&oaep_item;
414 return CKM_RSA_PKCS_OAEP;
416 tor_assert_unreached();
418 return CKM_INVALID_MECHANISM;
432 const char *from,
size_t fromlen,
int padding)
440 if (BUG(! env->pubkey))
443 unsigned int result_len = 0;
444 SECItem *item = NULL;
445 CK_MECHANISM_TYPE m = padding_to_mechanism(padding, &item);
447 SECStatus s = PK11_PubEncrypt(env->pubkey, m, item,
448 (
unsigned char *)to, &result_len,
450 (
const unsigned char *)from,
451 (
unsigned int)fromlen,
453 if (s != SECSuccess) {
454 crypto_nss_log_errors(
LOG_WARN,
"encrypting to an RSA key");
458 return (
int)result_len;
472 const char *from,
size_t fromlen,
473 int padding,
int warnOnFailure)
484 unsigned int result_len = 0;
485 SECItem *item = NULL;
486 CK_MECHANISM_TYPE m = padding_to_mechanism(padding, &item);
487 SECStatus s = PK11_PrivDecrypt(key->seckey, m, item,
488 (
unsigned char *)to, &result_len,
490 (
const unsigned char *)from,
491 (
unsigned int)fromlen);
493 if (s != SECSuccess) {
495 crypto_nss_log_errors(severity,
"decrypting with an RSA key");
499 return (
int)result_len;
513 const char *from,
size_t fromlen))
524 .data = (
unsigned char *) from,
525 .len = (
unsigned int) fromlen,
529 .data = (
unsigned char *) to,
530 .len = (
unsigned int) tolen
533 s = PK11_VerifyRecover(key->pubkey, &sig, &dsig, NULL);
537 return (
int)dsig.len;
550 const char *from,
size_t fromlen)
563 .data = (
unsigned char *)to,
564 .len = (
unsigned int) tolen
568 .data = (
unsigned char *)from,
569 .len = (
unsigned int) fromlen
571 CK_MECHANISM_TYPE m = CKM_RSA_PKCS;
572 SECStatus s = PK11_SignWithMechanism(key->seckey, m, NULL,
575 if (s != SECSuccess) {
576 crypto_nss_log_errors(
LOG_WARN,
"signing with an RSA key");
585 static const unsigned char RSA_OID[] = {
586 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
598 if (pk->pubkey == NULL)
601 CERTSubjectPublicKeyInfo *info;
602 info = SECKEY_CreateSubjectPublicKeyInfo(pk->pubkey);
606 const SECItem *item = &info->subjectPublicKey;
607 size_t actual_len = (item->len) >> 3;
608 size_t n_used = MIN(actual_len, dest_len);
609 memcpy(dest, item->data, n_used);
611 SECKEY_DestroySubjectPublicKeyInfo(info);
624 CERTSubjectPublicKeyInfo info = {
628 .data = (
unsigned char *)RSA_OID,
629 .len =
sizeof(RSA_OID)
632 .subjectPublicKey = {
634 .data = (
unsigned char *)str,
635 .len = (
unsigned int)(len << 3)
639 SECKEYPublicKey *pub = SECKEY_ExtractPublicKey(&info);
644 result->pubkey = pub;
648 DISABLE_GCC_WARNING(
"-Wunused-parameter")
657 char *dest,
size_t destlen)
663 SECKEYPrivateKeyInfo *info = PK11_ExportPrivKeyInfo(pk->seckey, NULL);
666 SECItem *item = &info->privateKey;
668 if (destlen < item->len) {
669 SECKEY_DestroyPrivateKeyInfo(info, PR_TRUE);
672 int result = (int)item->len;
673 memcpy(dest, item->data, item->len);
674 SECKEY_DestroyPrivateKeyInfo(info, PR_TRUE);
691 PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS, NULL);
695 SECKEYPrivateKeyInfo info = {
699 .data = (
unsigned char *)RSA_OID,
700 .len =
sizeof(RSA_OID)
705 .data = (
unsigned char *)str,
711 SECKEYPrivateKey *seckey = NULL;
713 s = PK11_ImportPrivateKeyInfoAndReturnKey(slot, &info,
723 if (s == SECSuccess && seckey) {
725 output->seckey = seckey;
726 output->pubkey = SECKEY_ConvertToPublicKey(seckey);
729 crypto_nss_log_errors(
LOG_WARN,
"decoding an RSA private key");
733 crypto_pk_free(output);
738 const int bits = SECKEY_PublicKeyStrengthInBits(output->pubkey);
739 if (max_bits >= 0 && bits > max_bits) {
740 log_info(
LD_CRYPTO,
"Private key longer than expected.");
741 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.