@@ -98,6 +98,27 @@ static int ext_cmp(const void *void_a, const void *void_b) {
98
98
return ext_stack_cmp (a , b );
99
99
}
100
100
101
+ static int x509v3_ext_method_validate (const X509V3_EXT_METHOD * ext_method ) {
102
+ if (ext_method == NULL ) {
103
+ return 0 ;
104
+ }
105
+
106
+ if (ext_method -> ext_nid == NID_id_pkix_OCSP_Nonce &&
107
+ ext_method -> d2i != NULL && ext_method -> i2d != NULL &&
108
+ ext_method -> ext_new != NULL && ext_method -> ext_free != NULL ) {
109
+ // |NID_id_pkix_OCSP_Nonce| is the only extension using the "old-style"
110
+ // ASN.1 callbacks for backwards compatibility reasons.
111
+ // Note: See |v3_ext_method| under "include/openssl/x509.h".
112
+ return 1 ;
113
+ }
114
+
115
+ if (ext_method -> it == NULL ) {
116
+ OPENSSL_PUT_ERROR (X509V3 , X509V3_R_OPERATION_NOT_DEFINED );
117
+ return 0 ;
118
+ }
119
+ return 1 ;
120
+ }
121
+
101
122
const X509V3_EXT_METHOD * X509V3_EXT_get_nid (int nid ) {
102
123
X509V3_EXT_METHOD tmp ;
103
124
const X509V3_EXT_METHOD * t = & tmp , * const * ret ;
@@ -109,7 +130,7 @@ const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid) {
109
130
tmp .ext_nid = nid ;
110
131
ret = bsearch (& t , standard_exts , STANDARD_EXTENSION_COUNT ,
111
132
sizeof (X509V3_EXT_METHOD * ), ext_cmp );
112
- if (ret ) {
133
+ if (ret != NULL && x509v3_ext_method_validate ( * ret ) ) {
113
134
return * ret ;
114
135
}
115
136
if (!ext_list ) {
@@ -119,7 +140,12 @@ const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid) {
119
140
if (!sk_X509V3_EXT_METHOD_find_awslc (ext_list , & idx , & tmp )) {
120
141
return NULL ;
121
142
}
122
- return sk_X509V3_EXT_METHOD_value (ext_list , idx );
143
+
144
+ const X509V3_EXT_METHOD * method = sk_X509V3_EXT_METHOD_value (ext_list , idx );
145
+ if (method != NULL && x509v3_ext_method_validate (method )) {
146
+ return method ;
147
+ }
148
+ return NULL ;
123
149
}
124
150
125
151
const X509V3_EXT_METHOD * X509V3_EXT_get (const X509_EXTENSION * ext ) {
@@ -130,19 +156,34 @@ const X509V3_EXT_METHOD *X509V3_EXT_get(const X509_EXTENSION *ext) {
130
156
return X509V3_EXT_get_nid (nid );
131
157
}
132
158
133
- int X509V3_EXT_free ( int nid , void * ext_data ) {
134
- const X509V3_EXT_METHOD * ext_method = X509V3_EXT_get_nid ( nid );
159
+ int x509v3_ext_free_with_method ( const X509V3_EXT_METHOD * ext_method ,
160
+ void * ext_data ) {
135
161
if (ext_method == NULL ) {
136
162
OPENSSL_PUT_ERROR (X509V3 , X509V3_R_CANNOT_FIND_FREE_FUNCTION );
137
163
return 0 ;
138
164
}
139
165
140
- ASN1_item_free (ext_data , ASN1_ITEM_ptr (ext_method -> it ));
166
+ if (ext_method -> it != NULL ) {
167
+ ASN1_item_free (ext_data , ASN1_ITEM_ptr (ext_method -> it ));
168
+ } else if (ext_method -> ext_nid == NID_id_pkix_OCSP_Nonce &&
169
+ ext_method -> ext_free != NULL ) {
170
+ // |NID_id_pkix_OCSP_Nonce| is the only extension using the "old-style"
171
+ // ASN.1 callbacks for backwards compatibility reasons.
172
+ // Note: See |v3_ext_method| under "include/openssl/x509.h".
173
+ ext_method -> ext_free (ext_data );
174
+ } else {
175
+ OPENSSL_PUT_ERROR (X509V3 , X509V3_R_CANNOT_FIND_FREE_FUNCTION );
176
+ return 0 ;
177
+ }
141
178
return 1 ;
142
179
}
143
180
181
+ int X509V3_EXT_free (int nid , void * ext_data ) {
182
+ return x509v3_ext_free_with_method (X509V3_EXT_get_nid (nid ), ext_data );
183
+ }
184
+
144
185
int X509V3_EXT_add_alias (int nid_to , int nid_from ) {
145
- OPENSSL_BEGIN_ALLOW_DEPRECATED
186
+ OPENSSL_BEGIN_ALLOW_DEPRECATED
146
187
const X509V3_EXT_METHOD * ext ;
147
188
X509V3_EXT_METHOD * tmpext ;
148
189
@@ -161,7 +202,7 @@ OPENSSL_BEGIN_ALLOW_DEPRECATED
161
202
return 0 ;
162
203
}
163
204
return 1 ;
164
- OPENSSL_END_ALLOW_DEPRECATED
205
+ OPENSSL_END_ALLOW_DEPRECATED
165
206
}
166
207
167
208
// Legacy function: we don't need to add standard extensions any more because
@@ -179,14 +220,25 @@ void *X509V3_EXT_d2i(const X509_EXTENSION *ext) {
179
220
return NULL ;
180
221
}
181
222
p = ext -> value -> data ;
182
- void * ret =
183
- ASN1_item_d2i (NULL , & p , ext -> value -> length , ASN1_ITEM_ptr (method -> it ));
223
+ void * ret = NULL ;
224
+ if (method -> it ) {
225
+ ret =
226
+ ASN1_item_d2i (NULL , & p , ext -> value -> length , ASN1_ITEM_ptr (method -> it ));
227
+ } else if (method -> ext_nid == NID_id_pkix_OCSP_Nonce && method -> d2i != NULL ) {
228
+ // |NID_id_pkix_OCSP_Nonce| is the only extension using the "old-style"
229
+ // ASN.1 callbacks for backwards compatibility reasons.
230
+ // Note: See |v3_ext_method| under "include/openssl/x509.h".
231
+ ret = method -> d2i (NULL , & p , ext -> value -> length );
232
+ } else {
233
+ assert (0 );
234
+ }
235
+
184
236
if (ret == NULL ) {
185
237
return NULL ;
186
238
}
187
239
// Check for trailing data.
188
240
if (p != ext -> value -> data + ext -> value -> length ) {
189
- ASN1_item_free ( ret , ASN1_ITEM_ptr ( method -> it ) );
241
+ x509v3_ext_free_with_method ( method , ret );
190
242
OPENSSL_PUT_ERROR (X509V3 , X509V3_R_TRAILING_DATA_IN_EXTENSION );
191
243
return NULL ;
192
244
}
0 commit comments