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