Coverage Report

Created: 2025-07-11 06:14

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