1 /* $OpenBSD: ssl_sigalgs.c,v 1.16 2019/01/24 00:07:58 beck Exp $ */ 2 /* 3 * Copyright (c) 2018-2019 Bob Beck <beck@openbsd.org> 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 12 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 14 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 15 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 #include <string.h> 18 #include <stdlib.h> 19 20 #include <openssl/evp.h> 21 22 #include "bytestring.h" 23 #include "ssl_locl.h" 24 #include "ssl_sigalgs.h" 25 #include "tls13_internal.h" 26 27 const struct ssl_sigalg sigalgs[] = { 28 { 29 .value = SIGALG_RSA_PKCS1_SHA512, 30 .md = EVP_sha512, 31 .key_type = EVP_PKEY_RSA, 32 .pkey_idx = SSL_PKEY_RSA_SIGN, 33 }, 34 { 35 .value = SIGALG_ECDSA_SECP521R1_SHA512, 36 .md = EVP_sha512, 37 .key_type = EVP_PKEY_EC, 38 .pkey_idx = SSL_PKEY_ECC, 39 .curve_nid = NID_secp521r1, 40 }, 41 #ifndef OPENSSL_NO_GOST 42 { 43 .value = SIGALG_GOSTR12_512_STREEBOG_512, 44 .md = EVP_streebog512, 45 .key_type = EVP_PKEY_GOSTR12_512, 46 .pkey_idx = SSL_PKEY_GOST01, /* XXX */ 47 }, 48 #endif 49 { 50 .value = SIGALG_RSA_PKCS1_SHA384, 51 .md = EVP_sha384, 52 .key_type = EVP_PKEY_RSA, 53 .pkey_idx = SSL_PKEY_RSA_SIGN, 54 }, 55 { 56 .value = SIGALG_ECDSA_SECP384R1_SHA384, 57 .md = EVP_sha384, 58 .key_type = EVP_PKEY_EC, 59 .pkey_idx = SSL_PKEY_ECC, 60 .curve_nid = NID_secp384r1, 61 }, 62 { 63 .value = SIGALG_RSA_PKCS1_SHA256, 64 .md = EVP_sha256, 65 .key_type = EVP_PKEY_RSA, 66 .pkey_idx = SSL_PKEY_RSA_SIGN, 67 }, 68 { 69 .value = SIGALG_ECDSA_SECP256R1_SHA256, 70 .md = EVP_sha256, 71 .key_type = EVP_PKEY_EC, 72 .pkey_idx = SSL_PKEY_ECC, 73 .curve_nid = NID_X9_62_prime256v1, 74 }, 75 #ifndef OPENSSL_NO_GOST 76 { 77 .value = SIGALG_GOSTR12_256_STREEBOG_256, 78 .md = EVP_streebog256, 79 .key_type = EVP_PKEY_GOSTR12_256, 80 .pkey_idx = SSL_PKEY_GOST01, /* XXX */ 81 }, 82 { 83 .value = SIGALG_GOSTR01_GOST94, 84 .md = EVP_gostr341194, 85 .key_type = EVP_PKEY_GOSTR01, 86 .pkey_idx = SSL_PKEY_GOST01, 87 }, 88 #endif 89 { 90 .value = SIGALG_RSA_PSS_RSAE_SHA256, 91 .md = EVP_sha256, 92 .key_type = EVP_PKEY_RSA, 93 .pkey_idx = SSL_PKEY_RSA_SIGN, 94 .flags = SIGALG_FLAG_RSA_PSS, 95 }, 96 { 97 .value = SIGALG_RSA_PSS_RSAE_SHA384, 98 .md = EVP_sha384, 99 .key_type = EVP_PKEY_RSA, 100 .pkey_idx = SSL_PKEY_RSA_SIGN, 101 .flags = SIGALG_FLAG_RSA_PSS, 102 }, 103 { 104 .value = SIGALG_RSA_PSS_RSAE_SHA512, 105 .md = EVP_sha512, 106 .key_type = EVP_PKEY_RSA, 107 .pkey_idx = SSL_PKEY_RSA_SIGN, 108 .flags = SIGALG_FLAG_RSA_PSS, 109 }, 110 { 111 .value = SIGALG_RSA_PSS_PSS_SHA256, 112 .md = EVP_sha256, 113 .key_type = EVP_PKEY_RSA, 114 .pkey_idx = SSL_PKEY_RSA_SIGN, 115 .flags = SIGALG_FLAG_RSA_PSS, 116 }, 117 { 118 .value = SIGALG_RSA_PSS_PSS_SHA384, 119 .md = EVP_sha384, 120 .key_type = EVP_PKEY_RSA, 121 .pkey_idx = SSL_PKEY_RSA_SIGN, 122 .flags = SIGALG_FLAG_RSA_PSS, 123 }, 124 { 125 .value = SIGALG_RSA_PSS_PSS_SHA512, 126 .md = EVP_sha512, 127 .key_type = EVP_PKEY_RSA, 128 .pkey_idx = SSL_PKEY_RSA_SIGN, 129 .flags = SIGALG_FLAG_RSA_PSS, 130 }, 131 { 132 .value = SIGALG_RSA_PKCS1_SHA224, 133 .md = EVP_sha224, 134 .key_type = EVP_PKEY_RSA, 135 .pkey_idx = SSL_PKEY_RSA_SIGN, 136 }, 137 { 138 .value = SIGALG_ECDSA_SECP224R1_SHA224, 139 .md = EVP_sha224, 140 .key_type = EVP_PKEY_EC, 141 .pkey_idx = SSL_PKEY_ECC, 142 }, 143 { 144 .value = SIGALG_RSA_PKCS1_SHA1, 145 .key_type = EVP_PKEY_RSA, 146 .pkey_idx = SSL_PKEY_RSA_SIGN, 147 .md = EVP_sha1, 148 }, 149 { 150 .value = SIGALG_ECDSA_SHA1, 151 .key_type = EVP_PKEY_EC, 152 .md = EVP_sha1, 153 .pkey_idx = SSL_PKEY_ECC, 154 }, 155 { 156 .value = SIGALG_RSA_PKCS1_MD5_SHA1, 157 .key_type = EVP_PKEY_RSA, 158 .pkey_idx = SSL_PKEY_RSA_SIGN, 159 .md = EVP_md5_sha1, 160 }, 161 { 162 .value = SIGALG_NONE, 163 }, 164 }; 165 166 /* Sigalgs for tls 1.3, in preference order, */ 167 uint16_t tls13_sigalgs[] = { 168 SIGALG_RSA_PSS_RSAE_SHA512, 169 SIGALG_RSA_PKCS1_SHA512, 170 SIGALG_ECDSA_SECP521R1_SHA512, 171 SIGALG_RSA_PSS_RSAE_SHA384, 172 SIGALG_RSA_PKCS1_SHA384, 173 SIGALG_ECDSA_SECP384R1_SHA384, 174 SIGALG_RSA_PSS_RSAE_SHA256, 175 SIGALG_RSA_PKCS1_SHA256, 176 SIGALG_ECDSA_SECP256R1_SHA256, 177 }; 178 size_t tls13_sigalgs_len = (sizeof(tls13_sigalgs) / sizeof(tls13_sigalgs[0])); 179 180 /* Sigalgs for tls 1.2, in preference order, */ 181 uint16_t tls12_sigalgs[] = { 182 SIGALG_RSA_PSS_RSAE_SHA512, 183 SIGALG_RSA_PKCS1_SHA512, 184 SIGALG_ECDSA_SECP521R1_SHA512, 185 SIGALG_RSA_PSS_RSAE_SHA384, 186 SIGALG_RSA_PKCS1_SHA384, 187 SIGALG_ECDSA_SECP384R1_SHA384, 188 SIGALG_RSA_PSS_RSAE_SHA256, 189 SIGALG_RSA_PKCS1_SHA256, 190 SIGALG_ECDSA_SECP256R1_SHA256, 191 SIGALG_RSA_PKCS1_SHA1, /* XXX */ 192 SIGALG_ECDSA_SHA1, /* XXX */ 193 }; 194 size_t tls12_sigalgs_len = (sizeof(tls12_sigalgs) / sizeof(tls12_sigalgs[0])); 195 196 const struct ssl_sigalg * 197 ssl_sigalg_lookup(uint16_t sigalg) 198 { 199 int i; 200 201 for (i = 0; sigalgs[i].value != SIGALG_NONE; i++) { 202 if (sigalgs[i].value == sigalg) 203 return &sigalgs[i]; 204 } 205 206 return NULL; 207 } 208 209 const struct ssl_sigalg * 210 ssl_sigalg(uint16_t sigalg, uint16_t *values, size_t len) 211 { 212 const struct ssl_sigalg *sap; 213 int i; 214 215 for (i = 0; i < len; i++) { 216 if (values[i] == sigalg) 217 break; 218 } 219 if (values[i] == sigalg) { 220 if ((sap = ssl_sigalg_lookup(sigalg)) != NULL) 221 return sap; 222 } 223 224 return NULL; 225 } 226 227 int 228 ssl_sigalgs_build(CBB *cbb, uint16_t *values, size_t len) 229 { 230 size_t i; 231 232 for (i = 0; sigalgs[i].value != SIGALG_NONE; i++); 233 if (len > i) 234 return 0; 235 236 /* XXX check for duplicates and other sanity BS? */ 237 238 /* Add values in order as long as they are supported. */ 239 for (i = 0; i < len; i++) { 240 /* Do not allow the legacy value for < 1.2 to be used */ 241 if (values[i] == SIGALG_RSA_PKCS1_MD5_SHA1) 242 return 0; 243 244 if (ssl_sigalg_lookup(values[i]) != NULL) { 245 if (!CBB_add_u16(cbb, values[i])) 246 return 0; 247 } else 248 return 0; 249 } 250 return 1; 251 } 252 253 int 254 ssl_sigalg_pkey_ok(const struct ssl_sigalg *sigalg, EVP_PKEY *pkey) 255 { 256 if (sigalg == NULL || pkey == NULL) 257 return 0; 258 if (sigalg->key_type != pkey->type) 259 return 0; 260 261 if ((sigalg->flags & SIGALG_FLAG_RSA_PSS)) { 262 /* 263 * RSA PSS Must have an RSA key that needs to be at 264 * least as big as twice the size of the hash + 2 265 */ 266 if (pkey->type != EVP_PKEY_RSA || 267 EVP_PKEY_size(pkey) < (2 * EVP_MD_size(sigalg->md()) + 2)) 268 return 0; 269 } 270 271 if (pkey->type == EVP_PKEY_EC) { 272 if (sigalg->curve_nid == 0) 273 return 0; 274 /* Curve must match for EC keys */ 275 if (EC_GROUP_get_curve_name(EC_KEY_get0_group 276 (EVP_PKEY_get0_EC_KEY(pkey))) != sigalg->curve_nid) { 277 return 1; /* XXX www.videolan.org curve mismatch */ 278 } 279 } 280 281 return 1; 282 } 283