crypto_rsa_nss.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  1. /* Copyright (c) 2001, Matej Pfajfar.
  2. * Copyright (c) 2001-2004, Roger Dingledine.
  3. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  4. * Copyright (c) 2007-2019, The Tor Project, Inc. */
  5. /* See LICENSE for licensing information */
  6. /**
  7. * \file crypto_rsa.c
  8. * \brief NSS implementations of our RSA code.
  9. **/
  10. #include "lib/crypt_ops/crypto_rsa.h"
  11. #include "lib/crypt_ops/crypto_nss_mgt.h"
  12. #include "lib/crypt_ops/crypto_util.h"
  13. #include "lib/ctime/di_ops.h"
  14. #include "lib/encoding/binascii.h"
  15. #include "lib/fs/files.h"
  16. #include "lib/intmath/cmp.h"
  17. #include "lib/intmath/muldiv.h"
  18. #include "lib/log/log.h"
  19. #include "lib/log/util_bug.h"
  20. #include <string.h>
  21. #include <keyhi.h>
  22. #include <pk11pub.h>
  23. #include <secder.h>
  24. #ifdef ENABLE_OPENSSL
  25. #include <openssl/rsa.h>
  26. #include <openssl/evp.h>
  27. #endif
  28. /** Declaration for crypto_pk_t structure. */
  29. struct crypto_pk_t
  30. {
  31. SECKEYPrivateKey *seckey;
  32. SECKEYPublicKey *pubkey;
  33. };
  34. /** Return true iff <b>key</b> contains the private-key portion of the RSA
  35. * key. */
  36. int
  37. crypto_pk_key_is_private(const crypto_pk_t *key)
  38. {
  39. return key && key->seckey;
  40. }
  41. /** used by tortls.c: wrap a SecKEYPublicKey in a crypto_pk_t. Take ownership
  42. * of the RSA object. */
  43. crypto_pk_t *
  44. crypto_pk_new_from_nss_pubkey(struct SECKEYPublicKeyStr *pub)
  45. {
  46. crypto_pk_t *result = tor_malloc_zero(sizeof(crypto_pk_t));
  47. result->pubkey = pub;
  48. return result;
  49. }
  50. /** Return the SECKEYPublicKey for the provided crypto_pk_t. */
  51. const SECKEYPublicKey *
  52. crypto_pk_get_nss_pubkey(const crypto_pk_t *key)
  53. {
  54. tor_assert(key);
  55. return key->pubkey;
  56. }
  57. /** Return the SECKEYPrivateKey for the provided crypto_pk_t, or NULL if it
  58. * does not exist. */
  59. const SECKEYPrivateKey *
  60. crypto_pk_get_nss_privkey(const crypto_pk_t *key)
  61. {
  62. tor_assert(key);
  63. return key->seckey;
  64. }
  65. #ifdef ENABLE_OPENSSL
  66. /** used by tortls.c: wrap an RSA* in a crypto_pk_t. Take ownership of the
  67. * RSA object. */
  68. crypto_pk_t *
  69. crypto_new_pk_from_openssl_rsa_(RSA *rsa)
  70. {
  71. crypto_pk_t *pk = NULL;
  72. unsigned char *buf = NULL;
  73. int len = i2d_RSAPublicKey(rsa, &buf);
  74. RSA_free(rsa);
  75. if (len < 0 || buf == NULL)
  76. goto end;
  77. pk = crypto_pk_asn1_decode((const char *)buf, len);
  78. end:
  79. if (buf)
  80. OPENSSL_free(buf);
  81. return pk;
  82. }
  83. /** Helper, used by tor-gencert.c. Return the RSA from a
  84. * crypto_pk_t. */
  85. struct rsa_st *
  86. crypto_pk_get_openssl_rsa_(crypto_pk_t *pk)
  87. {
  88. size_t buflen = crypto_pk_keysize(pk)*16;
  89. unsigned char *buf = tor_malloc_zero(buflen);
  90. const unsigned char *cp = buf;
  91. RSA *rsa = NULL;
  92. int used = crypto_pk_asn1_encode_private(pk, (char*)buf, buflen);
  93. if (used < 0)
  94. goto end;
  95. rsa = d2i_RSAPrivateKey(NULL, &cp, used);
  96. end:
  97. memwipe(buf, 0, buflen);
  98. tor_free(buf);
  99. return rsa;
  100. }
  101. /** used by tortls.c: get an equivalent EVP_PKEY* for a crypto_pk_t. Iff
  102. * private is set, include the private-key portion of the key. Return a valid
  103. * pointer on success, and NULL on failure. */
  104. MOCK_IMPL(struct evp_pkey_st *,
  105. crypto_pk_get_openssl_evp_pkey_,(crypto_pk_t *pk, int private))
  106. {
  107. size_t buflen = crypto_pk_keysize(pk)*16;
  108. unsigned char *buf = tor_malloc_zero(buflen);
  109. const unsigned char *cp = buf;
  110. RSA *rsa = NULL;
  111. EVP_PKEY *result = NULL;
  112. if (private) {
  113. int len = crypto_pk_asn1_encode_private(pk, (char*)buf, buflen);
  114. if (len < 0)
  115. goto end;
  116. rsa = d2i_RSAPrivateKey(NULL, &cp, len);
  117. } else {
  118. int len = crypto_pk_asn1_encode(pk, (char*)buf, buflen);
  119. if (len < 0)
  120. goto end;
  121. rsa = d2i_RSAPublicKey(NULL, &cp, len);
  122. }
  123. if (!rsa)
  124. goto end;
  125. if (!(result = EVP_PKEY_new()))
  126. goto end;
  127. if (!(EVP_PKEY_assign_RSA(result, rsa))) {
  128. EVP_PKEY_free(result);
  129. RSA_free(rsa);
  130. result = NULL;
  131. }
  132. end:
  133. memwipe(buf, 0, buflen);
  134. tor_free(buf);
  135. return result;
  136. }
  137. #endif
  138. /** Allocate and return storage for a public key. The key itself will not yet
  139. * be set.
  140. */
  141. MOCK_IMPL(crypto_pk_t *,
  142. crypto_pk_new,(void))
  143. {
  144. crypto_pk_t *result = tor_malloc_zero(sizeof(crypto_pk_t));
  145. return result;
  146. }
  147. /** Release the NSS objects held in <b>key</b> */
  148. static void
  149. crypto_pk_clear(crypto_pk_t *key)
  150. {
  151. if (key->pubkey)
  152. SECKEY_DestroyPublicKey(key->pubkey);
  153. if (key->seckey)
  154. SECKEY_DestroyPrivateKey(key->seckey);
  155. memset(key, 0, sizeof(crypto_pk_t));
  156. }
  157. /** Release a reference to an asymmetric key; when all the references
  158. * are released, free the key.
  159. */
  160. void
  161. crypto_pk_free_(crypto_pk_t *key)
  162. {
  163. if (!key)
  164. return;
  165. crypto_pk_clear(key);
  166. tor_free(key);
  167. }
  168. /** Generate a <b>bits</b>-bit new public/private keypair in <b>env</b>.
  169. * Return 0 on success, -1 on failure.
  170. */
  171. MOCK_IMPL(int,
  172. crypto_pk_generate_key_with_bits,(crypto_pk_t *key, int bits))
  173. {
  174. tor_assert(key);
  175. PK11RSAGenParams params = {
  176. .keySizeInBits = bits,
  177. .pe = TOR_RSA_EXPONENT
  178. };
  179. int result = -1;
  180. PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS_KEY_PAIR_GEN, NULL);
  181. SECKEYPrivateKey *seckey = NULL;
  182. SECKEYPublicKey *pubkey = NULL;
  183. if (!slot) {
  184. crypto_nss_log_errors(LOG_WARN, "getting slot for RSA keygen");
  185. goto done;
  186. }
  187. seckey = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, &params,
  188. &pubkey,
  189. PR_FALSE /*isPerm */,
  190. PR_FALSE /*isSensitive*/,
  191. NULL);
  192. if (seckey == NULL || pubkey == NULL) {
  193. crypto_nss_log_errors(LOG_WARN, "generating an RSA key");
  194. goto done;
  195. }
  196. crypto_pk_clear(key);
  197. key->seckey = seckey;
  198. key->pubkey = pubkey;
  199. seckey = NULL;
  200. pubkey = NULL;
  201. result = 0;
  202. done:
  203. if (slot)
  204. PK11_FreeSlot(slot);
  205. if (pubkey)
  206. SECKEY_DestroyPublicKey(pubkey);
  207. if (seckey)
  208. SECKEY_DestroyPrivateKey(seckey);
  209. return result;
  210. }
  211. /** Return true iff <b>env</b> is a valid private key.
  212. */
  213. int
  214. crypto_pk_is_valid_private_key(const crypto_pk_t *key)
  215. {
  216. /* We don't need to do validation here, since unlike OpenSSL, NSS won't let
  217. * us load private keys without validating them. */
  218. return key && key->seckey;
  219. }
  220. /** Return true iff <b>env</b> contains a public key whose public exponent
  221. * equals 65537.
  222. */
  223. int
  224. crypto_pk_public_exponent_ok(const crypto_pk_t *key)
  225. {
  226. return key &&
  227. key->pubkey &&
  228. key->pubkey->keyType == rsaKey &&
  229. DER_GetUInteger(&key->pubkey->u.rsa.publicExponent) == TOR_RSA_EXPONENT;
  230. }
  231. /** Compare two big-endian integers stored in a and b; return a tristate.
  232. */
  233. STATIC int
  234. secitem_uint_cmp(const SECItem *a, const SECItem *b)
  235. {
  236. const unsigned abits = SECKEY_BigIntegerBitLength(a);
  237. const unsigned bbits = SECKEY_BigIntegerBitLength(b);
  238. if (abits < bbits)
  239. return -1;
  240. else if (abits > bbits)
  241. return 1;
  242. /* okay, they have the same number of bits set. Get a pair of aligned
  243. * pointers to their bytes that are set... */
  244. const unsigned nbytes = CEIL_DIV(abits, 8);
  245. tor_assert(nbytes <= a->len);
  246. tor_assert(nbytes <= b->len);
  247. const unsigned char *aptr = a->data + (a->len - nbytes);
  248. const unsigned char *bptr = b->data + (b->len - nbytes);
  249. /* And compare them. */
  250. return fast_memcmp(aptr, bptr, nbytes);
  251. }
  252. /** Compare the public-key components of a and b. Return less than 0
  253. * if a\<b, 0 if a==b, and greater than 0 if a\>b. A NULL key is
  254. * considered to be less than all non-NULL keys, and equal to itself.
  255. *
  256. * Note that this may leak information about the keys through timing.
  257. */
  258. int
  259. crypto_pk_cmp_keys(const crypto_pk_t *a, const crypto_pk_t *b)
  260. {
  261. int result;
  262. char a_is_non_null = (a != NULL) && (a->pubkey != NULL);
  263. char b_is_non_null = (b != NULL) && (b->pubkey != NULL);
  264. char an_argument_is_null = !a_is_non_null | !b_is_non_null;
  265. result = tor_memcmp(&a_is_non_null, &b_is_non_null, sizeof(a_is_non_null));
  266. if (an_argument_is_null)
  267. return result;
  268. // This is all Tor uses with this structure.
  269. tor_assert(a->pubkey->keyType == rsaKey);
  270. tor_assert(b->pubkey->keyType == rsaKey);
  271. const SECItem *a_n, *a_e, *b_n, *b_e;
  272. a_n = &a->pubkey->u.rsa.modulus;
  273. b_n = &b->pubkey->u.rsa.modulus;
  274. a_e = &a->pubkey->u.rsa.publicExponent;
  275. b_e = &b->pubkey->u.rsa.publicExponent;
  276. result = secitem_uint_cmp(a_n, b_n);
  277. if (result)
  278. return result;
  279. return secitem_uint_cmp(a_e, b_e);
  280. }
  281. /** Return the size of the public key modulus in <b>env</b>, in bytes. */
  282. size_t
  283. crypto_pk_keysize(const crypto_pk_t *key)
  284. {
  285. tor_assert(key);
  286. tor_assert(key->pubkey);
  287. return SECKEY_PublicKeyStrength(key->pubkey);
  288. }
  289. /** Return the size of the public key modulus of <b>env</b>, in bits. */
  290. int
  291. crypto_pk_num_bits(crypto_pk_t *key)
  292. {
  293. tor_assert(key);
  294. tor_assert(key->pubkey);
  295. return SECKEY_PublicKeyStrengthInBits(key->pubkey);
  296. }
  297. /**
  298. * Make a copy of <b>key</b> and return it.
  299. */
  300. crypto_pk_t *
  301. crypto_pk_dup_key(crypto_pk_t *key)
  302. {
  303. crypto_pk_t *result = crypto_pk_new();
  304. if (key->pubkey)
  305. result->pubkey = SECKEY_CopyPublicKey(key->pubkey);
  306. if (key->seckey)
  307. result->seckey = SECKEY_CopyPrivateKey(key->seckey);
  308. return result;
  309. }
  310. /** For testing: replace dest with src. (Dest must have a refcount
  311. * of 1) */
  312. void
  313. crypto_pk_assign_public(crypto_pk_t *dest, const crypto_pk_t *src)
  314. {
  315. crypto_pk_clear(dest);
  316. if (src->pubkey)
  317. dest->pubkey = SECKEY_CopyPublicKey(src->pubkey);
  318. }
  319. /** For testing: replace dest with src. (Dest must have a refcount
  320. * of 1) */
  321. void
  322. crypto_pk_assign_private(crypto_pk_t *dest, const crypto_pk_t *src)
  323. {
  324. crypto_pk_clear(dest);
  325. if (src->pubkey)
  326. dest->pubkey = SECKEY_CopyPublicKey(src->pubkey);
  327. if (src->seckey)
  328. dest->seckey = SECKEY_CopyPrivateKey(src->seckey);
  329. }
  330. /** Make a real honest-to-goodness copy of <b>env</b>, and return it.
  331. * Returns NULL on failure. */
  332. crypto_pk_t *
  333. crypto_pk_copy_full(crypto_pk_t *key)
  334. {
  335. // These aren't reference-counted is nss, so it's fine to just
  336. // use the same function.
  337. return crypto_pk_dup_key(key);
  338. }
  339. static const CK_RSA_PKCS_OAEP_PARAMS oaep_params = {
  340. .hashAlg = CKM_SHA_1,
  341. .mgf = CKG_MGF1_SHA1,
  342. .source = CKZ_DATA_SPECIFIED,
  343. .pSourceData = NULL,
  344. .ulSourceDataLen = 0
  345. };
  346. static const SECItem oaep_item = {
  347. .type = siBuffer,
  348. .data = (unsigned char *) &oaep_params,
  349. .len = sizeof(oaep_params)
  350. };
  351. /** Return the mechanism code and parameters for a given padding method when
  352. * used with RSA */
  353. static CK_MECHANISM_TYPE
  354. padding_to_mechanism(int padding, SECItem **item_out)
  355. {
  356. switch (padding) {
  357. case PK_PKCS1_OAEP_PADDING:
  358. *item_out = (SECItem *)&oaep_item;
  359. return CKM_RSA_PKCS_OAEP;
  360. default:
  361. tor_assert_unreached();
  362. *item_out = NULL;
  363. return CKM_INVALID_MECHANISM;
  364. }
  365. }
  366. /** Encrypt <b>fromlen</b> bytes from <b>from</b> with the public key
  367. * in <b>env</b>, using the padding method <b>padding</b>. On success,
  368. * write the result to <b>to</b>, and return the number of bytes
  369. * written. On failure, return -1.
  370. *
  371. * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
  372. * at least the length of the modulus of <b>env</b>.
  373. */
  374. int
  375. crypto_pk_public_encrypt(crypto_pk_t *env, char *to, size_t tolen,
  376. const char *from, size_t fromlen, int padding)
  377. {
  378. tor_assert(env);
  379. tor_assert(to);
  380. tor_assert(from);
  381. tor_assert(tolen < INT_MAX);
  382. tor_assert(fromlen < INT_MAX);
  383. if (BUG(! env->pubkey))
  384. return -1;
  385. unsigned int result_len = 0;
  386. SECItem *item = NULL;
  387. CK_MECHANISM_TYPE m = padding_to_mechanism(padding, &item);
  388. SECStatus s = PK11_PubEncrypt(env->pubkey, m, item,
  389. (unsigned char *)to, &result_len,
  390. (unsigned int)tolen,
  391. (const unsigned char *)from,
  392. (unsigned int)fromlen,
  393. NULL);
  394. if (s != SECSuccess) {
  395. crypto_nss_log_errors(LOG_WARN, "encrypting to an RSA key");
  396. return -1;
  397. }
  398. return (int)result_len;
  399. }
  400. /** Decrypt <b>fromlen</b> bytes from <b>from</b> with the private key
  401. * in <b>env</b>, using the padding method <b>padding</b>. On success,
  402. * write the result to <b>to</b>, and return the number of bytes
  403. * written. On failure, return -1.
  404. *
  405. * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
  406. * at least the length of the modulus of <b>key</b>.
  407. */
  408. int
  409. crypto_pk_private_decrypt(crypto_pk_t *key, char *to,
  410. size_t tolen,
  411. const char *from, size_t fromlen,
  412. int padding, int warnOnFailure)
  413. {
  414. tor_assert(key);
  415. tor_assert(to);
  416. tor_assert(from);
  417. tor_assert(tolen < INT_MAX);
  418. tor_assert(fromlen < INT_MAX);
  419. if (!crypto_pk_key_is_private(key))
  420. return -1; /* Not a private key. */
  421. unsigned int result_len = 0;
  422. SECItem *item = NULL;
  423. CK_MECHANISM_TYPE m = padding_to_mechanism(padding, &item);
  424. SECStatus s = PK11_PrivDecrypt(key->seckey, m, item,
  425. (unsigned char *)to, &result_len,
  426. (unsigned int)tolen,
  427. (const unsigned char *)from,
  428. (unsigned int)fromlen);
  429. if (s != SECSuccess) {
  430. const int severity = warnOnFailure ? LOG_WARN : LOG_INFO;
  431. crypto_nss_log_errors(severity, "decrypting with an RSA key");
  432. return -1;
  433. }
  434. return (int)result_len;
  435. }
  436. /** Check the signature in <b>from</b> (<b>fromlen</b> bytes long) with the
  437. * public key in <b>key</b>, using PKCS1 padding. On success, write the
  438. * signed data to <b>to</b>, and return the number of bytes written.
  439. * On failure, return -1.
  440. *
  441. * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
  442. * at least the length of the modulus of <b>key</b>.
  443. */
  444. MOCK_IMPL(int,
  445. crypto_pk_public_checksig,(const crypto_pk_t *key, char *to,
  446. size_t tolen,
  447. const char *from, size_t fromlen))
  448. {
  449. tor_assert(key);
  450. tor_assert(to);
  451. tor_assert(from);
  452. tor_assert(tolen < INT_MAX);
  453. tor_assert(fromlen < INT_MAX);
  454. tor_assert(key->pubkey);
  455. SECItem sig = {
  456. .type = siBuffer,
  457. .data = (unsigned char *) from,
  458. .len = (unsigned int) fromlen,
  459. };
  460. SECItem dsig = {
  461. .type = siBuffer,
  462. .data = (unsigned char *) to,
  463. .len = (unsigned int) tolen
  464. };
  465. SECStatus s;
  466. s = PK11_VerifyRecover(key->pubkey, &sig, &dsig, NULL);
  467. if (s != SECSuccess)
  468. return -1;
  469. return (int)dsig.len;
  470. }
  471. /** Sign <b>fromlen</b> bytes of data from <b>from</b> with the private key in
  472. * <b>env</b>, using PKCS1 padding. On success, write the signature to
  473. * <b>to</b>, and return the number of bytes written. On failure, return
  474. * -1.
  475. *
  476. * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
  477. * at least the length of the modulus of <b>env</b>.
  478. */
  479. int
  480. crypto_pk_private_sign(const crypto_pk_t *key, char *to, size_t tolen,
  481. const char *from, size_t fromlen)
  482. {
  483. tor_assert(key);
  484. tor_assert(to);
  485. tor_assert(from);
  486. tor_assert(tolen < INT_MAX);
  487. tor_assert(fromlen < INT_MAX);
  488. if (BUG(!crypto_pk_key_is_private(key)))
  489. return -1;
  490. SECItem sig = {
  491. .type = siBuffer,
  492. .data = (unsigned char *)to,
  493. .len = (unsigned int) tolen
  494. };
  495. SECItem hash = {
  496. .type = siBuffer,
  497. .data = (unsigned char *)from,
  498. .len = (unsigned int) fromlen
  499. };
  500. CK_MECHANISM_TYPE m = CKM_RSA_PKCS;
  501. SECStatus s = PK11_SignWithMechanism(key->seckey, m, NULL,
  502. &sig, &hash);
  503. if (s != SECSuccess) {
  504. crypto_nss_log_errors(LOG_WARN, "signing with an RSA key");
  505. return -1;
  506. }
  507. return (int)sig.len;
  508. }
  509. /* "This has lead to people trading hard-to-find object identifiers and ASN.1
  510. * definitions like baseball cards" - Peter Gutmann, "X.509 Style Guide". */
  511. static const unsigned char RSA_OID[] = {
  512. /* RSADSI */ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
  513. /* PKCS1 */ 0x01, 0x01,
  514. /* RSA */ 0x01
  515. };
  516. /** ASN.1-encode the public portion of <b>pk</b> into <b>dest</b>.
  517. * Return -1 on error, or the number of characters used on success.
  518. */
  519. int
  520. crypto_pk_asn1_encode(const crypto_pk_t *pk, char *dest, size_t dest_len)
  521. {
  522. tor_assert(pk);
  523. if (pk->pubkey == NULL)
  524. return -1;
  525. CERTSubjectPublicKeyInfo *info;
  526. info = SECKEY_CreateSubjectPublicKeyInfo(pk->pubkey);
  527. if (! info)
  528. return -1;
  529. const SECItem *item = &info->subjectPublicKey;
  530. size_t actual_len = (item->len) >> 3; /* bits to bytes */
  531. size_t n_used = MIN(actual_len, dest_len);
  532. memcpy(dest, item->data, n_used);
  533. SECKEY_DestroySubjectPublicKeyInfo(info);
  534. return (int) n_used;
  535. }
  536. /** Decode an ASN.1-encoded public key from <b>str</b>; return the result on
  537. * success and NULL on failure.
  538. */
  539. crypto_pk_t *
  540. crypto_pk_asn1_decode(const char *str, size_t len)
  541. {
  542. tor_assert(str);
  543. if (len >= INT_MAX)
  544. return NULL;
  545. CERTSubjectPublicKeyInfo info = {
  546. .algorithm = {
  547. .algorithm = {
  548. .type = siDEROID,
  549. .data = (unsigned char *)RSA_OID,
  550. .len = sizeof(RSA_OID)
  551. }
  552. },
  553. .subjectPublicKey = {
  554. .type = siBuffer,
  555. .data = (unsigned char *)str,
  556. .len = (unsigned int)(len << 3) /* bytes to bits */
  557. }
  558. };
  559. SECKEYPublicKey *pub = SECKEY_ExtractPublicKey(&info);
  560. if (pub == NULL)
  561. return NULL;
  562. crypto_pk_t *result = crypto_pk_new();
  563. result->pubkey = pub;
  564. return result;
  565. }
  566. DISABLE_GCC_WARNING(unused-parameter)
  567. /** Given a crypto_pk_t <b>pk</b>, allocate a new buffer containing the Base64
  568. * encoding of the DER representation of the private key into the
  569. * <b>dest_len</b>-byte buffer in <b>dest</b>.
  570. * Return the number of bytes written on success, -1 on failure.
  571. */
  572. int
  573. crypto_pk_asn1_encode_private(const crypto_pk_t *pk,
  574. char *dest, size_t destlen)
  575. {
  576. tor_assert(destlen <= INT_MAX);
  577. if (!crypto_pk_key_is_private(pk))
  578. return -1;
  579. SECKEYPrivateKeyInfo *info = PK11_ExportPrivKeyInfo(pk->seckey, NULL);
  580. if (!info)
  581. return -1;
  582. SECItem *item = &info->privateKey;
  583. if (destlen < item->len) {
  584. SECKEY_DestroyPrivateKeyInfo(info, PR_TRUE);
  585. return -1;
  586. }
  587. int result = (int)item->len;
  588. memcpy(dest, item->data, item->len);
  589. SECKEY_DestroyPrivateKeyInfo(info, PR_TRUE);
  590. return result;
  591. }
  592. /** Given a buffer containing the DER representation of the
  593. * private key <b>str</b>, decode and return the result on success, or NULL
  594. * on failure.
  595. */
  596. crypto_pk_t *
  597. crypto_pk_asn1_decode_private(const char *str, size_t len)
  598. {
  599. tor_assert(str);
  600. tor_assert(len < INT_MAX);
  601. PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS, NULL);
  602. if (!slot)
  603. return NULL;
  604. SECKEYPrivateKeyInfo info = {
  605. .algorithm = {
  606. .algorithm = {
  607. .type = siBuffer,
  608. .data = (unsigned char *)RSA_OID,
  609. .len = sizeof(RSA_OID)
  610. }
  611. },
  612. .privateKey = {
  613. .type = siBuffer,
  614. .data = (unsigned char *)str,
  615. .len = (int)len,
  616. }
  617. };
  618. SECStatus s;
  619. SECKEYPrivateKey *seckey = NULL;
  620. s = PK11_ImportPrivateKeyInfoAndReturnKey(slot, &info,
  621. NULL /* nickname */,
  622. NULL /* publicValue */,
  623. PR_FALSE /* isPerm */,
  624. PR_FALSE /* isPrivate */,
  625. KU_ALL /* keyUsage */,
  626. &seckey, NULL);
  627. crypto_pk_t *output = NULL;
  628. if (s == SECSuccess && seckey) {
  629. output = crypto_pk_new();
  630. output->seckey = seckey;
  631. output->pubkey = SECKEY_ConvertToPublicKey(seckey);
  632. tor_assert(output->pubkey);
  633. } else {
  634. crypto_nss_log_errors(LOG_WARN, "decoding an RSA private key");
  635. }
  636. if (! crypto_pk_is_valid_private_key(output)) {
  637. crypto_pk_free(output);
  638. output = NULL;
  639. }
  640. if (slot)
  641. PK11_FreeSlot(slot);
  642. return output;
  643. }