1 /* $OpenBSD: ssl_sigalgs.c,v 1.11 2018/11/16 02:41:16 beck Exp $ */ 2 /* 3 * Copyright (c) 2018, 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_SECP512R1_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.2, in preference order, */ 167 uint16_t tls12_sigalgs[] = { 168 SIGALG_RSA_PKCS1_SHA512, 169 SIGALG_ECDSA_SECP512R1_SHA512, 170 SIGALG_GOSTR12_512_STREEBOG_512, 171 SIGALG_RSA_PKCS1_SHA384, 172 SIGALG_ECDSA_SECP384R1_SHA384, 173 SIGALG_RSA_PKCS1_SHA256, 174 SIGALG_ECDSA_SECP256R1_SHA256, 175 SIGALG_GOSTR12_256_STREEBOG_256, 176 SIGALG_GOSTR01_GOST94, 177 SIGALG_RSA_PKCS1_SHA224, 178 SIGALG_ECDSA_SECP224R1_SHA224, 179 SIGALG_RSA_PKCS1_SHA1, /* XXX */ 180 SIGALG_ECDSA_SHA1, /* XXX */ 181 }; 182 size_t tls12_sigalgs_len = (sizeof(tls12_sigalgs) / sizeof(tls12_sigalgs[0])); 183 184 const struct ssl_sigalg * 185 ssl_sigalg_lookup(uint16_t sigalg) 186 { 187 int i; 188 189 for (i = 0; sigalgs[i].value != SIGALG_NONE; i++) { 190 if (sigalgs[i].value == sigalg) 191 return &sigalgs[i]; 192 } 193 194 return NULL; 195 } 196 197 const struct ssl_sigalg * 198 ssl_sigalg(uint16_t sigalg, uint16_t *values, size_t len) 199 { 200 const struct ssl_sigalg *sap; 201 int i; 202 203 for (i = 0; i < len; i++) { 204 if (values[i] == sigalg) 205 break; 206 } 207 if (values[i] == sigalg) { 208 if ((sap = ssl_sigalg_lookup(sigalg)) != NULL) 209 return sap; 210 } 211 212 return NULL; 213 } 214 215 int 216 ssl_sigalgs_build(CBB *cbb, uint16_t *values, size_t len) 217 { 218 size_t i; 219 220 for (i = 0; sigalgs[i].value != SIGALG_NONE; i++); 221 if (len > i) 222 return 0; 223 224 /* XXX check for duplicates and other sanity BS? */ 225 226 /* Add values in order as long as they are supported. */ 227 for (i = 0; i < len; i++) { 228 /* Do not allow the legacy value for < 1.2 to be used */ 229 if (values[i] == SIGALG_RSA_PKCS1_MD5_SHA1) 230 return 0; 231 232 if (ssl_sigalg_lookup(values[i]) != NULL) { 233 if (!CBB_add_u16(cbb, values[i])) 234 return 0; 235 } else 236 return 0; 237 } 238 return 1; 239 } 240 241 int 242 ssl_sigalg_pkey_ok(const struct ssl_sigalg *sigalg, EVP_PKEY *pkey) 243 { 244 if (sigalg == NULL || pkey == NULL) 245 return 0; 246 if (sigalg->key_type != pkey->type) 247 return 0; 248 249 if ((sigalg->flags & SIGALG_FLAG_RSA_PSS)) { 250 /* 251 * RSA PSS Must have an RSA key that needs to be at 252 * least as big as twice the size of the hash + 2 253 */ 254 if (pkey->type != EVP_PKEY_RSA || 255 EVP_PKEY_size(pkey) < (2 * EVP_MD_size(sigalg->md()) + 2)) 256 return 0; 257 } 258 259 if (pkey->type == EVP_PKEY_EC) { 260 if (sigalg->curve_nid == 0) 261 return 0; 262 /* Curve must match for EC keys */ 263 if (EC_GROUP_get_curve_name(EC_KEY_get0_group 264 (EVP_PKEY_get0_EC_KEY(pkey))) != sigalg->curve_nid) { 265 return 1; /* XXX www.videolan.org curve mismatch */ 266 } 267 } 268 269 return 1; 270 } 271