asn1cmn.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. #include "cmmf.h"
  5. #include "cmmfi.h"
  6. SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
  7. SEC_ASN1_MKSUB(SEC_AnyTemplate)
  8. SEC_ASN1_MKSUB(SEC_IntegerTemplate)
  9. SEC_ASN1_MKSUB(SEC_SignedCertificateTemplate)
  10. static const SEC_ASN1Template CMMFCertResponseTemplate[] = {
  11. { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFCertResponse) },
  12. { SEC_ASN1_INTEGER, offsetof(CMMFCertResponse, certReqId) },
  13. { SEC_ASN1_INLINE, offsetof(CMMFCertResponse, status),
  14. CMMFPKIStatusInfoTemplate },
  15. { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER,
  16. offsetof(CMMFCertResponse, certifiedKeyPair),
  17. CMMFCertifiedKeyPairTemplate },
  18. { 0 }
  19. };
  20. static const SEC_ASN1Template CMMFCertOrEncCertTemplate[] = {
  21. { SEC_ASN1_ANY, offsetof(CMMFCertOrEncCert, derValue), NULL,
  22. sizeof(CMMFCertOrEncCert) },
  23. { 0 }
  24. };
  25. const SEC_ASN1Template CMMFCertifiedKeyPairTemplate[] = {
  26. { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFCertifiedKeyPair) },
  27. { SEC_ASN1_INLINE, offsetof(CMMFCertifiedKeyPair, certOrEncCert),
  28. CMMFCertOrEncCertTemplate },
  29. { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER | 0,
  30. offsetof(CMMFCertifiedKeyPair, privateKey),
  31. CRMFEncryptedValueTemplate },
  32. { SEC_ASN1_NO_STREAM | SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
  33. SEC_ASN1_XTRN | 1,
  34. offsetof(CMMFCertifiedKeyPair, derPublicationInfo),
  35. SEC_ASN1_SUB(SEC_AnyTemplate) },
  36. { 0 }
  37. };
  38. const SEC_ASN1Template CMMFPKIStatusInfoTemplate[] = {
  39. { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFPKIStatusInfo) },
  40. { SEC_ASN1_INTEGER, offsetof(CMMFPKIStatusInfo, status) },
  41. { SEC_ASN1_OPTIONAL | SEC_ASN1_UTF8_STRING,
  42. offsetof(CMMFPKIStatusInfo, statusString) },
  43. { SEC_ASN1_OPTIONAL | SEC_ASN1_BIT_STRING,
  44. offsetof(CMMFPKIStatusInfo, failInfo) },
  45. { 0 }
  46. };
  47. const SEC_ASN1Template CMMFSequenceOfCertsTemplate[] = {
  48. { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, 0,
  49. SEC_ASN1_SUB(SEC_SignedCertificateTemplate) }
  50. };
  51. const SEC_ASN1Template CMMFRandTemplate[] = {
  52. { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFRand) },
  53. { SEC_ASN1_INTEGER, offsetof(CMMFRand, integer) },
  54. { SEC_ASN1_OCTET_STRING, offsetof(CMMFRand, senderHash) },
  55. { 0 }
  56. };
  57. const SEC_ASN1Template CMMFPOPODecKeyRespContentTemplate[] = {
  58. { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN,
  59. offsetof(CMMFPOPODecKeyRespContent, responses),
  60. SEC_ASN1_SUB(SEC_IntegerTemplate),
  61. sizeof(CMMFPOPODecKeyRespContent) },
  62. { 0 }
  63. };
  64. const SEC_ASN1Template CMMFCertOrEncCertEncryptedCertTemplate[] = {
  65. { SEC_ASN1_CONTEXT_SPECIFIC | 1,
  66. 0,
  67. CRMFEncryptedValueTemplate },
  68. { 0 }
  69. };
  70. const SEC_ASN1Template CMMFCertOrEncCertCertificateTemplate[] = {
  71. { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
  72. 0,
  73. SEC_ASN1_SUB(SEC_SignedCertificateTemplate) },
  74. { 0 }
  75. };
  76. const SEC_ASN1Template CMMFCertRepContentTemplate[] = {
  77. { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFCertRepContent) },
  78. { SEC_ASN1_CONSTRUCTED | SEC_ASN1_OPTIONAL |
  79. SEC_ASN1_CONTEXT_SPECIFIC | 1,
  80. offsetof(CMMFCertRepContent, caPubs),
  81. CMMFSequenceOfCertsTemplate },
  82. { SEC_ASN1_SEQUENCE_OF, offsetof(CMMFCertRepContent, response),
  83. CMMFCertResponseTemplate },
  84. { 0 }
  85. };
  86. static const SEC_ASN1Template CMMFChallengeTemplate[] = {
  87. { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFChallenge) },
  88. { SEC_ASN1_POINTER | SEC_ASN1_OPTIONAL | SEC_ASN1_XTRN,
  89. offsetof(CMMFChallenge, owf),
  90. SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
  91. { SEC_ASN1_OCTET_STRING, offsetof(CMMFChallenge, witness) },
  92. { SEC_ASN1_ANY, offsetof(CMMFChallenge, senderDER) },
  93. { SEC_ASN1_OCTET_STRING, offsetof(CMMFChallenge, key) },
  94. { SEC_ASN1_OCTET_STRING, offsetof(CMMFChallenge, challenge) },
  95. { 0 }
  96. };
  97. const SEC_ASN1Template CMMFPOPODecKeyChallContentTemplate[] = {
  98. { SEC_ASN1_SEQUENCE_OF, offsetof(CMMFPOPODecKeyChallContent, challenges),
  99. CMMFChallengeTemplate, sizeof(CMMFPOPODecKeyChallContent) },
  100. { 0 }
  101. };
  102. SECStatus
  103. cmmf_decode_process_cert_response(PLArenaPool *poolp,
  104. CERTCertDBHandle *db,
  105. CMMFCertResponse *inCertResp)
  106. {
  107. SECStatus rv = SECSuccess;
  108. if (inCertResp->certifiedKeyPair != NULL) {
  109. rv = cmmf_decode_process_certified_key_pair(poolp,
  110. db,
  111. inCertResp->certifiedKeyPair);
  112. }
  113. return rv;
  114. }
  115. static CERTCertificate *
  116. cmmf_DecodeDERCertificate(CERTCertDBHandle *db, SECItem *derCert)
  117. {
  118. CERTCertificate *newCert;
  119. newCert = CERT_NewTempCertificate(db, derCert, NULL, PR_FALSE, PR_TRUE);
  120. return newCert;
  121. }
  122. static CMMFCertOrEncCertChoice
  123. cmmf_get_certorenccertchoice_from_der(SECItem *der)
  124. {
  125. CMMFCertOrEncCertChoice retChoice;
  126. switch (der->data[0] & 0x0f) {
  127. case 0:
  128. retChoice = cmmfCertificate;
  129. break;
  130. case 1:
  131. retChoice = cmmfEncryptedCert;
  132. break;
  133. default:
  134. retChoice = cmmfNoCertOrEncCert;
  135. break;
  136. }
  137. return retChoice;
  138. }
  139. static SECStatus
  140. cmmf_decode_process_certorenccert(PLArenaPool *poolp,
  141. CERTCertDBHandle *db,
  142. CMMFCertOrEncCert *inCertOrEncCert)
  143. {
  144. SECStatus rv = SECSuccess;
  145. inCertOrEncCert->choice =
  146. cmmf_get_certorenccertchoice_from_der(&inCertOrEncCert->derValue);
  147. switch (inCertOrEncCert->choice) {
  148. case cmmfCertificate: {
  149. /* The DER has implicit tagging, so we gotta switch it to
  150. * un-tagged in order for the ASN1 parser to understand it.
  151. * Saving the bits that were changed.
  152. */
  153. inCertOrEncCert->derValue.data[0] = 0x30;
  154. inCertOrEncCert->cert.certificate =
  155. cmmf_DecodeDERCertificate(db, &inCertOrEncCert->derValue);
  156. if (inCertOrEncCert->cert.certificate == NULL) {
  157. rv = SECFailure;
  158. }
  159. } break;
  160. case cmmfEncryptedCert:
  161. PORT_Assert(poolp);
  162. if (!poolp) {
  163. PORT_SetError(SEC_ERROR_INVALID_ARGS);
  164. rv = SECFailure;
  165. break;
  166. }
  167. inCertOrEncCert->cert.encryptedCert =
  168. PORT_ArenaZNew(poolp, CRMFEncryptedValue);
  169. if (inCertOrEncCert->cert.encryptedCert == NULL) {
  170. rv = SECFailure;
  171. break;
  172. }
  173. rv = SEC_ASN1Decode(poolp, inCertOrEncCert->cert.encryptedCert,
  174. CMMFCertOrEncCertEncryptedCertTemplate,
  175. (const char *)inCertOrEncCert->derValue.data,
  176. inCertOrEncCert->derValue.len);
  177. break;
  178. default:
  179. rv = SECFailure;
  180. }
  181. return rv;
  182. }
  183. SECStatus
  184. cmmf_decode_process_certified_key_pair(PLArenaPool *poolp,
  185. CERTCertDBHandle *db,
  186. CMMFCertifiedKeyPair *inCertKeyPair)
  187. {
  188. return cmmf_decode_process_certorenccert(poolp,
  189. db,
  190. &inCertKeyPair->certOrEncCert);
  191. }