diff options
Diffstat (limited to 'sshkey.c')
-rw-r--r-- | sshkey.c | 104 |
1 files changed, 83 insertions, 21 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshkey.c,v 1.64 2018/03/22 07:05:48 markus Exp $ */ | 1 | /* $OpenBSD: sshkey.c,v 1.65 2018/07/03 11:39:54 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2008 Alexander von Gernler. All rights reserved. | 4 | * Copyright (c) 2008 Alexander von Gernler. All rights reserved. |
@@ -83,46 +83,64 @@ static int sshkey_from_blob_internal(struct sshbuf *buf, | |||
83 | struct keytype { | 83 | struct keytype { |
84 | const char *name; | 84 | const char *name; |
85 | const char *shortname; | 85 | const char *shortname; |
86 | const char *sigalg; | ||
86 | int type; | 87 | int type; |
87 | int nid; | 88 | int nid; |
88 | int cert; | 89 | int cert; |
89 | int sigonly; | 90 | int sigonly; |
90 | }; | 91 | }; |
91 | static const struct keytype keytypes[] = { | 92 | static const struct keytype keytypes[] = { |
92 | { "ssh-ed25519", "ED25519", KEY_ED25519, 0, 0, 0 }, | 93 | { "ssh-ed25519", "ED25519", NULL, KEY_ED25519, 0, 0, 0 }, |
93 | { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", | 94 | { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", NULL, |
94 | KEY_ED25519_CERT, 0, 1, 0 }, | 95 | KEY_ED25519_CERT, 0, 1, 0 }, |
95 | #ifdef WITH_XMSS | 96 | #ifdef WITH_XMSS |
96 | { "ssh-xmss@openssh.com", "XMSS", KEY_XMSS, 0, 0, 0 }, | 97 | { "ssh-xmss@openssh.com", "XMSS", NULL, KEY_XMSS, 0, 0, 0 }, |
97 | { "ssh-xmss-cert-v01@openssh.com", "XMSS-CERT", | 98 | { "ssh-xmss-cert-v01@openssh.com", "XMSS-CERT", NULL, |
98 | KEY_XMSS_CERT, 0, 1, 0 }, | 99 | KEY_XMSS_CERT, 0, 1, 0 }, |
99 | #endif /* WITH_XMSS */ | 100 | #endif /* WITH_XMSS */ |
100 | #ifdef WITH_OPENSSL | 101 | #ifdef WITH_OPENSSL |
101 | { "ssh-rsa", "RSA", KEY_RSA, 0, 0, 0 }, | 102 | { "ssh-rsa", "RSA", NULL, KEY_RSA, 0, 0, 0 }, |
102 | { "rsa-sha2-256", "RSA", KEY_RSA, 0, 0, 1 }, | 103 | { "rsa-sha2-256", "RSA", NULL, KEY_RSA, 0, 0, 1 }, |
103 | { "rsa-sha2-512", "RSA", KEY_RSA, 0, 0, 1 }, | 104 | { "rsa-sha2-512", "RSA", NULL, KEY_RSA, 0, 0, 1 }, |
104 | { "ssh-dss", "DSA", KEY_DSA, 0, 0, 0 }, | 105 | { "ssh-dss", "DSA", NULL, KEY_DSA, 0, 0, 0 }, |
105 | # ifdef OPENSSL_HAS_ECC | 106 | # ifdef OPENSSL_HAS_ECC |
106 | { "ecdsa-sha2-nistp256", "ECDSA", KEY_ECDSA, NID_X9_62_prime256v1, 0, 0 }, | 107 | { "ecdsa-sha2-nistp256", "ECDSA", NULL, |
107 | { "ecdsa-sha2-nistp384", "ECDSA", KEY_ECDSA, NID_secp384r1, 0, 0 }, | 108 | KEY_ECDSA, NID_X9_62_prime256v1, 0, 0 }, |
109 | { "ecdsa-sha2-nistp384", "ECDSA", NULL, | ||
110 | KEY_ECDSA, NID_secp384r1, 0, 0 }, | ||
108 | # ifdef OPENSSL_HAS_NISTP521 | 111 | # ifdef OPENSSL_HAS_NISTP521 |
109 | { "ecdsa-sha2-nistp521", "ECDSA", KEY_ECDSA, NID_secp521r1, 0, 0 }, | 112 | { "ecdsa-sha2-nistp521", "ECDSA", NULL, |
113 | KEY_ECDSA, NID_secp521r1, 0, 0 }, | ||
110 | # endif /* OPENSSL_HAS_NISTP521 */ | 114 | # endif /* OPENSSL_HAS_NISTP521 */ |
111 | # endif /* OPENSSL_HAS_ECC */ | 115 | # endif /* OPENSSL_HAS_ECC */ |
112 | { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", KEY_RSA_CERT, 0, 1, 0 }, | 116 | { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", NULL, |
113 | { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", KEY_DSA_CERT, 0, 1, 0 }, | 117 | KEY_RSA_CERT, 0, 1, 0 }, |
118 | { "rsa-sha2-256-cert-v01@openssh.com", "RSA-CERT", | ||
119 | "ssh-rsa-sha2-256", KEY_RSA_CERT, 0, 1, 1 }, | ||
120 | { "rsa-sha2-512-cert-v01@openssh.com", "RSA-CERT", | ||
121 | "ssh-rsa-sha2-512", KEY_RSA_CERT, 0, 1, 1 }, | ||
122 | { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", NULL, | ||
123 | KEY_DSA_CERT, 0, 1, 0 }, | ||
124 | { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", NULL, | ||
125 | KEY_RSA_CERT, 0, 1, 0 }, | ||
126 | { "rsa-sha2-256-cert-v01@openssh.com", "RSA-CERT", | ||
127 | "ssh-rsa-sha2-256", KEY_RSA_CERT, 0, 1, 1 }, | ||
128 | { "rsa-sha2-512-cert-v01@openssh.com", "RSA-CERT", | ||
129 | "ssh-rsa-sha2-512", KEY_RSA_CERT, 0, 1, 1 }, | ||
130 | { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", NULL, | ||
131 | KEY_DSA_CERT, 0, 1, 0 }, | ||
114 | # ifdef OPENSSL_HAS_ECC | 132 | # ifdef OPENSSL_HAS_ECC |
115 | { "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-CERT", | 133 | { "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-CERT", NULL, |
116 | KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1, 0 }, | 134 | KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1, 0 }, |
117 | { "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA-CERT", | 135 | { "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA-CERT", NULL, |
118 | KEY_ECDSA_CERT, NID_secp384r1, 1, 0 }, | 136 | KEY_ECDSA_CERT, NID_secp384r1, 1, 0 }, |
119 | # ifdef OPENSSL_HAS_NISTP521 | 137 | # ifdef OPENSSL_HAS_NISTP521 |
120 | { "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT", | 138 | { "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT", NULL, |
121 | KEY_ECDSA_CERT, NID_secp521r1, 1, 0 }, | 139 | KEY_ECDSA_CERT, NID_secp521r1, 1, 0 }, |
122 | # endif /* OPENSSL_HAS_NISTP521 */ | 140 | # endif /* OPENSSL_HAS_NISTP521 */ |
123 | # endif /* OPENSSL_HAS_ECC */ | 141 | # endif /* OPENSSL_HAS_ECC */ |
124 | #endif /* WITH_OPENSSL */ | 142 | #endif /* WITH_OPENSSL */ |
125 | { NULL, NULL, -1, -1, 0, 0 } | 143 | { NULL, NULL, NULL, -1, -1, 0, 0 } |
126 | }; | 144 | }; |
127 | 145 | ||
128 | const char * | 146 | const char * |
@@ -2198,8 +2216,8 @@ sshkey_froms(struct sshbuf *buf, struct sshkey **keyp) | |||
2198 | return r; | 2216 | return r; |
2199 | } | 2217 | } |
2200 | 2218 | ||
2201 | int | 2219 | static int |
2202 | sshkey_sigtype(const u_char *sig, size_t siglen, char **sigtypep) | 2220 | get_sigtype(const u_char *sig, size_t siglen, char **sigtypep) |
2203 | { | 2221 | { |
2204 | int r; | 2222 | int r; |
2205 | struct sshbuf *b = NULL; | 2223 | struct sshbuf *b = NULL; |
@@ -2223,6 +2241,50 @@ sshkey_sigtype(const u_char *sig, size_t siglen, char **sigtypep) | |||
2223 | return r; | 2241 | return r; |
2224 | } | 2242 | } |
2225 | 2243 | ||
2244 | /* | ||
2245 | * Returns the expected signature algorithm for a given public key algorithm. | ||
2246 | */ | ||
2247 | static const char * | ||
2248 | sigalg_by_name(const char *name) | ||
2249 | { | ||
2250 | const struct keytype *kt; | ||
2251 | |||
2252 | for (kt = keytypes; kt->type != -1; kt++) { | ||
2253 | if (strcmp(kt->name, name) != 0) | ||
2254 | continue; | ||
2255 | if (kt->sigalg != NULL) | ||
2256 | return kt->sigalg; | ||
2257 | if (!kt->cert) | ||
2258 | return kt->name; | ||
2259 | return sshkey_ssh_name_from_type_nid( | ||
2260 | sshkey_type_plain(kt->type), kt->nid); | ||
2261 | } | ||
2262 | return NULL; | ||
2263 | } | ||
2264 | |||
2265 | /* | ||
2266 | * Verifies that the signature algorithm appearing inside the signature blob | ||
2267 | * matches that which was requested. | ||
2268 | */ | ||
2269 | int | ||
2270 | sshkey_check_sigtype(const u_char *sig, size_t siglen, | ||
2271 | const char *requested_alg) | ||
2272 | { | ||
2273 | const char *expected_alg; | ||
2274 | char *sigtype = NULL; | ||
2275 | int r; | ||
2276 | |||
2277 | if (requested_alg == NULL) | ||
2278 | return 0; | ||
2279 | if ((expected_alg = sigalg_by_name(requested_alg)) == NULL) | ||
2280 | return SSH_ERR_INVALID_ARGUMENT; | ||
2281 | if ((r = get_sigtype(sig, siglen, &sigtype)) != 0) | ||
2282 | return r; | ||
2283 | r = strcmp(expected_alg, sigtype) == 0; | ||
2284 | free(sigtype); | ||
2285 | return r ? 0 : SSH_ERR_SIGN_ALG_UNSUPPORTED; | ||
2286 | } | ||
2287 | |||
2226 | int | 2288 | int |
2227 | sshkey_sign(const struct sshkey *key, | 2289 | sshkey_sign(const struct sshkey *key, |
2228 | u_char **sigp, size_t *lenp, | 2290 | u_char **sigp, size_t *lenp, |