crmfget.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. /* -*- Mode: C; tab-width: 8 -*-*/
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "crmf.h"
  6. #include "crmfi.h"
  7. #include "keyhi.h"
  8. #include "secder.h"
  9. CRMFPOPChoice
  10. CRMF_CertReqMsgGetPOPType(CRMFCertReqMsg *inCertReqMsg)
  11. {
  12. PORT_Assert(inCertReqMsg != NULL);
  13. if (inCertReqMsg != NULL && inCertReqMsg->pop != NULL) {
  14. return inCertReqMsg->pop->popUsed;
  15. }
  16. return crmfNoPOPChoice;
  17. }
  18. static SECStatus
  19. crmf_destroy_validity(CRMFOptionalValidity *inValidity, PRBool freeit)
  20. {
  21. if (inValidity != NULL) {
  22. if (inValidity->notBefore.data != NULL) {
  23. PORT_Free(inValidity->notBefore.data);
  24. }
  25. if (inValidity->notAfter.data != NULL) {
  26. PORT_Free(inValidity->notAfter.data);
  27. }
  28. if (freeit) {
  29. PORT_Free(inValidity);
  30. }
  31. }
  32. return SECSuccess;
  33. }
  34. static SECStatus
  35. crmf_copy_cert_request_validity(PLArenaPool *poolp,
  36. CRMFOptionalValidity **destValidity,
  37. CRMFOptionalValidity *srcValidity)
  38. {
  39. CRMFOptionalValidity *myValidity = NULL;
  40. SECStatus rv;
  41. *destValidity = myValidity = (poolp == NULL) ? PORT_ZNew(CRMFOptionalValidity)
  42. : PORT_ArenaZNew(poolp, CRMFOptionalValidity);
  43. if (myValidity == NULL) {
  44. goto loser;
  45. }
  46. if (srcValidity->notBefore.data != NULL) {
  47. rv = SECITEM_CopyItem(poolp, &myValidity->notBefore,
  48. &srcValidity->notBefore);
  49. if (rv != SECSuccess) {
  50. goto loser;
  51. }
  52. }
  53. if (srcValidity->notAfter.data != NULL) {
  54. rv = SECITEM_CopyItem(poolp, &myValidity->notAfter,
  55. &srcValidity->notAfter);
  56. if (rv != SECSuccess) {
  57. goto loser;
  58. }
  59. }
  60. return SECSuccess;
  61. loser:
  62. if (myValidity != NULL && poolp == NULL) {
  63. crmf_destroy_validity(myValidity, PR_TRUE);
  64. }
  65. return SECFailure;
  66. }
  67. static SECStatus
  68. crmf_copy_extensions(PLArenaPool *poolp,
  69. CRMFCertTemplate *destTemplate,
  70. CRMFCertExtension **srcExt)
  71. {
  72. int numExt = 0, i;
  73. CRMFCertExtension **myExtArray = NULL;
  74. while (srcExt[numExt] != NULL) {
  75. numExt++;
  76. }
  77. if (numExt == 0) {
  78. /*No extensions to copy.*/
  79. destTemplate->extensions = NULL;
  80. destTemplate->numExtensions = 0;
  81. return SECSuccess;
  82. }
  83. destTemplate->extensions = myExtArray =
  84. PORT_NewArray(CRMFCertExtension *, numExt + 1);
  85. if (myExtArray == NULL) {
  86. goto loser;
  87. }
  88. for (i = 0; i < numExt; i++) {
  89. myExtArray[i] = crmf_copy_cert_extension(poolp, srcExt[i]);
  90. if (myExtArray[i] == NULL) {
  91. goto loser;
  92. }
  93. }
  94. destTemplate->numExtensions = numExt;
  95. myExtArray[numExt] = NULL;
  96. return SECSuccess;
  97. loser:
  98. if (myExtArray != NULL) {
  99. if (poolp == NULL) {
  100. for (i = 0; myExtArray[i] != NULL; i++) {
  101. CRMF_DestroyCertExtension(myExtArray[i]);
  102. }
  103. }
  104. PORT_Free(myExtArray);
  105. }
  106. destTemplate->extensions = NULL;
  107. destTemplate->numExtensions = 0;
  108. return SECFailure;
  109. }
  110. static SECStatus
  111. crmf_copy_cert_request_template(PLArenaPool *poolp,
  112. CRMFCertTemplate *destTemplate,
  113. CRMFCertTemplate *srcTemplate)
  114. {
  115. SECStatus rv;
  116. if (srcTemplate->version.data != NULL) {
  117. rv = SECITEM_CopyItem(poolp, &destTemplate->version,
  118. &srcTemplate->version);
  119. if (rv != SECSuccess) {
  120. goto loser;
  121. }
  122. }
  123. if (srcTemplate->serialNumber.data != NULL) {
  124. rv = SECITEM_CopyItem(poolp, &destTemplate->serialNumber,
  125. &srcTemplate->serialNumber);
  126. if (rv != SECSuccess) {
  127. goto loser;
  128. }
  129. }
  130. if (srcTemplate->signingAlg != NULL) {
  131. rv = crmf_template_copy_secalg(poolp, &destTemplate->signingAlg,
  132. srcTemplate->signingAlg);
  133. if (rv != SECSuccess) {
  134. goto loser;
  135. }
  136. }
  137. if (srcTemplate->issuer != NULL) {
  138. rv = crmf_copy_cert_name(poolp, &destTemplate->issuer,
  139. srcTemplate->issuer);
  140. if (rv != SECSuccess) {
  141. goto loser;
  142. }
  143. }
  144. if (srcTemplate->validity != NULL) {
  145. rv = crmf_copy_cert_request_validity(poolp, &destTemplate->validity,
  146. srcTemplate->validity);
  147. if (rv != SECSuccess) {
  148. goto loser;
  149. }
  150. }
  151. if (srcTemplate->subject != NULL) {
  152. rv = crmf_copy_cert_name(poolp, &destTemplate->subject,
  153. srcTemplate->subject);
  154. if (rv != SECSuccess) {
  155. goto loser;
  156. }
  157. }
  158. if (srcTemplate->publicKey != NULL) {
  159. rv = crmf_template_add_public_key(poolp, &destTemplate->publicKey,
  160. srcTemplate->publicKey);
  161. if (rv != SECSuccess) {
  162. goto loser;
  163. }
  164. }
  165. if (srcTemplate->issuerUID.data != NULL) {
  166. rv = crmf_make_bitstring_copy(poolp, &destTemplate->issuerUID,
  167. &srcTemplate->issuerUID);
  168. if (rv != SECSuccess) {
  169. goto loser;
  170. }
  171. }
  172. if (srcTemplate->subjectUID.data != NULL) {
  173. rv = crmf_make_bitstring_copy(poolp, &destTemplate->subjectUID,
  174. &srcTemplate->subjectUID);
  175. if (rv != SECSuccess) {
  176. goto loser;
  177. }
  178. }
  179. if (srcTemplate->extensions != NULL) {
  180. rv = crmf_copy_extensions(poolp, destTemplate,
  181. srcTemplate->extensions);
  182. if (rv != SECSuccess) {
  183. goto loser;
  184. }
  185. }
  186. return SECSuccess;
  187. loser:
  188. return SECFailure;
  189. }
  190. static CRMFControl *
  191. crmf_copy_control(PLArenaPool *poolp, CRMFControl *srcControl)
  192. {
  193. CRMFControl *newControl;
  194. SECStatus rv;
  195. newControl = (poolp == NULL) ? PORT_ZNew(CRMFControl) : PORT_ArenaZNew(poolp, CRMFControl);
  196. if (newControl == NULL) {
  197. goto loser;
  198. }
  199. newControl->tag = srcControl->tag;
  200. rv = SECITEM_CopyItem(poolp, &newControl->derTag, &srcControl->derTag);
  201. if (rv != SECSuccess) {
  202. goto loser;
  203. }
  204. rv = SECITEM_CopyItem(poolp, &newControl->derValue, &srcControl->derValue);
  205. if (rv != SECSuccess) {
  206. goto loser;
  207. }
  208. /* We only handle PKIArchiveOptions Control right now. But if in
  209. * the future, more controls that are part of the union are added,
  210. * then they need to be handled here as well.
  211. */
  212. switch (newControl->tag) {
  213. case SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS:
  214. rv = crmf_copy_pkiarchiveoptions(poolp,
  215. &newControl->value.archiveOptions,
  216. &srcControl->value.archiveOptions);
  217. break;
  218. default:
  219. rv = SECSuccess;
  220. }
  221. if (rv != SECSuccess) {
  222. goto loser;
  223. }
  224. return newControl;
  225. loser:
  226. if (poolp == NULL && newControl != NULL) {
  227. CRMF_DestroyControl(newControl);
  228. }
  229. return NULL;
  230. }
  231. static SECStatus
  232. crmf_copy_cert_request_controls(PLArenaPool *poolp,
  233. CRMFCertRequest *destReq,
  234. CRMFCertRequest *srcReq)
  235. {
  236. int numControls, i;
  237. CRMFControl **myControls = NULL;
  238. numControls = CRMF_CertRequestGetNumControls(srcReq);
  239. if (numControls == 0) {
  240. /* No Controls To Copy*/
  241. return SECSuccess;
  242. }
  243. myControls = destReq->controls = PORT_NewArray(CRMFControl *,
  244. numControls + 1);
  245. if (myControls == NULL) {
  246. goto loser;
  247. }
  248. for (i = 0; i < numControls; i++) {
  249. myControls[i] = crmf_copy_control(poolp, srcReq->controls[i]);
  250. if (myControls[i] == NULL) {
  251. goto loser;
  252. }
  253. }
  254. myControls[numControls] = NULL;
  255. return SECSuccess;
  256. loser:
  257. if (myControls != NULL) {
  258. if (poolp == NULL) {
  259. for (i = 0; myControls[i] != NULL; i++) {
  260. CRMF_DestroyControl(myControls[i]);
  261. }
  262. }
  263. PORT_Free(myControls);
  264. }
  265. return SECFailure;
  266. }
  267. CRMFCertRequest *
  268. crmf_copy_cert_request(PLArenaPool *poolp, CRMFCertRequest *srcReq)
  269. {
  270. CRMFCertRequest *newReq = NULL;
  271. SECStatus rv;
  272. if (srcReq == NULL) {
  273. return NULL;
  274. }
  275. newReq = (poolp == NULL) ? PORT_ZNew(CRMFCertRequest) : PORT_ArenaZNew(poolp, CRMFCertRequest);
  276. if (newReq == NULL) {
  277. goto loser;
  278. }
  279. rv = SECITEM_CopyItem(poolp, &newReq->certReqId, &srcReq->certReqId);
  280. if (rv != SECSuccess) {
  281. goto loser;
  282. }
  283. rv = crmf_copy_cert_request_template(poolp, &newReq->certTemplate,
  284. &srcReq->certTemplate);
  285. if (rv != SECSuccess) {
  286. goto loser;
  287. }
  288. rv = crmf_copy_cert_request_controls(poolp, newReq, srcReq);
  289. if (rv != SECSuccess) {
  290. goto loser;
  291. }
  292. return newReq;
  293. loser:
  294. if (newReq != NULL && poolp == NULL) {
  295. CRMF_DestroyCertRequest(newReq);
  296. PORT_Free(newReq);
  297. }
  298. return NULL;
  299. }
  300. SECStatus
  301. CRMF_DestroyGetValidity(CRMFGetValidity *inValidity)
  302. {
  303. PORT_Assert(inValidity != NULL);
  304. if (inValidity != NULL) {
  305. if (inValidity->notAfter) {
  306. PORT_Free(inValidity->notAfter);
  307. inValidity->notAfter = NULL;
  308. }
  309. if (inValidity->notBefore) {
  310. PORT_Free(inValidity->notBefore);
  311. inValidity->notBefore = NULL;
  312. }
  313. }
  314. return SECSuccess;
  315. }
  316. SECStatus
  317. crmf_make_bitstring_copy(PLArenaPool *arena, SECItem *dest, SECItem *src)
  318. {
  319. int origLenBits;
  320. int bytesToCopy;
  321. SECStatus rv;
  322. origLenBits = src->len;
  323. bytesToCopy = CRMF_BITS_TO_BYTES(origLenBits);
  324. src->len = bytesToCopy;
  325. rv = SECITEM_CopyItem(arena, dest, src);
  326. src->len = origLenBits;
  327. if (rv != SECSuccess) {
  328. return rv;
  329. }
  330. dest->len = origLenBits;
  331. return SECSuccess;
  332. }
  333. int
  334. CRMF_CertRequestGetNumberOfExtensions(CRMFCertRequest *inCertReq)
  335. {
  336. CRMFCertTemplate *certTemplate;
  337. int count = 0;
  338. certTemplate = &inCertReq->certTemplate;
  339. if (certTemplate->extensions) {
  340. while (certTemplate->extensions[count] != NULL)
  341. count++;
  342. }
  343. return count;
  344. }
  345. SECOidTag
  346. CRMF_CertExtensionGetOidTag(CRMFCertExtension *inExtension)
  347. {
  348. PORT_Assert(inExtension != NULL);
  349. if (inExtension == NULL) {
  350. return SEC_OID_UNKNOWN;
  351. }
  352. return SECOID_FindOIDTag(&inExtension->id);
  353. }
  354. PRBool
  355. CRMF_CertExtensionGetIsCritical(CRMFCertExtension *inExt)
  356. {
  357. PORT_Assert(inExt != NULL);
  358. if (inExt == NULL) {
  359. return PR_FALSE;
  360. }
  361. return inExt->critical.data != NULL;
  362. }
  363. SECItem *
  364. CRMF_CertExtensionGetValue(CRMFCertExtension *inExtension)
  365. {
  366. PORT_Assert(inExtension != NULL);
  367. if (inExtension == NULL) {
  368. return NULL;
  369. }
  370. return SECITEM_DupItem(&inExtension->value);
  371. }
  372. SECStatus
  373. CRMF_DestroyPOPOSigningKey(CRMFPOPOSigningKey *inKey)
  374. {
  375. PORT_Assert(inKey != NULL);
  376. if (inKey != NULL) {
  377. if (inKey->derInput.data != NULL) {
  378. SECITEM_FreeItem(&inKey->derInput, PR_FALSE);
  379. }
  380. if (inKey->algorithmIdentifier != NULL) {
  381. SECOID_DestroyAlgorithmID(inKey->algorithmIdentifier, PR_TRUE);
  382. }
  383. if (inKey->signature.data != NULL) {
  384. SECITEM_FreeItem(&inKey->signature, PR_FALSE);
  385. }
  386. PORT_Free(inKey);
  387. }
  388. return SECSuccess;
  389. }
  390. SECStatus
  391. CRMF_DestroyPOPOPrivKey(CRMFPOPOPrivKey *inPrivKey)
  392. {
  393. PORT_Assert(inPrivKey != NULL);
  394. if (inPrivKey != NULL) {
  395. SECITEM_FreeItem(&inPrivKey->message.thisMessage, PR_FALSE);
  396. PORT_Free(inPrivKey);
  397. }
  398. return SECSuccess;
  399. }
  400. int
  401. CRMF_CertRequestGetNumControls(CRMFCertRequest *inCertReq)
  402. {
  403. int count = 0;
  404. PORT_Assert(inCertReq != NULL);
  405. if (inCertReq == NULL) {
  406. return 0;
  407. }
  408. if (inCertReq->controls) {
  409. while (inCertReq->controls[count] != NULL)
  410. count++;
  411. }
  412. return count;
  413. }