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