xref: /dragonfly/contrib/wpa_supplicant/src/tls/tlsv1_client_ocsp.c (revision 3a84a4273475ed07d0ab1c2dfeffdfedef35d9cd)
1 /*
2  * TLSv1 client - OCSP
3  * Copyright (c) 2015, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "includes.h"
10 
11 #include "common.h"
12 #include "crypto/tls.h"
13 #include "crypto/sha1.h"
14 #include "asn1.h"
15 #include "x509v3.h"
16 #include "tlsv1_common.h"
17 #include "tlsv1_record.h"
18 #include "tlsv1_client.h"
19 #include "tlsv1_client_i.h"
20 
21 
22 /* RFC 6960, 4.2.1: OCSPResponseStatus ::= ENUMERATED */
23 enum ocsp_response_status {
24           OCSP_RESP_STATUS_SUCCESSFUL = 0,
25           OCSP_RESP_STATUS_MALFORMED_REQ = 1,
26           OCSP_RESP_STATUS_INT_ERROR = 2,
27           OCSP_RESP_STATUS_TRY_LATER = 3,
28           /* 4 not used */
29           OCSP_RESP_STATUS_SIG_REQUIRED = 5,
30           OCSP_RESP_STATUS_UNAUTHORIZED = 6,
31 };
32 
33 
is_oid_basic_ocsp_resp(struct asn1_oid * oid)34 static int is_oid_basic_ocsp_resp(struct asn1_oid *oid)
35 {
36           return oid->len == 10 &&
37                     oid->oid[0] == 1 /* iso */ &&
38                     oid->oid[1] == 3 /* identified-organization */ &&
39                     oid->oid[2] == 6 /* dod */ &&
40                     oid->oid[3] == 1 /* internet */ &&
41                     oid->oid[4] == 5 /* security */ &&
42                     oid->oid[5] == 5 /* mechanisms */ &&
43                     oid->oid[6] == 7 /* id-pkix */ &&
44                     oid->oid[7] == 48 /* id-ad */ &&
45                     oid->oid[8] == 1 /* id-pkix-ocsp */ &&
46                     oid->oid[9] == 1 /* id-pkix-ocsp-basic */;
47 }
48 
49 
ocsp_responder_id_match(struct x509_certificate * signer,struct x509_name * name,const u8 * key_hash)50 static int ocsp_responder_id_match(struct x509_certificate *signer,
51                                            struct x509_name *name, const u8 *key_hash)
52 {
53           if (key_hash) {
54                     u8 hash[SHA1_MAC_LEN];
55                     const u8 *addr[1] = { signer->public_key };
56                     size_t len[1] = { signer->public_key_len };
57 
58                     if (sha1_vector(1, addr, len, hash) < 0)
59                               return 0;
60                     return os_memcmp(hash, key_hash, SHA1_MAC_LEN) == 0;
61           }
62 
63           return x509_name_compare(&signer->subject, name) == 0;
64 }
65 
66 
ocsp_hash_data(struct asn1_oid * alg,const u8 * data,size_t data_len,u8 * hash)67 static unsigned int ocsp_hash_data(struct asn1_oid *alg, const u8 *data,
68                                            size_t data_len, u8 *hash)
69 {
70           const u8 *addr[1] = { data };
71           size_t len[1] = { data_len };
72           char buf[100];
73 
74           if (x509_sha1_oid(alg)) {
75                     if (sha1_vector(1, addr, len, hash) < 0)
76                               return 0;
77                     wpa_hexdump(MSG_MSGDUMP, "OCSP: Hash (SHA1)", hash, 20);
78                     return 20;
79           }
80 
81           if (x509_sha256_oid(alg)) {
82                     if (sha256_vector(1, addr, len, hash) < 0)
83                               return 0;
84                     wpa_hexdump(MSG_MSGDUMP, "OCSP: Hash (SHA256)", hash, 32);
85                     return 32;
86           }
87 
88           if (x509_sha384_oid(alg)) {
89                     if (sha384_vector(1, addr, len, hash) < 0)
90                               return 0;
91                     wpa_hexdump(MSG_MSGDUMP, "OCSP: Hash (SHA384)", hash, 48);
92                     return 48;
93           }
94 
95           if (x509_sha512_oid(alg)) {
96                     if (sha512_vector(1, addr, len, hash) < 0)
97                               return 0;
98                     wpa_hexdump(MSG_MSGDUMP, "OCSP: Hash (SHA512)", hash, 64);
99                     return 64;
100           }
101 
102 
103           asn1_oid_to_str(alg, buf, sizeof(buf));
104           wpa_printf(MSG_DEBUG, "OCSP: Could not calculate hash with alg %s",
105                        buf);
106           return 0;
107 }
108 
109 
tls_process_ocsp_single_response(struct tlsv1_client * conn,struct x509_certificate * cert,struct x509_certificate * issuer,const u8 * resp,size_t len,enum tls_ocsp_result * res)110 static int tls_process_ocsp_single_response(struct tlsv1_client *conn,
111                                                       struct x509_certificate *cert,
112                                                       struct x509_certificate *issuer,
113                                                       const u8 *resp, size_t len,
114                                                       enum tls_ocsp_result *res)
115 {
116           struct asn1_hdr hdr;
117           const u8 *pos, *end;
118           struct x509_algorithm_identifier alg;
119           const u8 *name_hash, *key_hash;
120           size_t name_hash_len, key_hash_len;
121           const u8 *serial_number;
122           size_t serial_number_len;
123           u8 hash[64];
124           unsigned int hash_len;
125           unsigned int cert_status;
126           os_time_t update;
127           struct os_time now;
128 
129           wpa_hexdump(MSG_MSGDUMP, "OCSP: SingleResponse", resp, len);
130 
131           /*
132            * SingleResponse ::= SEQUENCE {
133            *    certID                       CertID,
134            *    certStatus                   CertStatus,
135            *    thisUpdate                   GeneralizedTime,
136            *    nextUpdate         [0]       EXPLICIT GeneralizedTime OPTIONAL,
137            *    singleExtensions   [1]       EXPLICIT Extensions OPTIONAL }
138            */
139 
140           /* CertID ::= SEQUENCE */
141           if (asn1_get_next(resp, len, &hdr) < 0 ||
142               hdr.class != ASN1_CLASS_UNIVERSAL ||
143               hdr.tag != ASN1_TAG_SEQUENCE) {
144                     wpa_printf(MSG_DEBUG,
145                                  "OCSP: Expected SEQUENCE (CertID) - found class %d tag 0x%x",
146                                  hdr.class, hdr.tag);
147                     return -1;
148           }
149           pos = hdr.payload;
150           end = hdr.payload + hdr.length;
151 
152           /*
153            * CertID ::= SEQUENCE {
154            *    hashAlgorithm           AlgorithmIdentifier,
155            *    issuerNameHash          OCTET STRING,
156            *    issuerKeyHash           OCTET STRING,
157            *    serialNumber            CertificateSerialNumber }
158            */
159 
160           /* hashAlgorithm  AlgorithmIdentifier */
161           if (x509_parse_algorithm_identifier(pos, end - pos, &alg, &pos))
162                     return -1;
163 
164           /* issuerNameHash  OCTET STRING */
165           if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
166               hdr.class != ASN1_CLASS_UNIVERSAL ||
167               hdr.tag != ASN1_TAG_OCTETSTRING) {
168                     wpa_printf(MSG_DEBUG,
169                                  "OCSP: Expected OCTET STRING (issuerNameHash) - found class %d tag 0x%x",
170                                  hdr.class, hdr.tag);
171                     return -1;
172           }
173           name_hash = hdr.payload;
174           name_hash_len = hdr.length;
175           wpa_hexdump(MSG_DEBUG, "OCSP: issuerNameHash",
176                         name_hash, name_hash_len);
177           pos = hdr.payload + hdr.length;
178 
179           wpa_hexdump(MSG_DEBUG, "OCSP: Issuer subject DN",
180                         issuer->subject_dn, issuer->subject_dn_len);
181           hash_len = ocsp_hash_data(&alg.oid, issuer->subject_dn,
182                                           issuer->subject_dn_len, hash);
183           if (hash_len == 0 || name_hash_len != hash_len ||
184               os_memcmp(name_hash, hash, hash_len) != 0) {
185                     wpa_printf(MSG_DEBUG, "OCSP: issuerNameHash mismatch");
186                     wpa_hexdump(MSG_DEBUG, "OCSP: Calculated issuerNameHash",
187                                   hash, hash_len);
188                     return -1;
189           }
190 
191           /* issuerKeyHash  OCTET STRING */
192           if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
193               hdr.class != ASN1_CLASS_UNIVERSAL ||
194               hdr.tag != ASN1_TAG_OCTETSTRING) {
195                     wpa_printf(MSG_DEBUG,
196                                  "OCSP: Expected OCTET STRING (issuerKeyHash) - found class %d tag 0x%x",
197                                  hdr.class, hdr.tag);
198                     return -1;
199           }
200           key_hash = hdr.payload;
201           key_hash_len = hdr.length;
202           wpa_hexdump(MSG_DEBUG, "OCSP: issuerKeyHash", key_hash, key_hash_len);
203           pos = hdr.payload + hdr.length;
204 
205           hash_len = ocsp_hash_data(&alg.oid, issuer->public_key,
206                                           issuer->public_key_len, hash);
207           if (hash_len == 0 || key_hash_len != hash_len ||
208               os_memcmp(key_hash, hash, hash_len) != 0) {
209                     wpa_printf(MSG_DEBUG, "OCSP: issuerKeyHash mismatch");
210                     wpa_hexdump(MSG_DEBUG, "OCSP: Calculated issuerKeyHash",
211                                   hash, hash_len);
212                     return -1;
213           }
214 
215           /* serialNumber CertificateSerialNumber ::= INTEGER */
216           if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
217               hdr.class != ASN1_CLASS_UNIVERSAL ||
218               hdr.tag != ASN1_TAG_INTEGER ||
219               hdr.length < 1 || hdr.length > X509_MAX_SERIAL_NUM_LEN) {
220                     wpa_printf(MSG_DEBUG, "OCSP: No INTEGER tag found for serialNumber; class=%d tag=0x%x length=%u",
221                                  hdr.class, hdr.tag, hdr.length);
222                     return -1;
223           }
224           serial_number = hdr.payload;
225           serial_number_len = hdr.length;
226           while (serial_number_len > 0 && serial_number[0] == 0) {
227                     serial_number++;
228                     serial_number_len--;
229           }
230           wpa_hexdump(MSG_MSGDUMP, "OCSP: serialNumber", serial_number,
231                         serial_number_len);
232 
233           if (serial_number_len != cert->serial_number_len ||
234               os_memcmp(serial_number, cert->serial_number,
235                           serial_number_len) != 0) {
236                     wpa_printf(MSG_DEBUG, "OCSP: serialNumber mismatch");
237                     return -1;
238           }
239 
240           pos = end;
241           end = resp + len;
242 
243           /* certStatus CertStatus ::= CHOICE */
244           if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
245               hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
246                     wpa_printf(MSG_DEBUG,
247                                  "OCSP: Expected CHOICE (CertStatus) - found class %d tag 0x%x",
248                                  hdr.class, hdr.tag);
249                     return -1;
250           }
251           cert_status = hdr.tag;
252           wpa_printf(MSG_DEBUG, "OCSP: certStatus=%u", cert_status);
253           wpa_hexdump(MSG_DEBUG, "OCSP: CertStatus additional data",
254                         hdr.payload, hdr.length);
255           pos = hdr.payload + hdr.length;
256 
257           os_get_time(&now);
258           /* thisUpdate  GeneralizedTime */
259           if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
260               hdr.class != ASN1_CLASS_UNIVERSAL ||
261               hdr.tag != ASN1_TAG_GENERALIZEDTIME ||
262               x509_parse_time(hdr.payload, hdr.length, hdr.tag, &update) < 0) {
263                     wpa_printf(MSG_DEBUG, "OCSP: Failed to parse thisUpdate");
264                     return -1;
265           }
266           wpa_printf(MSG_DEBUG, "OCSP: thisUpdate %lu", (unsigned long) update);
267           pos = hdr.payload + hdr.length;
268           if ((unsigned long) now.sec < (unsigned long) update) {
269                     wpa_printf(MSG_DEBUG,
270                                  "OCSP: thisUpdate time in the future (response not yet valid)");
271                     return -1;
272           }
273 
274           /* nextUpdate  [0]  EXPLICIT GeneralizedTime OPTIONAL */
275           if (pos < end) {
276                     if (asn1_get_next(pos, end - pos, &hdr) < 0)
277                               return -1;
278                     if (hdr.class == ASN1_CLASS_CONTEXT_SPECIFIC && hdr.tag == 0) {
279                               const u8 *next = hdr.payload + hdr.length;
280 
281                               if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 ||
282                                   hdr.class != ASN1_CLASS_UNIVERSAL ||
283                                   hdr.tag != ASN1_TAG_GENERALIZEDTIME ||
284                                   x509_parse_time(hdr.payload, hdr.length, hdr.tag,
285                                                       &update) < 0) {
286                                         wpa_printf(MSG_DEBUG,
287                                                      "OCSP: Failed to parse nextUpdate");
288                                         return -1;
289                               }
290                               wpa_printf(MSG_DEBUG, "OCSP: nextUpdate %lu",
291                                            (unsigned long) update);
292                               pos = next;
293                               if ((unsigned long) now.sec > (unsigned long) update) {
294                                         wpa_printf(MSG_DEBUG, "OCSP: nextUpdate time in the past (response has expired)");
295                                         return -1;
296                               }
297                     }
298           }
299 
300           /* singleExtensions  [1]  EXPLICIT Extensions OPTIONAL */
301           if (pos < end) {
302                     wpa_hexdump(MSG_MSGDUMP, "OCSP: singleExtensions",
303                                   pos, end - pos);
304                     /* Ignore for now */
305           }
306 
307           if (cert_status == 0 /* good */)
308                     *res = TLS_OCSP_GOOD;
309           else if (cert_status == 1 /* revoked */)
310                     *res = TLS_OCSP_REVOKED;
311           else
312                     return -1;
313           return 0;
314 }
315 
316 
317 static enum tls_ocsp_result
tls_process_ocsp_responses(struct tlsv1_client * conn,struct x509_certificate * cert,struct x509_certificate * issuer,const u8 * resp,size_t len)318 tls_process_ocsp_responses(struct tlsv1_client *conn,
319                                  struct x509_certificate *cert,
320                                  struct x509_certificate *issuer, const u8 *resp,
321                                  size_t len)
322 {
323           struct asn1_hdr hdr;
324           const u8 *pos, *end;
325           enum tls_ocsp_result res;
326 
327           pos = resp;
328           end = resp + len;
329           while (pos < end) {
330                     /* SingleResponse ::= SEQUENCE */
331                     if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
332                         hdr.class != ASN1_CLASS_UNIVERSAL ||
333                         hdr.tag != ASN1_TAG_SEQUENCE) {
334                               wpa_printf(MSG_DEBUG,
335                                            "OCSP: Expected SEQUENCE (SingleResponse) - found class %d tag 0x%x",
336                                            hdr.class, hdr.tag);
337                               return TLS_OCSP_INVALID;
338                     }
339                     if (tls_process_ocsp_single_response(conn, cert, issuer,
340                                                                  hdr.payload, hdr.length,
341                                                                  &res) == 0)
342                               return res;
343                     pos = hdr.payload + hdr.length;
344           }
345 
346           wpa_printf(MSG_DEBUG,
347                        "OCSP: Did not find a response matching the server certificate");
348           return TLS_OCSP_NO_RESPONSE;
349 }
350 
351 
352 static enum tls_ocsp_result
tls_process_basic_ocsp_response(struct tlsv1_client * conn,struct x509_certificate * srv_cert,const u8 * resp,size_t len)353 tls_process_basic_ocsp_response(struct tlsv1_client *conn,
354                                         struct x509_certificate *srv_cert,
355                                         const u8 *resp, size_t len)
356 {
357           struct asn1_hdr hdr;
358           const u8 *pos, *end;
359           const u8 *resp_data, *sign_value, *key_hash = NULL, *responses;
360           const u8 *resp_data_signed;
361           size_t resp_data_len, sign_value_len, responses_len;
362           size_t resp_data_signed_len;
363           struct x509_algorithm_identifier alg;
364           struct x509_certificate *certs = NULL, *last_cert = NULL;
365           struct x509_certificate *issuer, *signer;
366           struct x509_name name; /* used if key_hash == NULL */
367           char buf[100];
368           os_time_t produced_at;
369           enum tls_ocsp_result res;
370 
371           wpa_hexdump(MSG_MSGDUMP, "OCSP: BasicOCSPResponse", resp, len);
372 
373           os_memset(&name, 0, sizeof(name));
374 
375           /*
376            * RFC 6960, 4.2.1:
377            * BasicOCSPResponse       ::= SEQUENCE {
378            *    tbsResponseData      ResponseData,
379            *    signatureAlgorithm   AlgorithmIdentifier,
380            *    signature            BIT STRING,
381            *    certs            [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
382            */
383 
384           if (asn1_get_next(resp, len, &hdr) < 0 ||
385               hdr.class != ASN1_CLASS_UNIVERSAL ||
386               hdr.tag != ASN1_TAG_SEQUENCE) {
387                     wpa_printf(MSG_DEBUG,
388                                  "OCSP: Expected SEQUENCE (BasicOCSPResponse) - found class %d tag 0x%x",
389                                  hdr.class, hdr.tag);
390                     return TLS_OCSP_INVALID;
391           }
392           pos = hdr.payload;
393           end = hdr.payload + hdr.length;
394 
395           /* ResponseData ::= SEQUENCE */
396           if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
397               hdr.class != ASN1_CLASS_UNIVERSAL ||
398               hdr.tag != ASN1_TAG_SEQUENCE) {
399                     wpa_printf(MSG_DEBUG,
400                                  "OCSP: Expected SEQUENCE (ResponseData) - found class %d tag 0x%x",
401                                  hdr.class, hdr.tag);
402                     return TLS_OCSP_INVALID;
403           }
404           resp_data = hdr.payload;
405           resp_data_len = hdr.length;
406           resp_data_signed = pos;
407           pos = hdr.payload + hdr.length;
408           resp_data_signed_len = pos - resp_data_signed;
409 
410           /* signatureAlgorithm  AlgorithmIdentifier */
411           if (x509_parse_algorithm_identifier(pos, end - pos, &alg, &pos))
412                     return TLS_OCSP_INVALID;
413 
414           /* signature  BIT STRING */
415           if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
416               hdr.class != ASN1_CLASS_UNIVERSAL ||
417               hdr.tag != ASN1_TAG_BITSTRING) {
418                     wpa_printf(MSG_DEBUG,
419                                  "OCSP: Expected BITSTRING (signature) - found class %d tag 0x%x",
420                                  hdr.class, hdr.tag);
421                     return TLS_OCSP_INVALID;
422           }
423           if (hdr.length < 1)
424                     return TLS_OCSP_INVALID;
425           pos = hdr.payload;
426           if (*pos) {
427                     wpa_printf(MSG_DEBUG, "OCSP: BITSTRING - %d unused bits", *pos);
428                     /* PKCS #1 v1.5 10.2.1:
429                      * It is an error if the length in bits of the signature S is
430                      * not a multiple of eight.
431                      */
432                     return TLS_OCSP_INVALID;
433           }
434           sign_value = pos + 1;
435           sign_value_len = hdr.length - 1;
436           pos += hdr.length;
437           wpa_hexdump(MSG_MSGDUMP, "OCSP: signature", sign_value, sign_value_len);
438 
439           /* certs  [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL */
440           if (pos < end) {
441                     if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
442                         hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC ||
443                         hdr.tag != 0) {
444                               wpa_printf(MSG_DEBUG,
445                                            "OCSP: Expected [0] EXPLICIT (certs) - found class %d tag 0x%x",
446                                            hdr.class, hdr.tag);
447                               return TLS_OCSP_INVALID;
448                     }
449                     wpa_hexdump(MSG_MSGDUMP, "OCSP: certs",
450                                   hdr.payload, hdr.length);
451                     pos = hdr.payload;
452                     end = hdr.payload + hdr.length;
453                     while (pos < end) {
454                               struct x509_certificate *cert;
455 
456                               if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
457                                   hdr.class != ASN1_CLASS_UNIVERSAL ||
458                                   hdr.tag != ASN1_TAG_SEQUENCE) {
459                                         wpa_printf(MSG_DEBUG,
460                                                      "OCSP: Expected SEQUENCE (Certificate) - found class %d tag 0x%x",
461                                                      hdr.class, hdr.tag);
462                                         goto fail;
463                               }
464 
465                               cert = x509_certificate_parse(hdr.payload, hdr.length);
466                               if (!cert)
467                                         goto fail;
468                               if (last_cert) {
469                                         last_cert->next = cert;
470                                         last_cert = cert;
471                               } else {
472                                         last_cert = certs = cert;
473                               }
474                               pos = hdr.payload + hdr.length;
475                     }
476           }
477 
478           /*
479            * ResponseData ::= SEQUENCE {
480            *    version              [0] EXPLICIT Version DEFAULT v1,
481            *    responderID              ResponderID,
482            *    producedAt               GeneralizedTime,
483            *    responses                SEQUENCE OF SingleResponse,
484            *    responseExtensions   [1] EXPLICIT Extensions OPTIONAL }
485            */
486           pos = resp_data;
487           end = resp_data + resp_data_len;
488           wpa_hexdump(MSG_MSGDUMP, "OCSP: ResponseData", pos, end - pos);
489 
490           /*
491            * version [0] EXPLICIT Version DEFAULT v1
492            * Version ::= INTEGER { v1(0) }
493            */
494           if (asn1_get_next(pos, end - pos, &hdr) < 0 &&
495               hdr.class == ASN1_CLASS_CONTEXT_SPECIFIC &&
496               hdr.tag == 0) {
497                     if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
498                         hdr.class != ASN1_CLASS_UNIVERSAL ||
499                         hdr.tag != ASN1_TAG_INTEGER ||
500                         hdr.length != 1) {
501                               wpa_printf(MSG_DEBUG,
502                                            "OCSP: No INTEGER (len=1) tag found for version field - found class %d tag 0x%x length %d",
503                                            hdr.class, hdr.tag, hdr.length);
504                               goto fail;
505                     }
506                     wpa_printf(MSG_DEBUG, "OCSP: ResponseData version %u",
507                                  hdr.payload[0]);
508                     if (hdr.payload[0] != 0) {
509                               wpa_printf(MSG_DEBUG,
510                                            "OCSP: Unsupported ResponseData version %u",
511                                            hdr.payload[0]);
512                               goto no_resp;
513                     }
514                     pos = hdr.payload + hdr.length;
515           } else {
516                     wpa_printf(MSG_DEBUG,
517                                  "OCSP: Default ResponseData version (v1)");
518           }
519 
520           /*
521            * ResponderID ::= CHOICE {
522            *    byName              [1] Name,
523            *    byKey               [2] KeyHash }
524            */
525           if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
526               hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
527                     wpa_printf(MSG_DEBUG,
528                                  "OCSP: Expected CHOICE (ResponderID) - found class %d tag 0x%x",
529                                  hdr.class, hdr.tag);
530                     goto fail;
531           }
532 
533           if (hdr.tag == 1) {
534                     /* Name */
535                     if (x509_parse_name(hdr.payload, hdr.length, &name, &pos) < 0)
536                               goto fail;
537                     x509_name_string(&name, buf, sizeof(buf));
538                     wpa_printf(MSG_DEBUG, "OCSP: ResponderID byName Name: %s", buf);
539           } else if (hdr.tag == 2) {
540                     /* KeyHash ::= OCTET STRING */
541                     if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 ||
542                         hdr.class != ASN1_CLASS_UNIVERSAL ||
543                         hdr.tag != ASN1_TAG_OCTETSTRING) {
544                               wpa_printf(MSG_DEBUG,
545                                            "OCSP: Expected OCTET STRING (KeyHash) - found class %d tag 0x%x",
546                                            hdr.class, hdr.tag);
547                               goto fail;
548                     }
549                     key_hash = hdr.payload;
550                     wpa_hexdump(MSG_DEBUG, "OCSP: ResponderID byKey KeyHash",
551                                   key_hash, hdr.length);
552                     if (hdr.length != SHA1_MAC_LEN) {
553                               wpa_printf(MSG_DEBUG,
554                                            "OCSP: Unexpected byKey KeyHash length %u - expected %u for SHA-1",
555                                            hdr.length, SHA1_MAC_LEN);
556                               goto fail;
557                     }
558                     pos = hdr.payload + hdr.length;
559           } else {
560                     wpa_printf(MSG_DEBUG, "OCSP: Unexpected ResponderID CHOICE %u",
561                                  hdr.tag);
562                     goto fail;
563           }
564 
565           /* producedAt  GeneralizedTime */
566           if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
567               hdr.class != ASN1_CLASS_UNIVERSAL ||
568               hdr.tag != ASN1_TAG_GENERALIZEDTIME ||
569               x509_parse_time(hdr.payload, hdr.length, hdr.tag,
570                                   &produced_at) < 0) {
571                     wpa_printf(MSG_DEBUG, "OCSP: Failed to parse producedAt");
572                     goto fail;
573           }
574           wpa_printf(MSG_DEBUG, "OCSP: producedAt %lu",
575                        (unsigned long) produced_at);
576           pos = hdr.payload + hdr.length;
577 
578           /* responses  SEQUENCE OF SingleResponse */
579           if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
580               hdr.class != ASN1_CLASS_UNIVERSAL ||
581               hdr.tag != ASN1_TAG_SEQUENCE) {
582                     wpa_printf(MSG_DEBUG,
583                                  "OCSP: Expected SEQUENCE (responses) - found class %d tag 0x%x",
584                                  hdr.class, hdr.tag);
585                     goto fail;
586           }
587           responses = hdr.payload;
588           responses_len = hdr.length;
589           wpa_hexdump(MSG_MSGDUMP, "OCSP: responses", responses, responses_len);
590           pos = hdr.payload + hdr.length;
591 
592           if (pos < end) {
593                     /* responseExtensions  [1] EXPLICIT Extensions OPTIONAL */
594                     wpa_hexdump(MSG_MSGDUMP, "OCSP: responseExtensions",
595                                   pos, end - pos);
596                     /* Ignore for now. */
597           }
598 
599           if (!srv_cert) {
600                     wpa_printf(MSG_DEBUG,
601                                  "OCSP: Server certificate not known - cannot check OCSP response");
602                     goto no_resp;
603           }
604 
605           if (srv_cert->next) {
606                     /* Issuer has already been verified in the chain */
607                     issuer = srv_cert->next;
608           } else {
609                     /* Find issuer from the set of trusted certificates */
610                     for (issuer = conn->cred ? conn->cred->trusted_certs : NULL;
611                          issuer; issuer = issuer->next) {
612                               if (x509_name_compare(&srv_cert->issuer,
613                                                         &issuer->subject) == 0)
614                                         break;
615                     }
616           }
617           if (!issuer) {
618                     wpa_printf(MSG_DEBUG,
619                                  "OCSP: Server certificate issuer not known - cannot check OCSP response");
620                     goto no_resp;
621           }
622 
623           if (ocsp_responder_id_match(issuer, &name, key_hash)) {
624                     wpa_printf(MSG_DEBUG,
625                                  "OCSP: Server certificate issuer certificate matches ResponderID");
626                     signer = issuer;
627           } else {
628                     for (signer = certs; signer; signer = signer->next) {
629                               if (!ocsp_responder_id_match(signer, &name, key_hash) ||
630                                   x509_name_compare(&srv_cert->issuer,
631                                                         &issuer->subject) != 0 ||
632                                   !(signer->ext_key_usage &
633                                     X509_EXT_KEY_USAGE_OCSP) ||
634                                   x509_certificate_check_signature(issuer, signer) <
635                                   0)
636                                         continue;
637                               wpa_printf(MSG_DEBUG,
638                                            "OCSP: An extra certificate from the response matches ResponderID and is trusted as an OCSP signer");
639                               break;
640                     }
641                     if (!signer) {
642                               wpa_printf(MSG_DEBUG,
643                                            "OCSP: Could not find OCSP signer certificate");
644                               goto no_resp;
645                     }
646           }
647 
648           x509_free_name(&name);
649           os_memset(&name, 0, sizeof(name));
650           x509_certificate_chain_free(certs);
651           certs = NULL;
652 
653           if (x509_check_signature(signer, &alg, sign_value, sign_value_len,
654                                          resp_data_signed, resp_data_signed_len) < 0) {
655                         wpa_printf(MSG_DEBUG, "OCSP: Invalid signature");
656                         return TLS_OCSP_INVALID;
657           }
658 
659           res = tls_process_ocsp_responses(conn, srv_cert, issuer,
660                                                    responses, responses_len);
661           if (res == TLS_OCSP_REVOKED)
662                     srv_cert->ocsp_revoked = 1;
663           else if (res == TLS_OCSP_GOOD)
664                     srv_cert->ocsp_good = 1;
665           return res;
666 
667 no_resp:
668           x509_free_name(&name);
669           x509_certificate_chain_free(certs);
670           return TLS_OCSP_NO_RESPONSE;
671 
672 fail:
673           x509_free_name(&name);
674           x509_certificate_chain_free(certs);
675           return TLS_OCSP_INVALID;
676 }
677 
678 
tls_process_ocsp_response(struct tlsv1_client * conn,const u8 * resp,size_t len)679 enum tls_ocsp_result tls_process_ocsp_response(struct tlsv1_client *conn,
680                                                          const u8 *resp, size_t len)
681 {
682           struct asn1_hdr hdr;
683           const u8 *pos, *end;
684           u8 resp_status;
685           struct asn1_oid oid;
686           char obuf[80];
687           struct x509_certificate *cert;
688           enum tls_ocsp_result res = TLS_OCSP_NO_RESPONSE;
689           enum tls_ocsp_result res_first = res;
690 
691           wpa_hexdump(MSG_MSGDUMP, "TLSv1: OCSPResponse", resp, len);
692 
693           /*
694            * RFC 6960, 4.2.1:
695            * OCSPResponse ::= SEQUENCE {
696            *    responseStatus  OCSPResponseStatus,
697            *    responseBytes   [0] EXPLICIT ResponseBytes OPTIONAL }
698            */
699 
700           if (asn1_get_next(resp, len, &hdr) < 0 ||
701               hdr.class != ASN1_CLASS_UNIVERSAL ||
702               hdr.tag != ASN1_TAG_SEQUENCE) {
703                     wpa_printf(MSG_DEBUG,
704                                  "OCSP: Expected SEQUENCE (OCSPResponse) - found class %d tag 0x%x",
705                                  hdr.class, hdr.tag);
706                     return TLS_OCSP_INVALID;
707           }
708           pos = hdr.payload;
709           end = hdr.payload + hdr.length;
710 
711           /* OCSPResponseStatus ::= ENUMERATED */
712           if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
713               hdr.class != ASN1_CLASS_UNIVERSAL ||
714               hdr.tag != ASN1_TAG_ENUMERATED ||
715               hdr.length != 1) {
716                     wpa_printf(MSG_DEBUG,
717                                  "OCSP: Expected ENUMERATED (responseStatus) - found class %d tag 0x%x length %u",
718                                  hdr.class, hdr.tag, hdr.length);
719                     return TLS_OCSP_INVALID;
720           }
721           resp_status = hdr.payload[0];
722           wpa_printf(MSG_DEBUG, "OCSP: responseStatus %u", resp_status);
723           pos = hdr.payload + hdr.length;
724           if (resp_status != OCSP_RESP_STATUS_SUCCESSFUL) {
725                     wpa_printf(MSG_DEBUG, "OCSP: No stapling result");
726                     return TLS_OCSP_NO_RESPONSE;
727           }
728 
729           /* responseBytes   [0] EXPLICIT ResponseBytes OPTIONAL */
730           if (pos == end)
731                     return TLS_OCSP_NO_RESPONSE;
732 
733           if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
734               hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC ||
735               hdr.tag != 0) {
736                     wpa_printf(MSG_DEBUG,
737                                  "OCSP: Expected [0] EXPLICIT (responseBytes) - found class %d tag 0x%x",
738                                  hdr.class, hdr.tag);
739                     return TLS_OCSP_INVALID;
740           }
741 
742           /*
743            * ResponseBytes ::= SEQUENCE {
744            *     responseType   OBJECT IDENTIFIER,
745            *     response       OCTET STRING }
746            */
747 
748           if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 ||
749               hdr.class != ASN1_CLASS_UNIVERSAL ||
750               hdr.tag != ASN1_TAG_SEQUENCE) {
751                     wpa_printf(MSG_DEBUG,
752                                  "OCSP: Expected SEQUENCE (ResponseBytes) - found class %d tag 0x%x",
753                                  hdr.class, hdr.tag);
754                     return TLS_OCSP_INVALID;
755           }
756           pos = hdr.payload;
757           end = hdr.payload + hdr.length;
758 
759           /* responseType   OBJECT IDENTIFIER */
760           if (asn1_get_oid(pos, end - pos, &oid, &pos)) {
761                     wpa_printf(MSG_DEBUG,
762                                  "OCSP: Failed to parse OID (responseType)");
763                     return TLS_OCSP_INVALID;
764           }
765           asn1_oid_to_str(&oid, obuf, sizeof(obuf));
766           wpa_printf(MSG_DEBUG, "OCSP: responseType %s", obuf);
767           if (!is_oid_basic_ocsp_resp(&oid)) {
768                     wpa_printf(MSG_DEBUG, "OCSP: Ignore unsupported response type");
769                     return TLS_OCSP_NO_RESPONSE;
770           }
771 
772           /* response       OCTET STRING */
773           if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
774               hdr.class != ASN1_CLASS_UNIVERSAL ||
775               hdr.tag != ASN1_TAG_OCTETSTRING) {
776                     wpa_printf(MSG_DEBUG,
777                                  "OCSP: Expected OCTET STRING (response) - found class %d tag 0x%x",
778                                  hdr.class, hdr.tag);
779                     return TLS_OCSP_INVALID;
780           }
781 
782           cert = conn->server_cert;
783           while (cert) {
784                     if (!cert->ocsp_good && !cert->ocsp_revoked) {
785                               char sbuf[128];
786 
787                               x509_name_string(&cert->subject, sbuf, sizeof(sbuf));
788                               wpa_printf(MSG_DEBUG,
789                                            "OCSP: Trying to find certificate status for %s",
790                                            sbuf);
791 
792                               res = tls_process_basic_ocsp_response(conn, cert,
793                                                                             hdr.payload,
794                                                                             hdr.length);
795                               if (cert == conn->server_cert)
796                                         res_first = res;
797                     }
798                     if (res == TLS_OCSP_REVOKED || cert->issuer_trusted)
799                               break;
800                     cert = cert->next;
801           }
802           return res == TLS_OCSP_REVOKED ? res : res_first;
803 }
804