respcmn.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  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 "cmmf.h"
  6. #include "cmmfi.h"
  7. #include "secitem.h"
  8. #include "secder.h"
  9. SECStatus
  10. cmmf_DestroyPKIStatusInfo(CMMFPKIStatusInfo *info, PRBool freeit)
  11. {
  12. if (info->status.data != NULL) {
  13. PORT_Free(info->status.data);
  14. info->status.data = NULL;
  15. }
  16. if (info->statusString.data != NULL) {
  17. PORT_Free(info->statusString.data);
  18. info->statusString.data = NULL;
  19. }
  20. if (info->failInfo.data != NULL) {
  21. PORT_Free(info->failInfo.data);
  22. info->failInfo.data = NULL;
  23. }
  24. if (freeit) {
  25. PORT_Free(info);
  26. }
  27. return SECSuccess;
  28. }
  29. SECStatus
  30. CMMF_DestroyCertResponse(CMMFCertResponse *inCertResp)
  31. {
  32. PORT_Assert(inCertResp != NULL);
  33. if (inCertResp != NULL) {
  34. if (inCertResp->certReqId.data != NULL) {
  35. PORT_Free(inCertResp->certReqId.data);
  36. }
  37. cmmf_DestroyPKIStatusInfo(&inCertResp->status, PR_FALSE);
  38. if (inCertResp->certifiedKeyPair != NULL) {
  39. CMMF_DestroyCertifiedKeyPair(inCertResp->certifiedKeyPair);
  40. }
  41. PORT_Free(inCertResp);
  42. }
  43. return SECSuccess;
  44. }
  45. SECStatus
  46. CMMF_DestroyCertRepContent(CMMFCertRepContent *inCertRepContent)
  47. {
  48. PORT_Assert(inCertRepContent != NULL);
  49. if (inCertRepContent != NULL) {
  50. CMMFCertResponse **pResponse = inCertRepContent->response;
  51. if (pResponse != NULL) {
  52. for (; *pResponse != NULL; pResponse++) {
  53. CMMFCertifiedKeyPair *certKeyPair = (*pResponse)->certifiedKeyPair;
  54. /* XXX Why not call CMMF_DestroyCertifiedKeyPair or
  55. ** XXX cmmf_DestroyCertOrEncCert ?
  56. */
  57. if (certKeyPair != NULL &&
  58. certKeyPair->certOrEncCert.choice == cmmfCertificate &&
  59. certKeyPair->certOrEncCert.cert.certificate != NULL) {
  60. CERT_DestroyCertificate(certKeyPair->certOrEncCert.cert.certificate);
  61. certKeyPair->certOrEncCert.cert.certificate = NULL;
  62. }
  63. }
  64. }
  65. if (inCertRepContent->caPubs) {
  66. CERTCertificate **caPubs = inCertRepContent->caPubs;
  67. for (; *caPubs; ++caPubs) {
  68. CERT_DestroyCertificate(*caPubs);
  69. *caPubs = NULL;
  70. }
  71. }
  72. if (inCertRepContent->poolp != NULL) {
  73. PORT_FreeArena(inCertRepContent->poolp, PR_TRUE);
  74. }
  75. }
  76. return SECSuccess;
  77. }
  78. SECStatus
  79. CMMF_DestroyPOPODecKeyChallContent(CMMFPOPODecKeyChallContent *inDecKeyCont)
  80. {
  81. PORT_Assert(inDecKeyCont != NULL);
  82. if (inDecKeyCont != NULL && inDecKeyCont->poolp) {
  83. PORT_FreeArena(inDecKeyCont->poolp, PR_FALSE);
  84. }
  85. return SECSuccess;
  86. }
  87. SECStatus
  88. crmf_create_prtime(SECItem *src, PRTime **dest)
  89. {
  90. *dest = PORT_ZNew(PRTime);
  91. return DER_DecodeTimeChoice(*dest, src);
  92. }
  93. CRMFCertExtension *
  94. crmf_copy_cert_extension(PLArenaPool *poolp, CRMFCertExtension *inExtension)
  95. {
  96. PRBool isCritical;
  97. SECOidTag id;
  98. SECItem *data;
  99. CRMFCertExtension *newExt;
  100. PORT_Assert(inExtension != NULL);
  101. if (inExtension == NULL) {
  102. return NULL;
  103. }
  104. id = CRMF_CertExtensionGetOidTag(inExtension);
  105. isCritical = CRMF_CertExtensionGetIsCritical(inExtension);
  106. data = CRMF_CertExtensionGetValue(inExtension);
  107. newExt = crmf_create_cert_extension(poolp, id,
  108. isCritical,
  109. data);
  110. SECITEM_FreeItem(data, PR_TRUE);
  111. return newExt;
  112. }
  113. static SECItem *
  114. cmmf_encode_certificate(CERTCertificate *inCert)
  115. {
  116. return SEC_ASN1EncodeItem(NULL, NULL, inCert,
  117. SEC_ASN1_GET(SEC_SignedCertificateTemplate));
  118. }
  119. CERTCertList *
  120. cmmf_MakeCertList(CERTCertificate **inCerts)
  121. {
  122. CERTCertList *certList;
  123. CERTCertificate *currCert;
  124. SECItem *derCert, *freeCert = NULL;
  125. SECStatus rv;
  126. int i;
  127. certList = CERT_NewCertList();
  128. if (certList == NULL) {
  129. return NULL;
  130. }
  131. for (i = 0; inCerts[i] != NULL; i++) {
  132. derCert = &inCerts[i]->derCert;
  133. if (derCert->data == NULL) {
  134. derCert = freeCert = cmmf_encode_certificate(inCerts[i]);
  135. }
  136. currCert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
  137. derCert, NULL, PR_FALSE, PR_TRUE);
  138. if (freeCert != NULL) {
  139. SECITEM_FreeItem(freeCert, PR_TRUE);
  140. freeCert = NULL;
  141. }
  142. if (currCert == NULL) {
  143. goto loser;
  144. }
  145. rv = CERT_AddCertToListTail(certList, currCert);
  146. if (rv != SECSuccess) {
  147. goto loser;
  148. }
  149. }
  150. return certList;
  151. loser:
  152. CERT_DestroyCertList(certList);
  153. return NULL;
  154. }
  155. CMMFPKIStatus
  156. cmmf_PKIStatusInfoGetStatus(CMMFPKIStatusInfo *inStatus)
  157. {
  158. long derVal;
  159. derVal = DER_GetInteger(&inStatus->status);
  160. if (derVal == -1 || derVal < cmmfGranted || derVal >= cmmfNumPKIStatus) {
  161. return cmmfNoPKIStatus;
  162. }
  163. return (CMMFPKIStatus)derVal;
  164. }
  165. int
  166. CMMF_CertRepContentGetNumResponses(CMMFCertRepContent *inCertRepContent)
  167. {
  168. int numResponses = 0;
  169. PORT_Assert(inCertRepContent != NULL);
  170. if (inCertRepContent != NULL && inCertRepContent->response != NULL) {
  171. while (inCertRepContent->response[numResponses] != NULL) {
  172. numResponses++;
  173. }
  174. }
  175. return numResponses;
  176. }
  177. SECStatus
  178. cmmf_DestroyCertOrEncCert(CMMFCertOrEncCert *certOrEncCert, PRBool freeit)
  179. {
  180. switch (certOrEncCert->choice) {
  181. case cmmfCertificate:
  182. CERT_DestroyCertificate(certOrEncCert->cert.certificate);
  183. certOrEncCert->cert.certificate = NULL;
  184. break;
  185. case cmmfEncryptedCert:
  186. crmf_destroy_encrypted_value(certOrEncCert->cert.encryptedCert,
  187. PR_TRUE);
  188. certOrEncCert->cert.encryptedCert = NULL;
  189. break;
  190. default:
  191. break;
  192. }
  193. if (freeit) {
  194. PORT_Free(certOrEncCert);
  195. }
  196. return SECSuccess;
  197. }
  198. SECStatus
  199. cmmf_copy_secitem(PLArenaPool *poolp, SECItem *dest, SECItem *src)
  200. {
  201. SECStatus rv;
  202. if (src->data != NULL) {
  203. rv = SECITEM_CopyItem(poolp, dest, src);
  204. } else {
  205. dest->data = NULL;
  206. dest->len = 0;
  207. rv = SECSuccess;
  208. }
  209. return rv;
  210. }
  211. SECStatus
  212. CMMF_DestroyCertifiedKeyPair(CMMFCertifiedKeyPair *inCertKeyPair)
  213. {
  214. PORT_Assert(inCertKeyPair != NULL);
  215. if (inCertKeyPair != NULL) {
  216. cmmf_DestroyCertOrEncCert(&inCertKeyPair->certOrEncCert, PR_FALSE);
  217. if (inCertKeyPair->privateKey) {
  218. crmf_destroy_encrypted_value(inCertKeyPair->privateKey, PR_TRUE);
  219. }
  220. if (inCertKeyPair->derPublicationInfo.data) {
  221. PORT_Free(inCertKeyPair->derPublicationInfo.data);
  222. }
  223. PORT_Free(inCertKeyPair);
  224. }
  225. return SECSuccess;
  226. }
  227. SECStatus
  228. cmmf_CopyCertResponse(PLArenaPool *poolp,
  229. CMMFCertResponse *dest,
  230. CMMFCertResponse *src)
  231. {
  232. SECStatus rv;
  233. if (src->certReqId.data != NULL) {
  234. rv = SECITEM_CopyItem(poolp, &dest->certReqId, &src->certReqId);
  235. if (rv != SECSuccess) {
  236. return rv;
  237. }
  238. }
  239. rv = cmmf_CopyPKIStatusInfo(poolp, &dest->status, &src->status);
  240. if (rv != SECSuccess) {
  241. return rv;
  242. }
  243. if (src->certifiedKeyPair != NULL) {
  244. CMMFCertifiedKeyPair *destKeyPair;
  245. destKeyPair = (poolp == NULL) ? PORT_ZNew(CMMFCertifiedKeyPair) : PORT_ArenaZNew(poolp, CMMFCertifiedKeyPair);
  246. if (!destKeyPair) {
  247. return SECFailure;
  248. }
  249. rv = cmmf_CopyCertifiedKeyPair(poolp, destKeyPair,
  250. src->certifiedKeyPair);
  251. if (rv != SECSuccess) {
  252. if (!poolp) {
  253. CMMF_DestroyCertifiedKeyPair(destKeyPair);
  254. }
  255. return rv;
  256. }
  257. dest->certifiedKeyPair = destKeyPair;
  258. }
  259. return SECSuccess;
  260. }
  261. static SECStatus
  262. cmmf_CopyCertOrEncCert(PLArenaPool *poolp, CMMFCertOrEncCert *dest,
  263. CMMFCertOrEncCert *src)
  264. {
  265. SECStatus rv = SECSuccess;
  266. CRMFEncryptedValue *encVal;
  267. dest->choice = src->choice;
  268. rv = cmmf_copy_secitem(poolp, &dest->derValue, &src->derValue);
  269. switch (src->choice) {
  270. case cmmfCertificate:
  271. dest->cert.certificate = CERT_DupCertificate(src->cert.certificate);
  272. break;
  273. case cmmfEncryptedCert:
  274. encVal = (poolp == NULL) ? PORT_ZNew(CRMFEncryptedValue) : PORT_ArenaZNew(poolp, CRMFEncryptedValue);
  275. if (encVal == NULL) {
  276. return SECFailure;
  277. }
  278. rv = crmf_copy_encryptedvalue(poolp, src->cert.encryptedCert, encVal);
  279. if (rv != SECSuccess) {
  280. if (!poolp) {
  281. crmf_destroy_encrypted_value(encVal, PR_TRUE);
  282. }
  283. return rv;
  284. }
  285. dest->cert.encryptedCert = encVal;
  286. break;
  287. default:
  288. rv = SECFailure;
  289. }
  290. return rv;
  291. }
  292. SECStatus
  293. cmmf_CopyCertifiedKeyPair(PLArenaPool *poolp, CMMFCertifiedKeyPair *dest,
  294. CMMFCertifiedKeyPair *src)
  295. {
  296. SECStatus rv;
  297. rv = cmmf_CopyCertOrEncCert(poolp, &dest->certOrEncCert,
  298. &src->certOrEncCert);
  299. if (rv != SECSuccess) {
  300. return rv;
  301. }
  302. if (src->privateKey != NULL) {
  303. CRMFEncryptedValue *encVal;
  304. encVal = (poolp == NULL) ? PORT_ZNew(CRMFEncryptedValue) : PORT_ArenaZNew(poolp, CRMFEncryptedValue);
  305. if (encVal == NULL) {
  306. return SECFailure;
  307. }
  308. rv = crmf_copy_encryptedvalue(poolp, src->privateKey,
  309. encVal);
  310. if (rv != SECSuccess) {
  311. if (!poolp) {
  312. crmf_destroy_encrypted_value(encVal, PR_TRUE);
  313. }
  314. return rv;
  315. }
  316. dest->privateKey = encVal;
  317. }
  318. rv = cmmf_copy_secitem(poolp, &dest->derPublicationInfo,
  319. &src->derPublicationInfo);
  320. return rv;
  321. }
  322. SECStatus
  323. cmmf_CopyPKIStatusInfo(PLArenaPool *poolp, CMMFPKIStatusInfo *dest,
  324. CMMFPKIStatusInfo *src)
  325. {
  326. SECStatus rv;
  327. rv = cmmf_copy_secitem(poolp, &dest->status, &src->status);
  328. if (rv != SECSuccess) {
  329. return rv;
  330. }
  331. rv = cmmf_copy_secitem(poolp, &dest->statusString, &src->statusString);
  332. if (rv != SECSuccess) {
  333. return rv;
  334. }
  335. rv = cmmf_copy_secitem(poolp, &dest->failInfo, &src->failInfo);
  336. return rv;
  337. }
  338. CERTCertificate *
  339. cmmf_CertOrEncCertGetCertificate(CMMFCertOrEncCert *certOrEncCert,
  340. CERTCertDBHandle *certdb)
  341. {
  342. if (certOrEncCert->choice != cmmfCertificate ||
  343. certOrEncCert->cert.certificate == NULL) {
  344. return NULL;
  345. }
  346. return CERT_NewTempCertificate(certdb,
  347. &certOrEncCert->cert.certificate->derCert,
  348. NULL, PR_FALSE, PR_TRUE);
  349. }
  350. SECStatus
  351. cmmf_PKIStatusInfoSetStatus(CMMFPKIStatusInfo *statusInfo,
  352. PLArenaPool *poolp,
  353. CMMFPKIStatus inStatus)
  354. {
  355. SECItem *dummy;
  356. if (inStatus < cmmfGranted || inStatus >= cmmfNumPKIStatus) {
  357. return SECFailure;
  358. }
  359. dummy = SEC_ASN1EncodeInteger(poolp, &statusInfo->status, inStatus);
  360. PORT_Assert(dummy == &statusInfo->status);
  361. if (dummy != &statusInfo->status) {
  362. SECITEM_FreeItem(dummy, PR_TRUE);
  363. return SECFailure;
  364. }
  365. return SECSuccess;
  366. }