| 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 | |
| 90 (ourPool, point->distPoint.fullName); | |
| 91 | |
| 92 if (!point->derFullName || | |
| 93 !SEC_ASN1EncodeItem (ourPool, &point->derDistPoint, | |
| 94 point, FullNameTemplate)) | |
| 95 rv = SECFailure; | |
| 96 break; | |
| 97 | |
| 98 case relativeDistinguishedName: | |
| 99 if (!SEC_ASN1EncodeItem(ourPool, &point->derDistPoint, | |
| 100 point, RelativeNameTemplate)) | |
| 101 rv = SECFailure; | |
| 102 break; | |
| 103 | |
| 104 /* distributionPointName is omitted */ | |
| 105 case 0: break; | |
| 106 | |
| 107 default: | |
| 108 PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID); | |
| 109 rv = SECFailure; | |
| 110 break; | |
| 111 } | |
| 112 | |
| 113 if (rv != SECSuccess) | |
| 114 break; | |
| 115 | |
| 116 if (point->reasons.data) | |
| 117 PrepareBitStringForEncoding (&point->bitsmap, &point->reasons); | |
| 118 | |
| 119 if (point->crlIssuer) { | |
| 120 point->derCrlIssuer = cert_EncodeGeneralNames | |
| 121 (ourPool, point->crlIssuer); | |
| 122 if (!point->derCrlIssuer) { | |
| 123 rv = SECFailure; | |
| 124 break; | |
| 125 } | |
| 126 } | |
| 127 ++pointList; | |
| 128 } | |
| 129 if (rv != SECSuccess) | |
| 130 break; | |
| 131 if (!SEC_ASN1EncodeItem(arena, derValue, value, | |
| 132 CERTCRLDistributionPointsTemplate)) { | |
| 133 rv = SECFailure; | |
| 134 break; | |
| 135 } | |
| 136 } while (0); | |
| 137 PORT_FreeArena (ourPool, PR_FALSE); | |
| 138 return rv; | |
| 139 } | |
| 140 | |
| 141 CERTCrlDistributionPoints * | |
| 142 CERT_DecodeCRLDistributionPoints (PLArenaPool *arena, SECItem *encodedValue) | |
| 143 { | |
| 144 CERTCrlDistributionPoints *value = NULL; | |
| 145 CRLDistributionPoint **pointList, *point; | |
| 146 SECStatus rv = SECSuccess; | |
| 147 SECItem newEncodedValue; | |
| 148 | |
| 149 PORT_Assert (arena); | |
| 150 do { | |
| 151 value = PORT_ArenaZNew(arena, CERTCrlDistributionPoints); | |
| 152 if (value == NULL) { | |
| 153 rv = SECFailure; | |
| 154 break; | |
| 155 } | |
| 156 | |
| 157 /* copy the DER into the arena, since Quick DER returns data that points | |
| 158 into the DER input, which may get freed by the caller */ | |
| 159 rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue); | |
| 160 if (rv != SECSuccess) | |
| 161 break; | |
| 162 | |
| 163 rv = SEC_QuickDERDecodeItem(arena, &value->distPoints, | |
| 164 CERTCRLDistributionPointsTemplate, &newEncodedValue); | |
| 165 if (rv != SECSuccess) | |
| 166 break; | |
| 167 | |
| 168 pointList = value->distPoints; | |
| 169 while (NULL != (point = *pointList)) { | |
| 170 | |
| 171 /* get the data if the distributionPointName is not omitted */ | |
| 172 if (point->derDistPoint.data != NULL) { | |
| 173 rv = SEC_QuickDERDecodeItem(arena, point, | |
| 174 DistributionPointNameTemplate, &(point->derDistPoint)); | |
| 175 if (rv != SECSuccess) | |
| 176 break; | |
| 177 | |
| 178 switch (point->distPointType) { | |
| 179 case generalName: | |
| 180 point->distPoint.fullName = | |
| 181 cert_DecodeGeneralNames(arena, point->derFullName); | |
| 182 rv = point->distPoint.fullName ? SECSuccess : SECFailure; | |
| 183 break; | |
| 184 | |
| 185 case relativeDistinguishedName: | |
| 186 break; | |
| 187 | |
| 188 default: | |
| 189 PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID); | |
| 190 rv = SECFailure; | |
| 191 break; | |
| 192 } /* end switch */ | |
| 193 if (rv != SECSuccess) | |
| 194 break; | |
| 195 } /* end if */ | |
| 196 | |
| 197 /* Get the reason code if it's not omitted in the encoding */ | |
| 198 if (point->bitsmap.data != NULL) { | |
| 199 SECItem bitsmap = point->bitsmap; | |
| 200 DER_ConvertBitString(&bitsmap); | |
| 201 rv = SECITEM_CopyItem(arena, &point->reasons, &bitsmap); | |
| 202 if (rv != SECSuccess) | |
| 203 break; | |
| 204 } | |
| 205 | |
| 206 /* Get the crl issuer name if it's not omitted in the encoding */ | |
| 207 if (point->derCrlIssuer != NULL) { | |
| 208 point->crlIssuer = cert_DecodeGeneralNames(arena, | |
| 209 point->derCrlIssuer); | |
| 210 if (!point->crlIssuer) | |
| 211 break; | |
| 212 } | |
| 213 ++pointList; | |
| 214 } /* end while points remain */ | |
| 215 } while (0); | |
| 216 return (rv == SECSuccess ? value : NULL); | |
| 217 } | |
| OLD | NEW |