A local copy of OpenSSL from GitHub
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

311 lines
7.4 KiB

  1. /*
  2. * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <stdio.h>
  10. #include "internal/cryptlib.h"
  11. #include <openssl/pkcs12.h>
  12. #include "p12_local.h"
  13. DEFINE_STACK_OF(PKCS12_SAFEBAG)
  14. static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
  15. PKCS12_SAFEBAG *bag);
  16. static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid)
  17. {
  18. int idx;
  19. X509_ATTRIBUTE *attr;
  20. idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1);
  21. if (idx < 0)
  22. return 1;
  23. attr = EVP_PKEY_get_attr(pkey, idx);
  24. if (!X509at_add1_attr(&bag->attrib, attr))
  25. return 0;
  26. return 1;
  27. }
  28. PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert,
  29. STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter,
  30. int mac_iter, int keytype)
  31. {
  32. PKCS12 *p12 = NULL;
  33. STACK_OF(PKCS7) *safes = NULL;
  34. STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
  35. PKCS12_SAFEBAG *bag = NULL;
  36. int i;
  37. unsigned char keyid[EVP_MAX_MD_SIZE];
  38. unsigned int keyidlen = 0;
  39. /* Set defaults */
  40. if (!nid_cert)
  41. #ifdef OPENSSL_NO_RC2
  42. nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
  43. #else
  44. nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC;
  45. #endif
  46. if (!nid_key)
  47. nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
  48. if (!iter)
  49. iter = PKCS12_DEFAULT_ITER;
  50. if (!mac_iter)
  51. mac_iter = 1;
  52. if (pkey == NULL && cert == NULL && ca == NULL) {
  53. PKCS12err(PKCS12_F_PKCS12_CREATE, PKCS12_R_INVALID_NULL_ARGUMENT);
  54. return NULL;
  55. }
  56. if (pkey && cert) {
  57. if (!X509_check_private_key(cert, pkey))
  58. return NULL;
  59. if (!X509_digest(cert, EVP_sha1(), keyid, &keyidlen))
  60. return NULL;
  61. }
  62. if (cert) {
  63. bag = PKCS12_add_cert(&bags, cert);
  64. if (name && !PKCS12_add_friendlyname(bag, name, -1))
  65. goto err;
  66. if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
  67. goto err;
  68. }
  69. /* Add all other certificates */
  70. for (i = 0; i < sk_X509_num(ca); i++) {
  71. if (!PKCS12_add_cert(&bags, sk_X509_value(ca, i)))
  72. goto err;
  73. }
  74. if (bags && !PKCS12_add_safe(&safes, bags, nid_cert, iter, pass))
  75. goto err;
  76. sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
  77. bags = NULL;
  78. if (pkey) {
  79. bag = PKCS12_add_key(&bags, pkey, keytype, iter, nid_key, pass);
  80. if (!bag)
  81. goto err;
  82. if (!copy_bag_attr(bag, pkey, NID_ms_csp_name))
  83. goto err;
  84. if (!copy_bag_attr(bag, pkey, NID_LocalKeySet))
  85. goto err;
  86. if (name && !PKCS12_add_friendlyname(bag, name, -1))
  87. goto err;
  88. if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
  89. goto err;
  90. }
  91. if (bags && !PKCS12_add_safe(&safes, bags, -1, 0, NULL))
  92. goto err;
  93. sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
  94. bags = NULL;
  95. p12 = PKCS12_add_safes(safes, 0);
  96. if (p12 == NULL)
  97. goto err;
  98. sk_PKCS7_pop_free(safes, PKCS7_free);
  99. safes = NULL;
  100. if ((mac_iter != -1) &&
  101. !PKCS12_set_mac(p12, pass, -1, NULL, 0, mac_iter, NULL))
  102. goto err;
  103. return p12;
  104. err:
  105. PKCS12_free(p12);
  106. sk_PKCS7_pop_free(safes, PKCS7_free);
  107. sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
  108. return NULL;
  109. }
  110. PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert)
  111. {
  112. PKCS12_SAFEBAG *bag = NULL;
  113. char *name;
  114. int namelen = -1;
  115. unsigned char *keyid;
  116. int keyidlen = -1;
  117. /* Add user certificate */
  118. if ((bag = PKCS12_SAFEBAG_create_cert(cert)) == NULL)
  119. goto err;
  120. /*
  121. * Use friendlyName and localKeyID in certificate. (if present)
  122. */
  123. name = (char *)X509_alias_get0(cert, &namelen);
  124. if (name && !PKCS12_add_friendlyname(bag, name, namelen))
  125. goto err;
  126. keyid = X509_keyid_get0(cert, &keyidlen);
  127. if (keyid && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
  128. goto err;
  129. if (!pkcs12_add_bag(pbags, bag))
  130. goto err;
  131. return bag;
  132. err:
  133. PKCS12_SAFEBAG_free(bag);
  134. return NULL;
  135. }
  136. PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags,
  137. EVP_PKEY *key, int key_usage, int iter,
  138. int nid_key, const char *pass)
  139. {
  140. PKCS12_SAFEBAG *bag = NULL;
  141. PKCS8_PRIV_KEY_INFO *p8 = NULL;
  142. /* Make a PKCS#8 structure */
  143. if ((p8 = EVP_PKEY2PKCS8(key)) == NULL)
  144. goto err;
  145. if (key_usage && !PKCS8_add_keyusage(p8, key_usage))
  146. goto err;
  147. if (nid_key != -1) {
  148. bag = PKCS12_SAFEBAG_create_pkcs8_encrypt(nid_key, pass, -1, NULL, 0,
  149. iter, p8);
  150. PKCS8_PRIV_KEY_INFO_free(p8);
  151. } else
  152. bag = PKCS12_SAFEBAG_create0_p8inf(p8);
  153. if (!bag)
  154. goto err;
  155. if (!pkcs12_add_bag(pbags, bag))
  156. goto err;
  157. return bag;
  158. err:
  159. PKCS12_SAFEBAG_free(bag);
  160. return NULL;
  161. }
  162. PKCS12_SAFEBAG *PKCS12_add_secret(STACK_OF(PKCS12_SAFEBAG) **pbags,
  163. int nid_type, const unsigned char *value, int len)
  164. {
  165. PKCS12_SAFEBAG *bag = NULL;
  166. /* Add secret, storing the value as an octet string */
  167. if ((bag = PKCS12_SAFEBAG_create_secret(nid_type, V_ASN1_OCTET_STRING, value, len)) == NULL)
  168. goto err;
  169. if (!pkcs12_add_bag(pbags, bag))
  170. goto err;
  171. return bag;
  172. err:
  173. PKCS12_SAFEBAG_free(bag);
  174. return NULL;
  175. }
  176. int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
  177. int nid_safe, int iter, const char *pass)
  178. {
  179. PKCS7 *p7 = NULL;
  180. int free_safes = 0;
  181. if (*psafes == NULL) {
  182. *psafes = sk_PKCS7_new_null();
  183. if (*psafes == NULL)
  184. return 0;
  185. free_safes = 1;
  186. }
  187. if (nid_safe == 0)
  188. #ifdef OPENSSL_NO_RC2
  189. nid_safe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
  190. #else
  191. nid_safe = NID_pbe_WithSHA1And40BitRC2_CBC;
  192. #endif
  193. if (nid_safe == -1)
  194. p7 = PKCS12_pack_p7data(bags);
  195. else
  196. p7 = PKCS12_pack_p7encdata(nid_safe, pass, -1, NULL, 0, iter, bags);
  197. if (p7 == NULL)
  198. goto err;
  199. if (!sk_PKCS7_push(*psafes, p7))
  200. goto err;
  201. return 1;
  202. err:
  203. if (free_safes) {
  204. sk_PKCS7_free(*psafes);
  205. *psafes = NULL;
  206. }
  207. PKCS7_free(p7);
  208. return 0;
  209. }
  210. static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
  211. PKCS12_SAFEBAG *bag)
  212. {
  213. int free_bags = 0;
  214. if (pbags == NULL)
  215. return 1;
  216. if (*pbags == NULL) {
  217. *pbags = sk_PKCS12_SAFEBAG_new_null();
  218. if (*pbags == NULL)
  219. return 0;
  220. free_bags = 1;
  221. }
  222. if (!sk_PKCS12_SAFEBAG_push(*pbags, bag)) {
  223. if (free_bags) {
  224. sk_PKCS12_SAFEBAG_free(*pbags);
  225. *pbags = NULL;
  226. }
  227. return 0;
  228. }
  229. return 1;
  230. }
  231. PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7)
  232. {
  233. PKCS12 *p12;
  234. if (nid_p7 <= 0)
  235. nid_p7 = NID_pkcs7_data;
  236. p12 = PKCS12_init(nid_p7);
  237. if (p12 == NULL)
  238. return NULL;
  239. if (!PKCS12_pack_authsafes(p12, safes)) {
  240. PKCS12_free(p12);
  241. return NULL;
  242. }
  243. return p12;
  244. }