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 |