1 /*
2  * Copyright (C) 2019-2021 Nicola Di Lieto <nicola.dilieto@gmail.com>
3  *
4  * This file is part of uacme.
5  *
6  * uacme is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * uacme is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "config.h"
22 
23 #include <arpa/inet.h>
24 #include <err.h>
25 #include <errno.h>
26 #include <netdb.h>
27 #include <netinet/in.h>
28 #include <stdarg.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <sys/stat.h>
33 #include <sys/socket.h>
34 #include <sys/types.h>
35 #include <unistd.h>
36 
37 #include "base64.h"
38 #include "crypto.h"
39 #include "curlwrap.h"
40 #include "msg.h"
41 #if !defined(USE_OPENSSL)
42 #include "read-file.h"
43 #endif
44 
45 #if defined(USE_GNUTLS)
46 #include <gnutls/crypto.h>
47 #include <gnutls/ocsp.h>
48 #if HAVE_GNUTLS_X509_CRQ_SET_TLSFEATURES
49 #include <gnutls/x509-ext.h>
50 #endif
51 #if !HAVE_GNUTLS_DECODE_RS_VALUE
52 #include <libtasn1.h>
53 #endif
54 #elif defined(USE_OPENSSL)
55 #include <openssl/asn1.h>
56 #include <openssl/bio.h>
57 #include <openssl/bn.h>
58 #include <openssl/crypto.h>
59 #include <openssl/engine.h>
60 #include <openssl/err.h>
61 #include <openssl/evp.h>
62 #include <openssl/hmac.h>
63 #include <openssl/ocsp.h>
64 #include <openssl/opensslv.h>
65 #include <openssl/pem.h>
66 #include <openssl/rsa.h>
67 #include <openssl/ssl.h>
68 #include <openssl/x509.h>
69 #include <openssl/x509v3.h>
70 #elif defined(USE_MBEDTLS)
71 #include <mbedtls/asn1write.h>
72 #include <mbedtls/base64.h>
73 #include <mbedtls/ctr_drbg.h>
74 #include <mbedtls/entropy.h>
75 #include <mbedtls/error.h>
76 #include <mbedtls/md.h>
77 #include <mbedtls/oid.h>
78 #include <mbedtls/pem.h>
79 #include <mbedtls/pk.h>
80 #include <mbedtls/platform.h>
81 #include <mbedtls/sha1.h>
82 #include <mbedtls/version.h>
83 #include <mbedtls/x509_crt.h>
84 #include <mbedtls/x509_csr.h>
85 #endif
86 
87 #if defined(USE_GNUTLS)
88 #if GNUTLS_VERSION_NUMBER < 0x03031e
89 #error GnuTLS version 3.3.30 or later is required
90 #endif
91 
crypto_init(void)92 bool crypto_init(void)
93 {
94 #if HAVE_GNUTLS_DECODE_RS_VALUE
95     if (!gnutls_check_version("3.6.0")) {
96         warnx("crypto_init: GnuTLS version 3.6.0 or later is required");
97 #elif HAVE_GNUTLS_X509_CRQ_SET_TLSFEATURES
98     if (!gnutls_check_version("3.5.1")) {
99         warnx("crypto_init: GnuTLS version 3.5.1 or later is required");
100 #else
101     if (!gnutls_check_version("3.3.30")) {
102         warnx("crypto_init: GnuTLS version 3.3.30 or later is required");
103 #endif
104         return false;
105     }
106     gnutls_global_init();
107     return true;
108 }
109 
110 void crypto_deinit(void)
111 {
112     gnutls_global_deinit();
113 }
114 #elif defined(USE_OPENSSL)
115 #if OPENSSL_VERSION_NUMBER < 0x1010100fL
116 #error OpenSSL version 1.1.1 or later is required
117 #endif
118 
119 bool crypto_init(void)
120 {
121     if (OpenSSL_version_num() < 0x1010100fL) {
122         warnx("crypto_init: openssl version 1.1.1 or later is required");
123         return false;
124     }
125     return true;
126 }
127 
128 void crypto_deinit(void)
129 {
130 }
131 
132 static void openssl_error(const char *prefix)
133 {
134     unsigned long e;
135     while ((e = ERR_get_error()) != 0) {
136         warnx("%s: openssl %s", prefix, ERR_error_string(e, NULL));
137         return;
138     }
139 }
140 
141 static bool openssl_hash_fast(const EVP_MD *type,
142         const void *input, size_t len, unsigned char *output)
143 {
144     bool success = false;
145     EVP_MD_CTX *emc = EVP_MD_CTX_create();
146     if (!emc) {
147         openssl_error("openssl_hash_fast");
148         goto out;
149     }
150     if (!EVP_DigestInit_ex(emc, type, NULL)) {
151         openssl_error("openssl_hash_fast");
152         goto out;
153     }
154     if (!EVP_DigestUpdate(emc, input, len)) {
155         openssl_error("openssl_hash_fast");
156         goto out;
157     }
158     if (!EVP_DigestFinal_ex(emc, output, NULL)) {
159         openssl_error("openssl_hash_fast");
160         goto out;
161     }
162     success = true;
163 out:
164     if (emc)
165         EVP_MD_CTX_destroy(emc);
166     return success;
167 }
168 
169 static bool openssl_hmac_fast(const EVP_MD *type, const void *key,
170         size_t keylen, const void *input, size_t len, unsigned char *output)
171 {
172     bool success = false;
173     HMAC_CTX *hmac = HMAC_CTX_new();
174     if (!hmac) {
175         openssl_error("openssl_hmac_fast");
176         goto out;
177     }
178     if (!HMAC_Init_ex(hmac, key, keylen, type, NULL)) {
179         openssl_error("openssl_hmac_fast");
180         goto out;
181     }
182     if (!HMAC_Update(hmac, input, len)) {
183         openssl_error("openssl_hmac_fast");
184         goto out;
185     }
186     if (!HMAC_Final(hmac, output, NULL)) {
187         openssl_error("openssl_hmac_fast");
188         goto out;
189     }
190     success = true;
191 out:
192     if (hmac)
193         HMAC_CTX_free(hmac);
194     return success;
195 }
196 #elif defined(USE_MBEDTLS)
197 #if MBEDTLS_VERSION_NUMBER < 0x02100000
198 #error mbedTLS version 2.16 or later is required
199 #endif
200 
201 static mbedtls_entropy_context entropy;
202 static mbedtls_ctr_drbg_context ctr_drbg;
203 
204 static const char *_mbedtls_strerror(int code)
205 {
206     static char buf[0x100];
207     mbedtls_strerror(code, buf, sizeof(buf));
208     return buf;
209 }
210 
211 bool crypto_init(void)
212 {
213 #if defined(MBEDTLS_VERSION_C)
214     if (mbedtls_version_get_number() < 0x02100000) {
215         warnx("crypto_init: mbedTLS version 2.16 or later is required");
216         return false;
217     }
218 #endif
219     mbedtls_entropy_init(&entropy);
220     mbedtls_ctr_drbg_init(&ctr_drbg);
221     int r = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
222             &entropy, NULL, 0);
223     if (r) {
224         warnx("crypto_init: mbedtls_ctr_dbg_seed failed: %s",
225                 _mbedtls_strerror(r));
226         return false;
227     }
228     return true;
229 }
230 
231 void crypto_deinit(void)
232 {
233     mbedtls_ctr_drbg_free(&ctr_drbg);
234     mbedtls_entropy_free(&entropy);
235 }
236 
237 static int mbedtls_hash_fast(mbedtls_md_type_t md_type,
238         const void *input, size_t len, unsigned char *output)
239 {
240     const mbedtls_md_info_t *mdi = mbedtls_md_info_from_type(md_type);
241     if (!mdi) {
242         warnx("mbedtls_hash_fast: md_info not found");
243         return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE;
244     }
245     return mbedtls_md(mdi, input, len, output);
246 }
247 
248 static int mbedtls_hmac_fast(mbedtls_md_type_t md_type, const void *key,
249         size_t keylen, const void *input, size_t len, unsigned char *output)
250 {
251     const mbedtls_md_info_t *mdi = mbedtls_md_info_from_type(md_type);
252     if (!mdi) {
253         warnx("mbedtls_hmac_fast: md_info not found");
254         return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE;
255     }
256     return mbedtls_md_hmac(mdi, key, keylen, input, len, output);
257 }
258 #endif
259 
260 char *sha2_base64url(size_t bits, const char *format, ...)
261 {
262     char *input = NULL;
263     size_t encoded_hash_len;
264     char *encoded_hash = NULL;
265     const unsigned int hash_len = (bits+7)/8;
266     unsigned char *hash = NULL;
267     va_list ap;
268     va_start(ap, format);
269     if (vasprintf(&input, format, ap) < 0) {
270         warnx("sha2_base64url: vasprintf failed");
271         input = NULL;
272         goto out;
273     }
274 
275     hash = calloc(1, hash_len);
276     if (!hash) {
277         warn("sha2_base64url: calloc failed");
278         goto out;
279     }
280 
281 #if defined(USE_GNUTLS)
282     gnutls_digest_algorithm_t type;
283 #elif defined(USE_OPENSSL)
284     const EVP_MD *type;
285 #elif defined(USE_MBEDTLS)
286     mbedtls_md_type_t type;
287 #endif
288     switch (bits) {
289         case 256:
290 #if defined(USE_GNUTLS)
291             type = GNUTLS_DIG_SHA256;
292 #elif defined(USE_OPENSSL)
293             type = EVP_sha256();
294 #elif defined(USE_MBEDTLS)
295             type = MBEDTLS_MD_SHA256;
296 #endif
297             break;
298 
299         case 384:
300 #if defined(USE_GNUTLS)
301             type = GNUTLS_DIG_SHA384;
302 #elif defined(USE_OPENSSL)
303             type = EVP_sha384();
304 #elif defined(USE_MBEDTLS)
305             type = MBEDTLS_MD_SHA384;
306 #endif
307             break;
308 
309         default:
310             warnx("sha2_base64url: invalid hash bit length");
311             goto out;
312     }
313 
314 #if defined(USE_GNUTLS)
315     int r = gnutls_hash_fast(type, input, strlen(input), hash);
316     if (r != GNUTLS_E_SUCCESS) {
317         warnx("sha2_base64url: gnutls_hash_fast failed: %s",
318                 gnutls_strerror(r));
319         goto out;
320     }
321 #elif defined(USE_OPENSSL)
322     if (!openssl_hash_fast(type, input, strlen(input), hash)) {
323         warnx("sha2_base64url: openssl_hash_fast failed");
324         goto out;
325     }
326 #elif defined(USE_MBEDTLS)
327     int r = mbedtls_hash_fast(type, input, strlen(input), hash);
328     if (r != 0) {
329         warnx("sha2_base64url: mbedtls_hash_fast failed: %s",
330                 _mbedtls_strerror(r));
331         goto out;
332     }
333 #endif
334     encoded_hash_len = base64_ENCODED_LEN(hash_len,
335             base64_VARIANT_URLSAFE_NO_PADDING);
336     encoded_hash = calloc(1, encoded_hash_len);
337     if (!encoded_hash) {
338         warn("sha2_base64url: calloc failed");
339         goto out;
340     }
341     if (!bin2base64(encoded_hash, encoded_hash_len,
342                 hash, hash_len, base64_VARIANT_URLSAFE_NO_PADDING)) {
343         warnx("sha2_base64url: bin2base64 failed");
344         free(encoded_hash);
345         encoded_hash = NULL;
346         goto out;
347     }
348 out:
349     va_end(ap);
350     free(input);
351     free(hash);
352     return encoded_hash;
353 }
354 
355 char *hmac_base64url(size_t bits, const char *key, const char *format, ...)
356 {
357     char *input = NULL;
358     size_t encoded_hash_len;
359     char *encoded_hash = NULL;
360     const unsigned int hash_len = (bits+7)/8;
361     unsigned char *hash = NULL;
362     size_t keylen = strlen(key);
363     void *keybin = NULL;
364     va_list ap;
365     va_start(ap, format);
366     if (vasprintf(&input, format, ap) < 0) {
367         warnx("hmac_base64url: vasprintf failed");
368         input = NULL;
369         goto out;
370     }
371 
372     hash = calloc(1, hash_len);
373     if (!hash) {
374         warn("hmac_base64url: calloc failed");
375         goto out;
376     }
377 
378     keybin = calloc(1, keylen);
379     if (!keybin) {
380         warn("hmac_base64url: calloc failed");
381         goto out;
382     }
383 
384     if (base642bin(keybin, keylen, key, keylen, NULL, &keylen, NULL,
385                     base64_VARIANT_URLSAFE_NO_PADDING)) {
386         warnx("hmac_base64url: failed to decode key");
387         goto out;
388     }
389 
390 #if defined(USE_GNUTLS)
391     gnutls_mac_algorithm_t type;
392 #elif defined(USE_OPENSSL)
393     const EVP_MD *type;
394 #elif defined(USE_MBEDTLS)
395     mbedtls_md_type_t type;
396 #endif
397     switch (bits) {
398         case 256:
399 #if defined(USE_GNUTLS)
400             type = GNUTLS_MAC_SHA256;
401 #elif defined(USE_OPENSSL)
402             type = EVP_sha256();
403 #elif defined(USE_MBEDTLS)
404             type = MBEDTLS_MD_SHA256;
405 #endif
406             break;
407 
408         case 384:
409 #if defined(USE_GNUTLS)
410             type = GNUTLS_MAC_SHA384;
411 #elif defined(USE_OPENSSL)
412             type = EVP_sha384();
413 #elif defined(USE_MBEDTLS)
414             type = MBEDTLS_MD_SHA384;
415 #endif
416             break;
417 
418         case 512:
419 #if defined(USE_GNUTLS)
420             type = GNUTLS_MAC_SHA512;
421 #elif defined(USE_OPENSSL)
422             type = EVP_sha512();
423 #elif defined(USE_MBEDTLS)
424             type = MBEDTLS_MD_SHA512;
425 #endif
426             break;
427 
428         default:
429             warnx("hmac_base64url: invalid hmac bit length");
430             goto out;
431     }
432 
433 #if defined(USE_GNUTLS)
434     int r = gnutls_hmac_fast(type, keybin, keylen, input, strlen(input), hash);
435     if (r != GNUTLS_E_SUCCESS) {
436         warnx("hmac_base64url: gnutls_hmac_fast failed: %s",
437                 gnutls_strerror(r));
438         goto out;
439     }
440 #elif defined(USE_OPENSSL)
441     if (!openssl_hmac_fast(type, keybin, keylen, input, strlen(input), hash)) {
442         warnx("hmac_base64url: openssl_hmac_fast failed");
443         goto out;
444     }
445 #elif defined(USE_MBEDTLS)
446     int r = mbedtls_hmac_fast(type, keybin, keylen, input, strlen(input), hash);
447     if (r != 0) {
448         warnx("hmac_base64url: mbedtls_hmac_fast failed: %s",
449                 _mbedtls_strerror(r));
450         goto out;
451     }
452 #endif
453     encoded_hash_len = base64_ENCODED_LEN(hash_len,
454             base64_VARIANT_URLSAFE_NO_PADDING);
455     encoded_hash = calloc(1, encoded_hash_len);
456     if (!encoded_hash) {
457         warn("hmac_base64url: calloc failed");
458         goto out;
459     }
460     if (!bin2base64(encoded_hash, encoded_hash_len,
461                 hash, hash_len, base64_VARIANT_URLSAFE_NO_PADDING)) {
462         warnx("hmac_base64url: bin2base64 failed");
463         free(encoded_hash);
464         encoded_hash = NULL;
465         goto out;
466     }
467 out:
468     va_end(ap);
469     free(input);
470     free(hash);
471     free(keybin);
472     return encoded_hash;
473 }
474 
475 static char *bn2str(const unsigned char *data, size_t data_len, size_t pad_len)
476 {
477     char *ret = NULL;
478     unsigned char *buf = NULL;
479 
480     while (data_len && !*data) {
481         data++;
482         data_len--;
483     }
484 
485     if (pad_len == 0)
486         pad_len = data_len;
487     else if (pad_len < data_len) {
488         warnx("bn2str: insufficient pad_len");
489         goto out;
490     }
491 
492     buf = calloc(1, pad_len);
493     if (!buf) {
494         warn("bn2str: calloc failed");
495         goto out;
496     }
497     memcpy(buf + pad_len - data_len, data, data_len);
498 
499     size_t encoded_len = base64_ENCODED_LEN(pad_len,
500             base64_VARIANT_URLSAFE_NO_PADDING);
501     ret = calloc(1, encoded_len);
502     if (!ret) {
503         warn("bn2str: calloc failed");
504         goto out;
505     }
506     if (!bin2base64(ret, encoded_len, buf, pad_len,
507                 base64_VARIANT_URLSAFE_NO_PADDING)) {
508         free(ret);
509         ret = NULL;
510     }
511 out:
512     free(buf);
513     return ret;
514 }
515 
516 static bool rsa_params(privkey_t key, char **m, char **e)
517 {
518     int r;
519     char *_m = NULL;
520     char *_e = NULL;
521 #if defined(USE_GNUTLS)
522     gnutls_datum_t mod = {NULL, 0};
523     gnutls_datum_t exp = {NULL, 0};
524     if (gnutls_privkey_get_pk_algorithm(key, NULL) != GNUTLS_PK_RSA) {
525         warnx("rsa_params: not a RSA key");
526         goto out;
527     }
528     r = gnutls_privkey_export_rsa_raw(key, &mod, &exp,
529             NULL, NULL, NULL, NULL, NULL, NULL);
530     if (r < 0) {
531         warnx("rsa_params: gnutls_privkey_export_rsa_raw: %s",
532                 gnutls_strerror(r));
533         goto out;
534     }
535     _m = bn2str(mod.data, mod.size, 0);
536     if (!_m) {
537         warnx("rsa_params: bn2str failed");
538         goto out;
539     }
540     _e = bn2str(exp.data, exp.size, 0);
541     if (!_e) {
542         warnx("rsa_params: bn2str failed");
543         goto out;
544     }
545 #elif defined(USE_OPENSSL)
546     unsigned char *data = NULL;
547     RSA *rsa = EVP_PKEY_get0_RSA(key);
548     if (!rsa) {
549         openssl_error("rsa_params");
550         goto out;
551     }
552     r = BN_num_bytes(RSA_get0_n(rsa));
553     data = calloc(1, r);
554     if (!data) {
555         warn("rsa_params: calloc failed");
556         goto out;
557     }
558     if (BN_bn2bin(RSA_get0_n(rsa), data) != r) {
559         openssl_error("rsa_params");
560         goto out;
561     }
562     _m = bn2str(data, r, 0);
563     if (!_m) {
564         warnx("rsa_params: bn2str failed");
565         goto out;
566     }
567     free(data);
568     r = BN_num_bytes(RSA_get0_e(rsa));
569     data = calloc(1, r);
570     if (!data) {
571         warn("rsa_params: calloc failed");
572         goto out;
573     }
574     if (BN_bn2bin(RSA_get0_e(rsa), data) != r) {
575         openssl_error("rsa_params");
576         goto out;
577     }
578     _e = bn2str(data, r, 0);
579     if (!_e) {
580         warnx("rsa_params: bn2str failed");
581         goto out;
582     }
583 #elif defined(USE_MBEDTLS)
584     unsigned char *data = NULL;
585     size_t len;
586     if (!mbedtls_pk_can_do(key, MBEDTLS_PK_RSA)) {
587         warnx("rsa_params: not a RSA key");
588         goto out;
589     }
590     const mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*key);
591     len = mbedtls_mpi_size(&rsa->N);
592     data = calloc(1, len);
593     if (!data) {
594         warnx("rsa_params: calloc failed");
595         goto out;
596     }
597     r = mbedtls_mpi_write_binary(&rsa->N, data, len);
598     if (r) {
599         warnx("rsa_params: mbedtls_mpi_write_binary failed: %s",
600                 _mbedtls_strerror(r));
601         goto out;
602     }
603     _m = bn2str(data, len, 0);
604     if (!_m) {
605         warnx("rsa_params: bn2str failed");
606         goto out;
607     }
608     free(data);
609     len = mbedtls_mpi_size(&rsa->E);
610     data = calloc(1, len);
611     if (!data) {
612         warnx("rsa_params: calloc failed");
613         goto out;
614     }
615     r = mbedtls_mpi_write_binary(&rsa->E, data, len);
616     if (r) {
617         warnx("rsa_params: mbedtls_mpi_write_binary failed: %s",
618                 _mbedtls_strerror(r));
619         goto out;
620     }
621     _e = bn2str(data, len, 0);
622     if (!_e) {
623         warnx("rsa_params: bn2str failed");
624         goto out;
625     }
626 #endif
627 out:
628 #if defined(USE_GNUTLS)
629     free(mod.data);
630     free(exp.data);
631 #elif defined(USE_OPENSSL)
632     free(data);
633 #elif defined(USE_MBEDTLS)
634     free(data);
635 #endif
636     if (_e && _m) {
637         if (e)
638             *e = _e;
639         else
640             free(_e);
641         if (m)
642             *m = _m;
643         else
644             free(_m);
645         return true;
646     } else {
647         free(_e);
648         free(_m);
649         return false;
650     }
651 }
652 
653 static size_t ec_params(privkey_t key, char **x, char **y)
654 {
655     int r;
656     size_t bits = 0;
657     char *_x = NULL;
658     char *_y = NULL;
659 #if defined(USE_GNUTLS)
660     gnutls_ecc_curve_t curve;
661     gnutls_datum_t dx = {NULL, 0};
662     gnutls_datum_t dy = {NULL, 0};
663     if (gnutls_privkey_get_pk_algorithm(key, NULL) != GNUTLS_PK_EC) {
664         warnx("ec_params: not a EC key");
665         goto out;
666     }
667     r = gnutls_privkey_export_ecc_raw(key, &curve, &dx, &dy, NULL);
668     if (r < 0) {
669         warnx("ec_params: gnutls_privkey_export_ecc_raw: %s",
670                 gnutls_strerror(r));
671         goto out;
672     }
673     switch (curve) {
674         case GNUTLS_ECC_CURVE_SECP256R1:
675             bits = 256;
676             break;
677 
678         case GNUTLS_ECC_CURVE_SECP384R1:
679             bits = 384;
680             break;
681 
682         default:
683             warnx("ec_params: only \"prime256v1\" and \"secp384r1\" "
684                     "Elliptic Curves supported");
685             goto out;
686     }
687     _x = bn2str(dx.data, dx.size, (bits+7)/8);
688     if (!_x) {
689         warnx("ec_params: bn2str failed");
690         goto out;
691     }
692     _y = bn2str(dy.data, dy.size, (bits+7)/8);
693     if (!_y) {
694         warnx("ec_params: bn2str failed");
695         goto out;
696     }
697 #elif defined(USE_OPENSSL)
698     unsigned char *data = NULL;
699     BIGNUM *bx = BN_new();
700     BIGNUM *by = BN_new();
701     if (!bx || !by) {
702         openssl_error("ec_params");
703         goto out;
704     }
705     EC_KEY *ec = EVP_PKEY_get0_EC_KEY(key);
706     if (!ec) {
707         openssl_error("ec_params");
708         goto out;
709     }
710     const EC_GROUP *g = EC_KEY_get0_group(ec);
711     if (!g) {
712         openssl_error("ec_params");
713     }
714     switch (EC_GROUP_get_curve_name(g)) {
715         case NID_X9_62_prime256v1:
716             bits = 256;
717             break;
718 
719         case NID_secp384r1:
720             bits = 384;
721             break;
722 
723         default:
724             warnx("ec_params: only \"prime256v1\" and \"secp384r1\" "
725                     "Elliptic Curves supported");
726             goto out;
727     }
728     const EC_POINT *pubkey = EC_KEY_get0_public_key(ec);
729     if (!pubkey) {
730         openssl_error("ec_params");
731         goto out;
732     }
733     if (!EC_POINT_get_affine_coordinates(g, pubkey, bx, by, NULL)) {
734         openssl_error("ec_params");
735         goto out;
736     }
737     r = BN_num_bytes(bx);
738     data = calloc(1, r);
739     if (!data) {
740         warn("ec_params: calloc failed");
741         goto out;
742     }
743     if (BN_bn2bin(bx, data) != r) {
744         openssl_error("ec_params");
745         goto out;
746     }
747     _x = bn2str(data, r, (bits+7)/8);
748     if (!_x) {
749         warnx("ec_params: bn2str failed");
750         goto out;
751     }
752     free(data);
753     r = BN_num_bytes(by);
754     data = calloc(1, r);
755     if (!data) {
756         warn("ec_params: calloc failed");
757         goto out;
758     }
759     if (BN_bn2bin(by, data) != r) {
760         openssl_error("ec_params");
761         goto out;
762     }
763     _y = bn2str(data, r, (bits+7)/8);
764     if (!_y) {
765         warnx("ec_params: bn2str failed");
766         goto out;
767     }
768 #elif defined(USE_MBEDTLS)
769     unsigned char *data = NULL;
770     size_t len;
771     if (!mbedtls_pk_can_do(key, MBEDTLS_PK_ECKEY)) {
772         warnx("ec_params: not a EC key");
773         goto out;
774     }
775     const mbedtls_ecp_keypair *ec = mbedtls_pk_ec(*key);
776     switch (ec->grp.id) {
777         case MBEDTLS_ECP_DP_SECP256R1:
778             bits = 256;
779             break;
780 
781         case MBEDTLS_ECP_DP_SECP384R1:
782             bits = 384;
783             break;
784 
785         default:
786             warnx("ec_params: only \"prime256v1\" and \"secp384r1\" "
787                     "Elliptic Curves supported");
788             goto out;
789     }
790     len = mbedtls_mpi_size(&ec->Q.X);
791     data = calloc(1, len);
792     if (!data) {
793         warnx("ec_params: calloc failed");
794         goto out;
795     }
796     r = mbedtls_mpi_write_binary(&ec->Q.X, data, len);
797     if (r) {
798         warnx("ec_params: mbedtls_mpi_write_binary failed: %s",
799                 _mbedtls_strerror(r));
800         goto out;
801     }
802     _x = bn2str(data, len, (bits+7)/8);
803     if (!_x) {
804         warnx("ec_params: bn2str failed");
805         goto out;
806     }
807     free(data);
808     len = mbedtls_mpi_size(&ec->Q.Y);
809     data = calloc(1, len);
810     if (!data) {
811         warnx("ec_params: calloc failed");
812         goto out;
813     }
814     r = mbedtls_mpi_write_binary(&ec->Q.Y, data, len);
815     if (r) {
816         warnx("ec_params: mbedtls_mpi_write_binary failed: %s",
817                 _mbedtls_strerror(r));
818         goto out;
819     }
820     _y = bn2str(data, len, (bits+7)/8);
821     if (!_y) {
822         warnx("ec_params: bn2str failed");
823         goto out;
824     }
825 #endif
826 out:
827 #if defined(USE_GNUTLS)
828     free(dx.data);
829     free(dy.data);
830 #elif defined(USE_OPENSSL)
831     if (bx)
832         BN_free(bx);
833     if (by)
834         BN_free(by);
835     free(data);
836 #elif defined(USE_MBEDTLS)
837     free(data);
838 #endif
839     if (_x && _y) {
840         if (x)
841             *x = _x;
842         else
843             free(_x);
844         if (y)
845             *y = _y;
846         else
847             free(_y);
848         return bits;
849     } else {
850         free(_x);
851         free(_y);
852         return 0;
853     }
854 }
855 
856 keytype_t key_type(privkey_t key)
857 {
858 #if defined(USE_GNUTLS)
859     switch (gnutls_privkey_get_pk_algorithm(key, NULL)) {
860         case GNUTLS_PK_RSA:
861             return PK_RSA;
862         case GNUTLS_PK_EC:
863             return PK_EC;
864 #elif defined(USE_OPENSSL)
865     switch (EVP_PKEY_base_id(key)) {
866         case EVP_PKEY_RSA:
867             return PK_RSA;
868         case EVP_PKEY_EC:
869             return PK_EC;
870 #elif defined(USE_MBEDTLS)
871     switch (mbedtls_pk_get_type(key)) {
872         case MBEDTLS_PK_RSA:
873             return PK_RSA;
874         case MBEDTLS_PK_ECKEY:
875             return PK_EC;
876 #endif
877         default:
878             return PK_NONE;
879     }
880 }
881 
882 char *jws_jwk(privkey_t key, const char **crv, const char **alg)
883 {
884     char *ret = NULL;
885     char *p1 = NULL;
886     char *p2 = NULL;
887     const char *_crv = NULL;
888     switch (key_type(key)) {
889         case PK_RSA:
890             if (!rsa_params(key, &p1, &p2)) {
891                 warnx("jws_jwk: rsa_params failed");
892                 goto out;
893             }
894             if (asprintf(&ret, "{\"kty\":\"RSA\",\"n\":\"%s\",\"e\":\"%s\"}",
895                         p1, p2) < 0) {
896                 warnx("jws_jwk: asprintf failed");
897                 ret = NULL;
898                 goto out;
899             }
900             if (alg) *alg = "RS256";
901             break;
902 
903         case PK_EC:
904             switch (ec_params(key, &p1, &p2)) {
905                 case 0:
906                     warnx("jws_jwk: ec_params failed");
907                     goto out;
908 
909                 case 256:
910                     _crv = "P-256";
911                     if (crv) *crv = _crv;
912                     if (alg) *alg = "ES256";
913                     break;
914 
915                 case 384:
916                     _crv = "P-384";
917                     if (crv) *crv = _crv;
918                     if (alg) *alg = "ES384";
919                     break;
920 
921                 default:
922                     warnx("jws_jwk: unsupported EC curve");
923                     goto out;
924             }
925             if (asprintf(&ret, "{\"kty\":\"EC\",\"crv\":\"%s\","
926                         "\"x\":\"%s\",\"y\":\"%s\"}", _crv, p1, p2) < 0) {
927                 warnx("jws_jwk: asprintf failed");
928                 ret = NULL;
929                 goto out;
930             }
931             break;
932 
933         default:
934             warnx("jws_jwk: only RSA/EC keys are supported");
935             goto out;
936     }
937  out:
938     free(p1);
939     free(p2);
940     return ret;
941 }
942 
943 char *jws_protected_jwk(const char *nonce, const char *url,
944         privkey_t key)
945 {
946     char *ret = NULL;
947     const char *crv = NULL;
948     const char *alg = NULL;
949     char *jwk = jws_jwk(key, &crv, &alg);
950     if (!jwk) {
951         warnx("jws_protected_jwk: jws_jwk failed");
952         goto out;
953     }
954 
955     if (nonce) {
956         if (asprintf(&ret, "{\"alg\":\"%s\",\"nonce\":\"%s\","
957                     "\"url\":\"%s\",\"jwk\":%s}", alg, nonce, url, jwk) < 0) {
958             warnx("jws_protected_jwk: asprintf failed");
959             ret = NULL;
960         }
961     } else {
962         if (asprintf(&ret, "{\"alg\":\"%s\",\"url\":\"%s\",\"jwk\":%s}",
963                     alg, url, jwk) < 0) {
964             warnx("jws_protected_jwk: asprintf failed");
965             ret = NULL;
966         }
967     }
968 out:
969     free(jwk);
970     return ret;
971 }
972 
973 char *jws_protected_kid(const char *nonce, const char *url,
974         const char *kid, privkey_t key)
975 {
976     char *ret = NULL;
977     const char *alg = NULL;
978     switch (key_type(key)) {
979         case PK_RSA:
980             alg = "RS256";
981             break;
982 
983         case PK_EC:
984             switch (ec_params(key, NULL, NULL)) {
985                 case 0:
986                     warnx("jws_protected_kid: ec_params failed");
987                     goto out;
988 
989                 case 256:
990                     alg = "ES256";
991                     break;
992 
993                 case 384:
994                     alg = "ES384";
995                     break;
996 
997                 default:
998                     warnx("jws_protected_kid: unsupported EC curve");
999                     goto out;
1000             }
1001             break;
1002 
1003         default:
1004             warnx("jws_protected_kid: only RSA/EC keys are supported");
1005             goto out;
1006     }
1007     if (asprintf(&ret, "{\"alg\":\"%s\",\"nonce\":\"%s\","
1008                 "\"url\":\"%s\",\"kid\":\"%s\"}", alg, nonce, url, kid) < 0) {
1009         warnx("jws_protected_kid: asprintf failed");
1010         ret = NULL;
1011     }
1012 out:
1013     return ret;
1014 }
1015 
1016 char *jws_protected_eab(size_t bits, const char *keyid, const char *url)
1017 {
1018     char *ret = NULL;
1019     if (asprintf(&ret, "{\"alg\":\"HS%zu\",\"kid\":\"%s\",\"url\":\"%s\"}",
1020             bits, keyid, url) < 0) {
1021         warnx("jws_protected_eab: asprintf failed");
1022         ret = NULL;
1023     }
1024     return ret;
1025 }
1026 
1027 char *jws_thumbprint(privkey_t key)
1028 {
1029     char *ret = NULL;
1030     char *p1 = NULL;
1031     char *p2 = NULL;
1032     const char *crv = NULL;
1033     switch (key_type(key)) {
1034         case PK_RSA:
1035             if (!rsa_params(key, &p1, &p2)) {
1036                 warnx("jws_thumbprint: rsa_params failed");
1037                 goto out;
1038             }
1039             ret = sha2_base64url(256, "{\"e\":\"%s\",\"kty\":\"RSA\","
1040                     "\"n\":\"%s\"}", p2, p1);
1041             if (!ret)
1042                 warnx("jws_thumbprint: sha2_base64url failed");
1043             break;
1044 
1045         case PK_EC:
1046             switch (ec_params(key, &p1, &p2)) {
1047                 case 0:
1048                     warnx("jws_thumbprint: ec_params failed");
1049                     goto out;
1050 
1051                 case 256:
1052                     crv = "P-256";
1053                     break;
1054 
1055                 case 384:
1056                     crv = "P-384";
1057                     break;
1058 
1059                 default:
1060                     warnx("jws_thumbprint: unsupported EC curve");
1061                     goto out;
1062             }
1063             ret = sha2_base64url(256, "{\"crv\":\"%s\",\"kty\":\"EC\","
1064                     "\"x\":\"%s\",\"y\":\"%s\"}", crv, p1, p2);
1065             if (!ret)
1066                 warnx("jws_thumbprint: sha2_base64url failed");
1067             break;
1068 
1069         default:
1070             warnx("jws_thumbprint: only RSA/EC keys are supported");
1071             goto out;
1072     }
1073 out:
1074     free(p1);
1075     free(p2);
1076     return ret;
1077 }
1078 
1079 #if defined(USE_GNUTLS)
1080 static unsigned char *gnutls_datum_data(gnutls_datum_t *d, bool free)
1081 {
1082     unsigned char *ret = malloc(d->size);
1083     if (!ret) {
1084         warn("gnutls_datum2mem: malloc failed");
1085         goto out;
1086     }
1087     memcpy(ret, d->data, d->size);
1088     if (free) {
1089         gnutls_free(d->data);
1090         d->data = NULL;
1091     }
1092 out:
1093     return ret;
1094 }
1095 #endif
1096 
1097 bool ec_decode(size_t hash_size, unsigned char **sig, size_t *sig_size)
1098 {
1099     int r;
1100 #if defined(USE_GNUTLS)
1101 #if HAVE_GNUTLS_DECODE_RS_VALUE
1102     gnutls_datum_t dr = {NULL, 0};
1103     gnutls_datum_t ds = {NULL, 0};
1104     gnutls_datum_t dsig = {*sig, *sig_size};
1105     r = gnutls_decode_rs_value(&dsig, &dr, &ds);
1106     if (r < 0) {
1107         warnx("ec_decode: gnutls_decode_rs_value: %s", gnutls_strerror(r));
1108         return false;
1109     }
1110     unsigned char *tmp = calloc(1, 2*hash_size);
1111     if (!tmp) {
1112         warn("ec_decode: calloc failed");
1113         gnutls_free(dr.data);
1114         gnutls_free(ds.data);
1115         return false;
1116     }
1117     if (dr.size >= hash_size)
1118         memcpy(tmp, dr.data + dr.size - hash_size, hash_size);
1119     else
1120         memcpy(tmp + hash_size - dr.size, dr.data, dr.size);
1121     if (ds.size >= hash_size)
1122         memcpy(tmp + hash_size, ds.data + ds.size - hash_size, hash_size);
1123     else
1124         memcpy(tmp + 2*hash_size - ds.size, ds.data, ds.size);
1125     gnutls_free(dr.data);
1126     gnutls_free(ds.data);
1127 #else
1128     int len;
1129     const unsigned char *p = *sig;
1130     int ps = *sig_size;
1131     unsigned long tag;
1132     unsigned char cls;
1133 
1134     r = asn1_get_tag_der(p, ps, &cls, &len, &tag);
1135     if (r != ASN1_SUCCESS) {
1136         warnx("ec_decode: asn1_get_tag_der: %s", asn1_strerror(r));
1137         return false;
1138     }
1139     if (cls != ASN1_CLASS_STRUCTURED || tag != ASN1_TAG_SEQUENCE) {
1140         warnx("ec_decode: unexpected ASN1 tag");
1141         return false;
1142     }
1143     p += len;
1144     ps -= len;
1145 
1146     r = asn1_get_length_der(p, ps, &len);
1147     if (r < 0) {
1148         warnx("ec_decode: asn1_get_length_der: %d", r);
1149         return false;
1150     }
1151     p += len;
1152     ps -= len;
1153 
1154     if (p + r != *sig + *sig_size) {
1155         warnx("ec_decode: signature lenght mismatch");
1156         return false;
1157     }
1158 
1159     unsigned char *tmp = calloc(1, 2*hash_size);
1160     if (!tmp) {
1161         warn("ec_decode: calloc failed");
1162         return false;
1163     }
1164 
1165     r = asn1_get_tag_der(p, ps, &cls, &len, &tag);
1166     if (r != ASN1_SUCCESS) {
1167         warnx("ec_decode: asn1_get_tag_der: %s", asn1_strerror(r));
1168         free(tmp);
1169         return false;
1170     }
1171     if (cls != ASN1_CLASS_UNIVERSAL || tag != ASN1_TAG_INTEGER) {
1172         warnx("ec_decode: unexpected ASN1 tag");
1173         free(tmp);
1174         return false;
1175     }
1176     p += len;
1177     ps -= len;
1178 
1179     r = asn1_get_length_der(p, ps, &len);
1180     if (r < 0) {
1181         warnx("ec_decode: asn1_get_length_der: %d", r);
1182         free(tmp);
1183         return false;
1184     }
1185     p += len;
1186     ps -= len;
1187 
1188     if (r >= (int)hash_size)
1189         memcpy(tmp, p + r - hash_size, hash_size);
1190     else
1191         memcpy(tmp + hash_size - r, p, r);
1192     p += r;
1193     ps -= r;
1194 
1195     r = asn1_get_tag_der(p, ps, &cls, &len, &tag);
1196     if (r != ASN1_SUCCESS) {
1197         warnx("ec_decode: asn1_get_tag_der: %s", asn1_strerror(r));
1198         free(tmp);
1199         return false;
1200     }
1201     if (cls != ASN1_CLASS_UNIVERSAL || tag != ASN1_TAG_INTEGER) {
1202         warnx("ec_decode: unexpected ASN1 tag");
1203         free(tmp);
1204         return false;
1205     }
1206     p += len;
1207     ps -= len;
1208 
1209     r = asn1_get_length_der(p, ps, &len);
1210     if (r < 0) {
1211         warnx("ec_decode: asn1_get_length_der: %d", r);
1212         free(tmp);
1213         return false;
1214     }
1215     p += len;
1216     ps -= len;
1217 
1218     if (r >= (int)hash_size)
1219         memcpy(tmp + hash_size, p + r - hash_size, hash_size);
1220     else
1221         memcpy(tmp + 2*hash_size - r, p, r);
1222     p += r;
1223     ps -= r;
1224 
1225     if (ps != 0) {
1226         warnx("ec_decode: signature lenght mismatch");
1227         free(tmp);
1228         return false;
1229     }
1230 #endif
1231 #elif defined(USE_OPENSSL)
1232     const unsigned char *p = *sig;
1233     ECDSA_SIG *s = d2i_ECDSA_SIG(NULL, &p, *sig_size);
1234     if (!s) {
1235         openssl_error("ec_decode");
1236         return false;
1237     }
1238     unsigned char *tmp = calloc(1, 2*hash_size);
1239     if (!tmp) {
1240         warn("ec_decode: calloc failed");
1241         ECDSA_SIG_free(s);
1242         return false;
1243     }
1244     r = BN_num_bytes(ECDSA_SIG_get0_r(s));
1245     unsigned char *data = calloc(1, r);
1246     if (!data) {
1247         warn("ec_decode: calloc failed");
1248         ECDSA_SIG_free(s);
1249         free(tmp);
1250         return false;
1251     }
1252     if (BN_bn2bin(ECDSA_SIG_get0_r(s), data) != r) {
1253         openssl_error("ec_decode");
1254         ECDSA_SIG_free(s);
1255         free(data);
1256         free(tmp);
1257         return false;
1258     }
1259     if (r >= (int)hash_size)
1260         memcpy(tmp, data + r - hash_size, hash_size);
1261     else
1262         memcpy(tmp + hash_size - r, data, r);
1263     free(data);
1264 
1265     r = BN_num_bytes(ECDSA_SIG_get0_s(s));
1266     data = calloc(1, r);
1267     if (!data) {
1268         warn("ec_decode: calloc failed");
1269         ECDSA_SIG_free(s);
1270         free(tmp);
1271         return false;
1272     }
1273     if (BN_bn2bin(ECDSA_SIG_get0_s(s), data) != r) {
1274         openssl_error("ec_decode");
1275         ECDSA_SIG_free(s);
1276         free(data);
1277         free(tmp);
1278         return false;
1279     }
1280     if (r >= (int)hash_size)
1281         memcpy(tmp + hash_size, data + r - hash_size, hash_size);
1282     else
1283         memcpy(tmp + 2*hash_size - r, data, r);
1284 
1285     ECDSA_SIG_free(s);
1286     free(data);
1287 #elif defined(USE_MBEDTLS)
1288     unsigned char *p = *sig;
1289     const unsigned char *end = p + *sig_size;
1290     size_t len;
1291     r = mbedtls_asn1_get_tag(&p, end, &len,
1292             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
1293     if (r != 0) {
1294         warnx("ec_decode: mbedtls_asn1_get_tag failed: %s",
1295                 _mbedtls_strerror(r));
1296         return false;
1297     }
1298     if (p + len != end) {
1299         warnx("ec_decode: signature lenght mismatch");
1300         return false;
1301     }
1302     unsigned char *tmp = calloc(1, 2*hash_size);
1303     if (!tmp) {
1304         warn("ec_decode: calloc failed");
1305         return false;
1306     }
1307     r = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER);
1308     if (r != 0) {
1309         warnx("ec_decode: mbedtls_asn1_get_tag failed: %s",
1310                 _mbedtls_strerror(r));
1311         free(tmp);
1312         return false;
1313     }
1314     if (len >= hash_size)
1315         memcpy(tmp, p + len - hash_size, hash_size);
1316     else
1317         memcpy(tmp + hash_size - len, p, len);
1318     p += len;
1319 
1320     r = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER);
1321     if (r != 0) {
1322         warnx("ec_decode: mbedtls_asn1_get_tag failed: %s",
1323                 _mbedtls_strerror(r));
1324         free(tmp);
1325         return false;
1326     }
1327     if (len >= hash_size)
1328         memcpy(tmp + hash_size, p + len - hash_size, hash_size);
1329     else
1330         memcpy(tmp + 2*hash_size - len, p, len);
1331 #endif
1332     free(*sig);
1333     *sig = tmp;
1334     *sig_size = 2*hash_size;
1335     return true;
1336 }
1337 
1338 char *jws_encode(const char *protected, const char *payload,
1339     privkey_t key)
1340 {
1341     char *jws = NULL;
1342     char *encoded_payload = encode_base64url(payload);
1343     char *encoded_protected = encode_base64url(protected);
1344     char *encoded_combined = NULL;
1345     unsigned char *signature = NULL;
1346     size_t signature_size = 0;
1347     char *encoded_signature = NULL;
1348     size_t hash_size = 0;
1349 #if defined(USE_GNUTLS)
1350     gnutls_digest_algorithm_t hash_type;
1351 #elif defined(USE_OPENSSL)
1352     EVP_MD_CTX *emc = NULL;
1353     const EVP_MD *hash_type;
1354     unsigned int len;
1355 #elif defined(USE_MBEDTLS)
1356     mbedtls_md_type_t hash_type;
1357     unsigned char *hash = NULL;
1358 #endif
1359 
1360     if (!encoded_payload || !encoded_protected) {
1361         warnx("jws_encode: encode_base64url failed");
1362         goto out;
1363     }
1364     if (asprintf(&encoded_combined, "%s.%s", encoded_protected,
1365                 encoded_payload) < 0) {
1366         warnx("jws_encode: asprintf failed");
1367         encoded_combined = NULL;
1368         goto out;
1369     }
1370 
1371     switch (key_type(key)) {
1372         case PK_RSA:
1373             hash_size = 32;
1374 #if defined(USE_GNUTLS)
1375             hash_type = GNUTLS_DIG_SHA256;
1376 #elif defined(USE_OPENSSL)
1377             hash_type = EVP_sha256();
1378 #elif defined(USE_MBEDTLS)
1379             hash_type = MBEDTLS_MD_SHA256;
1380 #endif
1381             break;
1382 
1383         case PK_EC:
1384             switch (ec_params(key, NULL, NULL)) {
1385                 case 0:
1386                     warnx("jws_encode: ec_params failed");
1387                     goto out;
1388 
1389                 case 256:
1390                     hash_size = 32;
1391 #if defined(USE_GNUTLS)
1392                     hash_type = GNUTLS_DIG_SHA256;
1393 #elif defined(USE_OPENSSL)
1394                     hash_type = EVP_sha256();
1395 #elif defined(USE_MBEDTLS)
1396                     hash_type = MBEDTLS_MD_SHA256;
1397 #endif
1398                     break;
1399 
1400                 case 384:
1401                     hash_size = 48;
1402 #if defined(USE_GNUTLS)
1403                     hash_type = GNUTLS_DIG_SHA384;
1404 #elif defined(USE_OPENSSL)
1405                     hash_type = EVP_sha384();
1406 #elif defined(USE_MBEDTLS)
1407                     hash_type = MBEDTLS_MD_SHA384;
1408 #endif
1409                     break;
1410 
1411                 default:
1412                     warnx("jws_encode: unsupported EC curve");
1413                     goto out;
1414             }
1415             break;
1416 
1417         default:
1418             warnx("jws_encode: only RSA/EC keys are supported");
1419             goto out;
1420     }
1421 
1422 #if defined(USE_GNUTLS)
1423     gnutls_datum_t data = {
1424         (unsigned char *)encoded_combined, strlen(encoded_combined)};
1425     gnutls_datum_t sign = {NULL, 0};
1426     int r = gnutls_privkey_sign_data(key, hash_type, 0, &data, &sign);
1427     if (r != GNUTLS_E_SUCCESS) {
1428         warnx("jws_encode: gnutls_privkey_sign_data: %s", gnutls_strerror(r));
1429         goto out;
1430     }
1431     signature_size = sign.size;
1432     signature = gnutls_datum_data(&sign, true);
1433     if (!signature) {
1434         warnx("jws_encode: gnutls_datum_data failed");
1435         goto out;
1436     }
1437 #elif defined(USE_OPENSSL)
1438     emc = EVP_MD_CTX_create();
1439     if (!emc) {
1440         openssl_error("jws_encode");
1441         goto out;
1442     }
1443     signature = calloc(1, EVP_PKEY_size(key));
1444     if (!signature) {
1445         warn("jws_encode: calloc failed");
1446         goto out;
1447     }
1448     if (!EVP_SignInit_ex(emc, hash_type, NULL)) {
1449         openssl_error("jws_encode");
1450         goto out;
1451     }
1452     if (!EVP_SignUpdate(emc, encoded_combined, strlen(encoded_combined))) {
1453         openssl_error("jws_encode");
1454         goto out;
1455     }
1456     if (!EVP_SignFinal(emc, signature, &len, key)) {
1457         openssl_error("jws_encode");
1458         goto out;
1459     }
1460     signature_size = len;
1461 #elif defined(USE_MBEDTLS)
1462     hash = calloc(1, hash_size);
1463     if (!hash) {
1464         warn("jws_encode: calloc failed");
1465         goto out;
1466     }
1467     int r = mbedtls_hash_fast(hash_type, encoded_combined,
1468             strlen(encoded_combined), hash);
1469     if (r != 0) {
1470         warnx("jws_encode: mbedtls_hash_fast failed: %s",
1471                 _mbedtls_strerror(r));
1472         goto out;
1473     }
1474     switch (mbedtls_pk_get_type(key)) {
1475         case MBEDTLS_PK_RSA:
1476             signature = calloc(1, mbedtls_pk_get_len(key));
1477             break;
1478 
1479         case MBEDTLS_PK_ECKEY:
1480             signature = calloc(1, 9+2*mbedtls_pk_get_len(key));
1481             break;
1482 
1483         default:
1484             warnx("jws_encode: only RSA/EC keys are supported");
1485             goto out;
1486     }
1487     if (!signature) {
1488         warn("jws_encode: calloc failed");
1489         goto out;
1490     }
1491     r = mbedtls_pk_sign(key, hash_type, hash, hash_size, signature,
1492             &signature_size, mbedtls_ctr_drbg_random, &ctr_drbg);
1493     if (r != 0) {
1494         warnx("jws_encode: mbedtls_pk_sign failed: %s",
1495                 _mbedtls_strerror(r));
1496         goto out;
1497     }
1498 #endif
1499     if (key_type(key) == PK_EC && !ec_decode(hash_size, &signature,
1500                 &signature_size)) {
1501         warnx("jws_encode: ec_decode failed");
1502         goto out;
1503     }
1504     size_t encoded_signature_len = base64_ENCODED_LEN(signature_size,
1505             base64_VARIANT_URLSAFE_NO_PADDING);
1506     encoded_signature = calloc(1, encoded_signature_len);
1507     if (!encoded_signature) {
1508         warn("jws_encode: calloc failed");
1509         goto out;
1510     }
1511     if (!bin2base64(encoded_signature, encoded_signature_len, signature,
1512                 signature_size, base64_VARIANT_URLSAFE_NO_PADDING)) {
1513         warnx("jws_encode: bin2base64 failed");
1514         goto out;
1515     }
1516     if (asprintf(&jws,
1517                 "{\"protected\":\"%s\","
1518                 "\"payload\":\"%s\","
1519                 "\"signature\":\"%s\"}",
1520                 encoded_protected,
1521                 encoded_payload,
1522                 encoded_signature) < 0) {
1523         warnx("jws_encode: asprintf failed");
1524         jws = NULL;
1525     }
1526 out:
1527 #if defined(USE_OPENSSL)
1528     if (emc)
1529         EVP_MD_CTX_destroy(emc);
1530 #elif defined(USE_MBEDTLS)
1531     free(hash);
1532 #endif
1533     free(encoded_payload);
1534     free(encoded_protected);
1535     free(encoded_combined);
1536     free(encoded_signature);
1537     free(signature);
1538     return jws;
1539 }
1540 
1541 char *jws_encode_hmac(const char *protected, const char *payload,
1542     size_t bits, const char *key)
1543 {
1544     char *jws = NULL;
1545     char *encoded_payload = encode_base64url(payload);
1546     char *encoded_protected = encode_base64url(protected);
1547     char *encoded_signature = NULL;
1548 
1549     if (!encoded_payload || !encoded_protected) {
1550         warnx("jws_encode_hmac: encode_base64url failed");
1551         goto out;
1552     }
1553 
1554     encoded_signature = hmac_base64url(bits, key, "%s.%s",
1555             encoded_protected, encoded_payload);
1556     if (!encoded_signature) {
1557         warnx("jws_encode_hmac: hmac_base64url failed");
1558         goto out;
1559     }
1560     if (asprintf(&jws,
1561                 "{\"protected\":\"%s\","
1562                 "\"payload\":\"%s\","
1563                 "\"signature\":\"%s\"}",
1564                 encoded_protected,
1565                 encoded_payload,
1566                 encoded_signature) < 0) {
1567         warnx("jws_encode_hmac: asprintf failed");
1568         jws = NULL;
1569     }
1570 out:
1571     free(encoded_payload);
1572     free(encoded_protected);
1573     free(encoded_signature);
1574     return jws;
1575 }
1576 
1577 static bool key_gen(keytype_t type, int bits, const char *keyfile)
1578 {
1579     bool success = false;
1580     int r;
1581 #if !defined(USE_OPENSSL)
1582     void *pem_data = NULL;
1583     size_t pem_size = 0;
1584 #endif
1585 #if defined(USE_GNUTLS)
1586     gnutls_x509_privkey_t key = NULL;
1587     r = gnutls_x509_privkey_init(&key);
1588     if (r != GNUTLS_E_SUCCESS) {
1589         warnx("key_gen: gnutls_x509_privkey_init: %s",
1590                 gnutls_strerror(r));
1591         goto out;
1592     }
1593     switch (type) {
1594         case PK_RSA:
1595             msg(1, "generating new %d-bit RSA key", bits);
1596             r = gnutls_x509_privkey_generate(key, GNUTLS_PK_RSA, bits, 0);
1597             break;
1598 
1599         case PK_EC:
1600             switch (bits) {
1601                 case 256:
1602                     msg(1, "generating new %d-bit EC key", bits);
1603                     r = gnutls_x509_privkey_generate(key, GNUTLS_PK_EC,
1604                         GNUTLS_CURVE_TO_BITS(GNUTLS_ECC_CURVE_SECP256R1), 0);
1605                     break;
1606 
1607                 case 384:
1608                     msg(1, "generating new %d-bit EC key", bits);
1609                     r = gnutls_x509_privkey_generate(key, GNUTLS_PK_EC,
1610                         GNUTLS_CURVE_TO_BITS(GNUTLS_ECC_CURVE_SECP384R1), 0);
1611                     break;
1612 
1613                 default:
1614                     warnx("key_gen: EC key size must be either 256 or 384");
1615                     goto out;
1616             }
1617             break;
1618 
1619         default:
1620             warnx("key_gen: only RSA/EC keys are supported");
1621             goto out;
1622     }
1623     if (r != GNUTLS_E_SUCCESS) {
1624         warnx("key_gen: gnutls_x509_privkey_generate: %s",
1625                 gnutls_strerror(r));
1626         goto out;
1627     }
1628     gnutls_datum_t data = {NULL, 0};
1629     r = gnutls_x509_privkey_export2(key, GNUTLS_X509_FMT_PEM, &data);
1630     if (r != GNUTLS_E_SUCCESS) {
1631         warnx("key_gen: gnutls_x509_privkey_export2: %s",
1632                 gnutls_strerror(r));
1633         goto out;
1634     }
1635     pem_size = data.size;
1636     pem_data = gnutls_datum_data(&data, true);
1637     if (!pem_data) {
1638         warnx("key_gen: gnutls_datum_data failed");
1639         goto out;
1640     }
1641 #elif defined(USE_OPENSSL)
1642     EVP_PKEY *key = NULL;
1643     EVP_PKEY_CTX *epc = NULL;
1644     switch (type) {
1645         case PK_RSA:
1646             epc = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
1647             break;
1648 
1649         case PK_EC:
1650             epc = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
1651             break;
1652 
1653         default:
1654             warnx("key_gen: only RSA/EC keys are supported");
1655             goto out;
1656     }
1657     if (!epc) {
1658         openssl_error("key_gen");
1659         goto out;
1660     }
1661     if (!EVP_PKEY_keygen_init(epc)) {
1662         openssl_error("key_gen");
1663         goto out;
1664     }
1665     switch (type) {
1666         case PK_RSA:
1667             msg(1, "generating new %d-bit RSA key", bits);
1668             if (!EVP_PKEY_CTX_set_rsa_keygen_bits(epc, bits)) {
1669                 openssl_error("key_gen");
1670                 goto out;
1671             }
1672             break;
1673 
1674         case PK_EC:
1675             switch (bits) {
1676                 case 256:
1677                     msg(1, "generating new %d-bit EC key", bits);
1678                     if (!EVP_PKEY_CTX_set_ec_paramgen_curve_nid(epc,
1679                                 NID_X9_62_prime256v1)) {
1680                         openssl_error("key_gen");
1681                         goto out;
1682                     }
1683                     break;
1684 
1685                 case 384:
1686                     msg(1, "generating new %d-bit EC key", bits);
1687                     if (!EVP_PKEY_CTX_set_ec_paramgen_curve_nid(epc,
1688                                 NID_secp384r1)) {
1689                         openssl_error("key_gen");
1690                         goto out;
1691                     }
1692                     break;
1693 
1694                 default:
1695                     warnx("key_gen: EC key size must be either 256 or 384");
1696                     goto out;
1697             }
1698             break;
1699 
1700         default:
1701             warnx("key_gen: only RSA/EC keys are supported");
1702             goto out;
1703     }
1704     if (!EVP_PKEY_keygen(epc, &key)) {
1705         openssl_error("key_gen");
1706         goto out;
1707     }
1708  #elif defined(USE_MBEDTLS)
1709     mbedtls_pk_context key;
1710     mbedtls_pk_init(&key);
1711     const mbedtls_pk_info_t *pki;
1712     switch (type) {
1713         case PK_RSA:
1714             pki = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA);
1715             break;
1716 
1717         case PK_EC:
1718             pki = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY);
1719             break;
1720 
1721         default:
1722             warnx("key_gen: only RSA/EC keys are supported");
1723             goto out;
1724     }
1725     if (!pki) {
1726         warnx("key_gen: mbedtls_pk_info_from_type failed");
1727         goto out;
1728     }
1729     r = mbedtls_pk_setup(&key, pki);
1730     if (r) {
1731         warnx("key_gen: mbedtls_pk_setup failed: %s",
1732                 _mbedtls_strerror(r));
1733         goto out;
1734     }
1735     switch (type) {
1736         case PK_RSA:
1737             msg(1, "generating new %d-bit RSA key", bits);
1738             r = mbedtls_rsa_gen_key(mbedtls_pk_rsa(key),
1739                     mbedtls_ctr_drbg_random, &ctr_drbg, bits, 65537);
1740             if (r) {
1741                 warnx("key_gen: mbedtls_rsa_gen_key failed: %s",
1742                         _mbedtls_strerror(r));
1743                 goto out;
1744             }
1745             break;
1746 
1747         case PK_EC:
1748             switch (bits) {
1749                 case 256:
1750                     msg(1, "generating new %d-bit EC key", bits);
1751                     r = mbedtls_ecp_gen_key(MBEDTLS_ECP_DP_SECP256R1,
1752                             mbedtls_pk_ec(key), mbedtls_ctr_drbg_random,
1753                             &ctr_drbg);
1754                     break;
1755 
1756                 case 384:
1757                     msg(1, "generating new %d-bit EC key", bits);
1758                     r = mbedtls_ecp_gen_key(MBEDTLS_ECP_DP_SECP384R1,
1759                             mbedtls_pk_ec(key), mbedtls_ctr_drbg_random,
1760                             &ctr_drbg);
1761                     break;
1762 
1763                 default:
1764                     warnx("key_gen: EC key size must be either 256 or 384");
1765                     goto out;
1766             }
1767             if (r) {
1768                 warnx("key_gen: mbedtls_ecp_gen_key failed: %s",
1769                         _mbedtls_strerror(r));
1770                 goto out;
1771             }
1772             break;
1773 
1774         default:
1775             warnx("key_gen: only RSA/EC keys are supported");
1776             goto out;
1777     }
1778     pem_size = 4096;
1779     while (1) {
1780         pem_data = calloc(1, pem_size);
1781         if (!pem_data) {
1782             warn("key_gen: calloc failed");
1783             goto out;
1784         }
1785         r = mbedtls_pk_write_key_pem(&key, pem_data, pem_size);
1786         if (r == 0)
1787             break;
1788         else if (r == MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) {
1789             free(pem_data);
1790             pem_size *= 2;
1791         } else {
1792             warnx("key_gen: mbedtls_pk_write_key_pem failed: %s",
1793                     _mbedtls_strerror(r));
1794             goto out;
1795         }
1796     }
1797     pem_size = strlen(pem_data);
1798 #endif
1799     mode_t prev = umask((S_IWUSR | S_IXUSR) | S_IRWXG | S_IRWXO);
1800     FILE *f = fopen(keyfile, "w");
1801     umask(prev);
1802     if (!f) {
1803         warn("key_gen: failed to create %s", keyfile);
1804         goto out;
1805     }
1806 #if defined(USE_OPENSSL)
1807     r = PEM_write_PrivateKey(f, key, NULL, NULL, 0, NULL, NULL);
1808     fclose(f);
1809     if (!r) {
1810         openssl_error("key_gen");
1811         warnx("key_gen: failed to write %s", keyfile);
1812         unlink(keyfile);
1813         goto out;
1814     }
1815 #else
1816     r = fwrite(pem_data, 1, pem_size, f);
1817     fclose(f);
1818     if (r != (int)pem_size) {
1819         warn("key_gen: failed to write to %s", keyfile);
1820         unlink(keyfile);
1821         goto out;
1822     }
1823 #endif
1824     msg(1, "key saved to %s", keyfile);
1825     success = true;
1826 out:
1827 #if defined(USE_GNUTLS)
1828     gnutls_x509_privkey_deinit(key);
1829     free(pem_data);
1830 #elif defined(USE_OPENSSL)
1831     if (key)
1832         EVP_PKEY_free(key);
1833     if (epc)
1834         EVP_PKEY_CTX_free(epc);
1835 #elif defined(USE_MBEDTLS)
1836     mbedtls_pk_free(&key);
1837     free(pem_data);
1838 #endif
1839     return success;
1840 }
1841 
1842 privkey_t key_load(keytype_t type, int bits, const char *format, ...)
1843 {
1844     privkey_t key = NULL;
1845     char *keyfile = NULL;
1846 #if !defined(USE_OPENSSL)
1847     int r;
1848     void *keydata = NULL;
1849     size_t keysize = 0;
1850 #endif
1851     va_list ap;
1852     va_start(ap, format);
1853     if (vasprintf(&keyfile, format, ap) < 0)
1854         keyfile = NULL;
1855     va_end(ap);
1856     if (!keyfile) {
1857         warnx("key_load: vasprintf failed");
1858         goto out;
1859     }
1860 
1861     msg(1, "loading key from %s", keyfile);
1862 #if defined(USE_OPENSSL)
1863     while (!key) {
1864         FILE *f = fopen(keyfile, "r");
1865         if (!f) {
1866             if (errno != ENOENT) {
1867                 warn("key_load: failed to open %s", keyfile);
1868                 goto out;
1869             } else {
1870                 msg(1, "%s not found", keyfile);
1871                 if (type == PK_NONE) {
1872                     warnx("key_load: %s does not exist", keyfile);
1873                     goto out;
1874                 }
1875                 if (!key_gen(type, bits, keyfile)) {
1876                     warnx("key_load: key_gen failed");
1877                     goto out;
1878                 }
1879             }
1880         } else {
1881             key = PEM_read_PrivateKey(f, NULL, NULL, NULL);
1882             fclose(f);
1883             if (!key) {
1884                 openssl_error("key_load");
1885                 warnx("key_load: failed to read %s", keyfile);
1886                 goto out;
1887             }
1888         }
1889     }
1890 #else
1891     while (!(keydata = read_file(keyfile, &keysize))) {
1892         if (errno != ENOENT) {
1893             warn("key_load: failed to read %s", keyfile);
1894             goto out;
1895         } else {
1896             msg(1, "%s not found", keyfile);
1897             if (type == PK_NONE) {
1898                 warnx("key_load: %s does not exist", keyfile);
1899                 goto out;
1900             }
1901             if (!key_gen(type, bits, keyfile)) {
1902                 warnx("key_load: key_gen failed");
1903                 goto out;
1904             }
1905         }
1906     }
1907 #endif
1908 
1909 #if defined(USE_GNUTLS)
1910     r = gnutls_privkey_init(&key);
1911     if (r != GNUTLS_E_SUCCESS) {
1912         warnx("key_load: gnutls_privkey_import_x509_raw: %s",
1913                 gnutls_strerror(r));
1914         goto out;
1915     }
1916     gnutls_datum_t data = {keydata, keysize};
1917     r = gnutls_privkey_import_x509_raw(key, &data,
1918             GNUTLS_X509_FMT_PEM, NULL, 0);
1919     if (r != GNUTLS_E_SUCCESS) {
1920         warnx("key_load: gnutls_privkey_import_x509_raw: %s",
1921                 gnutls_strerror(r));
1922         gnutls_privkey_deinit(key);
1923         key = NULL;
1924         goto out;
1925     }
1926 
1927     r = gnutls_privkey_verify_params(key);
1928     if (r != GNUTLS_E_SUCCESS) {
1929         warnx("key_load: gnutls_privkey_verify_params: %s",
1930                 gnutls_strerror(r));
1931         gnutls_privkey_deinit(key);
1932         key = NULL;
1933         goto out;
1934     }
1935 
1936 #elif defined(USE_MBEDTLS)
1937     key = calloc(1, sizeof(*key));
1938     if (!key) {
1939         warn("key_load: calloc failed");
1940         goto out;
1941     }
1942     mbedtls_pk_init(key);
1943     r = mbedtls_pk_parse_key(key, keydata, keysize+1, NULL, 0);
1944     if (r) {
1945         warnx("key_load: mbedtls_pk_parse failed: %s",
1946                 _mbedtls_strerror(r));
1947         free(key);
1948         key = NULL;
1949         goto out;
1950     }
1951 #endif
1952     switch (key_type(key)) {
1953         case PK_RSA:
1954             if (!rsa_params(key, NULL, NULL)) {
1955                 warnx("key_load: invalid key");
1956                 privkey_deinit(key);
1957                 key = NULL;
1958             }
1959             break;
1960 
1961         case PK_EC:
1962             if (!ec_params(key, NULL, NULL)) {
1963                 warnx("key_load: invalid key");
1964                 privkey_deinit(key);
1965                 key = NULL;
1966             }
1967             break;
1968 
1969         default:
1970             warnx("key_load: only RSA/EC keys are supported");
1971             privkey_deinit(key);
1972             key = NULL;
1973     }
1974 out:
1975     free(keyfile);
1976 #if !defined(USE_OPENSSL)
1977     free(keydata);
1978 #endif
1979     return key;
1980 }
1981 
1982 bool is_ip(const char *s, unsigned char *ip, size_t *ip_len)
1983 {
1984     bool ret = false;
1985     struct addrinfo hints, *ai;
1986     memset(&hints, 0, sizeof(hints));
1987     hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
1988     hints.ai_family = AF_UNSPEC;
1989 
1990     if (getaddrinfo(s, NULL, &hints, &ai) == 0) {
1991         if (ai->ai_family == AF_INET) {
1992             if (ip_len && *ip_len >= sizeof(struct in_addr)) {
1993                 struct sockaddr_in *s = (struct sockaddr_in *)ai->ai_addr;
1994                 *ip_len = sizeof(struct in_addr);
1995                 if (ip)
1996                     memcpy(ip, &s->sin_addr, sizeof(struct in_addr));
1997             }
1998             ret = true;
1999         } else if (ai->ai_family == AF_INET6) {
2000             if (ip_len && *ip_len >= sizeof(struct in6_addr)) {
2001                 struct sockaddr_in6 *s = (struct sockaddr_in6 *)ai->ai_addr;
2002                 *ip_len = sizeof(struct in6_addr);
2003                 if (ip)
2004                     memcpy(ip, &s->sin6_addr, sizeof(struct in6_addr));
2005             }
2006             ret = true;
2007         } else if (ip_len)
2008             *ip_len = 0;
2009         freeaddrinfo(ai);
2010     } else if (ip_len)
2011         *ip_len = 0;
2012 
2013     return ret;
2014 }
2015 
2016 char *csr_gen(char * const *names, bool status_req, privkey_t key)
2017 {
2018     char *req = NULL;
2019     unsigned char *csrdata = NULL;
2020     size_t csrsize = 0;
2021     int r;
2022 #if !defined(USE_OPENSSL)
2023     unsigned char ip[16];
2024     size_t ip_len;
2025 #endif
2026 #if defined(USE_GNUTLS)
2027     unsigned int key_usage = 0;
2028     gnutls_digest_algorithm_t hash_type;
2029     gnutls_pubkey_t pubkey = NULL;
2030     gnutls_x509_crq_t crq = NULL;
2031 #if HAVE_GNUTLS_X509_CRQ_SET_TLSFEATURES
2032     gnutls_x509_tlsfeatures_t tls_features = NULL;
2033 #endif
2034 #elif defined(USE_OPENSSL)
2035     const char *key_usage = NULL;
2036     const EVP_MD *hash_type;
2037     X509_REQ *crq = NULL;
2038     X509_NAME *name = NULL;
2039     STACK_OF(X509_EXTENSION) *exts = NULL;
2040     char *san = NULL;
2041 #elif defined(USE_MBEDTLS)
2042     unsigned int key_usage = 0;
2043     mbedtls_md_type_t hash_type;
2044     size_t buflen = 1024;
2045     unsigned char *buf = NULL;
2046     char *cn = NULL;
2047     mbedtls_x509write_csr csr;
2048     mbedtls_x509write_csr_init(&csr);
2049 #endif
2050 
2051     switch (key_type(key)) {
2052         case PK_RSA:
2053 #if defined(USE_GNUTLS)
2054             key_usage = GNUTLS_KEY_DIGITAL_SIGNATURE |
2055                 GNUTLS_KEY_KEY_ENCIPHERMENT;
2056             hash_type = GNUTLS_DIG_SHA256;
2057 #elif defined(USE_OPENSSL)
2058             key_usage = "critical, digitalSignature, keyEncipherment";
2059             hash_type = EVP_sha256();
2060 #elif defined(USE_MBEDTLS)
2061             key_usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE |
2062                 MBEDTLS_X509_KU_KEY_ENCIPHERMENT;
2063             hash_type = MBEDTLS_MD_SHA256;
2064 #endif
2065             break;
2066 
2067         case PK_EC:
2068 #if defined(USE_GNUTLS)
2069             key_usage = GNUTLS_KEY_DIGITAL_SIGNATURE;
2070 #elif defined(USE_OPENSSL)
2071             key_usage = "critical, digitalSignature";
2072 #elif defined(USE_MBEDTLS)
2073             key_usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
2074 #endif
2075             switch (ec_params(key, NULL, NULL)) {
2076                 case 0:
2077                     warnx("csr_gen: ec_params failed");
2078                     goto out;
2079 
2080                 case 256:
2081 #if defined(USE_GNUTLS)
2082                     hash_type = GNUTLS_DIG_SHA256;
2083 #elif defined(USE_OPENSSL)
2084                     hash_type = EVP_sha256();
2085 #elif defined(USE_MBEDTLS)
2086                     hash_type = MBEDTLS_MD_SHA256;
2087 #endif
2088                     break;
2089 
2090                 case 384:
2091 #if defined(USE_GNUTLS)
2092                     hash_type = GNUTLS_DIG_SHA384;
2093 #elif defined(USE_OPENSSL)
2094                     hash_type = EVP_sha384();
2095 #elif defined(USE_MBEDTLS)
2096                     hash_type = MBEDTLS_MD_SHA384;
2097 #endif
2098                     break;
2099 
2100                 default:
2101                     warnx("csr_gen: unsupported EC curve");
2102                     goto out;
2103             }
2104             break;
2105 
2106         default:
2107             warnx("csr_gen: only RSA/EC keys are supported");
2108             goto out;
2109     }
2110 
2111 #if defined(USE_GNUTLS)
2112     r = gnutls_x509_crq_init(&crq);
2113     if (r != GNUTLS_E_SUCCESS) {
2114         warnx("csr_gen: gnutls_x509_crq_init: %s", gnutls_strerror(r));
2115         goto out;
2116     }
2117 
2118     r = gnutls_x509_crq_set_dn_by_oid(crq, GNUTLS_OID_X520_COMMON_NAME, 0,
2119                 *names, strlen(*names));
2120     if (r != GNUTLS_E_SUCCESS) {
2121         warnx("csr_gen: gnutls_x509_crq_set_dn_by_oid: %s", gnutls_strerror(r));
2122         goto out;
2123     }
2124 
2125     while (*names) {
2126         ip_len = sizeof(ip);
2127         if (is_ip(*names, ip, &ip_len))
2128             r = gnutls_x509_crq_set_subject_alt_name(crq, GNUTLS_SAN_IPADDRESS,
2129                     ip, ip_len, GNUTLS_FSAN_APPEND);
2130         else
2131             r = gnutls_x509_crq_set_subject_alt_name(crq, GNUTLS_SAN_DNSNAME,
2132                     *names, strlen(*names), GNUTLS_FSAN_APPEND);
2133         if (r != GNUTLS_E_SUCCESS) {
2134             warnx("csr_gen: gnutls_x509_set_subject_alt_name: %s",
2135                     gnutls_strerror(r));
2136             goto out;
2137         }
2138         names++;
2139     }
2140 
2141     r = gnutls_x509_crq_set_key_usage(crq, key_usage);
2142     if (r != GNUTLS_E_SUCCESS) {
2143         warnx("csr_gen: gnutls_x509_crq_set_key_usage: %s",
2144                 gnutls_strerror(r));
2145         goto out;
2146     }
2147 
2148     if (status_req) {
2149 #if HAVE_GNUTLS_X509_CRQ_SET_TLSFEATURES
2150         r = gnutls_x509_tlsfeatures_init(&tls_features);
2151         if (r != GNUTLS_E_SUCCESS) {
2152             warnx("csr_gen: gnutls_x509_tlsfeatures_init: %s",
2153                     gnutls_strerror(r));
2154             goto out;
2155         }
2156 
2157         // status_request TLS feature (OCSP Must-Staple)
2158         r = gnutls_x509_tlsfeatures_add(tls_features, 5);
2159         if (r != GNUTLS_E_SUCCESS) {
2160             warnx("csr_gen: gnutls_x509_tlsfeatures_add: %s",
2161                     gnutls_strerror(r));
2162             goto out;
2163         }
2164 
2165         r = gnutls_x509_crq_set_tlsfeatures(crq, tls_features);
2166         if (r != GNUTLS_E_SUCCESS) {
2167             warnx("csr_gen: gnutls_x509_set_tlsfeatures: %s",
2168                     gnutls_strerror(r));
2169             goto out;
2170         }
2171 #else
2172         warnx("csr_gen: -m, --must-staple disabled at compile time "
2173                 "- consider recompiling with GnuTLS 3.5.1 or later");
2174         goto out;
2175 #endif
2176     }
2177 
2178     r = gnutls_pubkey_init(&pubkey);
2179     if (r != GNUTLS_E_SUCCESS) {
2180         warnx("csr_gen: gnutls_pubkey_init: %s", gnutls_strerror(r));
2181         goto out;
2182     }
2183 
2184     r = gnutls_pubkey_import_privkey(pubkey, key, 0, 0);
2185     if (r != GNUTLS_E_SUCCESS) {
2186         warnx("csr_gen: gnutls_pubkey_import_privkey: %s", gnutls_strerror(r));
2187         goto out;
2188     }
2189 
2190     r = gnutls_x509_crq_set_pubkey(crq, pubkey);
2191     if (r != GNUTLS_E_SUCCESS) {
2192         warnx("csr_gen: gnutls_x509_crq_set_pubkey: %s", gnutls_strerror(r));
2193         goto out;
2194     }
2195 
2196     gnutls_digest_algorithm_t dig;
2197     unsigned int mand;
2198     r = gnutls_pubkey_get_preferred_hash_algorithm(pubkey, &dig, &mand);
2199     if (r != GNUTLS_E_SUCCESS) {
2200         warnx("csr_gen: gnutls_pubkey_get_preferred_hash_algorithm: %s",
2201                 gnutls_strerror(r));
2202         goto out;
2203     }
2204     if (mand == 0)
2205         dig = hash_type;
2206     else if (dig != hash_type) {
2207         warnx("csr_gen: unsupported message digest");
2208         goto out;
2209     }
2210 
2211     r = gnutls_x509_crq_privkey_sign(crq, key, dig, 0);
2212     if (r != GNUTLS_E_SUCCESS) {
2213         warnx("csr_gen: gnutls_crq_privkey_sign: %s", gnutls_strerror(r));
2214         goto out;
2215     }
2216 
2217     gnutls_datum_t data = {NULL, 0};
2218     r = gnutls_x509_crq_export2(crq, GNUTLS_X509_FMT_DER, &data);
2219     if (r != GNUTLS_E_SUCCESS) {
2220         warnx("csr_gen: gnutls_x509_crq_export2: %s", gnutls_strerror(r));
2221         goto out;
2222     }
2223     csrsize = data.size;
2224     csrdata = gnutls_datum_data(&data, true);
2225     if (!csrdata) {
2226         warnx("csr_gen: gnutls_datum_data failed");
2227         goto out;
2228     }
2229 #elif defined(USE_OPENSSL)
2230     if (!(crq = X509_REQ_new())) {
2231         openssl_error("csr_gen");
2232         goto out;
2233     }
2234     if (!(name = X509_NAME_new())) {
2235         openssl_error("csr_gen");
2236         goto out;
2237     }
2238     if (!X509_REQ_set_pubkey(crq, key)) {
2239         openssl_error("csr_gen");
2240         goto out;
2241     }
2242     if (!X509_NAME_add_entry_by_txt(name, "CN",
2243                 MBSTRING_ASC, (unsigned char *)*names, -1, -1, 0)) {
2244         openssl_error("csr_gen");
2245         goto out;
2246     }
2247     if (!X509_REQ_set_subject_name(crq, name)) {
2248         openssl_error("csr_gen");
2249         goto out;
2250     }
2251     if (asprintf(&san, "%s:%s", is_ip(*names, NULL, NULL) ? "IP" : "DNS",
2252                 *names) < 0) {
2253         warnx("csr_gen: asprintf failed");
2254         san = NULL;
2255         goto out;
2256     }
2257     while (*++names) {
2258         char *tmp = NULL;
2259         if (asprintf(&tmp, "%s,%s:%s", san,
2260                     is_ip(*names, NULL, NULL) ? "IP" : "DNS", *names) < 0) {
2261             warnx("csr_gen: asprintf failed");
2262             goto out;
2263         }
2264         free(san);
2265         san = tmp;
2266     }
2267     exts = sk_X509_EXTENSION_new_null();
2268     if (!exts) {
2269         openssl_error("csr_gen");
2270         goto out;
2271     }
2272     X509_EXTENSION *ext = X509V3_EXT_conf_nid(NULL, NULL,
2273             NID_subject_alt_name, san);
2274     if (!ext) {
2275         openssl_error("csr_gen");
2276         goto out;
2277     }
2278     sk_X509_EXTENSION_push(exts, ext);
2279     ext = X509V3_EXT_conf_nid(NULL, NULL, NID_key_usage, key_usage);
2280     if (!ext) {
2281         openssl_error("csr_gen");
2282         goto out;
2283     }
2284     sk_X509_EXTENSION_push(exts, ext);
2285     if (status_req) {
2286         ext = X509V3_EXT_conf_nid(NULL, NULL, NID_tlsfeature,
2287                 "status_request");
2288         if (!ext) {
2289             openssl_error("csr_gen");
2290             goto out;
2291         }
2292         sk_X509_EXTENSION_push(exts, ext);
2293     }
2294     if (!X509_REQ_add_extensions(crq, exts)) {
2295         openssl_error("csr_gen");
2296         goto out;
2297     }
2298     if (!X509_REQ_sign(crq, key, hash_type)) {
2299         openssl_error("csr_gen");
2300         goto out;
2301     }
2302     r = i2d_X509_REQ(crq, NULL);
2303     if (r < 0) {
2304         openssl_error("csr_gen");
2305         goto out;
2306     }
2307     csrsize = r;
2308     csrdata = calloc(1, csrsize);
2309     if (!csrdata) {
2310         warn("csr_gen: calloc failed");
2311         goto out;
2312     }
2313     unsigned char *tmp = csrdata;
2314     if (i2d_X509_REQ(crq, &tmp) != (int)csrsize) {
2315         openssl_error("csr_gen");
2316         goto out;
2317     }
2318 #elif defined(USE_MBEDTLS)
2319     mbedtls_x509write_csr_set_key(&csr, key);
2320     mbedtls_x509write_csr_set_md_alg(&csr, hash_type);
2321 
2322     if (asprintf(&cn, "CN=%s", *names) < 0) {
2323         warnx("csr_gen: asprintf failed");
2324         cn = NULL;
2325         goto out;
2326     }
2327 
2328     r = mbedtls_x509write_csr_set_key_usage(&csr, key_usage);
2329     if (r) {
2330         warnx("csr_gen: mbedtls_x509write_csr_set_key_usage failed: %s",
2331                 _mbedtls_strerror(r));
2332         goto out;
2333     }
2334 
2335     r = mbedtls_x509write_csr_set_subject_name(&csr, cn);
2336     if (r) {
2337         warnx("csr_gen: mbedtls_x509write_csr_set_subject_name failed: %s",
2338                 _mbedtls_strerror(r));
2339         goto out;
2340     }
2341 
2342     while (1) {
2343         buflen *= 2;
2344         free(buf);
2345         buf = calloc(1, buflen);
2346         if (!buf) {
2347             warn("csr_gen: calloc failed");
2348             goto out;
2349         }
2350         unsigned char *p = buf + buflen;
2351         size_t len = 0;
2352         size_t count = 0;
2353         while (names[count]) count++;
2354         while (count--) {
2355             const unsigned char *data;
2356             size_t data_len;
2357             unsigned char tag;
2358 
2359             ip_len = sizeof(ip);
2360             if (is_ip(names[count], ip, &ip_len)) {
2361                 tag = MBEDTLS_ASN1_CONTEXT_SPECIFIC | 7;
2362                 data = ip;
2363                 data_len = ip_len;
2364             } else {
2365                 tag = MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2;
2366                 data = (const unsigned char *)names[count];
2367                 data_len = strlen(names[count]);
2368             }
2369 
2370             r = mbedtls_asn1_write_raw_buffer(&p, buf, data, data_len);
2371             if (r >= 0)
2372                 len += r;
2373             else if (r == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL)
2374                 break;
2375             else {
2376                 warnx("csr_gen: mbedtls_asn1_write_raw_buffer failed: %s",
2377                         _mbedtls_strerror(r));
2378                 goto out;
2379             }
2380             r = mbedtls_asn1_write_len(&p, buf, data_len);
2381             if (r >= 0)
2382                 len += r;
2383             else if (r == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL)
2384                 break;
2385             else {
2386                 warnx("csr_gen: mbedtls_asn1_write_len failed: %s",
2387                         _mbedtls_strerror(r));
2388                 goto out;
2389             }
2390             r = mbedtls_asn1_write_tag(&p, buf, tag);
2391             if (r >= 0)
2392                 len += r;
2393             else if (r == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL)
2394                 break;
2395             else {
2396                 warnx("csr_gen: mbedtls_asn1_write_tag failed: %s",
2397                         _mbedtls_strerror(r));
2398                 goto out;
2399             }
2400         }
2401         if (r == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL)
2402             continue;
2403         r = mbedtls_asn1_write_len(&p, buf, len);
2404         if (r >= 0)
2405             len += r;
2406         else if (r == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL)
2407             continue;
2408         else {
2409             warnx("csr_gen: mbedtls_asn1_write_len failed: %s",
2410                     _mbedtls_strerror(r));
2411             goto out;
2412         }
2413         r = mbedtls_asn1_write_tag(&p, buf,
2414                 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
2415         if (r >= 0)
2416             len += r;
2417         else if (r == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL)
2418             continue;
2419         else {
2420             warnx("csr_gen: mbedtls_asn1_write_tag failed: %s",
2421                     _mbedtls_strerror(r));
2422             goto out;
2423         }
2424         r = mbedtls_x509write_csr_set_extension(&csr,
2425                 MBEDTLS_OID_SUBJECT_ALT_NAME,
2426                 MBEDTLS_OID_SIZE(MBEDTLS_OID_SUBJECT_ALT_NAME),
2427                 buf + buflen - len, len);
2428         if (r) {
2429             warnx("csr_gen: mbedtls_x509write_csr_set_extension failed: %s",
2430                     _mbedtls_strerror(r));
2431             goto out;
2432         }
2433         if (!status_req)
2434             break;
2435         p = buf + buflen;
2436         len = 0;
2437         // status_request TLS feature (OCSP Must-Staple)
2438         r = mbedtls_asn1_write_int(&p, buf, 5);
2439         if (r >= 0)
2440             len += r;
2441         else if (r == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL)
2442             continue;
2443         else {
2444             warnx("csr_gen: mbedtls_asn1_write_int failed: %s",
2445                     _mbedtls_strerror(r));
2446             goto out;
2447         }
2448         r = mbedtls_asn1_write_len(&p, buf, len);
2449         if (r >= 0)
2450             len += r;
2451         else if (r == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL)
2452             continue;
2453         else {
2454             warnx("csr_gen: mbedtls_asn1_write_len failed: %s",
2455                     _mbedtls_strerror(r));
2456             goto out;
2457         }
2458         r = mbedtls_asn1_write_tag(&p, buf,
2459                 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
2460         if (r >= 0)
2461             len += r;
2462         else if (r == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL)
2463             continue;
2464         else {
2465             warnx("csr_gen: mbedtls_asn1_write_tag failed: %s",
2466                     _mbedtls_strerror(r));
2467             goto out;
2468         }
2469         r = mbedtls_x509write_csr_set_extension(&csr,
2470                 // http://oid-info.com/get/1.3.6.1.5.5.7.1.24
2471                 // pe(1) id-pe-tlsfeature(24)
2472                 MBEDTLS_OID_PKIX "\x01\x18",
2473                 MBEDTLS_OID_SIZE(MBEDTLS_OID_PKIX "\x01\x18"),
2474                 buf + buflen - len, len);
2475         if (r) {
2476             warnx("csr_gen: mbedtls_x509write_csr_set_extension failed: %s",
2477                     _mbedtls_strerror(r));
2478             goto out;
2479         }
2480         break;
2481     }
2482 
2483     while (1) {
2484         r = mbedtls_x509write_csr_der(&csr, buf, buflen,
2485                 mbedtls_ctr_drbg_random, &ctr_drbg);
2486         if (r > 0)
2487             break;
2488         else if (r == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL) {
2489             free(buf);
2490             buflen *= 2;
2491             buf = calloc(1, buflen);
2492             if (!buf) {
2493                 warn("csr_gen: calloc failed");
2494                 goto out;
2495             }
2496         } else {
2497             warnx("csr_gen: mbedtls_x509write_csr_der failed: %s",
2498                     _mbedtls_strerror(r));
2499             goto out;
2500         }
2501     }
2502     csrsize = r;
2503     csrdata = calloc(1, csrsize);
2504     if (!csrdata) {
2505         warn("csr_gen: calloc failed");
2506         goto out;
2507     }
2508     memcpy(csrdata, buf + buflen - csrsize, csrsize);
2509 #endif
2510     r = base64_ENCODED_LEN(csrsize, base64_VARIANT_URLSAFE_NO_PADDING);
2511     req = calloc(1, r);
2512     if (!req) {
2513         warn("csr_gen: calloc failed");
2514         goto out;
2515     }
2516     if (!bin2base64(req, r, csrdata, csrsize,
2517                 base64_VARIANT_URLSAFE_NO_PADDING)) {
2518         warnx("csr_gen: bin2base64 failed");
2519         free(req);
2520         req = NULL;
2521         goto out;
2522     }
2523 out:
2524 #if defined(USE_GNUTLS)
2525     gnutls_pubkey_deinit(pubkey);
2526 #if HAVE_GNUTLS_X509_CRQ_SET_TLSFEATURES
2527     if (tls_features)
2528         gnutls_x509_tlsfeatures_deinit(tls_features);
2529 #endif
2530     gnutls_x509_crq_deinit(crq);
2531 #elif defined(USE_OPENSSL)
2532     if (name)
2533         X509_NAME_free(name);
2534     if (crq)
2535         X509_REQ_free(crq);
2536     if (exts)
2537         sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
2538     free(san);
2539 #elif defined(USE_MBEDTLS)
2540     mbedtls_x509write_csr_free(&csr);
2541     free(buf);
2542     free(cn);
2543 #endif
2544     free(csrdata);
2545     return req;
2546 }
2547 
2548 #if defined(USE_GNUTLS)
2549 static char **csr_names(gnutls_x509_crq_t crq)
2550 {
2551     int i, r = 0, n = 0, ncn = 0, nsan = 0;
2552     char **ret = NULL;
2553     char **names = NULL;
2554     char *buf = NULL;
2555     char *ip = NULL;
2556     size_t size = 0;
2557     bool cn = true;
2558 
2559     do {
2560         r = cn ?
2561             gnutls_x509_crq_get_dn_by_oid(crq, GNUTLS_OID_X520_COMMON_NAME,
2562                     ncn, 0, buf, &size) :
2563             gnutls_x509_crq_get_subject_alt_name(crq, nsan, buf, &size,
2564                     NULL, NULL);
2565 
2566         switch (r) {
2567             case GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE:
2568                 if (cn) {
2569                     cn = false;
2570                     r = GNUTLS_E_SUCCESS;
2571                 }
2572                 break;
2573 
2574             case GNUTLS_E_SHORT_MEMORY_BUFFER:
2575                 buf = calloc(1, size);
2576                 if (!buf) {
2577                     warn("csr_names: calloc failed");
2578                     goto out;
2579                 }
2580                 break;
2581 
2582             case GNUTLS_SAN_IPADDRESS:
2583                 ip = calloc(1, INET6_ADDRSTRLEN);
2584                 if (!ip) {
2585                     warnx("csr_names: calloc failed");
2586                     goto out;
2587                 }
2588                 if (!inet_ntop(size == 4 ? AF_INET : AF_INET6, buf, ip,
2589                             INET6_ADDRSTRLEN)) {
2590                     warnx("csr_names: invalid IP address in Subj Alt Name");
2591                     free(ip);
2592                     ip = NULL;
2593                     continue;
2594                 }
2595                 free(buf);
2596                 buf = ip;
2597                 ip = NULL;
2598                 // intentional fallthrough
2599             case GNUTLS_E_SUCCESS:
2600             case GNUTLS_SAN_DNSNAME:
2601                 for (i = 0; i < n; i++) {
2602                     if (strcasecmp(buf, names[i]) == 0)
2603                         break;
2604                 }
2605                 if (i < n)
2606                     free(buf);
2607                 else {
2608                     names = realloc(names, (n + 2) * sizeof(buf));
2609                     if (!names) {
2610                         warn("csr_names: realloc failed");
2611                         goto out;
2612                     }
2613                     names[n++] = buf;
2614                     names[n] = NULL;
2615                 }
2616                 buf = NULL;
2617                 size = 0;
2618                 if (cn)
2619                     ncn++;
2620                 else
2621                     nsan++;
2622                 break;
2623 
2624             default:
2625                 if (r < 0) {
2626                     warnx("csr_names: %s: %s",
2627                             cn ? "gnutls_x509_crq_get_dn_by_oid" :
2628                             "gnutls_x509_crq_get_subject_alt_name",
2629                             gnutls_strerror(r));
2630                     goto out;
2631                 }
2632         }
2633     } while (r != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
2634 
2635     if (n > 0) {
2636         ret = names;
2637         names = NULL;
2638     }
2639 
2640 out:
2641     for (i = 0; names && names[i]; i++)
2642         free(names[i]);
2643     free(names);
2644     return ret;
2645 }
2646 #elif defined(USE_OPENSSL)
2647 static char **csr_names(X509_REQ *crq)
2648 {
2649     int i, n = 0, ncn = -1, nsan = 0;
2650     char **ret = NULL;
2651     char **names = NULL;
2652     bool cn = true;
2653     X509_NAME *name = NULL;
2654     STACK_OF(X509_EXTENSION) *exts = NULL;
2655     GENERAL_NAMES* alts = NULL;
2656 
2657     name = X509_REQ_get_subject_name(crq);
2658     if (!name)
2659         cn = false;
2660 
2661     exts = X509_REQ_get_extensions(crq);
2662     if (exts)
2663         alts = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL);
2664 
2665     while (1) {
2666         char *nm = NULL;
2667         if (cn) {
2668             ncn = X509_NAME_get_index_by_NID(name, NID_commonName, ncn);
2669             if (ncn < 0) {
2670                 cn = false;
2671                 continue;
2672             }
2673             X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, ncn);
2674             if (!entry)
2675                 continue;
2676             ASN1_STRING *str = X509_NAME_ENTRY_get_data(entry);
2677             if (!str)
2678                 continue;
2679             unsigned char *buf = NULL;
2680             int size = ASN1_STRING_to_UTF8(&buf, str);
2681             if (size < 0) {
2682                 openssl_error("csr_names");
2683                 continue;
2684             }
2685             nm = strndup((const char *)buf, size);
2686             if (!nm) {
2687                 warn("csr_names: strndup failed");
2688                 OPENSSL_free(buf);
2689                 goto out;
2690             }
2691             OPENSSL_free(buf);
2692         } else if (alts && nsan < sk_GENERAL_NAME_num(alts)) {
2693             int type;
2694             GENERAL_NAME *gn = sk_GENERAL_NAME_value(alts, nsan++);
2695             if (!gn)
2696                 continue;
2697             ASN1_STRING *value = GENERAL_NAME_get0_value(gn, &type);
2698             if (!value)
2699                 continue;
2700             if (type == GEN_DNS) {
2701                 unsigned char *buf = NULL;
2702                 int size = ASN1_STRING_to_UTF8(&buf, value);
2703                 if (size < 0) {
2704                     openssl_error("csr_names");
2705                     continue;
2706                 }
2707                 nm = strndup((const char *)buf, size);
2708                 if (!nm) {
2709                     warn("csr_names: strndup failed");
2710                     OPENSSL_free(buf);
2711                     goto out;
2712                 }
2713                 OPENSSL_free(buf);
2714             } else if (type == GEN_IPADD) {
2715                 int af;
2716                 int len;
2717                 switch (ASN1_STRING_length(value)) {
2718                     case 4:
2719                         af = AF_INET;
2720                         len = INET_ADDRSTRLEN;
2721                         break;
2722                     case 16:
2723                         af = AF_INET6;
2724                         len = INET6_ADDRSTRLEN;
2725                         break;
2726                     default:
2727                         warnx("csr_names: invalid IP address in Subj Alt Name");
2728                         continue;
2729                 }
2730                 nm = calloc(1, len);
2731                 if (!nm) {
2732                     warnx("csr_names: calloc failed");
2733                     goto out;
2734                 }
2735                 if (!inet_ntop(af, ASN1_STRING_get0_data(value), nm, len)) {
2736                     warnx("csr_names: invalid IP address in Subj Alt Name");
2737                     free(nm);
2738                     continue;
2739                 }
2740             }
2741         } else
2742             break;
2743 
2744         if (nm) {
2745             for (i = 0; i < n; i++) {
2746                 if (strcasecmp(nm, names[i]) == 0)
2747                     break;
2748             }
2749             if (i < n)
2750                 free(nm);
2751             else {
2752                 char **tmp = realloc(names, (n + 2) * sizeof(nm));
2753                 if (!tmp) {
2754                     warn("csr_names: realloc failed");
2755                     free(nm);
2756                     goto out;
2757                 }
2758                 names = tmp;
2759                 names[n++] = nm;
2760                 names[n] = NULL;
2761             }
2762         }
2763     }
2764 
2765     if (n > 0) {
2766         ret = names;
2767         names = NULL;
2768     }
2769 
2770 out:
2771     if (names) {
2772         for (i = 0; names[i]; i++)
2773             free(names[i]);
2774         free(names);
2775     }
2776     if (exts)
2777         sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
2778     if (alts)
2779         sk_GENERAL_NAME_pop_free(alts, GENERAL_NAME_free);
2780     return ret;
2781 }
2782 #elif defined(USE_MBEDTLS)
2783 // Unlike the built-in mbedTLS parser this function supports IP identifiers
2784 static int ext_san(unsigned char *p, size_t len, mbedtls_x509_sequence *san)
2785 {
2786     unsigned char *end = p + len;
2787     unsigned char *end_ext;
2788     int r;
2789 
2790     r = mbedtls_asn1_get_tag(&p, end, &len,
2791             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
2792     if (r)
2793         return MBEDTLS_ERR_X509_INVALID_EXTENSIONS + r;
2794 
2795     if (end != p + len)
2796         return MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
2797             MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
2798 
2799     while (p < end) {
2800         r = mbedtls_asn1_get_tag(&p, end, &len,
2801             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
2802         if (r)
2803             return MBEDTLS_ERR_X509_INVALID_EXTENSIONS + r;
2804 
2805         end_ext = p + len;
2806 
2807         r = mbedtls_asn1_get_tag(&p, end_ext, &len, MBEDTLS_ASN1_OID);
2808         if (r)
2809             return MBEDTLS_ERR_X509_INVALID_EXTENSIONS + r;
2810 
2811         if (len != MBEDTLS_OID_SIZE(MBEDTLS_OID_SUBJECT_ALT_NAME) ||
2812                 memcmp(MBEDTLS_OID_SUBJECT_ALT_NAME, p, len) != 0) {
2813             p = end_ext;
2814             continue;
2815         }
2816 
2817         p += len;
2818 
2819         int crit;
2820         r = mbedtls_asn1_get_bool(&p, end_ext, &crit);
2821         if (r && r != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)
2822             return MBEDTLS_ERR_X509_INVALID_EXTENSIONS + r;
2823 
2824         r = mbedtls_asn1_get_tag(&p, end_ext, &len, MBEDTLS_ASN1_OCTET_STRING);
2825         if (r)
2826             return MBEDTLS_ERR_X509_INVALID_EXTENSIONS + r;
2827 
2828         if (p + len != end_ext)
2829             return MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
2830                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
2831 
2832         r = mbedtls_asn1_get_tag(&p, end_ext, &len,
2833             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
2834         if (r)
2835             return MBEDTLS_ERR_X509_INVALID_EXTENSIONS + r;
2836 
2837         if (p + len != end_ext)
2838             return MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
2839                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
2840 
2841         while (p < end_ext) {
2842             unsigned char tag = *p++;
2843             r = mbedtls_asn1_get_len(&p, end_ext, &len);
2844             if (r)
2845                 return MBEDTLS_ERR_X509_INVALID_EXTENSIONS + r;
2846 
2847             if ((tag & MBEDTLS_ASN1_TAG_CLASS_MASK) !=
2848                     MBEDTLS_ASN1_CONTEXT_SPECIFIC)
2849                 return MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
2850                     MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
2851 
2852             if (san->buf.p) {
2853                 if (san->next)
2854                     return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
2855 
2856                 san->next = mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
2857                 if (!san->next)
2858                     return MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
2859                         MBEDTLS_ERR_ASN1_ALLOC_FAILED;
2860 
2861                 san = san->next;
2862             }
2863 
2864             san->buf.tag = tag;
2865             san->buf.len = len;
2866             san->buf.p = p;
2867             p += len;
2868         }
2869 
2870         san->next = NULL;
2871         if (p != end_ext)
2872             return MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
2873                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
2874     }
2875 
2876     return 0;
2877 }
2878 
2879 static int csr_san(const mbedtls_x509_csr *crq, mbedtls_x509_sequence *san)
2880 {
2881     unsigned char *p = crq->cri.p;
2882     size_t len = crq->cri.len;
2883     unsigned char *end = p + len;
2884     unsigned char *end_attr;
2885     int i = 0, r;
2886 
2887     r = mbedtls_asn1_get_tag(&p, end, &len,
2888             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
2889     if (r)
2890         return MBEDTLS_ERR_X509_INVALID_FORMAT + r;
2891 
2892     r = mbedtls_asn1_get_int(&p, end, &i);
2893     if (r && r != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)
2894         return MBEDTLS_ERR_X509_INVALID_VERSION + r;
2895 
2896     if (i != 0)
2897         return MBEDTLS_ERR_X509_UNKNOWN_VERSION;
2898 
2899     for (i = 0; i < 2; i++) {
2900         r = mbedtls_asn1_get_tag(&p, end, &len,
2901                 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
2902         if (r)
2903             return MBEDTLS_ERR_X509_INVALID_FORMAT + r;
2904         p += len;
2905     }
2906 
2907     r = mbedtls_asn1_get_tag(&p, end, &len,
2908             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
2909     if (r)
2910         return MBEDTLS_ERR_X509_INVALID_FORMAT + r;
2911 
2912     while (p < end) {
2913         r = mbedtls_asn1_get_tag(&p, end, &len,
2914             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
2915         if (r)
2916             return MBEDTLS_ERR_X509_INVALID_FORMAT + r;
2917 
2918         end_attr = p + len;
2919 
2920         r = mbedtls_asn1_get_tag(&p, end_attr, &len, MBEDTLS_ASN1_OID);
2921         if (r)
2922             return MBEDTLS_ERR_X509_INVALID_FORMAT + r;
2923 
2924         if (len == MBEDTLS_OID_SIZE(MBEDTLS_OID_PKCS9_CSR_EXT_REQ) &&
2925                 memcmp(MBEDTLS_OID_PKCS9_CSR_EXT_REQ, p, len) == 0) {
2926             p += len;
2927 
2928             r = mbedtls_asn1_get_tag(&p, end_attr, &len,
2929                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET);
2930             if (r)
2931                 return MBEDTLS_ERR_X509_INVALID_FORMAT + r;
2932             else
2933                 return ext_san(p, len, san);
2934         }
2935 
2936         p = end_attr;
2937     }
2938 
2939     return 0;
2940 }
2941 
2942 static char **csr_names(mbedtls_x509_csr *crq)
2943 {
2944     int i, n = 0;
2945     char **ret = NULL;
2946     char **names = NULL;
2947 
2948     mbedtls_x509_name *name = &crq->subject;
2949     mbedtls_x509_sequence sans, *san = &sans;
2950     memset(&sans, 0, sizeof(sans));
2951 
2952     i = csr_san(crq, san);
2953     if (i) {
2954         warnx("csr_names: csr_san failed: %s", _mbedtls_strerror(i));
2955         goto out;
2956     }
2957 
2958     while (1) {
2959         char *nm = NULL;
2960         if (name) {
2961             if (MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &name->oid) == 0) {
2962                 nm = strndup((const char *)name->val.p, name->val.len);
2963                 if (!nm) {
2964                     warn("csr_names: strndup failed");
2965                     goto out;
2966                 }
2967             }
2968             name = name->next;
2969         } else if (san) {
2970             if (san->buf.tag == (MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2)) {
2971                 nm = strndup((const char *)san->buf.p, san->buf.len);
2972                 if (!nm) {
2973                     warn("csr_names: strndup failed");
2974                     goto out;
2975                 }
2976             } else if (san->buf.tag == (MBEDTLS_ASN1_CONTEXT_SPECIFIC | 7)) {
2977                 int af;
2978                 int len = 0;
2979                 switch (san->buf.len) {
2980                     case 4:
2981                         af = AF_INET;
2982                         len = INET_ADDRSTRLEN;
2983                         break;
2984                     case 16:
2985                         af = AF_INET6;
2986                         len = INET6_ADDRSTRLEN;
2987                         break;
2988                     default:
2989                         warnx("csr_names: invalid IP address in Subj Alt Name");
2990                 }
2991                 if (len) {
2992                     nm = calloc(1, len);
2993                     if (!nm) {
2994                         warnx("csr_names: calloc failed");
2995                         goto out;
2996                     }
2997                     if (!inet_ntop(af, san->buf.p, nm, len)) {
2998                         warnx("csr_names: invalid IP address in Subj Alt Name");
2999                         free(nm);
3000                         nm = NULL;
3001                     }
3002                 }
3003             }
3004             san = san->next;
3005         } else
3006             break;
3007 
3008         if (nm) {
3009             for (i = 0; i < n; i++) {
3010                 if (strcasecmp(nm, names[i]) == 0)
3011                     break;
3012             }
3013             if (i < n)
3014                 free(nm);
3015             else {
3016                 char **tmp = realloc(names, (n + 2) * sizeof(nm));
3017                 if (!tmp) {
3018                     warn("csr_names: realloc failed");
3019                     free(nm);
3020                     goto out;
3021                 }
3022                 names = tmp;
3023                 names[n++] = nm;
3024                 names[n] = NULL;
3025             }
3026         }
3027     }
3028 
3029     if (n > 0) {
3030         ret = names;
3031         names = NULL;
3032     }
3033 
3034 out:
3035     if (names) {
3036         for (i = 0; names[i]; i++)
3037             free(names[i]);
3038         free(names);
3039     }
3040     while (sans.next) {
3041         san = sans.next;
3042         sans.next = san->next;
3043         mbedtls_free(san);
3044     }
3045     return ret;
3046 }
3047 #endif
3048 
3049 char *csr_load(const char *file, char ***names)
3050 {
3051     int r;
3052     char *ret = NULL;
3053     void *csrdata = NULL;
3054     size_t csrsize = 0;
3055 #if defined(USE_GNUTLS)
3056     gnutls_x509_crq_t crq = NULL;
3057 #elif defined(USE_MBEDTLS)
3058     mbedtls_x509_csr _crq, *crq = &_crq;
3059     mbedtls_x509_csr_init(crq);
3060 #elif defined(USE_OPENSSL)
3061     X509_REQ *crq = NULL;
3062 #endif
3063 
3064     msg(1, "loading certificate request from %s", file);
3065 
3066 #if defined(USE_OPENSSL)
3067     FILE *f = NULL;
3068     if (!(f = fopen(file, "r"))) {
3069         warn("csr_load: failed to open %s", file);
3070         goto out;
3071     }
3072     crq = PEM_read_X509_REQ(f, NULL, NULL, NULL);
3073     fclose(f);
3074     if (!crq) {
3075         openssl_error("csr_load");
3076         warnx("csr_load: failed to load %s", file);
3077         goto out;
3078     }
3079     r = i2d_X509_REQ(crq, NULL);
3080     if (r < 0) {
3081         openssl_error("csr_load");
3082         goto out;
3083     }
3084     csrsize = r;
3085     csrdata = calloc(1, csrsize);
3086     if (!csrdata) {
3087         warn("csr_load: calloc failed");
3088         goto out;
3089     }
3090     unsigned char *tmp = csrdata;
3091     if (i2d_X509_REQ(crq, &tmp) != (int)csrsize) {
3092         openssl_error("csr_load");
3093         goto out;
3094     }
3095 #else
3096     csrdata = read_file(file, &csrsize);
3097     if (!csrdata) {
3098         warn("csr_load: failed to read %s", file);
3099         goto out;
3100     }
3101 #endif
3102 #if defined(USE_GNUTLS)
3103     gnutls_datum_t data = {csrdata, csrsize};
3104     r = gnutls_x509_crq_init(&crq);
3105     if (r < 0) {
3106         warnx("csr_load: gnutls_x509_crq_init: %s", gnutls_strerror(r));
3107         goto out;
3108     }
3109     r = gnutls_x509_crq_import(crq, &data, GNUTLS_X509_FMT_PEM);
3110     if (r < 0) {
3111         warnx("csr_load: gnutls_x509_crq_import: %s", gnutls_strerror(r));
3112         goto out;
3113     }
3114     free(csrdata);
3115     csrdata = NULL;
3116     data.data = NULL;
3117     data.size = 0;
3118     r = gnutls_x509_crq_export2(crq, GNUTLS_X509_FMT_DER, &data);
3119     if (r != GNUTLS_E_SUCCESS) {
3120         warnx("csr_load: gnutls_x509_crq_export2: %s", gnutls_strerror(r));
3121         goto out;
3122     }
3123     csrsize = data.size;
3124     csrdata = gnutls_datum_data(&data, true);
3125     if (!csrdata) {
3126         warnx("csr_load: gnutls_datum_data failed");
3127         goto out;
3128     }
3129 #elif defined(USE_MBEDTLS)
3130     r = mbedtls_x509_csr_parse(crq, csrdata, csrsize+1);
3131     if (r < 0) {
3132         warnx("csr_load: mbedtls_x509_csr_parse failed: %s",
3133                 _mbedtls_strerror(r));
3134         goto out;
3135     }
3136     mbedtls_pem_context ctx;
3137     mbedtls_pem_init(&ctx);
3138     size_t len;
3139     r = mbedtls_pem_read_buffer(&ctx,
3140             "-----BEGIN CERTIFICATE REQUEST-----",
3141             "-----END CERTIFICATE REQUEST-----",
3142             csrdata, NULL, 0, &len);
3143     if (r) {
3144         warnx("csr_load: mbedtls_pem_read_buffer failed: %s",
3145                 _mbedtls_strerror(r));
3146         mbedtls_pem_free(&ctx);
3147         goto out;
3148     }
3149     free(csrdata);
3150     csrsize = ctx.buflen;
3151     csrdata = calloc(1, csrsize);
3152     if (!csrdata) {
3153         warn("csr_load: calloc failed");
3154         mbedtls_pem_free(&ctx);
3155         goto out;
3156     }
3157     memcpy(csrdata, ctx.buf, ctx.buflen);
3158     mbedtls_pem_free(&ctx);
3159 #endif
3160     r = base64_ENCODED_LEN(csrsize, base64_VARIANT_URLSAFE_NO_PADDING);
3161     ret = calloc(1, r);
3162     if (!ret) {
3163         warn("csr_load: calloc failed");
3164         goto out;
3165     }
3166     if (!bin2base64(ret, r, csrdata, csrsize,
3167                 base64_VARIANT_URLSAFE_NO_PADDING)) {
3168         warnx("csr_load: bin2base64 failed");
3169         free(ret);
3170         ret = NULL;
3171         goto out;
3172     }
3173     if (names) {
3174         char **tmp = csr_names(crq);
3175         if (tmp)
3176             *names = tmp;
3177         else {
3178             free(ret);
3179             ret = NULL;
3180         }
3181     }
3182 out:
3183     free(csrdata);
3184 #if defined(USE_GNUTLS)
3185     gnutls_x509_crq_deinit(crq);
3186 #elif defined(USE_MBEDTLS)
3187     mbedtls_x509_csr_free(crq);
3188 #elif defined(USE_OPENSSL)
3189     X509_REQ_free(crq);
3190 #endif
3191     return ret;
3192 }
3193 
3194 #if defined(USE_GNUTLS)
3195 static int cert_load(gnutls_x509_crt_t *crt, unsigned int crt_size,
3196         const char *format, ...)
3197 #elif defined(USE_OPENSSL)
3198 static int cert_load(X509 **crt, unsigned int crt_size,
3199         const char *format, ...)
3200 #elif defined(USE_MBEDTLS)
3201 static int cert_load(mbedtls_x509_crt **crt, const char *format, ...)
3202 #endif
3203 {
3204     char *certfile = NULL;
3205 #if !defined(USE_OPENSSL)
3206     void *certdata = NULL;
3207     size_t certsize = 0;
3208 #endif
3209     int ret = 0;
3210     int r;
3211     va_list ap;
3212 
3213 #if !defined(USE_MBEDTLS)
3214     if (crt_size < 1)
3215         return 0;
3216 #endif
3217 
3218     va_start(ap, format);
3219     if (vasprintf(&certfile, format, ap) < 0)
3220         certfile = NULL;
3221     va_end(ap);
3222     if (!certfile) {
3223         warnx("cert_load: vasprintf failed");
3224         goto out;
3225     }
3226 
3227 #if defined(USE_OPENSSL)
3228     FILE *f = NULL;
3229     if (!(f = fopen(certfile, "r"))) {
3230         if (errno == ENOENT)
3231             msg(1, "%s does not exist", certfile);
3232         else
3233             warn("cert_load: failed to open %s", certfile);
3234         goto out;
3235     }
3236     for (r = 0; r < (int)crt_size; r++) {
3237         crt[r] = PEM_read_X509(f, NULL, NULL, NULL);
3238         if (!crt[r])
3239             break;
3240     }
3241     fclose(f);
3242     if (r == 0) {
3243         openssl_error("cert_load");
3244         warnx("cert_load: failed to load %s", certfile);
3245         goto out;
3246     }
3247     ret = r;
3248 #else
3249     certdata = read_file(certfile, &certsize);
3250     if (!certdata) {
3251         if (errno == ENOENT)
3252             msg(1, "%s does not exist", certfile);
3253         else
3254             warn("cert_load: failed to read %s", certfile);
3255         goto out;
3256     }
3257 #endif
3258 #if defined(USE_GNUTLS)
3259     gnutls_datum_t data = {certdata, certsize};
3260     r = gnutls_x509_crt_list_import(crt, &crt_size, &data, GNUTLS_X509_FMT_PEM,
3261             GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
3262     if (r < 0) {
3263         warnx("cert_load: gnutls_x509_crt_list_import: %s", gnutls_strerror(r));
3264         goto out;
3265     }
3266     ret = r;
3267 #elif defined(USE_MBEDTLS)
3268     *crt = calloc(1, sizeof(**crt));
3269     if (!*crt) {
3270         warn("cert_load: calloc failed");
3271         goto out;
3272     }
3273     mbedtls_x509_crt_init(*crt);
3274     r = mbedtls_x509_crt_parse(*crt, certdata, certsize+1);
3275     if (r < 0) {
3276         warnx("cert_load: mbedtls_x509_crt_parse failed: %s",
3277                 _mbedtls_strerror(r));
3278         mbedtls_x509_crt_free(*crt);
3279         free(*crt);
3280         goto out;
3281     }
3282     if (r > 0) {
3283         warnx("cert_load: failed to parse %d certificates", r);
3284         mbedtls_x509_crt_free(*crt);
3285         free(*crt);
3286         goto out;
3287     }
3288     for (mbedtls_x509_crt *c = *crt; c; c = c->next)
3289         ret++;
3290 #endif
3291 out:
3292 #if !defined(USE_OPENSSL)
3293     free(certdata);
3294 #endif
3295     free(certfile);
3296     return ret;
3297 }
3298 
3299 bool cert_match(const char *cert, unsigned char *fingerprint,
3300         size_t fingerprint_len)
3301 {
3302     size_t certsize = strlen(cert);
3303     bool ret = false;
3304 
3305 #if defined(USE_GNUTLS)
3306     gnutls_x509_crt_t *crt = NULL;
3307     unsigned int crt_size = 0;
3308     gnutls_datum_t data = {(unsigned char *)cert, certsize};
3309     int r = gnutls_x509_crt_list_import2(&crt, &crt_size, &data,
3310             GNUTLS_X509_FMT_PEM, GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
3311     if (r < 0) {
3312         warnx("cert_match: gnutls_x509_crt_list_import2: %s",
3313                 gnutls_strerror(r));
3314         return ret;
3315     }
3316     for (unsigned int i = 0; i < crt_size; i++) {
3317         unsigned char fp[32];
3318         size_t s = sizeof(fp);
3319         r = gnutls_x509_crt_get_fingerprint(crt[i], GNUTLS_DIG_SHA256, fp, &s);
3320         if (r == 0 && fingerprint_len <= s &&
3321                 memcmp(fp, fingerprint, fingerprint_len) == 0)
3322             ret = true;
3323         gnutls_x509_crt_deinit(crt[i]);
3324     }
3325     gnutls_free(crt);
3326 #elif defined(USE_OPENSSL)
3327     BIO *bio = BIO_new_mem_buf(cert, certsize);
3328     if (!bio) {
3329         openssl_error("cert_match");
3330         return ret;
3331     }
3332     while (!BIO_eof(bio) && !ret) {
3333         unsigned char fp[32];
3334         unsigned int s = sizeof(fp);
3335         X509 *crt = PEM_read_bio_X509(bio, NULL, NULL, NULL);
3336         if (!crt)
3337             break;
3338         if (X509_digest(crt, EVP_sha256(), fp, &s) &&
3339                 fingerprint_len <= s &&
3340                 memcmp(fp, fingerprint, fingerprint_len) == 0)
3341             ret = true;
3342         X509_free(crt);
3343     }
3344     BIO_free(bio);
3345 #elif defined(USE_MBEDTLS)
3346     mbedtls_x509_crt crt;
3347     mbedtls_x509_crt_init(&crt);
3348     int r = mbedtls_x509_crt_parse(&crt, (unsigned char *)cert, certsize+1);
3349     if (r < 0) {
3350         warnx("cert_match: mbedtls_x509_crt_parse failed: %s",
3351                 _mbedtls_strerror(r));
3352         mbedtls_x509_crt_free(&crt);
3353         return ret;
3354     }
3355     if (r > 0) {
3356         warnx("cert_load: failed to parse %d certificates", r);
3357         mbedtls_x509_crt_free(&crt);
3358         return ret;
3359     }
3360     for (mbedtls_x509_crt *c = &crt; c; c = c->next) {
3361         unsigned char fp[32];
3362         r = mbedtls_hash_fast(MBEDTLS_MD_SHA256, c->raw.p, c->raw.len, fp);
3363         if (r == 0 && fingerprint_len <= sizeof(fp) &&
3364                 memcmp(fp, fingerprint, fingerprint_len) == 0)
3365             ret = true;
3366     }
3367     mbedtls_x509_crt_free(&crt);
3368 #endif
3369     return ret;
3370 }
3371 #if defined(USE_GNUTLS)
3372 static bool ocsp_check(gnutls_x509_crt_t *crt)
3373 {
3374     bool result = true;
3375     char *ocsp_uri = NULL;
3376     gnutls_ocsp_req_t req = NULL;
3377     gnutls_ocsp_resp_t rsp = NULL;
3378     gnutls_datum_t nreq = {NULL, 0};
3379     gnutls_datum_t nrsp = {NULL, 0};
3380     gnutls_datum_t req_data = {NULL, 0};
3381     gnutls_datum_t d = {NULL, 0};
3382     curldata_t *cd = NULL;
3383     int rc;
3384 
3385     if (!crt[0] || !crt[1])
3386         goto out;
3387 
3388     for (unsigned int seq = 0; true; seq++) {
3389         d.data = NULL;
3390         d.size = 0;
3391         rc = gnutls_x509_crt_get_authority_info_access(crt[0], seq,
3392                 GNUTLS_IA_OCSP_URI, &d, NULL);
3393         if (rc == GNUTLS_E_UNKNOWN_ALGORITHM)
3394             continue;
3395         else if (rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
3396             break;
3397         else if (rc != GNUTLS_E_SUCCESS) {
3398             warnx("ocsp_check: unable to retrieve OCSP URI: %s",
3399                     gnutls_strerror(rc));
3400             break;
3401         }
3402         ocsp_uri = calloc(1, d.size+1);
3403         if (!ocsp_uri) {
3404             warn("ocsp_check: calloc failed");
3405             gnutls_free(d.data);
3406             break;
3407         }
3408         memcpy(ocsp_uri, d.data, d.size);
3409         gnutls_free(d.data);
3410         break;
3411     }
3412     if (!ocsp_uri)
3413         goto out;
3414 
3415     rc = gnutls_ocsp_req_init(&req);
3416     if (rc != GNUTLS_E_SUCCESS) {
3417         warnx("ocsp_check: gnutls_ocsp_req_init failed: %s",
3418                 gnutls_strerror(rc));
3419         goto out;
3420     }
3421 
3422     rc = gnutls_ocsp_req_add_cert(req, GNUTLS_DIG_SHA1, crt[1], crt[0]);
3423     if (rc != GNUTLS_E_SUCCESS) {
3424         warnx("ocsp_check: gnutls_ocsp_req_add_cert failed: %s",
3425                 gnutls_strerror(rc));
3426         goto out;
3427     }
3428 
3429     rc = gnutls_ocsp_req_randomize_nonce(req);
3430     if (rc != GNUTLS_E_SUCCESS) {
3431         warnx("ocsp_check: gnutls_ocsp_req_randomize failed: %s",
3432                 gnutls_strerror(rc));
3433         goto out;
3434     }
3435 
3436     rc = gnutls_ocsp_req_export(req, &req_data);
3437     if (rc != GNUTLS_E_SUCCESS) {
3438         warnx("ocsp_check: gnutls_ocsp_req_export failed: %s",
3439                 gnutls_strerror(rc));
3440         goto out;
3441     }
3442 
3443     d.data = NULL;
3444     d.size = 0;
3445     rc = gnutls_ocsp_req_print(req, GNUTLS_OCSP_PRINT_FULL, &d);
3446     if (rc != GNUTLS_E_SUCCESS) {
3447         warnx("ocsp_check: gnutls_ocsp_req_print failed: %s",
3448                 gnutls_strerror(rc));
3449         gnutls_free(d.data);
3450         goto out;
3451     }
3452     msg(2, "ocsp_check: %.*s", d.size, d.data);
3453     gnutls_free(d.data);
3454 
3455     msg(1, "querying OCSP server at %s", ocsp_uri);
3456     msg_hd(3, "ocsp_check: HTTP post:\n", req_data.data, req_data.size);
3457     cd = curl_post(ocsp_uri, req_data.data, req_data.size,
3458             "Content-Type: application/ocsp-request", NULL);
3459     if (!cd) {
3460         warnx("ocsp_check: curl_post(\"%s\") failed", ocsp_uri);
3461         goto out;
3462     }
3463 
3464     if (cd->headers)
3465         msg(3, "ocsp_check: HTTP headers:\n%s", cd->headers);
3466     if (cd->body)
3467         msg_hd(3, "ocsp_check: HTTP body:\n", cd->body, cd->body_len);
3468 
3469     rc = gnutls_ocsp_resp_init(&rsp);
3470     if (rc != GNUTLS_E_SUCCESS) {
3471         warnx("ocsp_check: gnutls_ocsp_resp_init failed: %s",
3472                 gnutls_strerror(rc));
3473         goto out;
3474     }
3475 
3476     d.data = (unsigned char *)cd->body;
3477     d.size = cd->body_len;
3478     rc = gnutls_ocsp_resp_import(rsp, &d);
3479     if (rc != GNUTLS_E_SUCCESS) {
3480         warnx("ocsp_check: gnutls_ocsp_resp_import failed: %s",
3481                 gnutls_strerror(rc));
3482         goto out;
3483     }
3484 
3485     d.data = NULL;
3486     d.size = 0;
3487     rc = gnutls_ocsp_resp_print(rsp, GNUTLS_OCSP_PRINT_FULL, &d);
3488     if (rc != GNUTLS_E_SUCCESS) {
3489         warnx("ocsp_check: gnutls_ocsp_resp_print failed: %s",
3490                 gnutls_strerror(rc));
3491         gnutls_free(d.data);
3492         goto out;
3493     }
3494     msg(2, "ocsp_check: %.*s", d.size, d.data);
3495     gnutls_free(d.data);
3496 
3497     unsigned int verify;
3498     rc = gnutls_ocsp_resp_verify_direct(rsp, crt[1], &verify, 0);
3499     if (rc != GNUTLS_E_SUCCESS) {
3500         warnx("ocsp_check: gnutls_ocsp_resp_verify_direct failed: %s",
3501                 gnutls_strerror(rc));
3502         goto out;
3503     }
3504 
3505     if (verify != 0) {
3506         warnx("warning: failed to verify OCSP response (%d)", verify);
3507         goto out;
3508     }
3509 
3510     rc = gnutls_ocsp_resp_get_status(rsp);
3511     if (rc != GNUTLS_OCSP_RESP_SUCCESSFUL) {
3512         if (rc < 0)
3513             warnx("ocsp_check: gnutls_ocsp_resp_get_status failed: %s",
3514                     gnutls_strerror(rc));
3515         else
3516             warnx("OCSP response was unsuccessful (%d)", rc);
3517         goto out;
3518     }
3519 
3520     rc = gnutls_ocsp_resp_check_crt(rsp, 0, crt[0]);
3521     if (rc != GNUTLS_E_SUCCESS) {
3522         warnx("ocsp_check: gnutls_ocsp_resp_check_crt failed: %s",
3523                 gnutls_strerror(rc));
3524         goto out;
3525     }
3526 
3527     rc = gnutls_ocsp_req_get_nonce(req, NULL, &nreq);
3528     if (rc != GNUTLS_E_SUCCESS) {
3529         warnx("ocsp_check: gnutls_ocsp_req_get_nonce failed: %s",
3530                 gnutls_strerror(rc));
3531         goto out;
3532     }
3533 
3534     rc = gnutls_ocsp_resp_get_nonce(rsp, NULL, &nrsp);
3535     if (rc != GNUTLS_E_SUCCESS) {
3536         if (rc != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
3537             warnx("ocsp_check: gnutls_ocsp_rsp_get_nonce failed: %s",
3538                     gnutls_strerror(rc));
3539             goto out;
3540         } else
3541             msg(1, "OCSP response has no nonce");
3542     } else if (nreq.size != nrsp.size ||
3543             memcmp(nreq.data, nrsp.data, nreq.size)) {
3544         warnx("warning: OCSP response nonce mismatch");
3545         goto out;
3546     }
3547 
3548     unsigned int cert_status;
3549     rc = gnutls_ocsp_resp_get_single(rsp, 0, NULL, NULL, NULL, NULL,
3550             &cert_status, NULL, NULL, NULL, NULL);
3551     if (rc != GNUTLS_E_SUCCESS) {
3552         warnx("ocsp_check: gnutls_ocsp_rsp_get_single failed: %s",
3553                 gnutls_strerror(rc));
3554         goto out;
3555     }
3556 
3557     switch (cert_status) {
3558         case GNUTLS_OCSP_CERT_GOOD:
3559             msg(1, "OCSP certificate status is GOOD");
3560             break;
3561 
3562         case GNUTLS_OCSP_CERT_REVOKED:
3563             warnx("OCSP certificate status is REVOKED");
3564             result = false;
3565             break;
3566 
3567         case GNUTLS_OCSP_CERT_UNKNOWN:
3568         default:
3569             msg(1, "OCSP certificate status is UNKNOWN");
3570             break;
3571     }
3572 
3573 out:
3574     if (req)
3575         gnutls_ocsp_req_deinit(req);
3576     if (rsp)
3577         gnutls_ocsp_resp_deinit(rsp);
3578     gnutls_free(req_data.data);
3579     gnutls_free(nreq.data);
3580     gnutls_free(nrsp.data);
3581     curldata_free(cd);
3582     free(ocsp_uri);
3583     return result;
3584 }
3585 #elif defined(USE_OPENSSL)
3586 static bool ocsp_check(X509 **crt)
3587 {
3588     bool result = true;
3589     char *ocsp_uri = NULL;
3590     OCSP_REQUEST *req = NULL;
3591     unsigned char *reqdata = NULL;
3592     int reqsize = 0;
3593     OCSP_RESPONSE *rsp = NULL;
3594     OCSP_BASICRESP *brsp = NULL;
3595     OCSP_CERTID *id = NULL;
3596     STACK_OF(OCSP_CERTID) *ids = NULL;
3597     STACK_OF(OPENSSL_STRING) *ocsp_uris = NULL;
3598     STACK_OF(X509) *issuers = NULL;
3599     curldata_t *cd = NULL;
3600     int rc;
3601 
3602     if (!crt[0] || !crt[1])
3603         goto out;
3604 
3605     ocsp_uris = X509_get1_ocsp(crt[0]);
3606     if (!ocsp_uris) {
3607         openssl_error("ocsp_check");
3608         goto out;
3609     }
3610     for (int j = 0; !ocsp_uri && j < sk_OPENSSL_STRING_num(ocsp_uris); j++) {
3611         char *uri = sk_OPENSSL_STRING_value(ocsp_uris, j);
3612         if (uri && strlen(uri)) {
3613             ocsp_uri = strdup(uri);
3614             if (!ocsp_uri) {
3615                 warn("ocsp_check: strdup failed");
3616                 goto out;
3617             }
3618         }
3619     }
3620     if (!ocsp_uri)
3621         goto out;
3622 
3623     req = OCSP_REQUEST_new();
3624     if (!req) {
3625         openssl_error("ocsp_check");
3626         goto out;
3627     }
3628 
3629     ids = sk_OCSP_CERTID_new_null();
3630     if (!ids) {
3631         openssl_error("ocsp_check");
3632         goto out;
3633     }
3634 
3635     id = OCSP_cert_to_id(EVP_sha1(), crt[0], crt[1]);
3636     if (!id || !sk_OCSP_CERTID_push(ids, id)) {
3637         openssl_error("ocsp_check");
3638         goto out;
3639     }
3640 
3641     if (!OCSP_request_add0_id(req, id)) {
3642         openssl_error("ocsp_check");
3643         goto out;
3644     }
3645 
3646     if (!OCSP_request_add1_nonce(req, NULL, -1)) {
3647         openssl_error("ocsp_check");
3648         goto out;
3649     }
3650 
3651     rc = i2d_OCSP_REQUEST(req, NULL);
3652     if (rc < 0) {
3653         openssl_error("ocsp_check");
3654         goto out;
3655     }
3656     reqsize = rc;
3657     reqdata = calloc(1, reqsize);
3658     if (!reqdata) {
3659         warn("ocsp_check: calloc failed");
3660         goto out;
3661     }
3662     unsigned char *tmp = reqdata;
3663     if (i2d_OCSP_REQUEST(req, &tmp) != reqsize) {
3664         openssl_error("ocsp_check");
3665         goto out;
3666     }
3667 
3668     if (g_loglevel > 1) {
3669         BIO *out = BIO_new(BIO_s_mem());
3670         if (out) {
3671             if (OCSP_REQUEST_print(out, req, 0)) {
3672                 char *data = NULL;
3673                 int size = BIO_get_mem_data(out, &data);
3674                 warnx("ocsp_check: %.*s", size, data);
3675             }
3676             BIO_free(out);
3677         }
3678     }
3679 
3680     msg(1, "querying OCSP server at %s", ocsp_uri);
3681     msg_hd(3, "ocsp_check: HTTP post:\n", reqdata, reqsize);
3682     cd = curl_post(ocsp_uri, reqdata, reqsize,
3683             "Content-Type: application/ocsp-request", NULL);
3684     if (!cd) {
3685         warnx("ocsp_check: curl_post(\"%s\") failed", ocsp_uri);
3686         goto out;
3687     }
3688 
3689     if (cd->headers)
3690         msg(3, "ocsp_check: HTTP headers:\n%s", cd->headers);
3691     if (cd->body)
3692         msg_hd(3, "ocsp_check: HTTP body:\n", cd->body, cd->body_len);
3693 
3694     const unsigned char *tmp2 = (const unsigned char *)cd->body;
3695     rsp = d2i_OCSP_RESPONSE(NULL, &tmp2, cd->body_len);
3696     if (!rsp) {
3697         openssl_error("ocsp_check");
3698         goto out;
3699     }
3700 
3701     if (g_loglevel > 1) {
3702         BIO *out = BIO_new(BIO_s_mem());
3703         if (out) {
3704             if (OCSP_RESPONSE_print(out, rsp, 0)) {
3705                 char *data = NULL;
3706                 int size = BIO_get_mem_data(out, &data);
3707                 warnx("ocsp_check: %.*s", size, data);
3708             }
3709             BIO_free(out);
3710         }
3711     }
3712 
3713     rc = OCSP_response_status(rsp);
3714     if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
3715         if (rc < 0)
3716             openssl_error("ocsp_check");
3717         else
3718             warnx("OCSP response was unsuccessful (%d)", rc);
3719         goto out;
3720     }
3721 
3722     brsp = OCSP_response_get1_basic(rsp);
3723     if (!brsp) {
3724         openssl_error("ocsp_check");
3725         goto out;
3726     }
3727 
3728     rc = OCSP_check_nonce(req, brsp);
3729     if (rc < 0)
3730         msg(1, "OCSP response has no nonce");
3731     else if (rc == 0) {
3732         warnx("ocsp_check: OCSP_check_nonce failed");
3733         goto out;
3734     }
3735 
3736     issuers = sk_X509_new_null();
3737     if (!issuers) {
3738         openssl_error("ocsp_check");
3739         goto out;
3740     }
3741     sk_X509_push(issuers, crt[1]);
3742 
3743     if (OCSP_basic_verify(brsp, issuers, NULL, OCSP_TRUSTOTHER) <= 0) {
3744         openssl_error("ocsp_check");
3745         goto out;
3746     }
3747 
3748     int status;
3749     if (!OCSP_resp_find_status(brsp, id, &status, NULL, NULL, NULL, NULL)) {
3750         openssl_error("ocsp_check");
3751         goto out;
3752     }
3753 
3754     switch (status) {
3755         case V_OCSP_CERTSTATUS_GOOD:
3756             msg(1, "OCSP certificate status is GOOD");
3757             break;
3758 
3759         case V_OCSP_CERTSTATUS_REVOKED:
3760             warnx("OCSP certificate status is REVOKED");
3761             result = false;
3762             break;
3763 
3764         case V_OCSP_CERTSTATUS_UNKNOWN:
3765         default:
3766             msg(1, "OCSP certificate status is UNKNOWN");
3767             break;
3768     }
3769 
3770 out:
3771     free(ocsp_uri);
3772     free(reqdata);
3773     if (cd)
3774         curldata_free(cd);
3775     if (req)
3776         OCSP_REQUEST_free(req);
3777     if (rsp)
3778         OCSP_RESPONSE_free(rsp);
3779     if (brsp)
3780         OCSP_BASICRESP_free(brsp);
3781     if (ids)
3782         sk_OCSP_CERTID_free(ids);
3783     if (ocsp_uris)
3784         X509_email_free(ocsp_uris);
3785     if (issuers)
3786         sk_X509_free(issuers);
3787     return result;
3788 }
3789 #elif defined(USE_MBEDTLS)
3790 #define OID_AUTHORITY_INFO_ACCESS MBEDTLS_OID_PKIX "\x01\x01"
3791 #define OID_AD_OCSP MBEDTLS_OID_PKIX "\x30\x01"
3792 #define OID_AD_OCSP_BASIC OID_AD_OCSP "\x01"
3793 #define OID_AD_OCSP_NONCE OID_AD_OCSP "\x02"
3794 
3795 static int ext_parse_ocsp_uri(unsigned char *p, size_t len, const char **out)
3796 {
3797     unsigned char *end = p + len;
3798     unsigned char *end_ext;
3799     unsigned char *end_ad;
3800     int r;
3801 
3802     r = mbedtls_asn1_get_tag(&p, end, &len,
3803             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
3804     if (r)
3805         return MBEDTLS_ERR_X509_INVALID_EXTENSIONS + r;
3806 
3807     if (end != p + len)
3808         return MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
3809             MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
3810 
3811     while (p < end) {
3812         r = mbedtls_asn1_get_tag(&p, end, &len,
3813             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
3814         if (r)
3815             return MBEDTLS_ERR_X509_INVALID_EXTENSIONS + r;
3816 
3817         end_ext = p + len;
3818 
3819         r = mbedtls_asn1_get_tag(&p, end_ext, &len, MBEDTLS_ASN1_OID);
3820         if (r)
3821             return MBEDTLS_ERR_X509_INVALID_EXTENSIONS + r;
3822 
3823         if (len != MBEDTLS_OID_SIZE(OID_AUTHORITY_INFO_ACCESS) ||
3824                 memcmp(OID_AUTHORITY_INFO_ACCESS, p, len) != 0) {
3825             p = end_ext;
3826             continue;
3827         }
3828 
3829         p += len;
3830 
3831         int crit;
3832         r = mbedtls_asn1_get_bool(&p, end_ext, &crit);
3833         if (r && r != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)
3834             return MBEDTLS_ERR_X509_INVALID_EXTENSIONS + r;
3835 
3836         r = mbedtls_asn1_get_tag(&p, end_ext, &len, MBEDTLS_ASN1_OCTET_STRING);
3837         if (r)
3838             return MBEDTLS_ERR_X509_INVALID_EXTENSIONS + r;
3839 
3840         if (p + len != end_ext)
3841             return MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
3842                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
3843 
3844         r = mbedtls_asn1_get_tag(&p, end_ext, &len,
3845             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
3846         if (r)
3847             return MBEDTLS_ERR_X509_INVALID_EXTENSIONS + r;
3848 
3849         if (p + len != end_ext)
3850             return MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
3851                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
3852 
3853         while (p < end_ext) {
3854             r = mbedtls_asn1_get_tag(&p, end_ext, &len,
3855                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
3856             if (r)
3857                 return MBEDTLS_ERR_X509_INVALID_EXTENSIONS + r;
3858 
3859             end_ad = p + len;
3860 
3861             r = mbedtls_asn1_get_tag(&p, end_ad, &len, MBEDTLS_ASN1_OID);
3862             if (r)
3863                 return MBEDTLS_ERR_X509_INVALID_EXTENSIONS + r;
3864 
3865             if (len != MBEDTLS_OID_SIZE(OID_AD_OCSP) ||
3866                     memcmp(OID_AD_OCSP, p, len) != 0) {
3867                 p = end_ad;
3868                 continue;
3869             }
3870 
3871             p += len;
3872 
3873             r = mbedtls_asn1_get_tag(&p, end_ad, &len,
3874                     MBEDTLS_ASN1_CONTEXT_SPECIFIC | 6);
3875             if (r) {
3876                 p = end_ad;
3877                 continue;
3878             }
3879 
3880             *out = (const char *)p;
3881             return len;
3882         }
3883 
3884         if (p != end_ext)
3885             return MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
3886                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
3887     }
3888     return 0;
3889 }
3890 
3891 static int ocsp_req(mbedtls_x509_crt *crt, unsigned char *req, size_t size,
3892         const unsigned char **certid, size_t *certid_size)
3893 {
3894     int ret = 0;
3895     size_t ext_len = 0;
3896     size_t len = 0;
3897     const char *alg_oid;
3898     size_t alg_oid_len = 0;
3899     unsigned char hash[20];
3900     unsigned char *p = req + size;
3901     mbedtls_x509_crt *issuer = crt->next;
3902 
3903     if (!issuer)
3904         return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
3905 
3906     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(&p, req,
3907                 crt->serial.p, crt->serial.len));
3908     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, req,
3909                 crt->serial.len));
3910     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, req,
3911                 crt->serial.tag));
3912 
3913     for (size_t buf_size = 0x400; ; ) {
3914         unsigned char *buf = mbedtls_calloc(1, buf_size);
3915         if (!buf)
3916             return MBEDTLS_ERR_X509_ALLOC_FAILED;
3917         unsigned char *c = buf + buf_size;
3918         ret = mbedtls_pk_write_pubkey(&c, buf, &issuer->pk);
3919         if (ret >= 0)
3920             ret = mbedtls_sha1_ret(buf + buf_size - ret, ret, hash);
3921         mbedtls_free(buf);
3922         if (ret == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL) {
3923             buf_size *= 2;
3924             continue;
3925         }
3926         if (ret < 0)
3927             return ret;
3928         break;
3929     }
3930 
3931     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_octet_string(&p, req,
3932                 hash, sizeof(hash)));
3933 
3934     ret = mbedtls_sha1_ret(crt->issuer_raw.p, crt->issuer_raw.len, hash);
3935     if (ret)
3936         return ret;
3937 
3938     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_octet_string(&p, req,
3939                 hash, sizeof(hash)));
3940 
3941     ret = mbedtls_oid_get_oid_by_md(MBEDTLS_MD_SHA1, &alg_oid, &alg_oid_len);
3942     if (ret)
3943         return ret;
3944 
3945     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_algorithm_identifier(&p, req,
3946                 alg_oid, alg_oid_len, 0));
3947 
3948     if (certid)
3949         *certid = p;
3950     if (certid_size)
3951         *certid_size = len;
3952 
3953     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, req, len));
3954     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, req,
3955                 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
3956 
3957     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, req, len));
3958     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, req,
3959                 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
3960 
3961     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, req, len));
3962     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, req,
3963                 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
3964 
3965     len += ext_len;
3966 
3967     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, req, len));
3968     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, req,
3969                 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
3970 
3971     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, req, len));
3972     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, req,
3973                 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
3974 
3975     memmove(req, p, len);
3976     if (certid)
3977         *certid -= p - req;
3978     return len;
3979 }
3980 
3981 static int ocsp_resp(unsigned char *p, size_t len,
3982         const unsigned char *certid, size_t certid_size, int *status)
3983 {
3984     const unsigned char *end = p + len;
3985     int i, r;
3986 
3987     r = mbedtls_asn1_get_tag(&p, end, &len,
3988             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
3989     if (r)
3990         return r;
3991 
3992     r = mbedtls_asn1_get_tag(&p, end, &len, 10); // ASN1_ENUMERATED
3993     if (r)
3994         return r;
3995 
3996     if (len == 0 || len > sizeof(int) || (*p & 0x80))
3997         return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
3998 
3999     while (len--)
4000         r = (r << 8) | *p++;
4001     if (r)
4002         return r;
4003 
4004     r = mbedtls_asn1_get_tag(&p, end, &len,
4005             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
4006     if (r)
4007         return r;
4008 
4009     r = mbedtls_asn1_get_tag(&p, end, &len,
4010             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
4011     if (r)
4012         return r;
4013     end = p + len;
4014 
4015     r = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID);
4016     if (r)
4017         return r;
4018 
4019     if (len != MBEDTLS_OID_SIZE(OID_AD_OCSP_BASIC) ||
4020             memcmp(OID_AD_OCSP_BASIC, p, len) != 0)
4021         return MBEDTLS_ERR_ASN1_INVALID_DATA;
4022     p += len;
4023 
4024     r = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
4025     if (r)
4026         return r;
4027     end = p + len;
4028 
4029     r = mbedtls_asn1_get_tag(&p, end, &len,
4030             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
4031     if (r)
4032         return r;
4033     end = p + len;
4034 
4035     r = mbedtls_asn1_get_tag(&p, end, &len,
4036             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
4037     if (r)
4038         return r;
4039     end = p + len;
4040 
4041     r = mbedtls_asn1_get_tag(&p, end, &len,
4042             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
4043     if (r && r != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)
4044         return r;
4045     if (r == 0) {
4046         int ver = 0;
4047         r = mbedtls_asn1_get_int(&p, end, &ver);
4048         if (r)
4049             return r;
4050         if (ver)
4051             return MBEDTLS_ERR_ASN1_INVALID_DATA;
4052     }
4053 
4054     for (i = 1; i < 3; i++) {
4055         r = mbedtls_asn1_get_tag(&p, end, &len,
4056                 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC | i);
4057         if (r && r != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)
4058             return r;
4059         if (r == 0)
4060             break;
4061     }
4062     if (i > 2)
4063         return MBEDTLS_ERR_ASN1_INVALID_DATA;
4064     p += len;
4065 
4066     r = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_GENERALIZED_TIME);
4067     if (r)
4068         return r;
4069     p += len;
4070 
4071     r = mbedtls_asn1_get_tag(&p, end, &len,
4072             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
4073     if (r)
4074         return r;
4075 
4076     r = mbedtls_asn1_get_tag(&p, end, &len,
4077             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
4078     if (r)
4079         return r;
4080 
4081     r = mbedtls_asn1_get_tag(&p, end, &len,
4082             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
4083     if (r)
4084         return r;
4085     if (certid_size != len || memcmp(certid, p, len) != 0)
4086         return MBEDTLS_ERR_ASN1_INVALID_DATA;
4087     p += len;
4088 
4089     for (i = 0; i < 3; i++) {
4090         r = mbedtls_asn1_get_tag(&p, end, &len,
4091                 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC | i);
4092         if (r && r != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)
4093             return r;
4094         if (r == 0)
4095             break;
4096 
4097         r = mbedtls_asn1_get_tag(&p, end, &len,
4098                 MBEDTLS_ASN1_CONTEXT_SPECIFIC | i);
4099         if (r && r != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)
4100             return r;
4101         if (r == 0)
4102             break;
4103     }
4104     if (i > 2)
4105         return MBEDTLS_ERR_ASN1_INVALID_DATA;
4106     else if (status)
4107         *status = i;
4108 
4109     return 0;
4110 }
4111 
4112 static bool ocsp_check(mbedtls_x509_crt *crt)
4113 {
4114     bool result = true;
4115     char *ocsp_uri = NULL;
4116     curldata_t *cd = NULL;
4117     unsigned char *req = NULL;
4118     size_t req_size = 0x100;
4119     const unsigned char *certid = NULL;
4120     size_t certid_size = 0;
4121 
4122     if (!crt->v3_ext.p || crt->v3_ext.len == 0)
4123         goto out;
4124 
4125     const char *tmp = NULL;
4126     int r = ext_parse_ocsp_uri(crt->v3_ext.p, crt->v3_ext.len, &tmp);
4127     if (r < 0)
4128         warnx("ocsp_check: ext_parse_ocsp_uri failed: %s",
4129                 _mbedtls_strerror(r));
4130     else if (r == 0)
4131         goto out;
4132 
4133     ocsp_uri = strndup(tmp, r);
4134     if (!ocsp_uri) {
4135         warn("ocsp_check: strndup failed");
4136         goto out;
4137     }
4138 
4139     while (!req) {
4140         req = calloc(1, req_size);
4141         if (!req) {
4142             warn("ocsp_check: calloc failed");
4143             goto out;
4144         }
4145         r = ocsp_req(crt, req, req_size, &certid, &certid_size);
4146         if (r == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL) {
4147             free(req);
4148             req = NULL;
4149             req_size *= 2;
4150         }
4151         else if (r < 0) {
4152             warnx("ocsp_check: ocsp_req failed: %s", _mbedtls_strerror(r));
4153             goto out;
4154         } else
4155             req_size = r;
4156     }
4157 
4158     msg(1, "querying OCSP server at %s", ocsp_uri);
4159     msg_hd(3, "ocsp_check: HTTP post:\n", req, req_size);
4160     cd = curl_post(ocsp_uri, req, req_size,
4161             "Content-Type: application/ocsp-request", NULL);
4162     if (!cd) {
4163         warnx("ocsp_check: curl_post(\"%s\") failed", ocsp_uri);
4164         goto out;
4165     }
4166 
4167     if (cd->headers)
4168         msg(3, "ocsp_check: HTTP headers:\n%s", cd->headers);
4169     if (cd->body)
4170         msg_hd(3, "ocsp_check: HTTP body:\n", cd->body, cd->body_len);
4171 
4172     int status;
4173     r = ocsp_resp((unsigned char *)cd->body, cd->body_len, certid, certid_size,
4174             &status);
4175     if (r < 0) {
4176         warnx("ocsp_check: ocsp_resp failed: %s",
4177                 _mbedtls_strerror(r));
4178         goto out;
4179     } else if (r > 0) {
4180         warnx("OCSP response was unsuccessful (%d)", r);
4181         goto out;
4182     } else switch (status) {
4183         case 0: // GOOD
4184             msg(1, "OCSP certificate status is GOOD");
4185             break;
4186 
4187         case 1: // REVOKED
4188             warnx("OCSP certificate status is REVOKED");
4189             result = false;
4190             break;
4191 
4192         case 2: // UNKNOWN
4193         default:
4194             msg(1, "OCSP certificate status is UNKNOWN");
4195             break;
4196     }
4197 
4198 out:
4199     free(ocsp_uri);
4200     free(req);
4201     if (cd)
4202         curldata_free(cd);
4203     return result;
4204 }
4205 #endif
4206 
4207 bool cert_valid(const char *certfile, char * const *names, int validity,
4208         bool status_check)
4209 {
4210     bool valid = false;
4211 #if defined(USE_GNUTLS)
4212     gnutls_x509_crt_t crt[2] = {NULL, NULL};
4213     int ncrt = cert_load(crt, 2, "%s", certfile);
4214     if (ncrt <= 0)
4215         goto out;
4216 
4217     time_t expiration = gnutls_x509_crt_get_expiration_time(crt[0]);
4218     if (expiration == (time_t)-1) {
4219         warnx("cert_valid: gnutls_x509_crt_get_expiration_time failed");
4220         goto out;
4221     }
4222 
4223     int days_left = (expiration - time(NULL))/(24*3600);
4224     msg(1, "%s expires in %d days", certfile, days_left);
4225     if (days_left < validity) {
4226         msg(1, "%s is due for renewal", certfile);
4227         goto out;
4228     }
4229 
4230     while (names && *names) {
4231         if (!gnutls_x509_crt_check_hostname2(crt[0], *names,
4232                     GNUTLS_VERIFY_DO_NOT_ALLOW_WILDCARDS)) {
4233             msg(1, "%s does not include %s", certfile, *names);
4234             goto out;
4235         }
4236         names++;
4237     }
4238 
4239     valid = true;
4240     if (status_check) {
4241         if (ncrt < 2)
4242             warn("no issuer certificate in %s, skipping OCSP check", certfile);
4243         else
4244             valid = ocsp_check(crt);
4245     }
4246 out:
4247     for (int i = 0; i < ncrt; i++)
4248         if (crt[i])
4249             gnutls_x509_crt_deinit(crt[i]);
4250 #elif defined(USE_OPENSSL)
4251     GENERAL_NAMES *san = NULL;
4252     X509_NAME *sname = NULL;
4253     X509 *crt[2] = {NULL, NULL};
4254     int ncrt = cert_load(crt, 2, "%s", certfile);
4255     if (ncrt <= 0)
4256         goto out;
4257     int days_left, sec;
4258     const ASN1_TIME *tm = X509_get0_notAfter(crt[0]);
4259     if (!tm || !ASN1_TIME_diff(&days_left, &sec, NULL, tm)) {
4260         warnx("cert_valid: invalid expiration time format in %s", certfile);
4261         goto out;
4262     }
4263     msg(1, "%s expires in %d days", certfile, days_left);
4264     if (days_left < validity) {
4265         msg(1, "%s is due for renewal", certfile);
4266         goto out;
4267     }
4268 
4269     int crit = 0;
4270     san = X509_get_ext_d2i(crt[0], NID_subject_alt_name, &crit, NULL);
4271     if (!san && crit < 0) {
4272         openssl_error("cert_valid");
4273         goto out;
4274     }
4275 
4276     sname = X509_get_subject_name(crt[0]);
4277 
4278     while (names && *names) {
4279         bool found = false;
4280 
4281         int count = sk_GENERAL_NAME_num(san);
4282         while (count-- && !found) {
4283             GENERAL_NAME *name = sk_GENERAL_NAME_value(san, count);
4284             if (!name)
4285                 continue;
4286             int type;
4287             ASN1_STRING *value = GENERAL_NAME_get0_value(name, &type);
4288             if (!value)
4289                 continue;
4290             if (type == GEN_DNS) {
4291                 unsigned char *s = NULL;
4292                 if (ASN1_STRING_to_UTF8(&s, (ASN1_STRING *)value) < 0) {
4293                     openssl_error("cert_valid");
4294                     continue;
4295                 } else if (s) {
4296                     if (strcasecmp((char *)s, *names) == 0)
4297                         found = true;
4298                     OPENSSL_free(s);
4299                 }
4300             } else if (type == GEN_IPADD) {
4301                 char s[INET6_ADDRSTRLEN];
4302                 int af;
4303                 switch (ASN1_STRING_length(value)) {
4304                     case 4:
4305                         af = AF_INET;
4306                         break;
4307                     case 16:
4308                         af = AF_INET6;
4309                         break;
4310                     default:
4311                         continue;
4312                 }
4313                 memset(s, 0, sizeof(s));
4314                 if (!inet_ntop(af, ASN1_STRING_get0_data(value), s, sizeof(s)))
4315                     continue;
4316                 if (strcasecmp(s, *names) == 0)
4317                     found = true;
4318             }
4319         }
4320 
4321         if (sname) {
4322             for (int i = -1; !found; ) {
4323                  i = X509_NAME_get_index_by_NID(sname, NID_commonName, i);
4324                  if (i < 0)
4325                      break;
4326                  X509_NAME_ENTRY *entry = X509_NAME_get_entry(sname, i);
4327                  if (!entry)
4328                      continue;
4329                  ASN1_STRING *str = X509_NAME_ENTRY_get_data(entry);
4330                  if (!str)
4331                      continue;
4332                  unsigned char *s = NULL;
4333                  if (ASN1_STRING_to_UTF8(&s, str) < 0) {
4334                      openssl_error("cert_valid");
4335                      continue;
4336                  }
4337                  if (strcasecmp((char *)s, *names) == 0)
4338                      found = true;
4339                  OPENSSL_free(s);
4340             }
4341         }
4342 
4343         if (!found) {
4344             msg(1, "%s does not include %s", certfile, *names);
4345             goto out;
4346         }
4347         names++;
4348     }
4349 
4350     valid = true;
4351     if (status_check) {
4352         if (ncrt < 2)
4353             warn("no issuer certificate in %s, skipping OCSP check", certfile);
4354         else
4355             valid = ocsp_check(crt);
4356     }
4357 out:
4358     for (int i = 0; i < ncrt; i++)
4359         if (crt[i])
4360             X509_free(crt[i]);
4361     if (san)
4362         GENERAL_NAMES_free(san);
4363 #elif defined(USE_MBEDTLS)
4364     mbedtls_x509_crt *crt = NULL;
4365     mbedtls_x509_sequence san;
4366     memset(&san, 0, sizeof(san));
4367 
4368     int ncrt = cert_load(&crt, "%s", certfile);
4369     if (ncrt < 1)
4370         goto out;
4371 
4372     struct tm texp = {
4373         .tm_sec = crt->valid_to.sec,
4374         .tm_min = crt->valid_to.min,
4375         .tm_hour = crt->valid_to.hour,
4376         .tm_mday = crt->valid_to.day,
4377         .tm_mon = crt->valid_to.mon - 1,
4378         .tm_year = crt->valid_to.year - 1900,
4379         .tm_isdst = -1
4380     };
4381 
4382     time_t expiration = mktime(&texp);
4383     if (expiration == (time_t)-1) {
4384         warnx("cert_valid: failed to determine expiration time");
4385         goto out;
4386     }
4387 
4388     int days_left = (expiration - time(NULL))/(24*3600);
4389     msg(1, "%s expires in %d days", certfile, days_left);
4390     if (days_left < validity) {
4391         msg(1, "%s is due for renewal", certfile);
4392         goto out;
4393     }
4394 
4395     if (crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) {
4396         int r = ext_san(crt->v3_ext.p, crt->v3_ext.len, &san);
4397         if (r) {
4398             warnx("cert_valid: ext_san failed: %s", _mbedtls_strerror(r));
4399             goto out;
4400         }
4401     }
4402 
4403     while (names && *names) {
4404         bool found = false;
4405         const mbedtls_x509_name *name = NULL;
4406         const mbedtls_x509_sequence *cur = NULL;
4407 
4408         for (cur = &san; cur && !found; cur = cur->next) {
4409             if (cur->buf.tag == (MBEDTLS_ASN1_CONTEXT_SPECIFIC|2)) {
4410                 if (strncasecmp(*names, (const char *)cur->buf.p,
4411                             strlen(*names)) == 0)
4412                     found = true;
4413             } else if (cur->buf.tag == (MBEDTLS_ASN1_CONTEXT_SPECIFIC|7)) {
4414                 char s[INET6_ADDRSTRLEN];
4415                 int af;
4416                 switch (cur->buf.len) {
4417                     case 4:
4418                         af = AF_INET;
4419                         break;
4420                     case 16:
4421                         af = AF_INET6;
4422                         break;
4423                     default:
4424                         continue;
4425                 }
4426                 memset(s, 0, sizeof(s));
4427                 if (!inet_ntop(af, cur->buf.p, s, sizeof(s)))
4428                     continue;
4429                 if (strcasecmp(s, *names) == 0)
4430                     found = true;
4431              }
4432         }
4433         for (name = &crt->subject; name != NULL && !found; name = name->next) {
4434             if (MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &name->oid) == 0 &&
4435                     strncasecmp(*names, (const char *)name->val.p,
4436                         strlen(*names)) == 0)
4437                 found = true;
4438         }
4439         if (!found) {
4440             msg(1, "%s does not include %s", certfile, *names);
4441             goto out;
4442         }
4443         names++;
4444     }
4445 
4446     valid = true;
4447     if (status_check) {
4448         if (ncrt < 2)
4449             warn("no issuer certificate in %s, skipping OCSP check", certfile);
4450         else
4451             valid = ocsp_check(crt);
4452     }
4453 out:
4454     if (crt) {
4455         mbedtls_x509_crt_free(crt);
4456         free(crt);
4457     }
4458     while (san.next) {
4459         mbedtls_x509_sequence *tmp = san.next;
4460         san.next = tmp->next;
4461         mbedtls_free(tmp);
4462     }
4463 #endif
4464     return valid;
4465 }
4466 
4467 char *cert_der_base64url(const char *certfile)
4468 {
4469     char *ret = NULL;
4470     void *certdata = NULL;
4471     size_t certsize = 0;
4472     int r;
4473 #if defined(USE_GNUTLS)
4474     gnutls_x509_crt_t crt = NULL;
4475     if (cert_load(&crt, 1, certfile) <= 0) {
4476         warnx("cert_der_base64url: cert_load failed");
4477         goto out;
4478     }
4479 
4480     gnutls_datum_t data = {NULL, 0};
4481     r = gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_DER, &data);
4482     gnutls_x509_crt_deinit(crt);
4483     if (r != GNUTLS_E_SUCCESS) {
4484         warnx("cert_der_base64url: gnutls_x509_crt_export2: %s",
4485                 gnutls_strerror(r));
4486         goto out;
4487     }
4488     certsize = data.size;
4489     certdata = gnutls_datum_data(&data, true);
4490     if (!certdata)
4491         goto out;
4492 #elif defined(USE_OPENSSL)
4493     X509 *crt = NULL;
4494     if (cert_load(&crt, 1, certfile) <= 0) {
4495         warnx("cert_der_base64url: cert_load failed");
4496         goto out;
4497     }
4498     r = i2d_X509(crt, NULL);
4499     if (r < 0) {
4500         openssl_error("cert_der_base64url");
4501         X509_free(crt);
4502         goto out;
4503     }
4504     certsize = r;
4505     certdata = calloc(1, certsize);
4506     if (!certdata) {
4507         warn("cert_der_base64url: calloc failed");
4508         X509_free(crt);
4509         goto out;
4510     }
4511     unsigned char *tmp = certdata;
4512     r = i2d_X509(crt, &tmp);
4513     X509_free(crt);
4514     if (r != (int)certsize) {
4515         openssl_error("cert_der_base64url");
4516         goto out;
4517     }
4518 #elif defined(USE_MBEDTLS)
4519     certdata = read_file(certfile, &certsize);
4520     if (!certdata) {
4521         warn("cert_der_base64url: error reading %s", certfile);
4522         goto out;
4523     }
4524     mbedtls_pem_context ctx;
4525     mbedtls_pem_init(&ctx);
4526     size_t len;
4527     r = mbedtls_pem_read_buffer(&ctx, "-----BEGIN CERTIFICATE-----",
4528             "-----END CERTIFICATE-----", certdata, NULL, 0, &len);
4529     if (r) {
4530         warnx("cert_der_base64url: mbedtls_pem_read_buffer failed: %s",
4531                 _mbedtls_strerror(r));
4532         mbedtls_pem_free(&ctx);
4533         goto out;
4534     }
4535     free(certdata);
4536     certsize = ctx.buflen;
4537     certdata = calloc(1, certsize);
4538     if (!certdata) {
4539         warn("cert_der_base64url: calloc failed");
4540         mbedtls_pem_free(&ctx);
4541         goto out;
4542     }
4543     memcpy(certdata, ctx.buf, ctx.buflen);
4544     mbedtls_pem_free(&ctx);
4545 #endif
4546     r = base64_ENCODED_LEN(certsize, base64_VARIANT_URLSAFE_NO_PADDING);
4547     if (!(ret = calloc(1, r))) {
4548         warn("cert_der_base64url: calloc failed");
4549         goto out;
4550     }
4551     if (!bin2base64(ret, r, certdata, certsize,
4552                 base64_VARIANT_URLSAFE_NO_PADDING)) {
4553         warnx("cert_der_base64url: bin2base64 failed");
4554         free(ret);
4555         ret = NULL;
4556         goto out;
4557     }
4558 out:
4559     free(certdata);
4560     return ret;
4561 }
4562