xconst.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  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. /*
  5. * X.509 Extension Encoding
  6. */
  7. #include "prtypes.h"
  8. #include "seccomon.h"
  9. #include "secdert.h"
  10. #include "secoidt.h"
  11. #include "secasn1t.h"
  12. #include "secasn1.h"
  13. #include "cert.h"
  14. #include "secder.h"
  15. #include "prprf.h"
  16. #include "xconst.h"
  17. #include "genname.h"
  18. #include "secasn1.h"
  19. #include "secerr.h"
  20. static const SEC_ASN1Template CERTSubjectKeyIDTemplate[] = {
  21. { SEC_ASN1_OCTET_STRING }
  22. };
  23. static const SEC_ASN1Template CERTIA5TypeTemplate[] = {
  24. { SEC_ASN1_IA5_STRING }
  25. };
  26. SEC_ASN1_MKSUB(SEC_GeneralizedTimeTemplate)
  27. static const SEC_ASN1Template CERTPrivateKeyUsagePeriodTemplate[] = {
  28. { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTPrivKeyUsagePeriod) },
  29. { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
  30. offsetof(CERTPrivKeyUsagePeriod, notBefore),
  31. SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) },
  32. { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
  33. offsetof(CERTPrivKeyUsagePeriod, notAfter),
  34. SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) },
  35. { 0 }
  36. };
  37. const SEC_ASN1Template CERTAltNameTemplate[] = {
  38. { SEC_ASN1_CONSTRUCTED, offsetof(CERTAltNameEncodedContext, encodedGenName),
  39. CERT_GeneralNamesTemplate }
  40. };
  41. const SEC_ASN1Template CERTAuthInfoAccessItemTemplate[] = {
  42. { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAuthInfoAccess) },
  43. { SEC_ASN1_OBJECT_ID, offsetof(CERTAuthInfoAccess, method) },
  44. { SEC_ASN1_ANY, offsetof(CERTAuthInfoAccess, derLocation) },
  45. { 0 }
  46. };
  47. const SEC_ASN1Template CERTAuthInfoAccessTemplate[] = {
  48. { SEC_ASN1_SEQUENCE_OF, 0, CERTAuthInfoAccessItemTemplate }
  49. };
  50. SECStatus
  51. CERT_EncodeSubjectKeyID(PLArenaPool *arena, const SECItem *srcString,
  52. SECItem *encodedValue)
  53. {
  54. SECStatus rv = SECSuccess;
  55. if (!srcString) {
  56. PORT_SetError(SEC_ERROR_INVALID_ARGS);
  57. return SECFailure;
  58. }
  59. if (SEC_ASN1EncodeItem(arena, encodedValue, srcString,
  60. CERTSubjectKeyIDTemplate) == NULL) {
  61. rv = SECFailure;
  62. }
  63. return (rv);
  64. }
  65. SECStatus
  66. CERT_EncodePrivateKeyUsagePeriod(PLArenaPool *arena,
  67. CERTPrivKeyUsagePeriod *pkup,
  68. SECItem *encodedValue)
  69. {
  70. SECStatus rv = SECSuccess;
  71. if (SEC_ASN1EncodeItem(arena, encodedValue, pkup,
  72. CERTPrivateKeyUsagePeriodTemplate) == NULL) {
  73. rv = SECFailure;
  74. }
  75. return (rv);
  76. }
  77. CERTPrivKeyUsagePeriod *
  78. CERT_DecodePrivKeyUsagePeriodExtension(PLArenaPool *arena, SECItem *extnValue)
  79. {
  80. SECStatus rv;
  81. CERTPrivKeyUsagePeriod *pPeriod;
  82. SECItem newExtnValue;
  83. /* allocate the certificate policies structure */
  84. pPeriod = PORT_ArenaZNew(arena, CERTPrivKeyUsagePeriod);
  85. if (pPeriod == NULL) {
  86. goto loser;
  87. }
  88. pPeriod->arena = arena;
  89. /* copy the DER into the arena, since Quick DER returns data that points
  90. into the DER input, which may get freed by the caller */
  91. rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue);
  92. if (rv != SECSuccess) {
  93. goto loser;
  94. }
  95. rv = SEC_QuickDERDecodeItem(
  96. arena, pPeriod, CERTPrivateKeyUsagePeriodTemplate, &newExtnValue);
  97. if (rv != SECSuccess) {
  98. goto loser;
  99. }
  100. return pPeriod;
  101. loser:
  102. return NULL;
  103. }
  104. SECStatus
  105. CERT_EncodeIA5TypeExtension(PLArenaPool *arena, char *value,
  106. SECItem *encodedValue)
  107. {
  108. SECItem encodeContext;
  109. SECStatus rv = SECSuccess;
  110. PORT_Memset(&encodeContext, 0, sizeof(encodeContext));
  111. if (value != NULL) {
  112. encodeContext.data = (unsigned char *)value;
  113. encodeContext.len = strlen(value);
  114. }
  115. if (SEC_ASN1EncodeItem(arena, encodedValue, &encodeContext,
  116. CERTIA5TypeTemplate) == NULL) {
  117. rv = SECFailure;
  118. }
  119. return (rv);
  120. }
  121. SECStatus
  122. CERT_EncodeAltNameExtension(PLArenaPool *arena, CERTGeneralName *value,
  123. SECItem *encodedValue)
  124. {
  125. SECItem **encodedGenName;
  126. SECStatus rv = SECSuccess;
  127. encodedGenName = cert_EncodeGeneralNames(arena, value);
  128. if (SEC_ASN1EncodeItem(arena, encodedValue, &encodedGenName,
  129. CERT_GeneralNamesTemplate) == NULL) {
  130. rv = SECFailure;
  131. }
  132. return rv;
  133. }
  134. CERTGeneralName *
  135. CERT_DecodeAltNameExtension(PLArenaPool *reqArena, SECItem *EncodedAltName)
  136. {
  137. SECStatus rv = SECSuccess;
  138. CERTAltNameEncodedContext encodedContext;
  139. SECItem *newEncodedAltName;
  140. if (!reqArena) {
  141. PORT_SetError(SEC_ERROR_INVALID_ARGS);
  142. return NULL;
  143. }
  144. newEncodedAltName = SECITEM_ArenaDupItem(reqArena, EncodedAltName);
  145. if (!newEncodedAltName) {
  146. return NULL;
  147. }
  148. encodedContext.encodedGenName = NULL;
  149. PORT_Memset(&encodedContext, 0, sizeof(CERTAltNameEncodedContext));
  150. rv = SEC_QuickDERDecodeItem(reqArena, &encodedContext,
  151. CERT_GeneralNamesTemplate, newEncodedAltName);
  152. if (rv == SECFailure) {
  153. goto loser;
  154. }
  155. if (encodedContext.encodedGenName && encodedContext.encodedGenName[0])
  156. return cert_DecodeGeneralNames(reqArena, encodedContext.encodedGenName);
  157. /* Extension contained an empty GeneralNames sequence */
  158. /* Treat as extension not found */
  159. PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
  160. loser:
  161. return NULL;
  162. }
  163. SECStatus
  164. CERT_EncodeNameConstraintsExtension(PLArenaPool *arena,
  165. CERTNameConstraints *value,
  166. SECItem *encodedValue)
  167. {
  168. SECStatus rv = SECSuccess;
  169. rv = cert_EncodeNameConstraints(value, arena, encodedValue);
  170. return rv;
  171. }
  172. CERTNameConstraints *
  173. CERT_DecodeNameConstraintsExtension(PLArenaPool *arena,
  174. const SECItem *encodedConstraints)
  175. {
  176. return cert_DecodeNameConstraints(arena, encodedConstraints);
  177. }
  178. CERTAuthInfoAccess **
  179. CERT_DecodeAuthInfoAccessExtension(PLArenaPool *reqArena,
  180. const SECItem *encodedExtension)
  181. {
  182. CERTAuthInfoAccess **info = NULL;
  183. SECStatus rv;
  184. int i;
  185. SECItem *newEncodedExtension;
  186. if (!reqArena) {
  187. PORT_SetError(SEC_ERROR_INVALID_ARGS);
  188. return NULL;
  189. }
  190. newEncodedExtension = SECITEM_ArenaDupItem(reqArena, encodedExtension);
  191. if (!newEncodedExtension) {
  192. return NULL;
  193. }
  194. rv = SEC_QuickDERDecodeItem(reqArena, &info, CERTAuthInfoAccessTemplate,
  195. newEncodedExtension);
  196. if (rv != SECSuccess || info == NULL) {
  197. return NULL;
  198. }
  199. for (i = 0; info[i] != NULL; i++) {
  200. info[i]->location =
  201. CERT_DecodeGeneralName(reqArena, &(info[i]->derLocation), NULL);
  202. }
  203. return info;
  204. }
  205. SECStatus
  206. CERT_EncodeInfoAccessExtension(PLArenaPool *arena, CERTAuthInfoAccess **info,
  207. SECItem *dest)
  208. {
  209. SECItem *dummy;
  210. int i;
  211. PORT_Assert(info != NULL);
  212. PORT_Assert(dest != NULL);
  213. if (info == NULL || dest == NULL) {
  214. return SECFailure;
  215. }
  216. for (i = 0; info[i] != NULL; i++) {
  217. if (CERT_EncodeGeneralName(info[i]->location, &(info[i]->derLocation),
  218. arena) == NULL)
  219. /* Note that this may leave some of the locations filled in. */
  220. return SECFailure;
  221. }
  222. dummy = SEC_ASN1EncodeItem(arena, dest, &info, CERTAuthInfoAccessTemplate);
  223. if (dummy == NULL) {
  224. return SECFailure;
  225. }
  226. return SECSuccess;
  227. }