| OLD | NEW |
| (Empty) |
| 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 /* | |
| 6 * Code for dealing with x.509 v3 CRL Distribution Point extension. | |
| 7 */ | |
| 8 #include "genname.h" | |
| 9 #include "certt.h" | |
| 10 #include "secerr.h" | |
| 11 | |
| 12 SEC_ASN1_MKSUB(SEC_AnyTemplate) | |
| 13 SEC_ASN1_MKSUB(SEC_BitStringTemplate) | |
| 14 | |
| 15 extern void PrepareBitStringForEncoding(SECItem *bitMap, SECItem *value); | |
| 16 | |
| 17 static const SEC_ASN1Template FullNameTemplate[] = { | |
| 18 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0, | |
| 19 offsetof(CRLDistributionPoint, derFullName), | |
| 20 CERT_GeneralNamesTemplate } | |
| 21 }; | |
| 22 | |
| 23 static const SEC_ASN1Template RelativeNameTemplate[] = { | |
| 24 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 1, | |
| 25 offsetof(CRLDistributionPoint, distPoint.relativeName), | |
| 26 CERT_RDNTemplate } | |
| 27 }; | |
| 28 | |
| 29 static const SEC_ASN1Template DistributionPointNameTemplate[] = { | |
| 30 { SEC_ASN1_CHOICE, | |
| 31 offsetof(CRLDistributionPoint, distPointType), NULL, | |
| 32 sizeof(CRLDistributionPoint) }, | |
| 33 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0, | |
| 34 offsetof(CRLDistributionPoint, derFullName), | |
| 35 CERT_GeneralNamesTemplate, generalName }, | |
| 36 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 1, | |
| 37 offsetof(CRLDistributionPoint, distPoint.relativeName), | |
| 38 CERT_RDNTemplate, relativeDistinguishedName }, | |
| 39 { 0 } | |
| 40 }; | |
| 41 | |
| 42 static const SEC_ASN1Template CRLDistributionPointTemplate[] = { | |
| 43 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CRLDistributionPoint) }, | |
| 44 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | | |
| 45 SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | SEC_ASN1_XTRN | 0, | |
| 46 offsetof(CRLDistributionPoint, derDistPoint), | |
| 47 SEC_ASN1_SUB(SEC_AnyTemplate) }, | |
| 48 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1, | |
| 49 offsetof(CRLDistributionPoint, bitsmap), | |
| 50 SEC_ASN1_SUB(SEC_BitStringTemplate) }, | |
| 51 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | | |
| 52 SEC_ASN1_CONSTRUCTED | 2, | |
| 53 offsetof(CRLDistributionPoint, derCrlIssuer), | |
| 54 CERT_GeneralNamesTemplate }, | |
| 55 { 0 } | |
| 56 }; | |
| 57 | |
| 58 const SEC_ASN1Template CERTCRLDistributionPointsTemplate[] = { | |
| 59 { SEC_ASN1_SEQUENCE_OF, 0, CRLDistributionPointTemplate } | |
| 60 }; | |
| 61 | |
| 62 SECStatus | |
| 63 CERT_EncodeCRLDistributionPoints(PLArenaPool *arena, | |
| 64 CERTCrlDistributionPoints *value, | |
| 65 SECItem *derValue) | |
| 66 { | |
| 67 CRLDistributionPoint **pointList, *point; | |
| 68 PLArenaPool *ourPool = NULL; | |
| 69 SECStatus rv = SECSuccess; | |
| 70 | |
| 71 PORT_Assert(derValue); | |
| 72 PORT_Assert(value && value->distPoints); | |
| 73 | |
| 74 do { | |
| 75 ourPool = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); | |
| 76 if (ourPool == NULL) { | |
| 77 rv = SECFailure; | |
| 78 break; | |
| 79 } | |
| 80 | |
| 81 pointList = value->distPoints; | |
| 82 while (*pointList) { | |
| 83 point = *pointList; | |
| 84 point->derFullName = NULL; | |
| 85 point->derDistPoint.data = NULL; | |
| 86 | |
| 87 switch (point->distPointType) { | |
| 88 case generalName: | |
| 89 point->derFullName = cert_EncodeGeneralNames(ourPool, point-
>distPoint.fullName); | |
| 90 | |
| 91 if (!point->derFullName || | |
| 92 !SEC_ASN1EncodeItem(ourPool, &point->derDistPoint, | |
| 93 point, FullNameTemplate)) | |
| 94 rv = SECFailure; | |
| 95 break; | |
| 96 | |
| 97 case relativeDistinguishedName: | |
| 98 if (!SEC_ASN1EncodeItem(ourPool, &point->derDistPoint, | |
| 99 point, RelativeNameTemplate)) | |
| 100 rv = SECFailure; | |
| 101 break; | |
| 102 | |
| 103 default: | |
| 104 PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID); | |
| 105 rv = SECFailure; | |
| 106 break; | |
| 107 } | |
| 108 | |
| 109 if (rv != SECSuccess) | |
| 110 break; | |
| 111 | |
| 112 if (point->reasons.data) | |
| 113 PrepareBitStringForEncoding(&point->bitsmap, &point->reasons); | |
| 114 | |
| 115 if (point->crlIssuer) { | |
| 116 point->derCrlIssuer = cert_EncodeGeneralNames(ourPool, point->cr
lIssuer); | |
| 117 if (!point->derCrlIssuer) { | |
| 118 rv = SECFailure; | |
| 119 break; | |
| 120 } | |
| 121 } | |
| 122 ++pointList; | |
| 123 } | |
| 124 if (rv != SECSuccess) | |
| 125 break; | |
| 126 if (!SEC_ASN1EncodeItem(arena, derValue, value, | |
| 127 CERTCRLDistributionPointsTemplate)) { | |
| 128 rv = SECFailure; | |
| 129 break; | |
| 130 } | |
| 131 } while (0); | |
| 132 PORT_FreeArena(ourPool, PR_FALSE); | |
| 133 return rv; | |
| 134 } | |
| 135 | |
| 136 CERTCrlDistributionPoints * | |
| 137 CERT_DecodeCRLDistributionPoints(PLArenaPool *arena, SECItem *encodedValue) | |
| 138 { | |
| 139 CERTCrlDistributionPoints *value = NULL; | |
| 140 CRLDistributionPoint **pointList, *point; | |
| 141 SECStatus rv = SECSuccess; | |
| 142 SECItem newEncodedValue; | |
| 143 | |
| 144 PORT_Assert(arena); | |
| 145 do { | |
| 146 value = PORT_ArenaZNew(arena, CERTCrlDistributionPoints); | |
| 147 if (value == NULL) { | |
| 148 rv = SECFailure; | |
| 149 break; | |
| 150 } | |
| 151 | |
| 152 /* copy the DER into the arena, since Quick DER returns data that points | |
| 153 into the DER input, which may get freed by the caller */ | |
| 154 rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue); | |
| 155 if (rv != SECSuccess) | |
| 156 break; | |
| 157 | |
| 158 rv = SEC_QuickDERDecodeItem(arena, &value->distPoints, | |
| 159 CERTCRLDistributionPointsTemplate, &newEncod
edValue); | |
| 160 if (rv != SECSuccess) | |
| 161 break; | |
| 162 | |
| 163 pointList = value->distPoints; | |
| 164 while (NULL != (point = *pointList)) { | |
| 165 | |
| 166 /* get the data if the distributionPointName is not omitted */ | |
| 167 if (point->derDistPoint.data != NULL) { | |
| 168 rv = SEC_QuickDERDecodeItem(arena, point, | |
| 169 DistributionPointNameTemplate, &(poi
nt->derDistPoint)); | |
| 170 if (rv != SECSuccess) | |
| 171 break; | |
| 172 | |
| 173 switch (point->distPointType) { | |
| 174 case generalName: | |
| 175 point->distPoint.fullName = | |
| 176 cert_DecodeGeneralNames(arena, point->derFullName); | |
| 177 rv = point->distPoint.fullName ? SECSuccess : SECFailure
; | |
| 178 break; | |
| 179 | |
| 180 case relativeDistinguishedName: | |
| 181 break; | |
| 182 | |
| 183 default: | |
| 184 PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID); | |
| 185 rv = SECFailure; | |
| 186 break; | |
| 187 } /* end switch */ | |
| 188 if (rv != SECSuccess) | |
| 189 break; | |
| 190 } /* end if */ | |
| 191 | |
| 192 /* Get the reason code if it's not omitted in the encoding */ | |
| 193 if (point->bitsmap.data != NULL) { | |
| 194 SECItem bitsmap = point->bitsmap; | |
| 195 DER_ConvertBitString(&bitsmap); | |
| 196 rv = SECITEM_CopyItem(arena, &point->reasons, &bitsmap); | |
| 197 if (rv != SECSuccess) | |
| 198 break; | |
| 199 } | |
| 200 | |
| 201 /* Get the crl issuer name if it's not omitted in the encoding */ | |
| 202 if (point->derCrlIssuer != NULL) { | |
| 203 point->crlIssuer = cert_DecodeGeneralNames(arena, | |
| 204 point->derCrlIssuer); | |
| 205 if (!point->crlIssuer) | |
| 206 break; | |
| 207 } | |
| 208 ++pointList; | |
| 209 } /* end while points remain */ | |
| 210 } while (0); | |
| 211 return (rv == SECSuccess ? value : NULL); | |
| 212 } | |
| OLD | NEW |