Updated to hostap_2_6
[mech_eap.git] / libeap / src / tls / tlsv1_client_ocsp.c
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
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
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
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
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
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
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
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 }