summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/Makefile3
-rw-r--r--src/lib/libcrypto/ec/ecx_methods.c22
-rw-r--r--src/lib/libcrypto/evp/evp_local.h5
-rw-r--r--src/lib/libcrypto/rsa/rsa_ameth.c56
-rw-r--r--src/lib/libcrypto/x509/x509.h10
-rw-r--r--src/lib/libcrypto/x509/x509_siginfo.c113
6 files changed, 204 insertions, 5 deletions
diff --git a/src/lib/libcrypto/Makefile b/src/lib/libcrypto/Makefile
index 30c63be8e4..b4407d566c 100644
--- a/src/lib/libcrypto/Makefile
+++ b/src/lib/libcrypto/Makefile
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile,v 1.202 2024/08/10 06:41:49 tb Exp $ 1# $OpenBSD: Makefile,v 1.203 2024/08/28 07:15:04 tb Exp $
2 2
3LIB= crypto 3LIB= crypto
4LIBREBUILD=y 4LIBREBUILD=y
@@ -589,6 +589,7 @@ SRCS+= x509_purp.c
589SRCS+= x509_r2x.c 589SRCS+= x509_r2x.c
590SRCS+= x509_req.c 590SRCS+= x509_req.c
591SRCS+= x509_set.c 591SRCS+= x509_set.c
592SRCS+= x509_siginfo.c
592SRCS+= x509_skey.c 593SRCS+= x509_skey.c
593SRCS+= x509_trs.c 594SRCS+= x509_trs.c
594SRCS+= x509_txt.c 595SRCS+= x509_txt.c
diff --git a/src/lib/libcrypto/ec/ecx_methods.c b/src/lib/libcrypto/ec/ecx_methods.c
index 70475e8dc1..6b5759d4fa 100644
--- a/src/lib/libcrypto/ec/ecx_methods.c
+++ b/src/lib/libcrypto/ec/ecx_methods.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ecx_methods.c,v 1.13 2024/04/02 04:04:07 tb Exp $ */ 1/* $OpenBSD: ecx_methods.c,v 1.14 2024/08/28 07:15:04 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2022 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2022 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -510,6 +510,24 @@ ecx_security_bits(const EVP_PKEY *pkey)
510} 510}
511 511
512static int 512static int
513ecx_signature_info(const X509_ALGOR *algor, int *md_nid, int *pkey_nid,
514 int *security_bits, uint32_t *flags)
515{
516 const ASN1_OBJECT *aobj;
517
518 X509_ALGOR_get0(&aobj, NULL, NULL, algor);
519 if (OBJ_obj2nid(aobj) != EVP_PKEY_ED25519)
520 return 0;
521
522 *md_nid = NID_undef;
523 *pkey_nid = NID_ED25519;
524 *security_bits = ED25519_SECURITY_BITS;
525 *flags = X509_SIG_INFO_TLS | X509_SIG_INFO_VALID;
526
527 return 1;
528}
529
530static int
513ecx_param_cmp(const EVP_PKEY *pkey1, const EVP_PKEY *pkey2) 531ecx_param_cmp(const EVP_PKEY *pkey1, const EVP_PKEY *pkey2)
514{ 532{
515 /* No parameters, so always equivalent. */ 533 /* No parameters, so always equivalent. */
@@ -929,6 +947,8 @@ const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
929 .pkey_bits = ecx_bits, 947 .pkey_bits = ecx_bits,
930 .pkey_security_bits = ecx_security_bits, 948 .pkey_security_bits = ecx_security_bits,
931 949
950 .signature_info = ecx_signature_info,
951
932 .param_cmp = ecx_param_cmp, 952 .param_cmp = ecx_param_cmp,
933 953
934 .pkey_free = ecx_free, 954 .pkey_free = ecx_free,
diff --git a/src/lib/libcrypto/evp/evp_local.h b/src/lib/libcrypto/evp/evp_local.h
index 3e90e068e6..5d541ffec4 100644
--- a/src/lib/libcrypto/evp/evp_local.h
+++ b/src/lib/libcrypto/evp/evp_local.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: evp_local.h,v 1.23 2024/08/22 12:24:24 tb Exp $ */ 1/* $OpenBSD: evp_local.h,v 1.24 2024/08/28 07:15:04 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2000. 3 * project 2000.
4 */ 4 */
@@ -112,6 +112,9 @@ struct evp_pkey_asn1_method_st {
112 int (*pkey_bits)(const EVP_PKEY *pk); 112 int (*pkey_bits)(const EVP_PKEY *pk);
113 int (*pkey_security_bits)(const EVP_PKEY *pk); 113 int (*pkey_security_bits)(const EVP_PKEY *pk);
114 114
115 int (*signature_info)(const X509_ALGOR *sig_alg, int *out_md_nid,
116 int *out_pkey_nid, int *out_security_bits, uint32_t *out_flags);
117
115 int (*param_decode)(EVP_PKEY *pkey, const unsigned char **pder, 118 int (*param_decode)(EVP_PKEY *pkey, const unsigned char **pder,
116 int derlen); 119 int derlen);
117 int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder); 120 int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder);
diff --git a/src/lib/libcrypto/rsa/rsa_ameth.c b/src/lib/libcrypto/rsa/rsa_ameth.c
index c722188c43..d7ce931733 100644
--- a/src/lib/libcrypto/rsa/rsa_ameth.c
+++ b/src/lib/libcrypto/rsa/rsa_ameth.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: rsa_ameth.c,v 1.58 2024/03/17 07:10:00 tb Exp $ */ 1/* $OpenBSD: rsa_ameth.c,v 1.59 2024/08/28 07:15:04 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006. 3 * project 2006.
4 */ 4 */
@@ -845,6 +845,58 @@ rsa_pss_get_param(const RSA_PSS_PARAMS *pss, const EVP_MD **pmd,
845 return 1; 845 return 1;
846} 846}
847 847
848static int
849rsa_pss_signature_info(const X509_ALGOR *alg, int *out_md_nid,
850 int *out_pkey_nid, int *out_security_bits, uint32_t *out_flags)
851{
852 RSA_PSS_PARAMS *pss = NULL;
853 const ASN1_OBJECT *aobj;
854 const EVP_MD *md, *mgf1md;
855 int md_len, salt_len;
856 int md_nid = NID_undef, pkey_nid = NID_undef;
857 int security_bits = -1;
858 uint32_t flags = 0;
859
860 X509_ALGOR_get0(&aobj, NULL, NULL, alg);
861 if (OBJ_obj2nid(aobj) != EVP_PKEY_RSA_PSS)
862 goto err;
863
864 if ((pss = rsa_pss_decode(alg)) == NULL)
865 goto err;
866 if (!rsa_pss_get_param(pss, &md, &mgf1md, &salt_len))
867 goto err;
868
869 if ((md_nid = EVP_MD_type(md)) == NID_undef)
870 goto err;
871 if ((md_len = EVP_MD_size(md)) <= 0)
872 goto err;
873
874 /*
875 * RFC 8446, section 4.2.3 - restricts the digest algorithm:
876 * - it must be one of SHA256, SHA384, and SHA512;
877 * - the same digest must be used in the mask generation function;
878 * - the salt length must match the output length of the digest.
879 * XXX - consider separate flags for these checks.
880 */
881 if (md_nid == NID_sha256 || md_nid == NID_sha384 || md_nid == NID_sha512) {
882 if (md_nid == EVP_MD_type(mgf1md) && salt_len == md_len)
883 flags |= X509_SIG_INFO_TLS;
884 }
885
886 security_bits = md_len * 4;
887 flags |= X509_SIG_INFO_VALID;
888
889 *out_md_nid = md_nid;
890 *out_pkey_nid = pkey_nid;
891 *out_security_bits = security_bits;
892 *out_flags = flags;
893
894 err:
895 RSA_PSS_PARAMS_free(pss);
896
897 return (flags & X509_SIG_INFO_VALID) != 0;
898}
899
848#ifndef OPENSSL_NO_CMS 900#ifndef OPENSSL_NO_CMS
849static int 901static int
850rsa_cms_verify(CMS_SignerInfo *si) 902rsa_cms_verify(CMS_SignerInfo *si)
@@ -1216,6 +1268,8 @@ const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth = {
1216 .pkey_bits = rsa_bits, 1268 .pkey_bits = rsa_bits,
1217 .pkey_security_bits = rsa_security_bits, 1269 .pkey_security_bits = rsa_security_bits,
1218 1270
1271 .signature_info = rsa_pss_signature_info,
1272
1219 .sig_print = rsa_sig_print, 1273 .sig_print = rsa_sig_print,
1220 1274
1221 .pkey_free = rsa_free, 1275 .pkey_free = rsa_free,
diff --git a/src/lib/libcrypto/x509/x509.h b/src/lib/libcrypto/x509/x509.h
index 87bc6dbb33..856ad19ba4 100644
--- a/src/lib/libcrypto/x509/x509.h
+++ b/src/lib/libcrypto/x509/x509.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: x509.h,v 1.112 2024/06/12 03:55:46 tb Exp $ */ 1/* $OpenBSD: x509.h,v 1.113 2024/08/28 07:15:04 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -622,6 +622,14 @@ X509 * d2i_X509_AUX(X509 **a,const unsigned char **pp,long length);
622 622
623int i2d_re_X509_tbs(X509 *x, unsigned char **pp); 623int i2d_re_X509_tbs(X509 *x, unsigned char **pp);
624 624
625#if defined(LIBRESSL_INTERNAL) || defined(LIBRESSL_NEXT_API)
626/* Flags returned by X509_get_signature_info(): valid and suitable for TLS. */
627#define X509_SIG_INFO_VALID 1
628#define X509_SIG_INFO_TLS 2
629int X509_get_signature_info(X509 *x, int *mdnid, int *pknid, int *secbits,
630 uint32_t *flags);
631#endif
632
625void X509_get0_signature(const ASN1_BIT_STRING **psig, 633void X509_get0_signature(const ASN1_BIT_STRING **psig,
626 const X509_ALGOR **palg, const X509 *x); 634 const X509_ALGOR **palg, const X509 *x);
627int X509_get_signature_nid(const X509 *x); 635int X509_get_signature_nid(const X509 *x);
diff --git a/src/lib/libcrypto/x509/x509_siginfo.c b/src/lib/libcrypto/x509/x509_siginfo.c
new file mode 100644
index 0000000000..9bbb133216
--- /dev/null
+++ b/src/lib/libcrypto/x509/x509_siginfo.c
@@ -0,0 +1,113 @@
1/* $OpenBSD: x509_siginfo.c,v 1.1 2024/08/28 07:15:04 tb Exp $ */
2
3/*
4 * Copyright (c) 2024 Theo Buehler <tb@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <openssl/evp.h>
20#include <openssl/objects.h>
21#include <openssl/x509.h>
22
23#include "evp_local.h"
24
25#include "x509_internal.h"
26
27static int
28x509_find_sigid_algs(const X509 *x509, int *out_md_nid, int *out_pkey_nid)
29{
30 const ASN1_OBJECT *aobj;
31 int nid;
32
33 *out_md_nid = NID_undef;
34 *out_pkey_nid = NID_undef;
35
36 X509_ALGOR_get0(&aobj, NULL, NULL, x509->sig_alg);
37 if ((nid = OBJ_obj2nid(aobj)) == NID_undef)
38 return 0;
39
40 return OBJ_find_sigid_algs(nid, out_md_nid, out_pkey_nid);
41}
42
43int
44X509_get_signature_info(X509 *x509, int *out_md_nid, int *out_pkey_nid,
45 int *out_security_bits, uint32_t *out_flags)
46{
47 const EVP_MD *md;
48 int md_nid = NID_undef, pkey_nid = NID_undef, security_bits = -1;
49 uint32_t flags = 0;
50
51 if (out_md_nid != NULL)
52 *out_md_nid = md_nid;
53 if (out_pkey_nid != NULL)
54 *out_pkey_nid = pkey_nid;
55 if (out_security_bits != NULL)
56 *out_security_bits = security_bits;
57 if (out_flags != NULL)
58 *out_flags = flags;
59
60 if (!x509v3_cache_extensions(x509))
61 goto err;
62
63 if (!x509_find_sigid_algs(x509, &md_nid, &pkey_nid))
64 goto err;
65
66 /*
67 * If md_nid == NID_undef, this means we need to consult the ameth.
68 * Handlers are available for EdDSA and RSA-PSS. No other signature
69 * algorithm with NID_undef should appear in a certificate.
70 */
71 if (md_nid == NID_undef) {
72 const EVP_PKEY_ASN1_METHOD *ameth;
73
74 if ((ameth = EVP_PKEY_asn1_find(NULL, pkey_nid)) == NULL ||
75 ameth->signature_info == NULL)
76 goto err;
77
78 if (!ameth->signature_info(x509->sig_alg, &md_nid, &pkey_nid,
79 &security_bits, &flags))
80 goto err;
81
82 goto done;
83 }
84
85 /* XXX - OpenSSL 3 special cases SHA-1 (63 bits) and MD5 (39 bits). */
86 if ((md = EVP_get_digestbynid(md_nid)) == NULL)
87 goto err;
88
89 /* Assume 4 bits of collision resistance per octet. */
90 if ((security_bits = EVP_MD_size(md)) <= 0)
91 goto err;
92 security_bits *= 4;
93
94 if (md_nid == NID_sha1 || md_nid == NID_sha256 ||
95 md_nid == NID_sha384 || md_nid == NID_sha512)
96 flags |= X509_SIG_INFO_TLS;
97
98 flags |= X509_SIG_INFO_VALID;
99
100 done:
101 if (out_md_nid != NULL)
102 *out_md_nid = md_nid;
103 if (out_pkey_nid != NULL)
104 *out_pkey_nid = pkey_nid;
105 if (out_security_bits != NULL)
106 *out_security_bits = security_bits;
107 if (out_flags != NULL)
108 *out_flags = flags;
109
110 err:
111 return (flags & X509_SIG_INFO_VALID) != 0;
112}
113LCRYPTO_ALIAS(X509_get_signature_info);