crypto_rsa_nss.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  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-2018, 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> has a valid key.
  212. */
  213. int
  214. crypto_pk_check_key(crypto_pk_t *key)
  215. {
  216. return key && key->pubkey;
  217. }
  218. /** Return true iff <b>env</b> contains a public key whose public exponent
  219. * equals 65537.
  220. */
  221. int
  222. crypto_pk_public_exponent_ok(crypto_pk_t *key)
  223. {
  224. return key &&
  225. key->pubkey &&
  226. key->pubkey->keyType == rsaKey &&
  227. DER_GetUInteger(&key->pubkey->u.rsa.publicExponent) == TOR_RSA_EXPONENT;
  228. }
  229. /** Compare two big-endian integers stored in a and b; return a tristate.
  230. */
  231. STATIC int
  232. secitem_uint_cmp(const SECItem *a, const SECItem *b)
  233. {
  234. const unsigned abits = SECKEY_BigIntegerBitLength(a);
  235. const unsigned bbits = SECKEY_BigIntegerBitLength(b);
  236. if (abits < bbits)
  237. return -1;
  238. else if (abits > bbits)
  239. return 1;
  240. /* okay, they have the same number of bits set. Get a pair of aligned
  241. * pointers to their bytes that are set... */
  242. const unsigned nbytes = CEIL_DIV(abits, 8);
  243. tor_assert(nbytes <= a->len);
  244. tor_assert(nbytes <= b->len);
  245. const unsigned char *aptr = a->data + (a->len - nbytes);
  246. const unsigned char *bptr = b->data + (b->len - nbytes);
  247. /* And compare them. */
  248. return fast_memcmp(aptr, bptr, nbytes);
  249. }
  250. /** Compare the public-key components of a and b. Return less than 0
  251. * if a\<b, 0 if a==b, and greater than 0 if a\>b. A NULL key is
  252. * considered to be less than all non-NULL keys, and equal to itself.
  253. *
  254. * Note that this may leak information about the keys through timing.
  255. */
  256. int
  257. crypto_pk_cmp_keys(const crypto_pk_t *a, const crypto_pk_t *b)
  258. {
  259. int result;
  260. char a_is_non_null = (a != NULL) && (a->pubkey != NULL);
  261. char b_is_non_null = (b != NULL) && (b->pubkey != NULL);
  262. char an_argument_is_null = !a_is_non_null | !b_is_non_null;
  263. result = tor_memcmp(&a_is_non_null, &b_is_non_null, sizeof(a_is_non_null));
  264. if (an_argument_is_null)
  265. return result;
  266. // This is all Tor uses with this structure.
  267. tor_assert(a->pubkey->keyType == rsaKey);
  268. tor_assert(b->pubkey->keyType == rsaKey);
  269. const SECItem *a_n, *a_e, *b_n, *b_e;
  270. a_n = &a->pubkey->u.rsa.modulus;
  271. b_n = &b->pubkey->u.rsa.modulus;
  272. a_e = &a->pubkey->u.rsa.publicExponent;
  273. b_e = &b->pubkey->u.rsa.publicExponent;
  274. result = secitem_uint_cmp(a_n, b_n);
  275. if (result)
  276. return result;
  277. return secitem_uint_cmp(a_e, b_e);
  278. }
  279. /** Return the size of the public key modulus in <b>env</b>, in bytes. */
  280. size_t
  281. crypto_pk_keysize(const crypto_pk_t *key)
  282. {
  283. tor_assert(key);
  284. tor_assert(key->pubkey);
  285. return SECKEY_PublicKeyStrength(key->pubkey);
  286. }
  287. /** Return the size of the public key modulus of <b>env</b>, in bits. */
  288. int
  289. crypto_pk_num_bits(crypto_pk_t *key)
  290. {
  291. tor_assert(key);
  292. tor_assert(key->pubkey);
  293. return SECKEY_PublicKeyStrengthInBits(key->pubkey);
  294. }
  295. /**
  296. * Make a copy of <b>key</b> and return it.
  297. */
  298. crypto_pk_t *
  299. crypto_pk_dup_key(crypto_pk_t *key)
  300. {
  301. crypto_pk_t *result = crypto_pk_new();
  302. if (key->pubkey)
  303. result->pubkey = SECKEY_CopyPublicKey(key->pubkey);
  304. if (key->seckey)
  305. result->seckey = SECKEY_CopyPrivateKey(key->seckey);
  306. return result;
  307. }
  308. /** For testing: replace dest with src. (Dest must have a refcount
  309. * of 1) */
  310. void
  311. crypto_pk_assign_public(crypto_pk_t *dest, const crypto_pk_t *src)
  312. {
  313. crypto_pk_clear(dest);
  314. if (src->pubkey)
  315. dest->pubkey = SECKEY_CopyPublicKey(src->pubkey);
  316. }
  317. /** For testing: replace dest with src. (Dest must have a refcount
  318. * of 1) */
  319. void
  320. crypto_pk_assign_private(crypto_pk_t *dest, const crypto_pk_t *src)
  321. {
  322. crypto_pk_clear(dest);
  323. if (src->pubkey)
  324. dest->pubkey = SECKEY_CopyPublicKey(src->pubkey);
  325. if (src->seckey)
  326. dest->seckey = SECKEY_CopyPrivateKey(src->seckey);
  327. }
  328. /** Make a real honest-to-goodness copy of <b>env</b>, and return it.
  329. * Returns NULL on failure. */
  330. crypto_pk_t *
  331. crypto_pk_copy_full(crypto_pk_t *key)
  332. {
  333. // These aren't reference-counted is nss, so it's fine to just
  334. // use the same function.
  335. return crypto_pk_dup_key(key);
  336. }
  337. static const CK_RSA_PKCS_OAEP_PARAMS oaep_params = {
  338. .hashAlg = CKM_SHA_1,
  339. .mgf = CKG_MGF1_SHA1,
  340. .source = CKZ_DATA_SPECIFIED,
  341. .pSourceData = NULL,
  342. .ulSourceDataLen = 0
  343. };
  344. static const SECItem oaep_item = {
  345. .type = siBuffer,
  346. .data = (unsigned char *) &oaep_params,
  347. .len = sizeof(oaep_params)
  348. };
  349. /** Return the mechanism code and parameters for a given padding method when
  350. * used with RSA */
  351. static CK_MECHANISM_TYPE
  352. padding_to_mechanism(int padding, SECItem **item_out)
  353. {
  354. switch (padding) {
  355. case PK_PKCS1_OAEP_PADDING:
  356. *item_out = (SECItem *)&oaep_item;
  357. return CKM_RSA_PKCS_OAEP;
  358. default:
  359. tor_assert_unreached();
  360. *item_out = NULL;
  361. return CKM_INVALID_MECHANISM;
  362. }
  363. }
  364. /** Encrypt <b>fromlen</b> bytes from <b>from</b> with the public key
  365. * in <b>env</b>, using the padding method <b>padding</b>. On success,
  366. * write the result to <b>to</b>, and return the number of bytes
  367. * written. On failure, return -1.
  368. *
  369. * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
  370. * at least the length of the modulus of <b>env</b>.
  371. */
  372. int
  373. crypto_pk_public_encrypt(crypto_pk_t *env, char *to, size_t tolen,
  374. const char *from, size_t fromlen, int padding)
  375. {
  376. tor_assert(env);
  377. tor_assert(to);
  378. tor_assert(from);
  379. tor_assert(tolen < INT_MAX);
  380. tor_assert(fromlen < INT_MAX);
  381. if (BUG(!crypto_pk_check_key(env)))
  382. return -1;
  383. unsigned int result_len = 0;
  384. SECItem *item = NULL;
  385. CK_MECHANISM_TYPE m = padding_to_mechanism(padding, &item);
  386. SECStatus s = PK11_PubEncrypt(env->pubkey, m, item,
  387. (unsigned char *)to, &result_len,
  388. (unsigned int)tolen,
  389. (const unsigned char *)from,
  390. (unsigned int)fromlen,
  391. NULL);
  392. if (s != SECSuccess) {
  393. crypto_nss_log_errors(LOG_WARN, "encrypting to an RSA key");
  394. return -1;
  395. }
  396. return (int)result_len;
  397. }
  398. /** Decrypt <b>fromlen</b> bytes from <b>from</b> with the private key
  399. * in <b>env</b>, using the padding method <b>padding</b>. On success,
  400. * write the result to <b>to</b>, and return the number of bytes
  401. * written. On failure, return -1.
  402. *
  403. * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
  404. * at least the length of the modulus of <b>key</b>.
  405. */
  406. int
  407. crypto_pk_private_decrypt(crypto_pk_t *key, char *to,
  408. size_t tolen,
  409. const char *from, size_t fromlen,
  410. int padding, int warnOnFailure)
  411. {
  412. tor_assert(key);
  413. tor_assert(to);
  414. tor_assert(from);
  415. tor_assert(tolen < INT_MAX);
  416. tor_assert(fromlen < INT_MAX);
  417. if (!crypto_pk_key_is_private(key))
  418. return -1; /* Not a private key. */
  419. unsigned int result_len = 0;
  420. SECItem *item = NULL;
  421. CK_MECHANISM_TYPE m = padding_to_mechanism(padding, &item);
  422. SECStatus s = PK11_PrivDecrypt(key->seckey, m, item,
  423. (unsigned char *)to, &result_len,
  424. (unsigned int)tolen,
  425. (const unsigned char *)from,
  426. (unsigned int)fromlen);
  427. if (s != SECSuccess) {
  428. const int severity = warnOnFailure ? LOG_WARN : LOG_INFO;
  429. crypto_nss_log_errors(severity, "decrypting with an RSA key");
  430. return -1;
  431. }
  432. return (int)result_len;
  433. }
  434. /** Check the signature in <b>from</b> (<b>fromlen</b> bytes long) with the
  435. * public key in <b>key</b>, using PKCS1 padding. On success, write the
  436. * signed data to <b>to</b>, and return the number of bytes written.
  437. * On failure, return -1.
  438. *
  439. * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
  440. * at least the length of the modulus of <b>key</b>.
  441. */
  442. MOCK_IMPL(int,
  443. crypto_pk_public_checksig,(const crypto_pk_t *key, char *to,
  444. size_t tolen,
  445. const char *from, size_t fromlen))
  446. {
  447. tor_assert(key);
  448. tor_assert(to);
  449. tor_assert(from);
  450. tor_assert(tolen < INT_MAX);
  451. tor_assert(fromlen < INT_MAX);
  452. tor_assert(key->pubkey);
  453. SECItem sig = {
  454. .type = siBuffer,
  455. .data = (unsigned char *) from,
  456. .len = (unsigned int) fromlen,
  457. };
  458. SECItem dsig = {
  459. .type = siBuffer,
  460. .data = (unsigned char *) to,
  461. .len = (unsigned int) tolen
  462. };
  463. SECStatus s;
  464. s = PK11_VerifyRecover(key->pubkey, &sig, &dsig, NULL);
  465. if (s != SECSuccess)
  466. return -1;
  467. return (int)dsig.len;
  468. }
  469. /** Sign <b>fromlen</b> bytes of data from <b>from</b> with the private key in
  470. * <b>env</b>, using PKCS1 padding. On success, write the signature to
  471. * <b>to</b>, and return the number of bytes written. On failure, return
  472. * -1.
  473. *
  474. * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
  475. * at least the length of the modulus of <b>env</b>.
  476. */
  477. int
  478. crypto_pk_private_sign(const crypto_pk_t *key, char *to, size_t tolen,
  479. const char *from, size_t fromlen)
  480. {
  481. tor_assert(key);
  482. tor_assert(to);
  483. tor_assert(from);
  484. tor_assert(tolen < INT_MAX);
  485. tor_assert(fromlen < INT_MAX);
  486. if (BUG(!crypto_pk_key_is_private(key)))
  487. return -1;
  488. SECItem sig = {
  489. .type = siBuffer,
  490. .data = (unsigned char *)to,
  491. .len = (unsigned int) tolen
  492. };
  493. SECItem hash = {
  494. .type = siBuffer,
  495. .data = (unsigned char *)from,
  496. .len = (unsigned int) fromlen
  497. };
  498. CK_MECHANISM_TYPE m = CKM_RSA_PKCS;
  499. SECStatus s = PK11_SignWithMechanism(key->seckey, m, NULL,
  500. &sig, &hash);
  501. if (s != SECSuccess) {
  502. crypto_nss_log_errors(LOG_WARN, "signing with an RSA key");
  503. return -1;
  504. }
  505. return (int)sig.len;
  506. }
  507. /* "This has lead to people trading hard-to-find object identifiers and ASN.1
  508. * definitions like baseball cards" - Peter Gutmann, "X.509 Style Guide". */
  509. static const unsigned char RSA_OID[] = {
  510. /* RSADSI */ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
  511. /* PKCS1 */ 0x01, 0x01,
  512. /* RSA */ 0x01
  513. };
  514. /** ASN.1-encode the public portion of <b>pk</b> into <b>dest</b>.
  515. * Return -1 on error, or the number of characters used on success.
  516. */
  517. int
  518. crypto_pk_asn1_encode(const crypto_pk_t *pk, char *dest, size_t dest_len)
  519. {
  520. tor_assert(pk);
  521. if (pk->pubkey == NULL)
  522. return -1;
  523. CERTSubjectPublicKeyInfo *info;
  524. info = SECKEY_CreateSubjectPublicKeyInfo(pk->pubkey);
  525. if (! info)
  526. return -1;
  527. const SECItem *item = &info->subjectPublicKey;
  528. size_t actual_len = (item->len) >> 3; /* bits to bytes */
  529. size_t n_used = MIN(actual_len, dest_len);
  530. memcpy(dest, item->data, n_used);
  531. SECKEY_DestroySubjectPublicKeyInfo(info);
  532. return (int) n_used;
  533. }
  534. /** Decode an ASN.1-encoded public key from <b>str</b>; return the result on
  535. * success and NULL on failure.
  536. */
  537. crypto_pk_t *
  538. crypto_pk_asn1_decode(const char *str, size_t len)
  539. {
  540. tor_assert(str);
  541. if (len >= INT_MAX)
  542. return NULL;
  543. CERTSubjectPublicKeyInfo info = {
  544. .algorithm = {
  545. .algorithm = {
  546. .type = siDEROID,
  547. .data = (unsigned char *)RSA_OID,
  548. .len = sizeof(RSA_OID)
  549. }
  550. },
  551. .subjectPublicKey = {
  552. .type = siBuffer,
  553. .data = (unsigned char *)str,
  554. .len = (unsigned int)(len << 3) /* bytes to bits */
  555. }
  556. };
  557. SECKEYPublicKey *pub = SECKEY_ExtractPublicKey(&info);
  558. if (pub == NULL)
  559. return NULL;
  560. crypto_pk_t *result = crypto_pk_new();
  561. result->pubkey = pub;
  562. return result;
  563. }
  564. DISABLE_GCC_WARNING(unused-parameter)
  565. /** Given a crypto_pk_t <b>pk</b>, allocate a new buffer containing the Base64
  566. * encoding of the DER representation of the private key into the
  567. * <b>dest_len</b>-byte buffer in <b>dest</b>.
  568. * Return the number of bytes written on success, -1 on failure.
  569. */
  570. int
  571. crypto_pk_asn1_encode_private(const crypto_pk_t *pk,
  572. char *dest, size_t destlen)
  573. {
  574. tor_assert(destlen <= INT_MAX);
  575. if (!crypto_pk_key_is_private(pk))
  576. return -1;
  577. SECKEYPrivateKeyInfo *info = PK11_ExportPrivKeyInfo(pk->seckey, NULL);
  578. if (!info)
  579. return -1;
  580. SECItem *item = &info->privateKey;
  581. if (destlen < item->len) {
  582. SECKEY_DestroyPrivateKeyInfo(info, PR_TRUE);
  583. return -1;
  584. }
  585. int result = (int)item->len;
  586. memcpy(dest, item->data, item->len);
  587. SECKEY_DestroyPrivateKeyInfo(info, PR_TRUE);
  588. return result;
  589. }
  590. /** Given a buffer containing the DER representation of the
  591. * private key <b>str</b>, decode and return the result on success, or NULL
  592. * on failure.
  593. */
  594. crypto_pk_t *
  595. crypto_pk_asn1_decode_private(const char *str, size_t len)
  596. {
  597. tor_assert(str);
  598. tor_assert(len < INT_MAX);
  599. SECKEYPrivateKeyInfo info = {
  600. .algorithm = {
  601. .algorithm = {
  602. .type = siBuffer,
  603. .data = (unsigned char *)RSA_OID,
  604. .len = sizeof(RSA_OID)
  605. }
  606. },
  607. .privateKey = {
  608. .type = siBuffer,
  609. .data = (unsigned char *)str,
  610. .len = (int)len,
  611. }
  612. };
  613. PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS, NULL);
  614. SECStatus s;
  615. SECKEYPrivateKey *seckey = NULL;
  616. s = PK11_ImportPrivateKeyInfoAndReturnKey(slot, &info,
  617. NULL /* nickname */,
  618. NULL /* publicValue */,
  619. PR_FALSE /* isPerm */,
  620. PR_FALSE /* isPrivate */,
  621. KU_ALL /* keyUsage */,
  622. &seckey, NULL);
  623. crypto_pk_t *output = NULL;
  624. if (s == SECSuccess && seckey) {
  625. output = crypto_pk_new();
  626. output->seckey = seckey;
  627. output->pubkey = SECKEY_ConvertToPublicKey(seckey);
  628. tor_assert(output->pubkey);
  629. } else {
  630. crypto_nss_log_errors(LOG_WARN, "decoding an RSA private key");
  631. }
  632. return output;
  633. }