1/* $OpenBSD: sshkey.c,v 1.21 2015/08/19 23:19:01 djm Exp $ */
| 1/* $OpenBSD: sshkey.c,v 1.31 2015/12/11 04:21:12 mmcc Exp $ */
|
2/* 3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2008 Alexander von Gernler. All rights reserved. 5 * Copyright (c) 2010,2011 Damien Miller. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28#include "includes.h" 29 30#include <sys/param.h> /* MIN MAX */ 31#include <sys/types.h> 32#include <netinet/in.h> 33 34#ifdef WITH_OPENSSL 35#include <openssl/evp.h> 36#include <openssl/err.h> 37#include <openssl/pem.h> 38#endif 39 40#include "crypto_api.h" 41 42#include <errno.h> 43#include <limits.h> 44#include <stdio.h> 45#include <string.h> 46#include <resolv.h> 47#ifdef HAVE_UTIL_H 48#include <util.h> 49#endif /* HAVE_UTIL_H */ 50 51#include "ssh2.h" 52#include "ssherr.h" 53#include "misc.h" 54#include "sshbuf.h" 55#include "rsa.h" 56#include "cipher.h" 57#include "digest.h" 58#define SSHKEY_INTERNAL 59#include "sshkey.h" 60#include "match.h" 61 62/* openssh private key file format */ 63#define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n" 64#define MARK_END "-----END OPENSSH PRIVATE KEY-----\n" 65#define MARK_BEGIN_LEN (sizeof(MARK_BEGIN) - 1) 66#define MARK_END_LEN (sizeof(MARK_END) - 1) 67#define KDFNAME "bcrypt" 68#define AUTH_MAGIC "openssh-key-v1" 69#define SALT_LEN 16 70#define DEFAULT_CIPHERNAME "aes256-cbc" 71#define DEFAULT_ROUNDS 16 72 73/* Version identification string for SSH v1 identity files. */ 74#define LEGACY_BEGIN "SSH PRIVATE KEY FILE FORMAT 1.1\n" 75 76static int sshkey_from_blob_internal(struct sshbuf *buf, 77 struct sshkey **keyp, int allow_cert); 78 79/* Supported key types */ 80struct keytype { 81 const char *name; 82 const char *shortname; 83 int type; 84 int nid; 85 int cert;
| 2/* 3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2008 Alexander von Gernler. All rights reserved. 5 * Copyright (c) 2010,2011 Damien Miller. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28#include "includes.h" 29 30#include <sys/param.h> /* MIN MAX */ 31#include <sys/types.h> 32#include <netinet/in.h> 33 34#ifdef WITH_OPENSSL 35#include <openssl/evp.h> 36#include <openssl/err.h> 37#include <openssl/pem.h> 38#endif 39 40#include "crypto_api.h" 41 42#include <errno.h> 43#include <limits.h> 44#include <stdio.h> 45#include <string.h> 46#include <resolv.h> 47#ifdef HAVE_UTIL_H 48#include <util.h> 49#endif /* HAVE_UTIL_H */ 50 51#include "ssh2.h" 52#include "ssherr.h" 53#include "misc.h" 54#include "sshbuf.h" 55#include "rsa.h" 56#include "cipher.h" 57#include "digest.h" 58#define SSHKEY_INTERNAL 59#include "sshkey.h" 60#include "match.h" 61 62/* openssh private key file format */ 63#define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n" 64#define MARK_END "-----END OPENSSH PRIVATE KEY-----\n" 65#define MARK_BEGIN_LEN (sizeof(MARK_BEGIN) - 1) 66#define MARK_END_LEN (sizeof(MARK_END) - 1) 67#define KDFNAME "bcrypt" 68#define AUTH_MAGIC "openssh-key-v1" 69#define SALT_LEN 16 70#define DEFAULT_CIPHERNAME "aes256-cbc" 71#define DEFAULT_ROUNDS 16 72 73/* Version identification string for SSH v1 identity files. */ 74#define LEGACY_BEGIN "SSH PRIVATE KEY FILE FORMAT 1.1\n" 75 76static int sshkey_from_blob_internal(struct sshbuf *buf, 77 struct sshkey **keyp, int allow_cert); 78 79/* Supported key types */ 80struct keytype { 81 const char *name; 82 const char *shortname; 83 int type; 84 int nid; 85 int cert;
|
| 86 int sigonly;
|
86}; 87static const struct keytype keytypes[] = {
| 87}; 88static const struct keytype keytypes[] = {
|
88 { "ssh-ed25519", "ED25519", KEY_ED25519, 0, 0 },
| 89 { "ssh-ed25519", "ED25519", KEY_ED25519, 0, 0, 0 },
|
89 { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT",
| 90 { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT",
|
90 KEY_ED25519_CERT, 0, 1 },
| 91 KEY_ED25519_CERT, 0, 1, 0 },
|
91#ifdef WITH_OPENSSL
| 92#ifdef WITH_OPENSSL
|
92 { NULL, "RSA1", KEY_RSA1, 0, 0 }, 93 { "ssh-rsa", "RSA", KEY_RSA, 0, 0 }, 94 { "ssh-dss", "DSA", KEY_DSA, 0, 0 },
| 93 { NULL, "RSA1", KEY_RSA1, 0, 0, 0 }, 94 { "ssh-rsa", "RSA", KEY_RSA, 0, 0, 0 }, 95 { "rsa-sha2-256", "RSA", KEY_RSA, 0, 0, 1 }, 96 { "rsa-sha2-512", "RSA", KEY_RSA, 0, 0, 1 }, 97 { "ssh-dss", "DSA", KEY_DSA, 0, 0, 0 },
|
95# ifdef OPENSSL_HAS_ECC
| 98# ifdef OPENSSL_HAS_ECC
|
96 { "ecdsa-sha2-nistp256", "ECDSA", KEY_ECDSA, NID_X9_62_prime256v1, 0 }, 97 { "ecdsa-sha2-nistp384", "ECDSA", KEY_ECDSA, NID_secp384r1, 0 },
| 99 { "ecdsa-sha2-nistp256", "ECDSA", KEY_ECDSA, NID_X9_62_prime256v1, 0, 0 }, 100 { "ecdsa-sha2-nistp384", "ECDSA", KEY_ECDSA, NID_secp384r1, 0, 0 },
|
98# ifdef OPENSSL_HAS_NISTP521
| 101# ifdef OPENSSL_HAS_NISTP521
|
99 { "ecdsa-sha2-nistp521", "ECDSA", KEY_ECDSA, NID_secp521r1, 0 },
| 102 { "ecdsa-sha2-nistp521", "ECDSA", KEY_ECDSA, NID_secp521r1, 0, 0 },
|
100# endif /* OPENSSL_HAS_NISTP521 */ 101# endif /* OPENSSL_HAS_ECC */
| 103# endif /* OPENSSL_HAS_NISTP521 */ 104# endif /* OPENSSL_HAS_ECC */
|
102 { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", KEY_RSA_CERT, 0, 1 }, 103 { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", KEY_DSA_CERT, 0, 1 },
| 105 { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", KEY_RSA_CERT, 0, 1, 0 }, 106 { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", KEY_DSA_CERT, 0, 1, 0 },
|
104# ifdef OPENSSL_HAS_ECC 105 { "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-CERT",
| 107# ifdef OPENSSL_HAS_ECC 108 { "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-CERT",
|
106 KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1 },
| 109 KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1, 0 },
|
107 { "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA-CERT",
| 110 { "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA-CERT",
|
108 KEY_ECDSA_CERT, NID_secp384r1, 1 },
| 111 KEY_ECDSA_CERT, NID_secp384r1, 1, 0 },
|
109# ifdef OPENSSL_HAS_NISTP521 110 { "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT",
| 112# ifdef OPENSSL_HAS_NISTP521 113 { "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT",
|
111 KEY_ECDSA_CERT, NID_secp521r1, 1 },
| 114 KEY_ECDSA_CERT, NID_secp521r1, 1, 0 },
|
112# endif /* OPENSSL_HAS_NISTP521 */ 113# endif /* OPENSSL_HAS_ECC */ 114#endif /* WITH_OPENSSL */
| 115# endif /* OPENSSL_HAS_NISTP521 */ 116# endif /* OPENSSL_HAS_ECC */ 117#endif /* WITH_OPENSSL */
|
115 { NULL, NULL, -1, -1, 0 }
| 118 { NULL, NULL, -1, -1, 0, 0 }
|
116}; 117 118const char * 119sshkey_type(const struct sshkey *k) 120{ 121 const struct keytype *kt; 122 123 for (kt = keytypes; kt->type != -1; kt++) { 124 if (kt->type == k->type) 125 return kt->shortname; 126 } 127 return "unknown"; 128} 129 130static const char * 131sshkey_ssh_name_from_type_nid(int type, int nid) 132{ 133 const struct keytype *kt; 134 135 for (kt = keytypes; kt->type != -1; kt++) { 136 if (kt->type == type && (kt->nid == 0 || kt->nid == nid)) 137 return kt->name; 138 } 139 return "ssh-unknown"; 140} 141 142int 143sshkey_type_is_cert(int type) 144{ 145 const struct keytype *kt; 146 147 for (kt = keytypes; kt->type != -1; kt++) { 148 if (kt->type == type) 149 return kt->cert; 150 } 151 return 0; 152} 153 154const char * 155sshkey_ssh_name(const struct sshkey *k) 156{ 157 return sshkey_ssh_name_from_type_nid(k->type, k->ecdsa_nid); 158} 159 160const char * 161sshkey_ssh_name_plain(const struct sshkey *k) 162{ 163 return sshkey_ssh_name_from_type_nid(sshkey_type_plain(k->type), 164 k->ecdsa_nid); 165} 166 167int 168sshkey_type_from_name(const char *name) 169{ 170 const struct keytype *kt; 171 172 for (kt = keytypes; kt->type != -1; kt++) { 173 /* Only allow shortname matches for plain key types */ 174 if ((kt->name != NULL && strcmp(name, kt->name) == 0) || 175 (!kt->cert && strcasecmp(kt->shortname, name) == 0)) 176 return kt->type; 177 } 178 return KEY_UNSPEC; 179} 180 181int 182sshkey_ecdsa_nid_from_name(const char *name) 183{ 184 const struct keytype *kt; 185 186 for (kt = keytypes; kt->type != -1; kt++) { 187 if (kt->type != KEY_ECDSA && kt->type != KEY_ECDSA_CERT) 188 continue; 189 if (kt->name != NULL && strcmp(name, kt->name) == 0) 190 return kt->nid; 191 } 192 return -1; 193} 194 195char * 196key_alg_list(int certs_only, int plain_only) 197{ 198 char *tmp, *ret = NULL; 199 size_t nlen, rlen = 0; 200 const struct keytype *kt; 201 202 for (kt = keytypes; kt->type != -1; kt++) {
| 119}; 120 121const char * 122sshkey_type(const struct sshkey *k) 123{ 124 const struct keytype *kt; 125 126 for (kt = keytypes; kt->type != -1; kt++) { 127 if (kt->type == k->type) 128 return kt->shortname; 129 } 130 return "unknown"; 131} 132 133static const char * 134sshkey_ssh_name_from_type_nid(int type, int nid) 135{ 136 const struct keytype *kt; 137 138 for (kt = keytypes; kt->type != -1; kt++) { 139 if (kt->type == type && (kt->nid == 0 || kt->nid == nid)) 140 return kt->name; 141 } 142 return "ssh-unknown"; 143} 144 145int 146sshkey_type_is_cert(int type) 147{ 148 const struct keytype *kt; 149 150 for (kt = keytypes; kt->type != -1; kt++) { 151 if (kt->type == type) 152 return kt->cert; 153 } 154 return 0; 155} 156 157const char * 158sshkey_ssh_name(const struct sshkey *k) 159{ 160 return sshkey_ssh_name_from_type_nid(k->type, k->ecdsa_nid); 161} 162 163const char * 164sshkey_ssh_name_plain(const struct sshkey *k) 165{ 166 return sshkey_ssh_name_from_type_nid(sshkey_type_plain(k->type), 167 k->ecdsa_nid); 168} 169 170int 171sshkey_type_from_name(const char *name) 172{ 173 const struct keytype *kt; 174 175 for (kt = keytypes; kt->type != -1; kt++) { 176 /* Only allow shortname matches for plain key types */ 177 if ((kt->name != NULL && strcmp(name, kt->name) == 0) || 178 (!kt->cert && strcasecmp(kt->shortname, name) == 0)) 179 return kt->type; 180 } 181 return KEY_UNSPEC; 182} 183 184int 185sshkey_ecdsa_nid_from_name(const char *name) 186{ 187 const struct keytype *kt; 188 189 for (kt = keytypes; kt->type != -1; kt++) { 190 if (kt->type != KEY_ECDSA && kt->type != KEY_ECDSA_CERT) 191 continue; 192 if (kt->name != NULL && strcmp(name, kt->name) == 0) 193 return kt->nid; 194 } 195 return -1; 196} 197 198char * 199key_alg_list(int certs_only, int plain_only) 200{ 201 char *tmp, *ret = NULL; 202 size_t nlen, rlen = 0; 203 const struct keytype *kt; 204 205 for (kt = keytypes; kt->type != -1; kt++) {
|
203 if (kt->name == NULL)
| 206 if (kt->name == NULL || kt->sigonly)
|
204 continue; 205 if ((certs_only && !kt->cert) || (plain_only && kt->cert)) 206 continue; 207 if (ret != NULL) 208 ret[rlen++] = '\n'; 209 nlen = strlen(kt->name); 210 if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { 211 free(ret); 212 return NULL; 213 } 214 ret = tmp; 215 memcpy(ret + rlen, kt->name, nlen + 1); 216 rlen += nlen; 217 } 218 return ret; 219} 220 221int 222sshkey_names_valid2(const char *names, int allow_wildcard) 223{ 224 char *s, *cp, *p; 225 const struct keytype *kt; 226 int type; 227 228 if (names == NULL || strcmp(names, "") == 0) 229 return 0; 230 if ((s = cp = strdup(names)) == NULL) 231 return 0; 232 for ((p = strsep(&cp, ",")); p && *p != '\0'; 233 (p = strsep(&cp, ","))) { 234 type = sshkey_type_from_name(p); 235 if (type == KEY_RSA1) { 236 free(s); 237 return 0; 238 } 239 if (type == KEY_UNSPEC) { 240 if (allow_wildcard) { 241 /* 242 * Try matching key types against the string. 243 * If any has a positive or negative match then 244 * the component is accepted. 245 */ 246 for (kt = keytypes; kt->type != -1; kt++) { 247 if (kt->type == KEY_RSA1) 248 continue; 249 if (match_pattern_list(kt->name, 250 p, 0) != 0) 251 break; 252 } 253 if (kt->type != -1) 254 continue; 255 } 256 free(s); 257 return 0; 258 } 259 } 260 free(s); 261 return 1; 262} 263 264u_int 265sshkey_size(const struct sshkey *k) 266{ 267 switch (k->type) { 268#ifdef WITH_OPENSSL 269 case KEY_RSA1: 270 case KEY_RSA: 271 case KEY_RSA_CERT: 272 return BN_num_bits(k->rsa->n); 273 case KEY_DSA: 274 case KEY_DSA_CERT: 275 return BN_num_bits(k->dsa->p); 276 case KEY_ECDSA: 277 case KEY_ECDSA_CERT: 278 return sshkey_curve_nid_to_bits(k->ecdsa_nid); 279#endif /* WITH_OPENSSL */ 280 case KEY_ED25519: 281 case KEY_ED25519_CERT: 282 return 256; /* XXX */ 283 } 284 return 0; 285} 286 287static int 288sshkey_type_is_valid_ca(int type) 289{ 290 switch (type) { 291 case KEY_RSA: 292 case KEY_DSA: 293 case KEY_ECDSA: 294 case KEY_ED25519: 295 return 1; 296 default: 297 return 0; 298 } 299} 300 301int 302sshkey_is_cert(const struct sshkey *k) 303{ 304 if (k == NULL) 305 return 0; 306 return sshkey_type_is_cert(k->type); 307} 308 309/* Return the cert-less equivalent to a certified key type */ 310int 311sshkey_type_plain(int type) 312{ 313 switch (type) { 314 case KEY_RSA_CERT: 315 return KEY_RSA; 316 case KEY_DSA_CERT: 317 return KEY_DSA; 318 case KEY_ECDSA_CERT: 319 return KEY_ECDSA; 320 case KEY_ED25519_CERT: 321 return KEY_ED25519; 322 default: 323 return type; 324 } 325} 326 327#ifdef WITH_OPENSSL 328/* XXX: these are really begging for a table-driven approach */ 329int 330sshkey_curve_name_to_nid(const char *name) 331{ 332 if (strcmp(name, "nistp256") == 0) 333 return NID_X9_62_prime256v1; 334 else if (strcmp(name, "nistp384") == 0) 335 return NID_secp384r1; 336# ifdef OPENSSL_HAS_NISTP521 337 else if (strcmp(name, "nistp521") == 0) 338 return NID_secp521r1; 339# endif /* OPENSSL_HAS_NISTP521 */ 340 else 341 return -1; 342} 343 344u_int 345sshkey_curve_nid_to_bits(int nid) 346{ 347 switch (nid) { 348 case NID_X9_62_prime256v1: 349 return 256; 350 case NID_secp384r1: 351 return 384; 352# ifdef OPENSSL_HAS_NISTP521 353 case NID_secp521r1: 354 return 521; 355# endif /* OPENSSL_HAS_NISTP521 */ 356 default: 357 return 0; 358 } 359} 360 361int 362sshkey_ecdsa_bits_to_nid(int bits) 363{ 364 switch (bits) { 365 case 256: 366 return NID_X9_62_prime256v1; 367 case 384: 368 return NID_secp384r1; 369# ifdef OPENSSL_HAS_NISTP521 370 case 521: 371 return NID_secp521r1; 372# endif /* OPENSSL_HAS_NISTP521 */ 373 default: 374 return -1; 375 } 376} 377 378const char * 379sshkey_curve_nid_to_name(int nid) 380{ 381 switch (nid) { 382 case NID_X9_62_prime256v1: 383 return "nistp256"; 384 case NID_secp384r1: 385 return "nistp384"; 386# ifdef OPENSSL_HAS_NISTP521 387 case NID_secp521r1: 388 return "nistp521"; 389# endif /* OPENSSL_HAS_NISTP521 */ 390 default: 391 return NULL; 392 } 393} 394 395int 396sshkey_ec_nid_to_hash_alg(int nid) 397{ 398 int kbits = sshkey_curve_nid_to_bits(nid); 399 400 if (kbits <= 0) 401 return -1; 402 403 /* RFC5656 section 6.2.1 */ 404 if (kbits <= 256) 405 return SSH_DIGEST_SHA256; 406 else if (kbits <= 384) 407 return SSH_DIGEST_SHA384; 408 else 409 return SSH_DIGEST_SHA512; 410} 411#endif /* WITH_OPENSSL */ 412 413static void 414cert_free(struct sshkey_cert *cert) 415{ 416 u_int i; 417 418 if (cert == NULL) 419 return;
| 207 continue; 208 if ((certs_only && !kt->cert) || (plain_only && kt->cert)) 209 continue; 210 if (ret != NULL) 211 ret[rlen++] = '\n'; 212 nlen = strlen(kt->name); 213 if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { 214 free(ret); 215 return NULL; 216 } 217 ret = tmp; 218 memcpy(ret + rlen, kt->name, nlen + 1); 219 rlen += nlen; 220 } 221 return ret; 222} 223 224int 225sshkey_names_valid2(const char *names, int allow_wildcard) 226{ 227 char *s, *cp, *p; 228 const struct keytype *kt; 229 int type; 230 231 if (names == NULL || strcmp(names, "") == 0) 232 return 0; 233 if ((s = cp = strdup(names)) == NULL) 234 return 0; 235 for ((p = strsep(&cp, ",")); p && *p != '\0'; 236 (p = strsep(&cp, ","))) { 237 type = sshkey_type_from_name(p); 238 if (type == KEY_RSA1) { 239 free(s); 240 return 0; 241 } 242 if (type == KEY_UNSPEC) { 243 if (allow_wildcard) { 244 /* 245 * Try matching key types against the string. 246 * If any has a positive or negative match then 247 * the component is accepted. 248 */ 249 for (kt = keytypes; kt->type != -1; kt++) { 250 if (kt->type == KEY_RSA1) 251 continue; 252 if (match_pattern_list(kt->name, 253 p, 0) != 0) 254 break; 255 } 256 if (kt->type != -1) 257 continue; 258 } 259 free(s); 260 return 0; 261 } 262 } 263 free(s); 264 return 1; 265} 266 267u_int 268sshkey_size(const struct sshkey *k) 269{ 270 switch (k->type) { 271#ifdef WITH_OPENSSL 272 case KEY_RSA1: 273 case KEY_RSA: 274 case KEY_RSA_CERT: 275 return BN_num_bits(k->rsa->n); 276 case KEY_DSA: 277 case KEY_DSA_CERT: 278 return BN_num_bits(k->dsa->p); 279 case KEY_ECDSA: 280 case KEY_ECDSA_CERT: 281 return sshkey_curve_nid_to_bits(k->ecdsa_nid); 282#endif /* WITH_OPENSSL */ 283 case KEY_ED25519: 284 case KEY_ED25519_CERT: 285 return 256; /* XXX */ 286 } 287 return 0; 288} 289 290static int 291sshkey_type_is_valid_ca(int type) 292{ 293 switch (type) { 294 case KEY_RSA: 295 case KEY_DSA: 296 case KEY_ECDSA: 297 case KEY_ED25519: 298 return 1; 299 default: 300 return 0; 301 } 302} 303 304int 305sshkey_is_cert(const struct sshkey *k) 306{ 307 if (k == NULL) 308 return 0; 309 return sshkey_type_is_cert(k->type); 310} 311 312/* Return the cert-less equivalent to a certified key type */ 313int 314sshkey_type_plain(int type) 315{ 316 switch (type) { 317 case KEY_RSA_CERT: 318 return KEY_RSA; 319 case KEY_DSA_CERT: 320 return KEY_DSA; 321 case KEY_ECDSA_CERT: 322 return KEY_ECDSA; 323 case KEY_ED25519_CERT: 324 return KEY_ED25519; 325 default: 326 return type; 327 } 328} 329 330#ifdef WITH_OPENSSL 331/* XXX: these are really begging for a table-driven approach */ 332int 333sshkey_curve_name_to_nid(const char *name) 334{ 335 if (strcmp(name, "nistp256") == 0) 336 return NID_X9_62_prime256v1; 337 else if (strcmp(name, "nistp384") == 0) 338 return NID_secp384r1; 339# ifdef OPENSSL_HAS_NISTP521 340 else if (strcmp(name, "nistp521") == 0) 341 return NID_secp521r1; 342# endif /* OPENSSL_HAS_NISTP521 */ 343 else 344 return -1; 345} 346 347u_int 348sshkey_curve_nid_to_bits(int nid) 349{ 350 switch (nid) { 351 case NID_X9_62_prime256v1: 352 return 256; 353 case NID_secp384r1: 354 return 384; 355# ifdef OPENSSL_HAS_NISTP521 356 case NID_secp521r1: 357 return 521; 358# endif /* OPENSSL_HAS_NISTP521 */ 359 default: 360 return 0; 361 } 362} 363 364int 365sshkey_ecdsa_bits_to_nid(int bits) 366{ 367 switch (bits) { 368 case 256: 369 return NID_X9_62_prime256v1; 370 case 384: 371 return NID_secp384r1; 372# ifdef OPENSSL_HAS_NISTP521 373 case 521: 374 return NID_secp521r1; 375# endif /* OPENSSL_HAS_NISTP521 */ 376 default: 377 return -1; 378 } 379} 380 381const char * 382sshkey_curve_nid_to_name(int nid) 383{ 384 switch (nid) { 385 case NID_X9_62_prime256v1: 386 return "nistp256"; 387 case NID_secp384r1: 388 return "nistp384"; 389# ifdef OPENSSL_HAS_NISTP521 390 case NID_secp521r1: 391 return "nistp521"; 392# endif /* OPENSSL_HAS_NISTP521 */ 393 default: 394 return NULL; 395 } 396} 397 398int 399sshkey_ec_nid_to_hash_alg(int nid) 400{ 401 int kbits = sshkey_curve_nid_to_bits(nid); 402 403 if (kbits <= 0) 404 return -1; 405 406 /* RFC5656 section 6.2.1 */ 407 if (kbits <= 256) 408 return SSH_DIGEST_SHA256; 409 else if (kbits <= 384) 410 return SSH_DIGEST_SHA384; 411 else 412 return SSH_DIGEST_SHA512; 413} 414#endif /* WITH_OPENSSL */ 415 416static void 417cert_free(struct sshkey_cert *cert) 418{ 419 u_int i; 420 421 if (cert == NULL) 422 return;
|
420 if (cert->certblob != NULL) 421 sshbuf_free(cert->certblob); 422 if (cert->critical != NULL) 423 sshbuf_free(cert->critical); 424 if (cert->extensions != NULL) 425 sshbuf_free(cert->extensions); 426 if (cert->key_id != NULL) 427 free(cert->key_id);
| 423 sshbuf_free(cert->certblob); 424 sshbuf_free(cert->critical); 425 sshbuf_free(cert->extensions); 426 free(cert->key_id);
|
428 for (i = 0; i < cert->nprincipals; i++) 429 free(cert->principals[i]);
| 427 for (i = 0; i < cert->nprincipals; i++) 428 free(cert->principals[i]);
|
430 if (cert->principals != NULL) 431 free(cert->principals); 432 if (cert->signature_key != NULL) 433 sshkey_free(cert->signature_key);
| 429 free(cert->principals); 430 sshkey_free(cert->signature_key);
|
434 explicit_bzero(cert, sizeof(*cert)); 435 free(cert); 436} 437 438static struct sshkey_cert * 439cert_new(void) 440{ 441 struct sshkey_cert *cert; 442 443 if ((cert = calloc(1, sizeof(*cert))) == NULL) 444 return NULL; 445 if ((cert->certblob = sshbuf_new()) == NULL || 446 (cert->critical = sshbuf_new()) == NULL || 447 (cert->extensions = sshbuf_new()) == NULL) { 448 cert_free(cert); 449 return NULL; 450 } 451 cert->key_id = NULL; 452 cert->principals = NULL; 453 cert->signature_key = NULL; 454 return cert; 455} 456 457struct sshkey * 458sshkey_new(int type) 459{ 460 struct sshkey *k; 461#ifdef WITH_OPENSSL 462 RSA *rsa; 463 DSA *dsa; 464#endif /* WITH_OPENSSL */ 465 466 if ((k = calloc(1, sizeof(*k))) == NULL) 467 return NULL; 468 k->type = type; 469 k->ecdsa = NULL; 470 k->ecdsa_nid = -1; 471 k->dsa = NULL; 472 k->rsa = NULL; 473 k->cert = NULL; 474 k->ed25519_sk = NULL; 475 k->ed25519_pk = NULL; 476 switch (k->type) { 477#ifdef WITH_OPENSSL 478 case KEY_RSA1: 479 case KEY_RSA: 480 case KEY_RSA_CERT: 481 if ((rsa = RSA_new()) == NULL || 482 (rsa->n = BN_new()) == NULL || 483 (rsa->e = BN_new()) == NULL) { 484 if (rsa != NULL) 485 RSA_free(rsa); 486 free(k); 487 return NULL; 488 } 489 k->rsa = rsa; 490 break; 491 case KEY_DSA: 492 case KEY_DSA_CERT: 493 if ((dsa = DSA_new()) == NULL || 494 (dsa->p = BN_new()) == NULL || 495 (dsa->q = BN_new()) == NULL || 496 (dsa->g = BN_new()) == NULL || 497 (dsa->pub_key = BN_new()) == NULL) { 498 if (dsa != NULL) 499 DSA_free(dsa); 500 free(k); 501 return NULL; 502 } 503 k->dsa = dsa; 504 break; 505 case KEY_ECDSA: 506 case KEY_ECDSA_CERT: 507 /* Cannot do anything until we know the group */ 508 break; 509#endif /* WITH_OPENSSL */ 510 case KEY_ED25519: 511 case KEY_ED25519_CERT: 512 /* no need to prealloc */ 513 break; 514 case KEY_UNSPEC: 515 break; 516 default: 517 free(k); 518 return NULL; 519 break; 520 } 521 522 if (sshkey_is_cert(k)) { 523 if ((k->cert = cert_new()) == NULL) { 524 sshkey_free(k); 525 return NULL; 526 } 527 } 528 529 return k; 530} 531 532int 533sshkey_add_private(struct sshkey *k) 534{ 535 switch (k->type) { 536#ifdef WITH_OPENSSL 537 case KEY_RSA1: 538 case KEY_RSA: 539 case KEY_RSA_CERT: 540#define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL) 541 if (bn_maybe_alloc_failed(k->rsa->d) || 542 bn_maybe_alloc_failed(k->rsa->iqmp) || 543 bn_maybe_alloc_failed(k->rsa->q) || 544 bn_maybe_alloc_failed(k->rsa->p) || 545 bn_maybe_alloc_failed(k->rsa->dmq1) || 546 bn_maybe_alloc_failed(k->rsa->dmp1)) 547 return SSH_ERR_ALLOC_FAIL; 548 break; 549 case KEY_DSA: 550 case KEY_DSA_CERT: 551 if (bn_maybe_alloc_failed(k->dsa->priv_key)) 552 return SSH_ERR_ALLOC_FAIL; 553 break; 554#undef bn_maybe_alloc_failed 555 case KEY_ECDSA: 556 case KEY_ECDSA_CERT: 557 /* Cannot do anything until we know the group */ 558 break; 559#endif /* WITH_OPENSSL */ 560 case KEY_ED25519: 561 case KEY_ED25519_CERT: 562 /* no need to prealloc */ 563 break; 564 case KEY_UNSPEC: 565 break; 566 default: 567 return SSH_ERR_INVALID_ARGUMENT; 568 } 569 return 0; 570} 571 572struct sshkey * 573sshkey_new_private(int type) 574{ 575 struct sshkey *k = sshkey_new(type); 576 577 if (k == NULL) 578 return NULL; 579 if (sshkey_add_private(k) != 0) { 580 sshkey_free(k); 581 return NULL; 582 } 583 return k; 584} 585 586void 587sshkey_free(struct sshkey *k) 588{ 589 if (k == NULL) 590 return; 591 switch (k->type) { 592#ifdef WITH_OPENSSL 593 case KEY_RSA1: 594 case KEY_RSA: 595 case KEY_RSA_CERT: 596 if (k->rsa != NULL) 597 RSA_free(k->rsa); 598 k->rsa = NULL; 599 break; 600 case KEY_DSA: 601 case KEY_DSA_CERT: 602 if (k->dsa != NULL) 603 DSA_free(k->dsa); 604 k->dsa = NULL; 605 break; 606# ifdef OPENSSL_HAS_ECC 607 case KEY_ECDSA: 608 case KEY_ECDSA_CERT: 609 if (k->ecdsa != NULL) 610 EC_KEY_free(k->ecdsa); 611 k->ecdsa = NULL; 612 break; 613# endif /* OPENSSL_HAS_ECC */ 614#endif /* WITH_OPENSSL */ 615 case KEY_ED25519: 616 case KEY_ED25519_CERT: 617 if (k->ed25519_pk) { 618 explicit_bzero(k->ed25519_pk, ED25519_PK_SZ); 619 free(k->ed25519_pk); 620 k->ed25519_pk = NULL; 621 } 622 if (k->ed25519_sk) { 623 explicit_bzero(k->ed25519_sk, ED25519_SK_SZ); 624 free(k->ed25519_sk); 625 k->ed25519_sk = NULL; 626 } 627 break; 628 case KEY_UNSPEC: 629 break; 630 default: 631 break; 632 } 633 if (sshkey_is_cert(k)) 634 cert_free(k->cert); 635 explicit_bzero(k, sizeof(*k)); 636 free(k); 637} 638 639static int 640cert_compare(struct sshkey_cert *a, struct sshkey_cert *b) 641{ 642 if (a == NULL && b == NULL) 643 return 1; 644 if (a == NULL || b == NULL) 645 return 0; 646 if (sshbuf_len(a->certblob) != sshbuf_len(b->certblob)) 647 return 0; 648 if (timingsafe_bcmp(sshbuf_ptr(a->certblob), sshbuf_ptr(b->certblob), 649 sshbuf_len(a->certblob)) != 0) 650 return 0; 651 return 1; 652} 653 654/* 655 * Compare public portions of key only, allowing comparisons between 656 * certificates and plain keys too. 657 */ 658int 659sshkey_equal_public(const struct sshkey *a, const struct sshkey *b) 660{ 661#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) 662 BN_CTX *bnctx; 663#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ 664 665 if (a == NULL || b == NULL || 666 sshkey_type_plain(a->type) != sshkey_type_plain(b->type)) 667 return 0; 668 669 switch (a->type) { 670#ifdef WITH_OPENSSL 671 case KEY_RSA1: 672 case KEY_RSA_CERT: 673 case KEY_RSA: 674 return a->rsa != NULL && b->rsa != NULL && 675 BN_cmp(a->rsa->e, b->rsa->e) == 0 && 676 BN_cmp(a->rsa->n, b->rsa->n) == 0; 677 case KEY_DSA_CERT: 678 case KEY_DSA: 679 return a->dsa != NULL && b->dsa != NULL && 680 BN_cmp(a->dsa->p, b->dsa->p) == 0 && 681 BN_cmp(a->dsa->q, b->dsa->q) == 0 && 682 BN_cmp(a->dsa->g, b->dsa->g) == 0 && 683 BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; 684# ifdef OPENSSL_HAS_ECC 685 case KEY_ECDSA_CERT: 686 case KEY_ECDSA: 687 if (a->ecdsa == NULL || b->ecdsa == NULL || 688 EC_KEY_get0_public_key(a->ecdsa) == NULL || 689 EC_KEY_get0_public_key(b->ecdsa) == NULL) 690 return 0; 691 if ((bnctx = BN_CTX_new()) == NULL) 692 return 0; 693 if (EC_GROUP_cmp(EC_KEY_get0_group(a->ecdsa), 694 EC_KEY_get0_group(b->ecdsa), bnctx) != 0 || 695 EC_POINT_cmp(EC_KEY_get0_group(a->ecdsa), 696 EC_KEY_get0_public_key(a->ecdsa), 697 EC_KEY_get0_public_key(b->ecdsa), bnctx) != 0) { 698 BN_CTX_free(bnctx); 699 return 0; 700 } 701 BN_CTX_free(bnctx); 702 return 1; 703# endif /* OPENSSL_HAS_ECC */ 704#endif /* WITH_OPENSSL */ 705 case KEY_ED25519: 706 case KEY_ED25519_CERT: 707 return a->ed25519_pk != NULL && b->ed25519_pk != NULL && 708 memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) == 0; 709 default: 710 return 0; 711 } 712 /* NOTREACHED */ 713} 714 715int 716sshkey_equal(const struct sshkey *a, const struct sshkey *b) 717{ 718 if (a == NULL || b == NULL || a->type != b->type) 719 return 0; 720 if (sshkey_is_cert(a)) { 721 if (!cert_compare(a->cert, b->cert)) 722 return 0; 723 } 724 return sshkey_equal_public(a, b); 725} 726 727static int 728to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain) 729{ 730 int type, ret = SSH_ERR_INTERNAL_ERROR; 731 const char *typename; 732 733 if (key == NULL) 734 return SSH_ERR_INVALID_ARGUMENT; 735 736 if (sshkey_is_cert(key)) { 737 if (key->cert == NULL) 738 return SSH_ERR_EXPECTED_CERT; 739 if (sshbuf_len(key->cert->certblob) == 0) 740 return SSH_ERR_KEY_LACKS_CERTBLOB; 741 } 742 type = force_plain ? sshkey_type_plain(key->type) : key->type; 743 typename = sshkey_ssh_name_from_type_nid(type, key->ecdsa_nid); 744 745 switch (type) { 746#ifdef WITH_OPENSSL 747 case KEY_DSA_CERT: 748 case KEY_ECDSA_CERT: 749 case KEY_RSA_CERT: 750#endif /* WITH_OPENSSL */ 751 case KEY_ED25519_CERT: 752 /* Use the existing blob */ 753 /* XXX modified flag? */ 754 if ((ret = sshbuf_putb(b, key->cert->certblob)) != 0) 755 return ret; 756 break; 757#ifdef WITH_OPENSSL 758 case KEY_DSA: 759 if (key->dsa == NULL) 760 return SSH_ERR_INVALID_ARGUMENT; 761 if ((ret = sshbuf_put_cstring(b, typename)) != 0 || 762 (ret = sshbuf_put_bignum2(b, key->dsa->p)) != 0 || 763 (ret = sshbuf_put_bignum2(b, key->dsa->q)) != 0 || 764 (ret = sshbuf_put_bignum2(b, key->dsa->g)) != 0 || 765 (ret = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0) 766 return ret; 767 break; 768# ifdef OPENSSL_HAS_ECC 769 case KEY_ECDSA: 770 if (key->ecdsa == NULL) 771 return SSH_ERR_INVALID_ARGUMENT; 772 if ((ret = sshbuf_put_cstring(b, typename)) != 0 || 773 (ret = sshbuf_put_cstring(b, 774 sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 || 775 (ret = sshbuf_put_eckey(b, key->ecdsa)) != 0) 776 return ret; 777 break; 778# endif 779 case KEY_RSA: 780 if (key->rsa == NULL) 781 return SSH_ERR_INVALID_ARGUMENT; 782 if ((ret = sshbuf_put_cstring(b, typename)) != 0 || 783 (ret = sshbuf_put_bignum2(b, key->rsa->e)) != 0 || 784 (ret = sshbuf_put_bignum2(b, key->rsa->n)) != 0) 785 return ret; 786 break; 787#endif /* WITH_OPENSSL */ 788 case KEY_ED25519: 789 if (key->ed25519_pk == NULL) 790 return SSH_ERR_INVALID_ARGUMENT; 791 if ((ret = sshbuf_put_cstring(b, typename)) != 0 || 792 (ret = sshbuf_put_string(b, 793 key->ed25519_pk, ED25519_PK_SZ)) != 0) 794 return ret; 795 break; 796 default: 797 return SSH_ERR_KEY_TYPE_UNKNOWN; 798 } 799 return 0; 800} 801 802int 803sshkey_putb(const struct sshkey *key, struct sshbuf *b) 804{ 805 return to_blob_buf(key, b, 0); 806} 807 808int 809sshkey_puts(const struct sshkey *key, struct sshbuf *b) 810{ 811 struct sshbuf *tmp; 812 int r; 813 814 if ((tmp = sshbuf_new()) == NULL) 815 return SSH_ERR_ALLOC_FAIL; 816 r = to_blob_buf(key, tmp, 0); 817 if (r == 0) 818 r = sshbuf_put_stringb(b, tmp); 819 sshbuf_free(tmp); 820 return r; 821} 822 823int 824sshkey_putb_plain(const struct sshkey *key, struct sshbuf *b) 825{ 826 return to_blob_buf(key, b, 1); 827} 828 829static int 830to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp, int force_plain) 831{ 832 int ret = SSH_ERR_INTERNAL_ERROR; 833 size_t len; 834 struct sshbuf *b = NULL; 835 836 if (lenp != NULL) 837 *lenp = 0; 838 if (blobp != NULL) 839 *blobp = NULL; 840 if ((b = sshbuf_new()) == NULL) 841 return SSH_ERR_ALLOC_FAIL; 842 if ((ret = to_blob_buf(key, b, force_plain)) != 0) 843 goto out; 844 len = sshbuf_len(b); 845 if (lenp != NULL) 846 *lenp = len; 847 if (blobp != NULL) { 848 if ((*blobp = malloc(len)) == NULL) { 849 ret = SSH_ERR_ALLOC_FAIL; 850 goto out; 851 } 852 memcpy(*blobp, sshbuf_ptr(b), len); 853 } 854 ret = 0; 855 out: 856 sshbuf_free(b); 857 return ret; 858} 859 860int 861sshkey_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp) 862{ 863 return to_blob(key, blobp, lenp, 0); 864} 865 866int 867sshkey_plain_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp) 868{ 869 return to_blob(key, blobp, lenp, 1); 870} 871 872int 873sshkey_fingerprint_raw(const struct sshkey *k, int dgst_alg, 874 u_char **retp, size_t *lenp) 875{ 876 u_char *blob = NULL, *ret = NULL; 877 size_t blob_len = 0; 878 int r = SSH_ERR_INTERNAL_ERROR; 879 880 if (retp != NULL) 881 *retp = NULL; 882 if (lenp != NULL) 883 *lenp = 0; 884 if (ssh_digest_bytes(dgst_alg) == 0) { 885 r = SSH_ERR_INVALID_ARGUMENT; 886 goto out; 887 } 888 889 if (k->type == KEY_RSA1) { 890#ifdef WITH_OPENSSL 891 int nlen = BN_num_bytes(k->rsa->n); 892 int elen = BN_num_bytes(k->rsa->e); 893 894 blob_len = nlen + elen; 895 if (nlen >= INT_MAX - elen || 896 (blob = malloc(blob_len)) == NULL) { 897 r = SSH_ERR_ALLOC_FAIL; 898 goto out; 899 } 900 BN_bn2bin(k->rsa->n, blob); 901 BN_bn2bin(k->rsa->e, blob + nlen); 902#endif /* WITH_OPENSSL */ 903 } else if ((r = to_blob(k, &blob, &blob_len, 1)) != 0) 904 goto out; 905 if ((ret = calloc(1, SSH_DIGEST_MAX_LENGTH)) == NULL) { 906 r = SSH_ERR_ALLOC_FAIL; 907 goto out; 908 } 909 if ((r = ssh_digest_memory(dgst_alg, blob, blob_len, 910 ret, SSH_DIGEST_MAX_LENGTH)) != 0) 911 goto out; 912 /* success */ 913 if (retp != NULL) { 914 *retp = ret; 915 ret = NULL; 916 } 917 if (lenp != NULL) 918 *lenp = ssh_digest_bytes(dgst_alg); 919 r = 0; 920 out: 921 free(ret); 922 if (blob != NULL) { 923 explicit_bzero(blob, blob_len); 924 free(blob); 925 } 926 return r; 927} 928 929static char * 930fingerprint_b64(const char *alg, u_char *dgst_raw, size_t dgst_raw_len) 931{ 932 char *ret; 933 size_t plen = strlen(alg) + 1; 934 size_t rlen = ((dgst_raw_len + 2) / 3) * 4 + plen + 1; 935 int r; 936 937 if (dgst_raw_len > 65536 || (ret = calloc(1, rlen)) == NULL) 938 return NULL; 939 strlcpy(ret, alg, rlen); 940 strlcat(ret, ":", rlen); 941 if (dgst_raw_len == 0) 942 return ret; 943 if ((r = b64_ntop(dgst_raw, dgst_raw_len, 944 ret + plen, rlen - plen)) == -1) { 945 explicit_bzero(ret, rlen); 946 free(ret); 947 return NULL; 948 } 949 /* Trim padding characters from end */ 950 ret[strcspn(ret, "=")] = '\0'; 951 return ret; 952} 953 954static char * 955fingerprint_hex(const char *alg, u_char *dgst_raw, size_t dgst_raw_len) 956{ 957 char *retval, hex[5]; 958 size_t i, rlen = dgst_raw_len * 3 + strlen(alg) + 2; 959 960 if (dgst_raw_len > 65536 || (retval = calloc(1, rlen)) == NULL) 961 return NULL; 962 strlcpy(retval, alg, rlen); 963 strlcat(retval, ":", rlen); 964 for (i = 0; i < dgst_raw_len; i++) { 965 snprintf(hex, sizeof(hex), "%s%02x", 966 i > 0 ? ":" : "", dgst_raw[i]); 967 strlcat(retval, hex, rlen); 968 } 969 return retval; 970} 971 972static char * 973fingerprint_bubblebabble(u_char *dgst_raw, size_t dgst_raw_len) 974{ 975 char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' }; 976 char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm', 977 'n', 'p', 'r', 's', 't', 'v', 'z', 'x' }; 978 u_int i, j = 0, rounds, seed = 1; 979 char *retval; 980 981 rounds = (dgst_raw_len / 2) + 1; 982 if ((retval = calloc(rounds, 6)) == NULL) 983 return NULL; 984 retval[j++] = 'x'; 985 for (i = 0; i < rounds; i++) { 986 u_int idx0, idx1, idx2, idx3, idx4; 987 if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) { 988 idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) + 989 seed) % 6; 990 idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15; 991 idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) + 992 (seed / 6)) % 6; 993 retval[j++] = vowels[idx0]; 994 retval[j++] = consonants[idx1]; 995 retval[j++] = vowels[idx2]; 996 if ((i + 1) < rounds) { 997 idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15; 998 idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15; 999 retval[j++] = consonants[idx3]; 1000 retval[j++] = '-'; 1001 retval[j++] = consonants[idx4]; 1002 seed = ((seed * 5) + 1003 ((((u_int)(dgst_raw[2 * i])) * 7) + 1004 ((u_int)(dgst_raw[(2 * i) + 1])))) % 36; 1005 } 1006 } else { 1007 idx0 = seed % 6; 1008 idx1 = 16; 1009 idx2 = seed / 6; 1010 retval[j++] = vowels[idx0]; 1011 retval[j++] = consonants[idx1]; 1012 retval[j++] = vowels[idx2]; 1013 } 1014 } 1015 retval[j++] = 'x'; 1016 retval[j++] = '\0'; 1017 return retval; 1018} 1019 1020/* 1021 * Draw an ASCII-Art representing the fingerprint so human brain can 1022 * profit from its built-in pattern recognition ability. 1023 * This technique is called "random art" and can be found in some 1024 * scientific publications like this original paper: 1025 * 1026 * "Hash Visualization: a New Technique to improve Real-World Security", 1027 * Perrig A. and Song D., 1999, International Workshop on Cryptographic 1028 * Techniques and E-Commerce (CrypTEC '99) 1029 * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf 1030 * 1031 * The subject came up in a talk by Dan Kaminsky, too. 1032 * 1033 * If you see the picture is different, the key is different. 1034 * If the picture looks the same, you still know nothing. 1035 * 1036 * The algorithm used here is a worm crawling over a discrete plane, 1037 * leaving a trace (augmenting the field) everywhere it goes. 1038 * Movement is taken from dgst_raw 2bit-wise. Bumping into walls 1039 * makes the respective movement vector be ignored for this turn. 1040 * Graphs are not unambiguous, because circles in graphs can be 1041 * walked in either direction. 1042 */ 1043 1044/* 1045 * Field sizes for the random art. Have to be odd, so the starting point 1046 * can be in the exact middle of the picture, and FLDBASE should be >=8 . 1047 * Else pictures would be too dense, and drawing the frame would 1048 * fail, too, because the key type would not fit in anymore. 1049 */ 1050#define FLDBASE 8 1051#define FLDSIZE_Y (FLDBASE + 1) 1052#define FLDSIZE_X (FLDBASE * 2 + 1) 1053static char * 1054fingerprint_randomart(const char *alg, u_char *dgst_raw, size_t dgst_raw_len, 1055 const struct sshkey *k) 1056{ 1057 /* 1058 * Chars to be used after each other every time the worm 1059 * intersects with itself. Matter of taste. 1060 */ 1061 char *augmentation_string = " .o+=*BOX@%&#/^SE"; 1062 char *retval, *p, title[FLDSIZE_X], hash[FLDSIZE_X]; 1063 u_char field[FLDSIZE_X][FLDSIZE_Y]; 1064 size_t i, tlen, hlen; 1065 u_int b; 1066 int x, y, r; 1067 size_t len = strlen(augmentation_string) - 1; 1068 1069 if ((retval = calloc((FLDSIZE_X + 3), (FLDSIZE_Y + 2))) == NULL) 1070 return NULL; 1071 1072 /* initialize field */ 1073 memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char)); 1074 x = FLDSIZE_X / 2; 1075 y = FLDSIZE_Y / 2; 1076 1077 /* process raw key */ 1078 for (i = 0; i < dgst_raw_len; i++) { 1079 int input; 1080 /* each byte conveys four 2-bit move commands */ 1081 input = dgst_raw[i]; 1082 for (b = 0; b < 4; b++) { 1083 /* evaluate 2 bit, rest is shifted later */ 1084 x += (input & 0x1) ? 1 : -1; 1085 y += (input & 0x2) ? 1 : -1; 1086 1087 /* assure we are still in bounds */ 1088 x = MAX(x, 0); 1089 y = MAX(y, 0); 1090 x = MIN(x, FLDSIZE_X - 1); 1091 y = MIN(y, FLDSIZE_Y - 1); 1092 1093 /* augment the field */ 1094 if (field[x][y] < len - 2) 1095 field[x][y]++; 1096 input = input >> 2; 1097 } 1098 } 1099 1100 /* mark starting point and end point*/ 1101 field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1; 1102 field[x][y] = len; 1103 1104 /* assemble title */ 1105 r = snprintf(title, sizeof(title), "[%s %u]", 1106 sshkey_type(k), sshkey_size(k)); 1107 /* If [type size] won't fit, then try [type]; fits "[ED25519-CERT]" */ 1108 if (r < 0 || r > (int)sizeof(title)) 1109 r = snprintf(title, sizeof(title), "[%s]", sshkey_type(k)); 1110 tlen = (r <= 0) ? 0 : strlen(title); 1111 1112 /* assemble hash ID. */ 1113 r = snprintf(hash, sizeof(hash), "[%s]", alg); 1114 hlen = (r <= 0) ? 0 : strlen(hash); 1115 1116 /* output upper border */ 1117 p = retval; 1118 *p++ = '+'; 1119 for (i = 0; i < (FLDSIZE_X - tlen) / 2; i++) 1120 *p++ = '-'; 1121 memcpy(p, title, tlen); 1122 p += tlen; 1123 for (i += tlen; i < FLDSIZE_X; i++) 1124 *p++ = '-'; 1125 *p++ = '+'; 1126 *p++ = '\n'; 1127 1128 /* output content */ 1129 for (y = 0; y < FLDSIZE_Y; y++) { 1130 *p++ = '|'; 1131 for (x = 0; x < FLDSIZE_X; x++) 1132 *p++ = augmentation_string[MIN(field[x][y], len)]; 1133 *p++ = '|'; 1134 *p++ = '\n'; 1135 } 1136 1137 /* output lower border */ 1138 *p++ = '+'; 1139 for (i = 0; i < (FLDSIZE_X - hlen) / 2; i++) 1140 *p++ = '-'; 1141 memcpy(p, hash, hlen); 1142 p += hlen; 1143 for (i += hlen; i < FLDSIZE_X; i++) 1144 *p++ = '-'; 1145 *p++ = '+'; 1146 1147 return retval; 1148} 1149 1150char * 1151sshkey_fingerprint(const struct sshkey *k, int dgst_alg, 1152 enum sshkey_fp_rep dgst_rep) 1153{ 1154 char *retval = NULL; 1155 u_char *dgst_raw; 1156 size_t dgst_raw_len; 1157 1158 if (sshkey_fingerprint_raw(k, dgst_alg, &dgst_raw, &dgst_raw_len) != 0) 1159 return NULL; 1160 switch (dgst_rep) { 1161 case SSH_FP_DEFAULT: 1162 if (dgst_alg == SSH_DIGEST_MD5) { 1163 retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg), 1164 dgst_raw, dgst_raw_len); 1165 } else { 1166 retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg), 1167 dgst_raw, dgst_raw_len); 1168 } 1169 break; 1170 case SSH_FP_HEX: 1171 retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg), 1172 dgst_raw, dgst_raw_len); 1173 break; 1174 case SSH_FP_BASE64: 1175 retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg), 1176 dgst_raw, dgst_raw_len); 1177 break; 1178 case SSH_FP_BUBBLEBABBLE: 1179 retval = fingerprint_bubblebabble(dgst_raw, dgst_raw_len); 1180 break; 1181 case SSH_FP_RANDOMART: 1182 retval = fingerprint_randomart(ssh_digest_alg_name(dgst_alg), 1183 dgst_raw, dgst_raw_len, k); 1184 break; 1185 default: 1186 explicit_bzero(dgst_raw, dgst_raw_len); 1187 free(dgst_raw); 1188 return NULL; 1189 } 1190 explicit_bzero(dgst_raw, dgst_raw_len); 1191 free(dgst_raw); 1192 return retval; 1193} 1194 1195#ifdef WITH_SSH1 1196/* 1197 * Reads a multiple-precision integer in decimal from the buffer, and advances 1198 * the pointer. The integer must already be initialized. This function is 1199 * permitted to modify the buffer. This leaves *cpp to point just beyond the 1200 * last processed character. 1201 */ 1202static int 1203read_decimal_bignum(char **cpp, BIGNUM *v) 1204{ 1205 char *cp; 1206 size_t e; 1207 int skip = 1; /* skip white space */ 1208 1209 cp = *cpp; 1210 while (*cp == ' ' || *cp == '\t') 1211 cp++; 1212 e = strspn(cp, "0123456789"); 1213 if (e == 0) 1214 return SSH_ERR_INVALID_FORMAT; 1215 if (e > SSHBUF_MAX_BIGNUM * 3) 1216 return SSH_ERR_BIGNUM_TOO_LARGE; 1217 if (cp[e] == '\0') 1218 skip = 0;
| 431 explicit_bzero(cert, sizeof(*cert)); 432 free(cert); 433} 434 435static struct sshkey_cert * 436cert_new(void) 437{ 438 struct sshkey_cert *cert; 439 440 if ((cert = calloc(1, sizeof(*cert))) == NULL) 441 return NULL; 442 if ((cert->certblob = sshbuf_new()) == NULL || 443 (cert->critical = sshbuf_new()) == NULL || 444 (cert->extensions = sshbuf_new()) == NULL) { 445 cert_free(cert); 446 return NULL; 447 } 448 cert->key_id = NULL; 449 cert->principals = NULL; 450 cert->signature_key = NULL; 451 return cert; 452} 453 454struct sshkey * 455sshkey_new(int type) 456{ 457 struct sshkey *k; 458#ifdef WITH_OPENSSL 459 RSA *rsa; 460 DSA *dsa; 461#endif /* WITH_OPENSSL */ 462 463 if ((k = calloc(1, sizeof(*k))) == NULL) 464 return NULL; 465 k->type = type; 466 k->ecdsa = NULL; 467 k->ecdsa_nid = -1; 468 k->dsa = NULL; 469 k->rsa = NULL; 470 k->cert = NULL; 471 k->ed25519_sk = NULL; 472 k->ed25519_pk = NULL; 473 switch (k->type) { 474#ifdef WITH_OPENSSL 475 case KEY_RSA1: 476 case KEY_RSA: 477 case KEY_RSA_CERT: 478 if ((rsa = RSA_new()) == NULL || 479 (rsa->n = BN_new()) == NULL || 480 (rsa->e = BN_new()) == NULL) { 481 if (rsa != NULL) 482 RSA_free(rsa); 483 free(k); 484 return NULL; 485 } 486 k->rsa = rsa; 487 break; 488 case KEY_DSA: 489 case KEY_DSA_CERT: 490 if ((dsa = DSA_new()) == NULL || 491 (dsa->p = BN_new()) == NULL || 492 (dsa->q = BN_new()) == NULL || 493 (dsa->g = BN_new()) == NULL || 494 (dsa->pub_key = BN_new()) == NULL) { 495 if (dsa != NULL) 496 DSA_free(dsa); 497 free(k); 498 return NULL; 499 } 500 k->dsa = dsa; 501 break; 502 case KEY_ECDSA: 503 case KEY_ECDSA_CERT: 504 /* Cannot do anything until we know the group */ 505 break; 506#endif /* WITH_OPENSSL */ 507 case KEY_ED25519: 508 case KEY_ED25519_CERT: 509 /* no need to prealloc */ 510 break; 511 case KEY_UNSPEC: 512 break; 513 default: 514 free(k); 515 return NULL; 516 break; 517 } 518 519 if (sshkey_is_cert(k)) { 520 if ((k->cert = cert_new()) == NULL) { 521 sshkey_free(k); 522 return NULL; 523 } 524 } 525 526 return k; 527} 528 529int 530sshkey_add_private(struct sshkey *k) 531{ 532 switch (k->type) { 533#ifdef WITH_OPENSSL 534 case KEY_RSA1: 535 case KEY_RSA: 536 case KEY_RSA_CERT: 537#define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL) 538 if (bn_maybe_alloc_failed(k->rsa->d) || 539 bn_maybe_alloc_failed(k->rsa->iqmp) || 540 bn_maybe_alloc_failed(k->rsa->q) || 541 bn_maybe_alloc_failed(k->rsa->p) || 542 bn_maybe_alloc_failed(k->rsa->dmq1) || 543 bn_maybe_alloc_failed(k->rsa->dmp1)) 544 return SSH_ERR_ALLOC_FAIL; 545 break; 546 case KEY_DSA: 547 case KEY_DSA_CERT: 548 if (bn_maybe_alloc_failed(k->dsa->priv_key)) 549 return SSH_ERR_ALLOC_FAIL; 550 break; 551#undef bn_maybe_alloc_failed 552 case KEY_ECDSA: 553 case KEY_ECDSA_CERT: 554 /* Cannot do anything until we know the group */ 555 break; 556#endif /* WITH_OPENSSL */ 557 case KEY_ED25519: 558 case KEY_ED25519_CERT: 559 /* no need to prealloc */ 560 break; 561 case KEY_UNSPEC: 562 break; 563 default: 564 return SSH_ERR_INVALID_ARGUMENT; 565 } 566 return 0; 567} 568 569struct sshkey * 570sshkey_new_private(int type) 571{ 572 struct sshkey *k = sshkey_new(type); 573 574 if (k == NULL) 575 return NULL; 576 if (sshkey_add_private(k) != 0) { 577 sshkey_free(k); 578 return NULL; 579 } 580 return k; 581} 582 583void 584sshkey_free(struct sshkey *k) 585{ 586 if (k == NULL) 587 return; 588 switch (k->type) { 589#ifdef WITH_OPENSSL 590 case KEY_RSA1: 591 case KEY_RSA: 592 case KEY_RSA_CERT: 593 if (k->rsa != NULL) 594 RSA_free(k->rsa); 595 k->rsa = NULL; 596 break; 597 case KEY_DSA: 598 case KEY_DSA_CERT: 599 if (k->dsa != NULL) 600 DSA_free(k->dsa); 601 k->dsa = NULL; 602 break; 603# ifdef OPENSSL_HAS_ECC 604 case KEY_ECDSA: 605 case KEY_ECDSA_CERT: 606 if (k->ecdsa != NULL) 607 EC_KEY_free(k->ecdsa); 608 k->ecdsa = NULL; 609 break; 610# endif /* OPENSSL_HAS_ECC */ 611#endif /* WITH_OPENSSL */ 612 case KEY_ED25519: 613 case KEY_ED25519_CERT: 614 if (k->ed25519_pk) { 615 explicit_bzero(k->ed25519_pk, ED25519_PK_SZ); 616 free(k->ed25519_pk); 617 k->ed25519_pk = NULL; 618 } 619 if (k->ed25519_sk) { 620 explicit_bzero(k->ed25519_sk, ED25519_SK_SZ); 621 free(k->ed25519_sk); 622 k->ed25519_sk = NULL; 623 } 624 break; 625 case KEY_UNSPEC: 626 break; 627 default: 628 break; 629 } 630 if (sshkey_is_cert(k)) 631 cert_free(k->cert); 632 explicit_bzero(k, sizeof(*k)); 633 free(k); 634} 635 636static int 637cert_compare(struct sshkey_cert *a, struct sshkey_cert *b) 638{ 639 if (a == NULL && b == NULL) 640 return 1; 641 if (a == NULL || b == NULL) 642 return 0; 643 if (sshbuf_len(a->certblob) != sshbuf_len(b->certblob)) 644 return 0; 645 if (timingsafe_bcmp(sshbuf_ptr(a->certblob), sshbuf_ptr(b->certblob), 646 sshbuf_len(a->certblob)) != 0) 647 return 0; 648 return 1; 649} 650 651/* 652 * Compare public portions of key only, allowing comparisons between 653 * certificates and plain keys too. 654 */ 655int 656sshkey_equal_public(const struct sshkey *a, const struct sshkey *b) 657{ 658#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) 659 BN_CTX *bnctx; 660#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ 661 662 if (a == NULL || b == NULL || 663 sshkey_type_plain(a->type) != sshkey_type_plain(b->type)) 664 return 0; 665 666 switch (a->type) { 667#ifdef WITH_OPENSSL 668 case KEY_RSA1: 669 case KEY_RSA_CERT: 670 case KEY_RSA: 671 return a->rsa != NULL && b->rsa != NULL && 672 BN_cmp(a->rsa->e, b->rsa->e) == 0 && 673 BN_cmp(a->rsa->n, b->rsa->n) == 0; 674 case KEY_DSA_CERT: 675 case KEY_DSA: 676 return a->dsa != NULL && b->dsa != NULL && 677 BN_cmp(a->dsa->p, b->dsa->p) == 0 && 678 BN_cmp(a->dsa->q, b->dsa->q) == 0 && 679 BN_cmp(a->dsa->g, b->dsa->g) == 0 && 680 BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; 681# ifdef OPENSSL_HAS_ECC 682 case KEY_ECDSA_CERT: 683 case KEY_ECDSA: 684 if (a->ecdsa == NULL || b->ecdsa == NULL || 685 EC_KEY_get0_public_key(a->ecdsa) == NULL || 686 EC_KEY_get0_public_key(b->ecdsa) == NULL) 687 return 0; 688 if ((bnctx = BN_CTX_new()) == NULL) 689 return 0; 690 if (EC_GROUP_cmp(EC_KEY_get0_group(a->ecdsa), 691 EC_KEY_get0_group(b->ecdsa), bnctx) != 0 || 692 EC_POINT_cmp(EC_KEY_get0_group(a->ecdsa), 693 EC_KEY_get0_public_key(a->ecdsa), 694 EC_KEY_get0_public_key(b->ecdsa), bnctx) != 0) { 695 BN_CTX_free(bnctx); 696 return 0; 697 } 698 BN_CTX_free(bnctx); 699 return 1; 700# endif /* OPENSSL_HAS_ECC */ 701#endif /* WITH_OPENSSL */ 702 case KEY_ED25519: 703 case KEY_ED25519_CERT: 704 return a->ed25519_pk != NULL && b->ed25519_pk != NULL && 705 memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) == 0; 706 default: 707 return 0; 708 } 709 /* NOTREACHED */ 710} 711 712int 713sshkey_equal(const struct sshkey *a, const struct sshkey *b) 714{ 715 if (a == NULL || b == NULL || a->type != b->type) 716 return 0; 717 if (sshkey_is_cert(a)) { 718 if (!cert_compare(a->cert, b->cert)) 719 return 0; 720 } 721 return sshkey_equal_public(a, b); 722} 723 724static int 725to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain) 726{ 727 int type, ret = SSH_ERR_INTERNAL_ERROR; 728 const char *typename; 729 730 if (key == NULL) 731 return SSH_ERR_INVALID_ARGUMENT; 732 733 if (sshkey_is_cert(key)) { 734 if (key->cert == NULL) 735 return SSH_ERR_EXPECTED_CERT; 736 if (sshbuf_len(key->cert->certblob) == 0) 737 return SSH_ERR_KEY_LACKS_CERTBLOB; 738 } 739 type = force_plain ? sshkey_type_plain(key->type) : key->type; 740 typename = sshkey_ssh_name_from_type_nid(type, key->ecdsa_nid); 741 742 switch (type) { 743#ifdef WITH_OPENSSL 744 case KEY_DSA_CERT: 745 case KEY_ECDSA_CERT: 746 case KEY_RSA_CERT: 747#endif /* WITH_OPENSSL */ 748 case KEY_ED25519_CERT: 749 /* Use the existing blob */ 750 /* XXX modified flag? */ 751 if ((ret = sshbuf_putb(b, key->cert->certblob)) != 0) 752 return ret; 753 break; 754#ifdef WITH_OPENSSL 755 case KEY_DSA: 756 if (key->dsa == NULL) 757 return SSH_ERR_INVALID_ARGUMENT; 758 if ((ret = sshbuf_put_cstring(b, typename)) != 0 || 759 (ret = sshbuf_put_bignum2(b, key->dsa->p)) != 0 || 760 (ret = sshbuf_put_bignum2(b, key->dsa->q)) != 0 || 761 (ret = sshbuf_put_bignum2(b, key->dsa->g)) != 0 || 762 (ret = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0) 763 return ret; 764 break; 765# ifdef OPENSSL_HAS_ECC 766 case KEY_ECDSA: 767 if (key->ecdsa == NULL) 768 return SSH_ERR_INVALID_ARGUMENT; 769 if ((ret = sshbuf_put_cstring(b, typename)) != 0 || 770 (ret = sshbuf_put_cstring(b, 771 sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 || 772 (ret = sshbuf_put_eckey(b, key->ecdsa)) != 0) 773 return ret; 774 break; 775# endif 776 case KEY_RSA: 777 if (key->rsa == NULL) 778 return SSH_ERR_INVALID_ARGUMENT; 779 if ((ret = sshbuf_put_cstring(b, typename)) != 0 || 780 (ret = sshbuf_put_bignum2(b, key->rsa->e)) != 0 || 781 (ret = sshbuf_put_bignum2(b, key->rsa->n)) != 0) 782 return ret; 783 break; 784#endif /* WITH_OPENSSL */ 785 case KEY_ED25519: 786 if (key->ed25519_pk == NULL) 787 return SSH_ERR_INVALID_ARGUMENT; 788 if ((ret = sshbuf_put_cstring(b, typename)) != 0 || 789 (ret = sshbuf_put_string(b, 790 key->ed25519_pk, ED25519_PK_SZ)) != 0) 791 return ret; 792 break; 793 default: 794 return SSH_ERR_KEY_TYPE_UNKNOWN; 795 } 796 return 0; 797} 798 799int 800sshkey_putb(const struct sshkey *key, struct sshbuf *b) 801{ 802 return to_blob_buf(key, b, 0); 803} 804 805int 806sshkey_puts(const struct sshkey *key, struct sshbuf *b) 807{ 808 struct sshbuf *tmp; 809 int r; 810 811 if ((tmp = sshbuf_new()) == NULL) 812 return SSH_ERR_ALLOC_FAIL; 813 r = to_blob_buf(key, tmp, 0); 814 if (r == 0) 815 r = sshbuf_put_stringb(b, tmp); 816 sshbuf_free(tmp); 817 return r; 818} 819 820int 821sshkey_putb_plain(const struct sshkey *key, struct sshbuf *b) 822{ 823 return to_blob_buf(key, b, 1); 824} 825 826static int 827to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp, int force_plain) 828{ 829 int ret = SSH_ERR_INTERNAL_ERROR; 830 size_t len; 831 struct sshbuf *b = NULL; 832 833 if (lenp != NULL) 834 *lenp = 0; 835 if (blobp != NULL) 836 *blobp = NULL; 837 if ((b = sshbuf_new()) == NULL) 838 return SSH_ERR_ALLOC_FAIL; 839 if ((ret = to_blob_buf(key, b, force_plain)) != 0) 840 goto out; 841 len = sshbuf_len(b); 842 if (lenp != NULL) 843 *lenp = len; 844 if (blobp != NULL) { 845 if ((*blobp = malloc(len)) == NULL) { 846 ret = SSH_ERR_ALLOC_FAIL; 847 goto out; 848 } 849 memcpy(*blobp, sshbuf_ptr(b), len); 850 } 851 ret = 0; 852 out: 853 sshbuf_free(b); 854 return ret; 855} 856 857int 858sshkey_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp) 859{ 860 return to_blob(key, blobp, lenp, 0); 861} 862 863int 864sshkey_plain_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp) 865{ 866 return to_blob(key, blobp, lenp, 1); 867} 868 869int 870sshkey_fingerprint_raw(const struct sshkey *k, int dgst_alg, 871 u_char **retp, size_t *lenp) 872{ 873 u_char *blob = NULL, *ret = NULL; 874 size_t blob_len = 0; 875 int r = SSH_ERR_INTERNAL_ERROR; 876 877 if (retp != NULL) 878 *retp = NULL; 879 if (lenp != NULL) 880 *lenp = 0; 881 if (ssh_digest_bytes(dgst_alg) == 0) { 882 r = SSH_ERR_INVALID_ARGUMENT; 883 goto out; 884 } 885 886 if (k->type == KEY_RSA1) { 887#ifdef WITH_OPENSSL 888 int nlen = BN_num_bytes(k->rsa->n); 889 int elen = BN_num_bytes(k->rsa->e); 890 891 blob_len = nlen + elen; 892 if (nlen >= INT_MAX - elen || 893 (blob = malloc(blob_len)) == NULL) { 894 r = SSH_ERR_ALLOC_FAIL; 895 goto out; 896 } 897 BN_bn2bin(k->rsa->n, blob); 898 BN_bn2bin(k->rsa->e, blob + nlen); 899#endif /* WITH_OPENSSL */ 900 } else if ((r = to_blob(k, &blob, &blob_len, 1)) != 0) 901 goto out; 902 if ((ret = calloc(1, SSH_DIGEST_MAX_LENGTH)) == NULL) { 903 r = SSH_ERR_ALLOC_FAIL; 904 goto out; 905 } 906 if ((r = ssh_digest_memory(dgst_alg, blob, blob_len, 907 ret, SSH_DIGEST_MAX_LENGTH)) != 0) 908 goto out; 909 /* success */ 910 if (retp != NULL) { 911 *retp = ret; 912 ret = NULL; 913 } 914 if (lenp != NULL) 915 *lenp = ssh_digest_bytes(dgst_alg); 916 r = 0; 917 out: 918 free(ret); 919 if (blob != NULL) { 920 explicit_bzero(blob, blob_len); 921 free(blob); 922 } 923 return r; 924} 925 926static char * 927fingerprint_b64(const char *alg, u_char *dgst_raw, size_t dgst_raw_len) 928{ 929 char *ret; 930 size_t plen = strlen(alg) + 1; 931 size_t rlen = ((dgst_raw_len + 2) / 3) * 4 + plen + 1; 932 int r; 933 934 if (dgst_raw_len > 65536 || (ret = calloc(1, rlen)) == NULL) 935 return NULL; 936 strlcpy(ret, alg, rlen); 937 strlcat(ret, ":", rlen); 938 if (dgst_raw_len == 0) 939 return ret; 940 if ((r = b64_ntop(dgst_raw, dgst_raw_len, 941 ret + plen, rlen - plen)) == -1) { 942 explicit_bzero(ret, rlen); 943 free(ret); 944 return NULL; 945 } 946 /* Trim padding characters from end */ 947 ret[strcspn(ret, "=")] = '\0'; 948 return ret; 949} 950 951static char * 952fingerprint_hex(const char *alg, u_char *dgst_raw, size_t dgst_raw_len) 953{ 954 char *retval, hex[5]; 955 size_t i, rlen = dgst_raw_len * 3 + strlen(alg) + 2; 956 957 if (dgst_raw_len > 65536 || (retval = calloc(1, rlen)) == NULL) 958 return NULL; 959 strlcpy(retval, alg, rlen); 960 strlcat(retval, ":", rlen); 961 for (i = 0; i < dgst_raw_len; i++) { 962 snprintf(hex, sizeof(hex), "%s%02x", 963 i > 0 ? ":" : "", dgst_raw[i]); 964 strlcat(retval, hex, rlen); 965 } 966 return retval; 967} 968 969static char * 970fingerprint_bubblebabble(u_char *dgst_raw, size_t dgst_raw_len) 971{ 972 char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' }; 973 char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm', 974 'n', 'p', 'r', 's', 't', 'v', 'z', 'x' }; 975 u_int i, j = 0, rounds, seed = 1; 976 char *retval; 977 978 rounds = (dgst_raw_len / 2) + 1; 979 if ((retval = calloc(rounds, 6)) == NULL) 980 return NULL; 981 retval[j++] = 'x'; 982 for (i = 0; i < rounds; i++) { 983 u_int idx0, idx1, idx2, idx3, idx4; 984 if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) { 985 idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) + 986 seed) % 6; 987 idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15; 988 idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) + 989 (seed / 6)) % 6; 990 retval[j++] = vowels[idx0]; 991 retval[j++] = consonants[idx1]; 992 retval[j++] = vowels[idx2]; 993 if ((i + 1) < rounds) { 994 idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15; 995 idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15; 996 retval[j++] = consonants[idx3]; 997 retval[j++] = '-'; 998 retval[j++] = consonants[idx4]; 999 seed = ((seed * 5) + 1000 ((((u_int)(dgst_raw[2 * i])) * 7) + 1001 ((u_int)(dgst_raw[(2 * i) + 1])))) % 36; 1002 } 1003 } else { 1004 idx0 = seed % 6; 1005 idx1 = 16; 1006 idx2 = seed / 6; 1007 retval[j++] = vowels[idx0]; 1008 retval[j++] = consonants[idx1]; 1009 retval[j++] = vowels[idx2]; 1010 } 1011 } 1012 retval[j++] = 'x'; 1013 retval[j++] = '\0'; 1014 return retval; 1015} 1016 1017/* 1018 * Draw an ASCII-Art representing the fingerprint so human brain can 1019 * profit from its built-in pattern recognition ability. 1020 * This technique is called "random art" and can be found in some 1021 * scientific publications like this original paper: 1022 * 1023 * "Hash Visualization: a New Technique to improve Real-World Security", 1024 * Perrig A. and Song D., 1999, International Workshop on Cryptographic 1025 * Techniques and E-Commerce (CrypTEC '99) 1026 * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf 1027 * 1028 * The subject came up in a talk by Dan Kaminsky, too. 1029 * 1030 * If you see the picture is different, the key is different. 1031 * If the picture looks the same, you still know nothing. 1032 * 1033 * The algorithm used here is a worm crawling over a discrete plane, 1034 * leaving a trace (augmenting the field) everywhere it goes. 1035 * Movement is taken from dgst_raw 2bit-wise. Bumping into walls 1036 * makes the respective movement vector be ignored for this turn. 1037 * Graphs are not unambiguous, because circles in graphs can be 1038 * walked in either direction. 1039 */ 1040 1041/* 1042 * Field sizes for the random art. Have to be odd, so the starting point 1043 * can be in the exact middle of the picture, and FLDBASE should be >=8 . 1044 * Else pictures would be too dense, and drawing the frame would 1045 * fail, too, because the key type would not fit in anymore. 1046 */ 1047#define FLDBASE 8 1048#define FLDSIZE_Y (FLDBASE + 1) 1049#define FLDSIZE_X (FLDBASE * 2 + 1) 1050static char * 1051fingerprint_randomart(const char *alg, u_char *dgst_raw, size_t dgst_raw_len, 1052 const struct sshkey *k) 1053{ 1054 /* 1055 * Chars to be used after each other every time the worm 1056 * intersects with itself. Matter of taste. 1057 */ 1058 char *augmentation_string = " .o+=*BOX@%&#/^SE"; 1059 char *retval, *p, title[FLDSIZE_X], hash[FLDSIZE_X]; 1060 u_char field[FLDSIZE_X][FLDSIZE_Y]; 1061 size_t i, tlen, hlen; 1062 u_int b; 1063 int x, y, r; 1064 size_t len = strlen(augmentation_string) - 1; 1065 1066 if ((retval = calloc((FLDSIZE_X + 3), (FLDSIZE_Y + 2))) == NULL) 1067 return NULL; 1068 1069 /* initialize field */ 1070 memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char)); 1071 x = FLDSIZE_X / 2; 1072 y = FLDSIZE_Y / 2; 1073 1074 /* process raw key */ 1075 for (i = 0; i < dgst_raw_len; i++) { 1076 int input; 1077 /* each byte conveys four 2-bit move commands */ 1078 input = dgst_raw[i]; 1079 for (b = 0; b < 4; b++) { 1080 /* evaluate 2 bit, rest is shifted later */ 1081 x += (input & 0x1) ? 1 : -1; 1082 y += (input & 0x2) ? 1 : -1; 1083 1084 /* assure we are still in bounds */ 1085 x = MAX(x, 0); 1086 y = MAX(y, 0); 1087 x = MIN(x, FLDSIZE_X - 1); 1088 y = MIN(y, FLDSIZE_Y - 1); 1089 1090 /* augment the field */ 1091 if (field[x][y] < len - 2) 1092 field[x][y]++; 1093 input = input >> 2; 1094 } 1095 } 1096 1097 /* mark starting point and end point*/ 1098 field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1; 1099 field[x][y] = len; 1100 1101 /* assemble title */ 1102 r = snprintf(title, sizeof(title), "[%s %u]", 1103 sshkey_type(k), sshkey_size(k)); 1104 /* If [type size] won't fit, then try [type]; fits "[ED25519-CERT]" */ 1105 if (r < 0 || r > (int)sizeof(title)) 1106 r = snprintf(title, sizeof(title), "[%s]", sshkey_type(k)); 1107 tlen = (r <= 0) ? 0 : strlen(title); 1108 1109 /* assemble hash ID. */ 1110 r = snprintf(hash, sizeof(hash), "[%s]", alg); 1111 hlen = (r <= 0) ? 0 : strlen(hash); 1112 1113 /* output upper border */ 1114 p = retval; 1115 *p++ = '+'; 1116 for (i = 0; i < (FLDSIZE_X - tlen) / 2; i++) 1117 *p++ = '-'; 1118 memcpy(p, title, tlen); 1119 p += tlen; 1120 for (i += tlen; i < FLDSIZE_X; i++) 1121 *p++ = '-'; 1122 *p++ = '+'; 1123 *p++ = '\n'; 1124 1125 /* output content */ 1126 for (y = 0; y < FLDSIZE_Y; y++) { 1127 *p++ = '|'; 1128 for (x = 0; x < FLDSIZE_X; x++) 1129 *p++ = augmentation_string[MIN(field[x][y], len)]; 1130 *p++ = '|'; 1131 *p++ = '\n'; 1132 } 1133 1134 /* output lower border */ 1135 *p++ = '+'; 1136 for (i = 0; i < (FLDSIZE_X - hlen) / 2; i++) 1137 *p++ = '-'; 1138 memcpy(p, hash, hlen); 1139 p += hlen; 1140 for (i += hlen; i < FLDSIZE_X; i++) 1141 *p++ = '-'; 1142 *p++ = '+'; 1143 1144 return retval; 1145} 1146 1147char * 1148sshkey_fingerprint(const struct sshkey *k, int dgst_alg, 1149 enum sshkey_fp_rep dgst_rep) 1150{ 1151 char *retval = NULL; 1152 u_char *dgst_raw; 1153 size_t dgst_raw_len; 1154 1155 if (sshkey_fingerprint_raw(k, dgst_alg, &dgst_raw, &dgst_raw_len) != 0) 1156 return NULL; 1157 switch (dgst_rep) { 1158 case SSH_FP_DEFAULT: 1159 if (dgst_alg == SSH_DIGEST_MD5) { 1160 retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg), 1161 dgst_raw, dgst_raw_len); 1162 } else { 1163 retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg), 1164 dgst_raw, dgst_raw_len); 1165 } 1166 break; 1167 case SSH_FP_HEX: 1168 retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg), 1169 dgst_raw, dgst_raw_len); 1170 break; 1171 case SSH_FP_BASE64: 1172 retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg), 1173 dgst_raw, dgst_raw_len); 1174 break; 1175 case SSH_FP_BUBBLEBABBLE: 1176 retval = fingerprint_bubblebabble(dgst_raw, dgst_raw_len); 1177 break; 1178 case SSH_FP_RANDOMART: 1179 retval = fingerprint_randomart(ssh_digest_alg_name(dgst_alg), 1180 dgst_raw, dgst_raw_len, k); 1181 break; 1182 default: 1183 explicit_bzero(dgst_raw, dgst_raw_len); 1184 free(dgst_raw); 1185 return NULL; 1186 } 1187 explicit_bzero(dgst_raw, dgst_raw_len); 1188 free(dgst_raw); 1189 return retval; 1190} 1191 1192#ifdef WITH_SSH1 1193/* 1194 * Reads a multiple-precision integer in decimal from the buffer, and advances 1195 * the pointer. The integer must already be initialized. This function is 1196 * permitted to modify the buffer. This leaves *cpp to point just beyond the 1197 * last processed character. 1198 */ 1199static int 1200read_decimal_bignum(char **cpp, BIGNUM *v) 1201{ 1202 char *cp; 1203 size_t e; 1204 int skip = 1; /* skip white space */ 1205 1206 cp = *cpp; 1207 while (*cp == ' ' || *cp == '\t') 1208 cp++; 1209 e = strspn(cp, "0123456789"); 1210 if (e == 0) 1211 return SSH_ERR_INVALID_FORMAT; 1212 if (e > SSHBUF_MAX_BIGNUM * 3) 1213 return SSH_ERR_BIGNUM_TOO_LARGE; 1214 if (cp[e] == '\0') 1215 skip = 0;
|
1219 else if (index(" \t\r\n", cp[e]) == NULL)
| 1216 else if (strchr(" \t\r\n", cp[e]) == NULL)
|
1220 return SSH_ERR_INVALID_FORMAT; 1221 cp[e] = '\0'; 1222 if (BN_dec2bn(&v, cp) <= 0) 1223 return SSH_ERR_INVALID_FORMAT; 1224 *cpp = cp + e + skip; 1225 return 0; 1226} 1227#endif /* WITH_SSH1 */ 1228 1229/* returns 0 ok, and < 0 error */ 1230int 1231sshkey_read(struct sshkey *ret, char **cpp) 1232{ 1233 struct sshkey *k; 1234 int retval = SSH_ERR_INVALID_FORMAT;
| 1217 return SSH_ERR_INVALID_FORMAT; 1218 cp[e] = '\0'; 1219 if (BN_dec2bn(&v, cp) <= 0) 1220 return SSH_ERR_INVALID_FORMAT; 1221 *cpp = cp + e + skip; 1222 return 0; 1223} 1224#endif /* WITH_SSH1 */ 1225 1226/* returns 0 ok, and < 0 error */ 1227int 1228sshkey_read(struct sshkey *ret, char **cpp) 1229{ 1230 struct sshkey *k; 1231 int retval = SSH_ERR_INVALID_FORMAT;
|
1235 char *cp, *space;
| 1232 char *ep, *cp, *space;
|
1236 int r, type, curve_nid = -1; 1237 struct sshbuf *blob; 1238#ifdef WITH_SSH1
| 1233 int r, type, curve_nid = -1; 1234 struct sshbuf *blob; 1235#ifdef WITH_SSH1
|
1239 char *ep;
| |
1240 u_long bits; 1241#endif /* WITH_SSH1 */ 1242 1243 cp = *cpp; 1244 1245 switch (ret->type) { 1246 case KEY_RSA1: 1247#ifdef WITH_SSH1 1248 /* Get number of bits. */ 1249 bits = strtoul(cp, &ep, 10);
| 1236 u_long bits; 1237#endif /* WITH_SSH1 */ 1238 1239 cp = *cpp; 1240 1241 switch (ret->type) { 1242 case KEY_RSA1: 1243#ifdef WITH_SSH1 1244 /* Get number of bits. */ 1245 bits = strtoul(cp, &ep, 10);
|
1250 if (*cp == '\0' || index(" \t\r\n", *ep) == NULL ||
| 1246 if (*cp == '\0' || strchr(" \t\r\n", *ep) == NULL ||
|
1251 bits == 0 || bits > SSHBUF_MAX_BIGNUM * 8) 1252 return SSH_ERR_INVALID_FORMAT; /* Bad bit count... */ 1253 /* Get public exponent, public modulus. */ 1254 if ((r = read_decimal_bignum(&ep, ret->rsa->e)) < 0) 1255 return r; 1256 if ((r = read_decimal_bignum(&ep, ret->rsa->n)) < 0) 1257 return r;
| 1247 bits == 0 || bits > SSHBUF_MAX_BIGNUM * 8) 1248 return SSH_ERR_INVALID_FORMAT; /* Bad bit count... */ 1249 /* Get public exponent, public modulus. */ 1250 if ((r = read_decimal_bignum(&ep, ret->rsa->e)) < 0) 1251 return r; 1252 if ((r = read_decimal_bignum(&ep, ret->rsa->n)) < 0) 1253 return r;
|
1258 *cpp = ep;
| |
1259 /* validate the claimed number of bits */ 1260 if (BN_num_bits(ret->rsa->n) != (int)bits) 1261 return SSH_ERR_KEY_BITS_MISMATCH;
| 1254 /* validate the claimed number of bits */ 1255 if (BN_num_bits(ret->rsa->n) != (int)bits) 1256 return SSH_ERR_KEY_BITS_MISMATCH;
|
| 1257 *cpp = ep;
|
1262 retval = 0; 1263#endif /* WITH_SSH1 */ 1264 break; 1265 case KEY_UNSPEC: 1266 case KEY_RSA: 1267 case KEY_DSA: 1268 case KEY_ECDSA: 1269 case KEY_ED25519: 1270 case KEY_DSA_CERT: 1271 case KEY_ECDSA_CERT: 1272 case KEY_RSA_CERT: 1273 case KEY_ED25519_CERT: 1274 space = strchr(cp, ' '); 1275 if (space == NULL) 1276 return SSH_ERR_INVALID_FORMAT; 1277 *space = '\0'; 1278 type = sshkey_type_from_name(cp); 1279 if (sshkey_type_plain(type) == KEY_ECDSA && 1280 (curve_nid = sshkey_ecdsa_nid_from_name(cp)) == -1) 1281 return SSH_ERR_EC_CURVE_INVALID; 1282 *space = ' '; 1283 if (type == KEY_UNSPEC) 1284 return SSH_ERR_INVALID_FORMAT; 1285 cp = space+1; 1286 if (*cp == '\0') 1287 return SSH_ERR_INVALID_FORMAT; 1288 if (ret->type != KEY_UNSPEC && ret->type != type) 1289 return SSH_ERR_KEY_TYPE_MISMATCH; 1290 if ((blob = sshbuf_new()) == NULL) 1291 return SSH_ERR_ALLOC_FAIL; 1292 /* trim comment */ 1293 space = strchr(cp, ' '); 1294 if (space) { 1295 /* advance 'space': skip whitespace */ 1296 *space++ = '\0'; 1297 while (*space == ' ' || *space == '\t') 1298 space++;
| 1258 retval = 0; 1259#endif /* WITH_SSH1 */ 1260 break; 1261 case KEY_UNSPEC: 1262 case KEY_RSA: 1263 case KEY_DSA: 1264 case KEY_ECDSA: 1265 case KEY_ED25519: 1266 case KEY_DSA_CERT: 1267 case KEY_ECDSA_CERT: 1268 case KEY_RSA_CERT: 1269 case KEY_ED25519_CERT: 1270 space = strchr(cp, ' '); 1271 if (space == NULL) 1272 return SSH_ERR_INVALID_FORMAT; 1273 *space = '\0'; 1274 type = sshkey_type_from_name(cp); 1275 if (sshkey_type_plain(type) == KEY_ECDSA && 1276 (curve_nid = sshkey_ecdsa_nid_from_name(cp)) == -1) 1277 return SSH_ERR_EC_CURVE_INVALID; 1278 *space = ' '; 1279 if (type == KEY_UNSPEC) 1280 return SSH_ERR_INVALID_FORMAT; 1281 cp = space+1; 1282 if (*cp == '\0') 1283 return SSH_ERR_INVALID_FORMAT; 1284 if (ret->type != KEY_UNSPEC && ret->type != type) 1285 return SSH_ERR_KEY_TYPE_MISMATCH; 1286 if ((blob = sshbuf_new()) == NULL) 1287 return SSH_ERR_ALLOC_FAIL; 1288 /* trim comment */ 1289 space = strchr(cp, ' '); 1290 if (space) { 1291 /* advance 'space': skip whitespace */ 1292 *space++ = '\0'; 1293 while (*space == ' ' || *space == '\t') 1294 space++;
|
1299 *cpp = space;
| 1295 ep = space;
|
1300 } else
| 1296 } else
|
1301 *cpp = cp + strlen(cp);
| 1297 ep = cp + strlen(cp);
|
1302 if ((r = sshbuf_b64tod(blob, cp)) != 0) { 1303 sshbuf_free(blob); 1304 return r; 1305 } 1306 if ((r = sshkey_from_blob(sshbuf_ptr(blob), 1307 sshbuf_len(blob), &k)) != 0) { 1308 sshbuf_free(blob); 1309 return r; 1310 } 1311 sshbuf_free(blob); 1312 if (k->type != type) { 1313 sshkey_free(k); 1314 return SSH_ERR_KEY_TYPE_MISMATCH; 1315 } 1316 if (sshkey_type_plain(type) == KEY_ECDSA && 1317 curve_nid != k->ecdsa_nid) { 1318 sshkey_free(k); 1319 return SSH_ERR_EC_CURVE_MISMATCH; 1320 } 1321 ret->type = type; 1322 if (sshkey_is_cert(ret)) { 1323 if (!sshkey_is_cert(k)) { 1324 sshkey_free(k); 1325 return SSH_ERR_EXPECTED_CERT; 1326 } 1327 if (ret->cert != NULL) 1328 cert_free(ret->cert); 1329 ret->cert = k->cert; 1330 k->cert = NULL; 1331 }
| 1298 if ((r = sshbuf_b64tod(blob, cp)) != 0) { 1299 sshbuf_free(blob); 1300 return r; 1301 } 1302 if ((r = sshkey_from_blob(sshbuf_ptr(blob), 1303 sshbuf_len(blob), &k)) != 0) { 1304 sshbuf_free(blob); 1305 return r; 1306 } 1307 sshbuf_free(blob); 1308 if (k->type != type) { 1309 sshkey_free(k); 1310 return SSH_ERR_KEY_TYPE_MISMATCH; 1311 } 1312 if (sshkey_type_plain(type) == KEY_ECDSA && 1313 curve_nid != k->ecdsa_nid) { 1314 sshkey_free(k); 1315 return SSH_ERR_EC_CURVE_MISMATCH; 1316 } 1317 ret->type = type; 1318 if (sshkey_is_cert(ret)) { 1319 if (!sshkey_is_cert(k)) { 1320 sshkey_free(k); 1321 return SSH_ERR_EXPECTED_CERT; 1322 } 1323 if (ret->cert != NULL) 1324 cert_free(ret->cert); 1325 ret->cert = k->cert; 1326 k->cert = NULL; 1327 }
|
| 1328 switch (sshkey_type_plain(ret->type)) {
|
1332#ifdef WITH_OPENSSL
| 1329#ifdef WITH_OPENSSL
|
1333 if (sshkey_type_plain(ret->type) == KEY_RSA) {
| 1330 case KEY_RSA:
|
1334 if (ret->rsa != NULL) 1335 RSA_free(ret->rsa); 1336 ret->rsa = k->rsa; 1337 k->rsa = NULL; 1338#ifdef DEBUG_PK 1339 RSA_print_fp(stderr, ret->rsa, 8); 1340#endif
| 1331 if (ret->rsa != NULL) 1332 RSA_free(ret->rsa); 1333 ret->rsa = k->rsa; 1334 k->rsa = NULL; 1335#ifdef DEBUG_PK 1336 RSA_print_fp(stderr, ret->rsa, 8); 1337#endif
|
1341 } 1342 if (sshkey_type_plain(ret->type) == KEY_DSA) {
| 1338 break; 1339 case KEY_DSA:
|
1343 if (ret->dsa != NULL) 1344 DSA_free(ret->dsa); 1345 ret->dsa = k->dsa; 1346 k->dsa = NULL; 1347#ifdef DEBUG_PK 1348 DSA_print_fp(stderr, ret->dsa, 8); 1349#endif
| 1340 if (ret->dsa != NULL) 1341 DSA_free(ret->dsa); 1342 ret->dsa = k->dsa; 1343 k->dsa = NULL; 1344#ifdef DEBUG_PK 1345 DSA_print_fp(stderr, ret->dsa, 8); 1346#endif
|
1350 }
| 1347 break;
|
1351# ifdef OPENSSL_HAS_ECC
| 1348# ifdef OPENSSL_HAS_ECC
|
1352 if (sshkey_type_plain(ret->type) == KEY_ECDSA) {
| 1349 case KEY_ECDSA:
|
1353 if (ret->ecdsa != NULL) 1354 EC_KEY_free(ret->ecdsa); 1355 ret->ecdsa = k->ecdsa; 1356 ret->ecdsa_nid = k->ecdsa_nid; 1357 k->ecdsa = NULL; 1358 k->ecdsa_nid = -1; 1359#ifdef DEBUG_PK 1360 sshkey_dump_ec_key(ret->ecdsa); 1361#endif
| 1350 if (ret->ecdsa != NULL) 1351 EC_KEY_free(ret->ecdsa); 1352 ret->ecdsa = k->ecdsa; 1353 ret->ecdsa_nid = k->ecdsa_nid; 1354 k->ecdsa = NULL; 1355 k->ecdsa_nid = -1; 1356#ifdef DEBUG_PK 1357 sshkey_dump_ec_key(ret->ecdsa); 1358#endif
|
1362 }
| 1359 break;
|
1363# endif /* OPENSSL_HAS_ECC */ 1364#endif /* WITH_OPENSSL */
| 1360# endif /* OPENSSL_HAS_ECC */ 1361#endif /* WITH_OPENSSL */
|
1365 if (sshkey_type_plain(ret->type) == KEY_ED25519) {
| 1362 case KEY_ED25519:
|
1366 free(ret->ed25519_pk); 1367 ret->ed25519_pk = k->ed25519_pk; 1368 k->ed25519_pk = NULL; 1369#ifdef DEBUG_PK 1370 /* XXX */ 1371#endif
| 1363 free(ret->ed25519_pk); 1364 ret->ed25519_pk = k->ed25519_pk; 1365 k->ed25519_pk = NULL; 1366#ifdef DEBUG_PK 1367 /* XXX */ 1368#endif
|
| 1369 break;
|
1372 }
| 1370 }
|
| 1371 *cpp = ep;
|
1373 retval = 0; 1374/*XXXX*/ 1375 sshkey_free(k); 1376 if (retval != 0) 1377 break; 1378 break; 1379 default: 1380 return SSH_ERR_INVALID_ARGUMENT; 1381 } 1382 return retval; 1383} 1384 1385int 1386sshkey_to_base64(const struct sshkey *key, char **b64p) 1387{ 1388 int r = SSH_ERR_INTERNAL_ERROR; 1389 struct sshbuf *b = NULL; 1390 char *uu = NULL; 1391 1392 if (b64p != NULL) 1393 *b64p = NULL; 1394 if ((b = sshbuf_new()) == NULL) 1395 return SSH_ERR_ALLOC_FAIL; 1396 if ((r = sshkey_putb(key, b)) != 0) 1397 goto out; 1398 if ((uu = sshbuf_dtob64(b)) == NULL) { 1399 r = SSH_ERR_ALLOC_FAIL; 1400 goto out; 1401 } 1402 /* Success */ 1403 if (b64p != NULL) { 1404 *b64p = uu; 1405 uu = NULL; 1406 } 1407 r = 0; 1408 out: 1409 sshbuf_free(b); 1410 free(uu); 1411 return r; 1412} 1413 1414static int 1415sshkey_format_rsa1(const struct sshkey *key, struct sshbuf *b) 1416{ 1417 int r = SSH_ERR_INTERNAL_ERROR; 1418#ifdef WITH_SSH1 1419 u_int bits = 0; 1420 char *dec_e = NULL, *dec_n = NULL; 1421 1422 if (key->rsa == NULL || key->rsa->e == NULL || 1423 key->rsa->n == NULL) { 1424 r = SSH_ERR_INVALID_ARGUMENT; 1425 goto out; 1426 } 1427 if ((dec_e = BN_bn2dec(key->rsa->e)) == NULL || 1428 (dec_n = BN_bn2dec(key->rsa->n)) == NULL) { 1429 r = SSH_ERR_ALLOC_FAIL; 1430 goto out; 1431 } 1432 /* size of modulus 'n' */ 1433 if ((bits = BN_num_bits(key->rsa->n)) <= 0) { 1434 r = SSH_ERR_INVALID_ARGUMENT; 1435 goto out; 1436 } 1437 if ((r = sshbuf_putf(b, "%u %s %s", bits, dec_e, dec_n)) != 0) 1438 goto out; 1439 1440 /* Success */ 1441 r = 0; 1442 out: 1443 if (dec_e != NULL) 1444 OPENSSL_free(dec_e); 1445 if (dec_n != NULL) 1446 OPENSSL_free(dec_n); 1447#endif /* WITH_SSH1 */ 1448 1449 return r; 1450} 1451 1452static int 1453sshkey_format_text(const struct sshkey *key, struct sshbuf *b) 1454{ 1455 int r = SSH_ERR_INTERNAL_ERROR; 1456 char *uu = NULL; 1457 1458 if (key->type == KEY_RSA1) { 1459 if ((r = sshkey_format_rsa1(key, b)) != 0) 1460 goto out; 1461 } else { 1462 /* Unsupported key types handled in sshkey_to_base64() */ 1463 if ((r = sshkey_to_base64(key, &uu)) != 0) 1464 goto out; 1465 if ((r = sshbuf_putf(b, "%s %s", 1466 sshkey_ssh_name(key), uu)) != 0) 1467 goto out; 1468 } 1469 r = 0; 1470 out: 1471 free(uu); 1472 return r; 1473} 1474 1475int 1476sshkey_write(const struct sshkey *key, FILE *f) 1477{ 1478 struct sshbuf *b = NULL; 1479 int r = SSH_ERR_INTERNAL_ERROR; 1480 1481 if ((b = sshbuf_new()) == NULL) 1482 return SSH_ERR_ALLOC_FAIL; 1483 if ((r = sshkey_format_text(key, b)) != 0) 1484 goto out; 1485 if (fwrite(sshbuf_ptr(b), sshbuf_len(b), 1, f) != 1) { 1486 if (feof(f)) 1487 errno = EPIPE; 1488 r = SSH_ERR_SYSTEM_ERROR; 1489 goto out; 1490 } 1491 /* Success */ 1492 r = 0; 1493 out: 1494 sshbuf_free(b); 1495 return r; 1496} 1497 1498const char * 1499sshkey_cert_type(const struct sshkey *k) 1500{ 1501 switch (k->cert->type) { 1502 case SSH2_CERT_TYPE_USER: 1503 return "user"; 1504 case SSH2_CERT_TYPE_HOST: 1505 return "host"; 1506 default: 1507 return "unknown"; 1508 } 1509} 1510 1511#ifdef WITH_OPENSSL 1512static int 1513rsa_generate_private_key(u_int bits, RSA **rsap) 1514{ 1515 RSA *private = NULL; 1516 BIGNUM *f4 = NULL; 1517 int ret = SSH_ERR_INTERNAL_ERROR; 1518 1519 if (rsap == NULL || 1520 bits < SSH_RSA_MINIMUM_MODULUS_SIZE || 1521 bits > SSHBUF_MAX_BIGNUM * 8) 1522 return SSH_ERR_INVALID_ARGUMENT; 1523 *rsap = NULL; 1524 if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) { 1525 ret = SSH_ERR_ALLOC_FAIL; 1526 goto out; 1527 } 1528 if (!BN_set_word(f4, RSA_F4) || 1529 !RSA_generate_key_ex(private, bits, f4, NULL)) { 1530 ret = SSH_ERR_LIBCRYPTO_ERROR; 1531 goto out; 1532 } 1533 *rsap = private; 1534 private = NULL; 1535 ret = 0; 1536 out: 1537 if (private != NULL) 1538 RSA_free(private); 1539 if (f4 != NULL) 1540 BN_free(f4); 1541 return ret; 1542} 1543 1544static int 1545dsa_generate_private_key(u_int bits, DSA **dsap) 1546{ 1547 DSA *private; 1548 int ret = SSH_ERR_INTERNAL_ERROR; 1549 1550 if (dsap == NULL || bits != 1024) 1551 return SSH_ERR_INVALID_ARGUMENT; 1552 if ((private = DSA_new()) == NULL) { 1553 ret = SSH_ERR_ALLOC_FAIL; 1554 goto out; 1555 } 1556 *dsap = NULL; 1557 if (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL, 1558 NULL, NULL) || !DSA_generate_key(private)) { 1559 ret = SSH_ERR_LIBCRYPTO_ERROR; 1560 goto out; 1561 } 1562 *dsap = private; 1563 private = NULL; 1564 ret = 0; 1565 out: 1566 if (private != NULL) 1567 DSA_free(private); 1568 return ret; 1569} 1570 1571# ifdef OPENSSL_HAS_ECC 1572int 1573sshkey_ecdsa_key_to_nid(EC_KEY *k) 1574{ 1575 EC_GROUP *eg; 1576 int nids[] = { 1577 NID_X9_62_prime256v1, 1578 NID_secp384r1, 1579# ifdef OPENSSL_HAS_NISTP521 1580 NID_secp521r1, 1581# endif /* OPENSSL_HAS_NISTP521 */ 1582 -1 1583 }; 1584 int nid; 1585 u_int i; 1586 BN_CTX *bnctx; 1587 const EC_GROUP *g = EC_KEY_get0_group(k); 1588 1589 /* 1590 * The group may be stored in a ASN.1 encoded private key in one of two 1591 * ways: as a "named group", which is reconstituted by ASN.1 object ID 1592 * or explicit group parameters encoded into the key blob. Only the 1593 * "named group" case sets the group NID for us, but we can figure 1594 * it out for the other case by comparing against all the groups that 1595 * are supported. 1596 */ 1597 if ((nid = EC_GROUP_get_curve_name(g)) > 0) 1598 return nid; 1599 if ((bnctx = BN_CTX_new()) == NULL) 1600 return -1; 1601 for (i = 0; nids[i] != -1; i++) { 1602 if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) { 1603 BN_CTX_free(bnctx); 1604 return -1; 1605 } 1606 if (EC_GROUP_cmp(g, eg, bnctx) == 0) 1607 break; 1608 EC_GROUP_free(eg); 1609 } 1610 BN_CTX_free(bnctx); 1611 if (nids[i] != -1) { 1612 /* Use the group with the NID attached */ 1613 EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE); 1614 if (EC_KEY_set_group(k, eg) != 1) { 1615 EC_GROUP_free(eg); 1616 return -1; 1617 } 1618 } 1619 return nids[i]; 1620} 1621 1622static int 1623ecdsa_generate_private_key(u_int bits, int *nid, EC_KEY **ecdsap) 1624{ 1625 EC_KEY *private; 1626 int ret = SSH_ERR_INTERNAL_ERROR; 1627 1628 if (nid == NULL || ecdsap == NULL || 1629 (*nid = sshkey_ecdsa_bits_to_nid(bits)) == -1) 1630 return SSH_ERR_INVALID_ARGUMENT; 1631 *ecdsap = NULL; 1632 if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) { 1633 ret = SSH_ERR_ALLOC_FAIL; 1634 goto out; 1635 } 1636 if (EC_KEY_generate_key(private) != 1) { 1637 ret = SSH_ERR_LIBCRYPTO_ERROR; 1638 goto out; 1639 } 1640 EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE); 1641 *ecdsap = private; 1642 private = NULL; 1643 ret = 0; 1644 out: 1645 if (private != NULL) 1646 EC_KEY_free(private); 1647 return ret; 1648} 1649# endif /* OPENSSL_HAS_ECC */ 1650#endif /* WITH_OPENSSL */ 1651 1652int 1653sshkey_generate(int type, u_int bits, struct sshkey **keyp) 1654{ 1655 struct sshkey *k; 1656 int ret = SSH_ERR_INTERNAL_ERROR; 1657 1658 if (keyp == NULL) 1659 return SSH_ERR_INVALID_ARGUMENT; 1660 *keyp = NULL; 1661 if ((k = sshkey_new(KEY_UNSPEC)) == NULL) 1662 return SSH_ERR_ALLOC_FAIL; 1663 switch (type) { 1664 case KEY_ED25519: 1665 if ((k->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL || 1666 (k->ed25519_sk = malloc(ED25519_SK_SZ)) == NULL) { 1667 ret = SSH_ERR_ALLOC_FAIL; 1668 break; 1669 } 1670 crypto_sign_ed25519_keypair(k->ed25519_pk, k->ed25519_sk); 1671 ret = 0; 1672 break; 1673#ifdef WITH_OPENSSL 1674 case KEY_DSA: 1675 ret = dsa_generate_private_key(bits, &k->dsa); 1676 break; 1677# ifdef OPENSSL_HAS_ECC 1678 case KEY_ECDSA: 1679 ret = ecdsa_generate_private_key(bits, &k->ecdsa_nid, 1680 &k->ecdsa); 1681 break; 1682# endif /* OPENSSL_HAS_ECC */ 1683 case KEY_RSA: 1684 case KEY_RSA1: 1685 ret = rsa_generate_private_key(bits, &k->rsa); 1686 break; 1687#endif /* WITH_OPENSSL */ 1688 default: 1689 ret = SSH_ERR_INVALID_ARGUMENT; 1690 } 1691 if (ret == 0) { 1692 k->type = type; 1693 *keyp = k; 1694 } else 1695 sshkey_free(k); 1696 return ret; 1697} 1698 1699int 1700sshkey_cert_copy(const struct sshkey *from_key, struct sshkey *to_key) 1701{ 1702 u_int i; 1703 const struct sshkey_cert *from; 1704 struct sshkey_cert *to; 1705 int ret = SSH_ERR_INTERNAL_ERROR; 1706 1707 if (to_key->cert != NULL) { 1708 cert_free(to_key->cert); 1709 to_key->cert = NULL; 1710 } 1711 1712 if ((from = from_key->cert) == NULL) 1713 return SSH_ERR_INVALID_ARGUMENT; 1714 1715 if ((to = to_key->cert = cert_new()) == NULL) 1716 return SSH_ERR_ALLOC_FAIL; 1717 1718 if ((ret = sshbuf_putb(to->certblob, from->certblob)) != 0 || 1719 (ret = sshbuf_putb(to->critical, from->critical)) != 0 ||
| 1372 retval = 0; 1373/*XXXX*/ 1374 sshkey_free(k); 1375 if (retval != 0) 1376 break; 1377 break; 1378 default: 1379 return SSH_ERR_INVALID_ARGUMENT; 1380 } 1381 return retval; 1382} 1383 1384int 1385sshkey_to_base64(const struct sshkey *key, char **b64p) 1386{ 1387 int r = SSH_ERR_INTERNAL_ERROR; 1388 struct sshbuf *b = NULL; 1389 char *uu = NULL; 1390 1391 if (b64p != NULL) 1392 *b64p = NULL; 1393 if ((b = sshbuf_new()) == NULL) 1394 return SSH_ERR_ALLOC_FAIL; 1395 if ((r = sshkey_putb(key, b)) != 0) 1396 goto out; 1397 if ((uu = sshbuf_dtob64(b)) == NULL) { 1398 r = SSH_ERR_ALLOC_FAIL; 1399 goto out; 1400 } 1401 /* Success */ 1402 if (b64p != NULL) { 1403 *b64p = uu; 1404 uu = NULL; 1405 } 1406 r = 0; 1407 out: 1408 sshbuf_free(b); 1409 free(uu); 1410 return r; 1411} 1412 1413static int 1414sshkey_format_rsa1(const struct sshkey *key, struct sshbuf *b) 1415{ 1416 int r = SSH_ERR_INTERNAL_ERROR; 1417#ifdef WITH_SSH1 1418 u_int bits = 0; 1419 char *dec_e = NULL, *dec_n = NULL; 1420 1421 if (key->rsa == NULL || key->rsa->e == NULL || 1422 key->rsa->n == NULL) { 1423 r = SSH_ERR_INVALID_ARGUMENT; 1424 goto out; 1425 } 1426 if ((dec_e = BN_bn2dec(key->rsa->e)) == NULL || 1427 (dec_n = BN_bn2dec(key->rsa->n)) == NULL) { 1428 r = SSH_ERR_ALLOC_FAIL; 1429 goto out; 1430 } 1431 /* size of modulus 'n' */ 1432 if ((bits = BN_num_bits(key->rsa->n)) <= 0) { 1433 r = SSH_ERR_INVALID_ARGUMENT; 1434 goto out; 1435 } 1436 if ((r = sshbuf_putf(b, "%u %s %s", bits, dec_e, dec_n)) != 0) 1437 goto out; 1438 1439 /* Success */ 1440 r = 0; 1441 out: 1442 if (dec_e != NULL) 1443 OPENSSL_free(dec_e); 1444 if (dec_n != NULL) 1445 OPENSSL_free(dec_n); 1446#endif /* WITH_SSH1 */ 1447 1448 return r; 1449} 1450 1451static int 1452sshkey_format_text(const struct sshkey *key, struct sshbuf *b) 1453{ 1454 int r = SSH_ERR_INTERNAL_ERROR; 1455 char *uu = NULL; 1456 1457 if (key->type == KEY_RSA1) { 1458 if ((r = sshkey_format_rsa1(key, b)) != 0) 1459 goto out; 1460 } else { 1461 /* Unsupported key types handled in sshkey_to_base64() */ 1462 if ((r = sshkey_to_base64(key, &uu)) != 0) 1463 goto out; 1464 if ((r = sshbuf_putf(b, "%s %s", 1465 sshkey_ssh_name(key), uu)) != 0) 1466 goto out; 1467 } 1468 r = 0; 1469 out: 1470 free(uu); 1471 return r; 1472} 1473 1474int 1475sshkey_write(const struct sshkey *key, FILE *f) 1476{ 1477 struct sshbuf *b = NULL; 1478 int r = SSH_ERR_INTERNAL_ERROR; 1479 1480 if ((b = sshbuf_new()) == NULL) 1481 return SSH_ERR_ALLOC_FAIL; 1482 if ((r = sshkey_format_text(key, b)) != 0) 1483 goto out; 1484 if (fwrite(sshbuf_ptr(b), sshbuf_len(b), 1, f) != 1) { 1485 if (feof(f)) 1486 errno = EPIPE; 1487 r = SSH_ERR_SYSTEM_ERROR; 1488 goto out; 1489 } 1490 /* Success */ 1491 r = 0; 1492 out: 1493 sshbuf_free(b); 1494 return r; 1495} 1496 1497const char * 1498sshkey_cert_type(const struct sshkey *k) 1499{ 1500 switch (k->cert->type) { 1501 case SSH2_CERT_TYPE_USER: 1502 return "user"; 1503 case SSH2_CERT_TYPE_HOST: 1504 return "host"; 1505 default: 1506 return "unknown"; 1507 } 1508} 1509 1510#ifdef WITH_OPENSSL 1511static int 1512rsa_generate_private_key(u_int bits, RSA **rsap) 1513{ 1514 RSA *private = NULL; 1515 BIGNUM *f4 = NULL; 1516 int ret = SSH_ERR_INTERNAL_ERROR; 1517 1518 if (rsap == NULL || 1519 bits < SSH_RSA_MINIMUM_MODULUS_SIZE || 1520 bits > SSHBUF_MAX_BIGNUM * 8) 1521 return SSH_ERR_INVALID_ARGUMENT; 1522 *rsap = NULL; 1523 if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) { 1524 ret = SSH_ERR_ALLOC_FAIL; 1525 goto out; 1526 } 1527 if (!BN_set_word(f4, RSA_F4) || 1528 !RSA_generate_key_ex(private, bits, f4, NULL)) { 1529 ret = SSH_ERR_LIBCRYPTO_ERROR; 1530 goto out; 1531 } 1532 *rsap = private; 1533 private = NULL; 1534 ret = 0; 1535 out: 1536 if (private != NULL) 1537 RSA_free(private); 1538 if (f4 != NULL) 1539 BN_free(f4); 1540 return ret; 1541} 1542 1543static int 1544dsa_generate_private_key(u_int bits, DSA **dsap) 1545{ 1546 DSA *private; 1547 int ret = SSH_ERR_INTERNAL_ERROR; 1548 1549 if (dsap == NULL || bits != 1024) 1550 return SSH_ERR_INVALID_ARGUMENT; 1551 if ((private = DSA_new()) == NULL) { 1552 ret = SSH_ERR_ALLOC_FAIL; 1553 goto out; 1554 } 1555 *dsap = NULL; 1556 if (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL, 1557 NULL, NULL) || !DSA_generate_key(private)) { 1558 ret = SSH_ERR_LIBCRYPTO_ERROR; 1559 goto out; 1560 } 1561 *dsap = private; 1562 private = NULL; 1563 ret = 0; 1564 out: 1565 if (private != NULL) 1566 DSA_free(private); 1567 return ret; 1568} 1569 1570# ifdef OPENSSL_HAS_ECC 1571int 1572sshkey_ecdsa_key_to_nid(EC_KEY *k) 1573{ 1574 EC_GROUP *eg; 1575 int nids[] = { 1576 NID_X9_62_prime256v1, 1577 NID_secp384r1, 1578# ifdef OPENSSL_HAS_NISTP521 1579 NID_secp521r1, 1580# endif /* OPENSSL_HAS_NISTP521 */ 1581 -1 1582 }; 1583 int nid; 1584 u_int i; 1585 BN_CTX *bnctx; 1586 const EC_GROUP *g = EC_KEY_get0_group(k); 1587 1588 /* 1589 * The group may be stored in a ASN.1 encoded private key in one of two 1590 * ways: as a "named group", which is reconstituted by ASN.1 object ID 1591 * or explicit group parameters encoded into the key blob. Only the 1592 * "named group" case sets the group NID for us, but we can figure 1593 * it out for the other case by comparing against all the groups that 1594 * are supported. 1595 */ 1596 if ((nid = EC_GROUP_get_curve_name(g)) > 0) 1597 return nid; 1598 if ((bnctx = BN_CTX_new()) == NULL) 1599 return -1; 1600 for (i = 0; nids[i] != -1; i++) { 1601 if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) { 1602 BN_CTX_free(bnctx); 1603 return -1; 1604 } 1605 if (EC_GROUP_cmp(g, eg, bnctx) == 0) 1606 break; 1607 EC_GROUP_free(eg); 1608 } 1609 BN_CTX_free(bnctx); 1610 if (nids[i] != -1) { 1611 /* Use the group with the NID attached */ 1612 EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE); 1613 if (EC_KEY_set_group(k, eg) != 1) { 1614 EC_GROUP_free(eg); 1615 return -1; 1616 } 1617 } 1618 return nids[i]; 1619} 1620 1621static int 1622ecdsa_generate_private_key(u_int bits, int *nid, EC_KEY **ecdsap) 1623{ 1624 EC_KEY *private; 1625 int ret = SSH_ERR_INTERNAL_ERROR; 1626 1627 if (nid == NULL || ecdsap == NULL || 1628 (*nid = sshkey_ecdsa_bits_to_nid(bits)) == -1) 1629 return SSH_ERR_INVALID_ARGUMENT; 1630 *ecdsap = NULL; 1631 if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) { 1632 ret = SSH_ERR_ALLOC_FAIL; 1633 goto out; 1634 } 1635 if (EC_KEY_generate_key(private) != 1) { 1636 ret = SSH_ERR_LIBCRYPTO_ERROR; 1637 goto out; 1638 } 1639 EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE); 1640 *ecdsap = private; 1641 private = NULL; 1642 ret = 0; 1643 out: 1644 if (private != NULL) 1645 EC_KEY_free(private); 1646 return ret; 1647} 1648# endif /* OPENSSL_HAS_ECC */ 1649#endif /* WITH_OPENSSL */ 1650 1651int 1652sshkey_generate(int type, u_int bits, struct sshkey **keyp) 1653{ 1654 struct sshkey *k; 1655 int ret = SSH_ERR_INTERNAL_ERROR; 1656 1657 if (keyp == NULL) 1658 return SSH_ERR_INVALID_ARGUMENT; 1659 *keyp = NULL; 1660 if ((k = sshkey_new(KEY_UNSPEC)) == NULL) 1661 return SSH_ERR_ALLOC_FAIL; 1662 switch (type) { 1663 case KEY_ED25519: 1664 if ((k->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL || 1665 (k->ed25519_sk = malloc(ED25519_SK_SZ)) == NULL) { 1666 ret = SSH_ERR_ALLOC_FAIL; 1667 break; 1668 } 1669 crypto_sign_ed25519_keypair(k->ed25519_pk, k->ed25519_sk); 1670 ret = 0; 1671 break; 1672#ifdef WITH_OPENSSL 1673 case KEY_DSA: 1674 ret = dsa_generate_private_key(bits, &k->dsa); 1675 break; 1676# ifdef OPENSSL_HAS_ECC 1677 case KEY_ECDSA: 1678 ret = ecdsa_generate_private_key(bits, &k->ecdsa_nid, 1679 &k->ecdsa); 1680 break; 1681# endif /* OPENSSL_HAS_ECC */ 1682 case KEY_RSA: 1683 case KEY_RSA1: 1684 ret = rsa_generate_private_key(bits, &k->rsa); 1685 break; 1686#endif /* WITH_OPENSSL */ 1687 default: 1688 ret = SSH_ERR_INVALID_ARGUMENT; 1689 } 1690 if (ret == 0) { 1691 k->type = type; 1692 *keyp = k; 1693 } else 1694 sshkey_free(k); 1695 return ret; 1696} 1697 1698int 1699sshkey_cert_copy(const struct sshkey *from_key, struct sshkey *to_key) 1700{ 1701 u_int i; 1702 const struct sshkey_cert *from; 1703 struct sshkey_cert *to; 1704 int ret = SSH_ERR_INTERNAL_ERROR; 1705 1706 if (to_key->cert != NULL) { 1707 cert_free(to_key->cert); 1708 to_key->cert = NULL; 1709 } 1710 1711 if ((from = from_key->cert) == NULL) 1712 return SSH_ERR_INVALID_ARGUMENT; 1713 1714 if ((to = to_key->cert = cert_new()) == NULL) 1715 return SSH_ERR_ALLOC_FAIL; 1716 1717 if ((ret = sshbuf_putb(to->certblob, from->certblob)) != 0 || 1718 (ret = sshbuf_putb(to->critical, from->critical)) != 0 ||
|
1720 (ret = sshbuf_putb(to->extensions, from->extensions) != 0))
| 1719 (ret = sshbuf_putb(to->extensions, from->extensions)) != 0)
|
1721 return ret; 1722 1723 to->serial = from->serial; 1724 to->type = from->type; 1725 if (from->key_id == NULL) 1726 to->key_id = NULL; 1727 else if ((to->key_id = strdup(from->key_id)) == NULL) 1728 return SSH_ERR_ALLOC_FAIL; 1729 to->valid_after = from->valid_after; 1730 to->valid_before = from->valid_before; 1731 if (from->signature_key == NULL) 1732 to->signature_key = NULL; 1733 else if ((ret = sshkey_from_private(from->signature_key, 1734 &to->signature_key)) != 0) 1735 return ret; 1736 1737 if (from->nprincipals > SSHKEY_CERT_MAX_PRINCIPALS) 1738 return SSH_ERR_INVALID_ARGUMENT; 1739 if (from->nprincipals > 0) { 1740 if ((to->principals = calloc(from->nprincipals, 1741 sizeof(*to->principals))) == NULL) 1742 return SSH_ERR_ALLOC_FAIL; 1743 for (i = 0; i < from->nprincipals; i++) { 1744 to->principals[i] = strdup(from->principals[i]); 1745 if (to->principals[i] == NULL) { 1746 to->nprincipals = i; 1747 return SSH_ERR_ALLOC_FAIL; 1748 } 1749 } 1750 } 1751 to->nprincipals = from->nprincipals; 1752 return 0; 1753} 1754 1755int 1756sshkey_from_private(const struct sshkey *k, struct sshkey **pkp) 1757{ 1758 struct sshkey *n = NULL; 1759 int ret = SSH_ERR_INTERNAL_ERROR; 1760
| 1720 return ret; 1721 1722 to->serial = from->serial; 1723 to->type = from->type; 1724 if (from->key_id == NULL) 1725 to->key_id = NULL; 1726 else if ((to->key_id = strdup(from->key_id)) == NULL) 1727 return SSH_ERR_ALLOC_FAIL; 1728 to->valid_after = from->valid_after; 1729 to->valid_before = from->valid_before; 1730 if (from->signature_key == NULL) 1731 to->signature_key = NULL; 1732 else if ((ret = sshkey_from_private(from->signature_key, 1733 &to->signature_key)) != 0) 1734 return ret; 1735 1736 if (from->nprincipals > SSHKEY_CERT_MAX_PRINCIPALS) 1737 return SSH_ERR_INVALID_ARGUMENT; 1738 if (from->nprincipals > 0) { 1739 if ((to->principals = calloc(from->nprincipals, 1740 sizeof(*to->principals))) == NULL) 1741 return SSH_ERR_ALLOC_FAIL; 1742 for (i = 0; i < from->nprincipals; i++) { 1743 to->principals[i] = strdup(from->principals[i]); 1744 if (to->principals[i] == NULL) { 1745 to->nprincipals = i; 1746 return SSH_ERR_ALLOC_FAIL; 1747 } 1748 } 1749 } 1750 to->nprincipals = from->nprincipals; 1751 return 0; 1752} 1753 1754int 1755sshkey_from_private(const struct sshkey *k, struct sshkey **pkp) 1756{ 1757 struct sshkey *n = NULL; 1758 int ret = SSH_ERR_INTERNAL_ERROR; 1759
|
1761 if (pkp != NULL) 1762 *pkp = NULL; 1763
| 1760 *pkp = NULL;
|
1764 switch (k->type) { 1765#ifdef WITH_OPENSSL 1766 case KEY_DSA: 1767 case KEY_DSA_CERT: 1768 if ((n = sshkey_new(k->type)) == NULL) 1769 return SSH_ERR_ALLOC_FAIL; 1770 if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) || 1771 (BN_copy(n->dsa->q, k->dsa->q) == NULL) || 1772 (BN_copy(n->dsa->g, k->dsa->g) == NULL) || 1773 (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL)) { 1774 sshkey_free(n); 1775 return SSH_ERR_ALLOC_FAIL; 1776 } 1777 break; 1778# ifdef OPENSSL_HAS_ECC 1779 case KEY_ECDSA: 1780 case KEY_ECDSA_CERT: 1781 if ((n = sshkey_new(k->type)) == NULL) 1782 return SSH_ERR_ALLOC_FAIL; 1783 n->ecdsa_nid = k->ecdsa_nid; 1784 n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); 1785 if (n->ecdsa == NULL) { 1786 sshkey_free(n); 1787 return SSH_ERR_ALLOC_FAIL; 1788 } 1789 if (EC_KEY_set_public_key(n->ecdsa, 1790 EC_KEY_get0_public_key(k->ecdsa)) != 1) { 1791 sshkey_free(n); 1792 return SSH_ERR_LIBCRYPTO_ERROR; 1793 } 1794 break; 1795# endif /* OPENSSL_HAS_ECC */ 1796 case KEY_RSA: 1797 case KEY_RSA1: 1798 case KEY_RSA_CERT: 1799 if ((n = sshkey_new(k->type)) == NULL) 1800 return SSH_ERR_ALLOC_FAIL; 1801 if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) || 1802 (BN_copy(n->rsa->e, k->rsa->e) == NULL)) { 1803 sshkey_free(n); 1804 return SSH_ERR_ALLOC_FAIL; 1805 } 1806 break; 1807#endif /* WITH_OPENSSL */ 1808 case KEY_ED25519: 1809 case KEY_ED25519_CERT: 1810 if ((n = sshkey_new(k->type)) == NULL) 1811 return SSH_ERR_ALLOC_FAIL; 1812 if (k->ed25519_pk != NULL) { 1813 if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) { 1814 sshkey_free(n); 1815 return SSH_ERR_ALLOC_FAIL; 1816 } 1817 memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ); 1818 } 1819 break; 1820 default: 1821 return SSH_ERR_KEY_TYPE_UNKNOWN; 1822 } 1823 if (sshkey_is_cert(k)) { 1824 if ((ret = sshkey_cert_copy(k, n)) != 0) { 1825 sshkey_free(n); 1826 return ret; 1827 } 1828 } 1829 *pkp = n; 1830 return 0; 1831} 1832 1833static int 1834cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf) 1835{ 1836 struct sshbuf *principals = NULL, *crit = NULL; 1837 struct sshbuf *exts = NULL, *ca = NULL; 1838 u_char *sig = NULL; 1839 size_t signed_len = 0, slen = 0, kidlen = 0; 1840 int ret = SSH_ERR_INTERNAL_ERROR; 1841 1842 /* Copy the entire key blob for verification and later serialisation */ 1843 if ((ret = sshbuf_putb(key->cert->certblob, certbuf)) != 0) 1844 return ret; 1845 1846 /* Parse body of certificate up to signature */ 1847 if ((ret = sshbuf_get_u64(b, &key->cert->serial)) != 0 || 1848 (ret = sshbuf_get_u32(b, &key->cert->type)) != 0 || 1849 (ret = sshbuf_get_cstring(b, &key->cert->key_id, &kidlen)) != 0 || 1850 (ret = sshbuf_froms(b, &principals)) != 0 || 1851 (ret = sshbuf_get_u64(b, &key->cert->valid_after)) != 0 || 1852 (ret = sshbuf_get_u64(b, &key->cert->valid_before)) != 0 || 1853 (ret = sshbuf_froms(b, &crit)) != 0 || 1854 (ret = sshbuf_froms(b, &exts)) != 0 || 1855 (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0 || 1856 (ret = sshbuf_froms(b, &ca)) != 0) { 1857 /* XXX debug print error for ret */ 1858 ret = SSH_ERR_INVALID_FORMAT; 1859 goto out; 1860 } 1861 1862 /* Signature is left in the buffer so we can calculate this length */ 1863 signed_len = sshbuf_len(key->cert->certblob) - sshbuf_len(b); 1864 1865 if ((ret = sshbuf_get_string(b, &sig, &slen)) != 0) { 1866 ret = SSH_ERR_INVALID_FORMAT; 1867 goto out; 1868 } 1869 1870 if (key->cert->type != SSH2_CERT_TYPE_USER && 1871 key->cert->type != SSH2_CERT_TYPE_HOST) { 1872 ret = SSH_ERR_KEY_CERT_UNKNOWN_TYPE; 1873 goto out; 1874 } 1875 1876 /* Parse principals section */ 1877 while (sshbuf_len(principals) > 0) { 1878 char *principal = NULL; 1879 char **oprincipals = NULL; 1880 1881 if (key->cert->nprincipals >= SSHKEY_CERT_MAX_PRINCIPALS) { 1882 ret = SSH_ERR_INVALID_FORMAT; 1883 goto out; 1884 } 1885 if ((ret = sshbuf_get_cstring(principals, &principal, 1886 NULL)) != 0) { 1887 ret = SSH_ERR_INVALID_FORMAT; 1888 goto out; 1889 } 1890 oprincipals = key->cert->principals; 1891 key->cert->principals = reallocarray(key->cert->principals, 1892 key->cert->nprincipals + 1, sizeof(*key->cert->principals)); 1893 if (key->cert->principals == NULL) { 1894 free(principal); 1895 key->cert->principals = oprincipals; 1896 ret = SSH_ERR_ALLOC_FAIL; 1897 goto out; 1898 } 1899 key->cert->principals[key->cert->nprincipals++] = principal; 1900 } 1901 1902 /* 1903 * Stash a copies of the critical options and extensions sections 1904 * for later use. 1905 */ 1906 if ((ret = sshbuf_putb(key->cert->critical, crit)) != 0 || 1907 (exts != NULL && 1908 (ret = sshbuf_putb(key->cert->extensions, exts)) != 0)) 1909 goto out; 1910 1911 /* 1912 * Validate critical options and extensions sections format. 1913 */ 1914 while (sshbuf_len(crit) != 0) { 1915 if ((ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0 || 1916 (ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0) { 1917 sshbuf_reset(key->cert->critical); 1918 ret = SSH_ERR_INVALID_FORMAT; 1919 goto out; 1920 } 1921 } 1922 while (exts != NULL && sshbuf_len(exts) != 0) { 1923 if ((ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0 || 1924 (ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0) { 1925 sshbuf_reset(key->cert->extensions); 1926 ret = SSH_ERR_INVALID_FORMAT; 1927 goto out; 1928 } 1929 } 1930 1931 /* Parse CA key and check signature */ 1932 if (sshkey_from_blob_internal(ca, &key->cert->signature_key, 0) != 0) { 1933 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; 1934 goto out; 1935 } 1936 if (!sshkey_type_is_valid_ca(key->cert->signature_key->type)) { 1937 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; 1938 goto out; 1939 } 1940 if ((ret = sshkey_verify(key->cert->signature_key, sig, slen, 1941 sshbuf_ptr(key->cert->certblob), signed_len, 0)) != 0) 1942 goto out; 1943 1944 /* Success */ 1945 ret = 0; 1946 out: 1947 sshbuf_free(ca); 1948 sshbuf_free(crit); 1949 sshbuf_free(exts); 1950 sshbuf_free(principals); 1951 free(sig); 1952 return ret; 1953} 1954 1955static int 1956sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, 1957 int allow_cert) 1958{ 1959 int type, ret = SSH_ERR_INTERNAL_ERROR; 1960 char *ktype = NULL, *curve = NULL; 1961 struct sshkey *key = NULL; 1962 size_t len; 1963 u_char *pk = NULL; 1964 struct sshbuf *copy; 1965#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) 1966 EC_POINT *q = NULL; 1967#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ 1968 1969#ifdef DEBUG_PK /* XXX */ 1970 sshbuf_dump(b, stderr); 1971#endif 1972 *keyp = NULL; 1973 if ((copy = sshbuf_fromb(b)) == NULL) { 1974 ret = SSH_ERR_ALLOC_FAIL; 1975 goto out; 1976 } 1977 if (sshbuf_get_cstring(b, &ktype, NULL) != 0) { 1978 ret = SSH_ERR_INVALID_FORMAT; 1979 goto out; 1980 } 1981 1982 type = sshkey_type_from_name(ktype); 1983 if (!allow_cert && sshkey_type_is_cert(type)) { 1984 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; 1985 goto out; 1986 } 1987 switch (type) { 1988#ifdef WITH_OPENSSL 1989 case KEY_RSA_CERT: 1990 /* Skip nonce */ 1991 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { 1992 ret = SSH_ERR_INVALID_FORMAT; 1993 goto out; 1994 } 1995 /* FALLTHROUGH */ 1996 case KEY_RSA: 1997 if ((key = sshkey_new(type)) == NULL) { 1998 ret = SSH_ERR_ALLOC_FAIL; 1999 goto out; 2000 } 2001 if (sshbuf_get_bignum2(b, key->rsa->e) != 0 || 2002 sshbuf_get_bignum2(b, key->rsa->n) != 0) { 2003 ret = SSH_ERR_INVALID_FORMAT; 2004 goto out; 2005 } 2006#ifdef DEBUG_PK 2007 RSA_print_fp(stderr, key->rsa, 8); 2008#endif 2009 break; 2010 case KEY_DSA_CERT: 2011 /* Skip nonce */ 2012 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { 2013 ret = SSH_ERR_INVALID_FORMAT; 2014 goto out; 2015 } 2016 /* FALLTHROUGH */ 2017 case KEY_DSA: 2018 if ((key = sshkey_new(type)) == NULL) { 2019 ret = SSH_ERR_ALLOC_FAIL; 2020 goto out; 2021 } 2022 if (sshbuf_get_bignum2(b, key->dsa->p) != 0 || 2023 sshbuf_get_bignum2(b, key->dsa->q) != 0 || 2024 sshbuf_get_bignum2(b, key->dsa->g) != 0 || 2025 sshbuf_get_bignum2(b, key->dsa->pub_key) != 0) { 2026 ret = SSH_ERR_INVALID_FORMAT; 2027 goto out; 2028 } 2029#ifdef DEBUG_PK 2030 DSA_print_fp(stderr, key->dsa, 8); 2031#endif 2032 break; 2033 case KEY_ECDSA_CERT: 2034 /* Skip nonce */ 2035 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { 2036 ret = SSH_ERR_INVALID_FORMAT; 2037 goto out; 2038 } 2039 /* FALLTHROUGH */ 2040# ifdef OPENSSL_HAS_ECC 2041 case KEY_ECDSA: 2042 if ((key = sshkey_new(type)) == NULL) { 2043 ret = SSH_ERR_ALLOC_FAIL; 2044 goto out; 2045 } 2046 key->ecdsa_nid = sshkey_ecdsa_nid_from_name(ktype); 2047 if (sshbuf_get_cstring(b, &curve, NULL) != 0) { 2048 ret = SSH_ERR_INVALID_FORMAT; 2049 goto out; 2050 } 2051 if (key->ecdsa_nid != sshkey_curve_name_to_nid(curve)) { 2052 ret = SSH_ERR_EC_CURVE_MISMATCH; 2053 goto out; 2054 } 2055 if (key->ecdsa != NULL) 2056 EC_KEY_free(key->ecdsa); 2057 if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) 2058 == NULL) { 2059 ret = SSH_ERR_EC_CURVE_INVALID; 2060 goto out; 2061 } 2062 if ((q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL) { 2063 ret = SSH_ERR_ALLOC_FAIL; 2064 goto out; 2065 } 2066 if (sshbuf_get_ec(b, q, EC_KEY_get0_group(key->ecdsa)) != 0) { 2067 ret = SSH_ERR_INVALID_FORMAT; 2068 goto out; 2069 } 2070 if (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa), 2071 q) != 0) { 2072 ret = SSH_ERR_KEY_INVALID_EC_VALUE; 2073 goto out; 2074 } 2075 if (EC_KEY_set_public_key(key->ecdsa, q) != 1) { 2076 /* XXX assume it is a allocation error */ 2077 ret = SSH_ERR_ALLOC_FAIL; 2078 goto out; 2079 } 2080#ifdef DEBUG_PK 2081 sshkey_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q); 2082#endif 2083 break; 2084# endif /* OPENSSL_HAS_ECC */ 2085#endif /* WITH_OPENSSL */ 2086 case KEY_ED25519_CERT: 2087 /* Skip nonce */ 2088 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { 2089 ret = SSH_ERR_INVALID_FORMAT; 2090 goto out; 2091 } 2092 /* FALLTHROUGH */ 2093 case KEY_ED25519: 2094 if ((ret = sshbuf_get_string(b, &pk, &len)) != 0) 2095 goto out; 2096 if (len != ED25519_PK_SZ) { 2097 ret = SSH_ERR_INVALID_FORMAT; 2098 goto out; 2099 } 2100 if ((key = sshkey_new(type)) == NULL) { 2101 ret = SSH_ERR_ALLOC_FAIL; 2102 goto out; 2103 } 2104 key->ed25519_pk = pk; 2105 pk = NULL; 2106 break; 2107 case KEY_UNSPEC: 2108 if ((key = sshkey_new(type)) == NULL) { 2109 ret = SSH_ERR_ALLOC_FAIL; 2110 goto out; 2111 } 2112 break; 2113 default: 2114 ret = SSH_ERR_KEY_TYPE_UNKNOWN; 2115 goto out; 2116 } 2117 2118 /* Parse certificate potion */ 2119 if (sshkey_is_cert(key) && (ret = cert_parse(b, key, copy)) != 0) 2120 goto out; 2121 2122 if (key != NULL && sshbuf_len(b) != 0) { 2123 ret = SSH_ERR_INVALID_FORMAT; 2124 goto out; 2125 } 2126 ret = 0; 2127 *keyp = key; 2128 key = NULL; 2129 out: 2130 sshbuf_free(copy); 2131 sshkey_free(key); 2132 free(ktype); 2133 free(curve); 2134 free(pk); 2135#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) 2136 if (q != NULL) 2137 EC_POINT_free(q); 2138#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ 2139 return ret; 2140} 2141 2142int 2143sshkey_from_blob(const u_char *blob, size_t blen, struct sshkey **keyp) 2144{ 2145 struct sshbuf *b; 2146 int r; 2147 2148 if ((b = sshbuf_from(blob, blen)) == NULL) 2149 return SSH_ERR_ALLOC_FAIL; 2150 r = sshkey_from_blob_internal(b, keyp, 1); 2151 sshbuf_free(b); 2152 return r; 2153} 2154 2155int 2156sshkey_fromb(struct sshbuf *b, struct sshkey **keyp) 2157{ 2158 return sshkey_from_blob_internal(b, keyp, 1); 2159} 2160 2161int 2162sshkey_froms(struct sshbuf *buf, struct sshkey **keyp) 2163{ 2164 struct sshbuf *b; 2165 int r; 2166 2167 if ((r = sshbuf_froms(buf, &b)) != 0) 2168 return r; 2169 r = sshkey_from_blob_internal(b, keyp, 1); 2170 sshbuf_free(b); 2171 return r; 2172} 2173 2174int 2175sshkey_sign(const struct sshkey *key, 2176 u_char **sigp, size_t *lenp,
| 1761 switch (k->type) { 1762#ifdef WITH_OPENSSL 1763 case KEY_DSA: 1764 case KEY_DSA_CERT: 1765 if ((n = sshkey_new(k->type)) == NULL) 1766 return SSH_ERR_ALLOC_FAIL; 1767 if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) || 1768 (BN_copy(n->dsa->q, k->dsa->q) == NULL) || 1769 (BN_copy(n->dsa->g, k->dsa->g) == NULL) || 1770 (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL)) { 1771 sshkey_free(n); 1772 return SSH_ERR_ALLOC_FAIL; 1773 } 1774 break; 1775# ifdef OPENSSL_HAS_ECC 1776 case KEY_ECDSA: 1777 case KEY_ECDSA_CERT: 1778 if ((n = sshkey_new(k->type)) == NULL) 1779 return SSH_ERR_ALLOC_FAIL; 1780 n->ecdsa_nid = k->ecdsa_nid; 1781 n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); 1782 if (n->ecdsa == NULL) { 1783 sshkey_free(n); 1784 return SSH_ERR_ALLOC_FAIL; 1785 } 1786 if (EC_KEY_set_public_key(n->ecdsa, 1787 EC_KEY_get0_public_key(k->ecdsa)) != 1) { 1788 sshkey_free(n); 1789 return SSH_ERR_LIBCRYPTO_ERROR; 1790 } 1791 break; 1792# endif /* OPENSSL_HAS_ECC */ 1793 case KEY_RSA: 1794 case KEY_RSA1: 1795 case KEY_RSA_CERT: 1796 if ((n = sshkey_new(k->type)) == NULL) 1797 return SSH_ERR_ALLOC_FAIL; 1798 if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) || 1799 (BN_copy(n->rsa->e, k->rsa->e) == NULL)) { 1800 sshkey_free(n); 1801 return SSH_ERR_ALLOC_FAIL; 1802 } 1803 break; 1804#endif /* WITH_OPENSSL */ 1805 case KEY_ED25519: 1806 case KEY_ED25519_CERT: 1807 if ((n = sshkey_new(k->type)) == NULL) 1808 return SSH_ERR_ALLOC_FAIL; 1809 if (k->ed25519_pk != NULL) { 1810 if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) { 1811 sshkey_free(n); 1812 return SSH_ERR_ALLOC_FAIL; 1813 } 1814 memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ); 1815 } 1816 break; 1817 default: 1818 return SSH_ERR_KEY_TYPE_UNKNOWN; 1819 } 1820 if (sshkey_is_cert(k)) { 1821 if ((ret = sshkey_cert_copy(k, n)) != 0) { 1822 sshkey_free(n); 1823 return ret; 1824 } 1825 } 1826 *pkp = n; 1827 return 0; 1828} 1829 1830static int 1831cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf) 1832{ 1833 struct sshbuf *principals = NULL, *crit = NULL; 1834 struct sshbuf *exts = NULL, *ca = NULL; 1835 u_char *sig = NULL; 1836 size_t signed_len = 0, slen = 0, kidlen = 0; 1837 int ret = SSH_ERR_INTERNAL_ERROR; 1838 1839 /* Copy the entire key blob for verification and later serialisation */ 1840 if ((ret = sshbuf_putb(key->cert->certblob, certbuf)) != 0) 1841 return ret; 1842 1843 /* Parse body of certificate up to signature */ 1844 if ((ret = sshbuf_get_u64(b, &key->cert->serial)) != 0 || 1845 (ret = sshbuf_get_u32(b, &key->cert->type)) != 0 || 1846 (ret = sshbuf_get_cstring(b, &key->cert->key_id, &kidlen)) != 0 || 1847 (ret = sshbuf_froms(b, &principals)) != 0 || 1848 (ret = sshbuf_get_u64(b, &key->cert->valid_after)) != 0 || 1849 (ret = sshbuf_get_u64(b, &key->cert->valid_before)) != 0 || 1850 (ret = sshbuf_froms(b, &crit)) != 0 || 1851 (ret = sshbuf_froms(b, &exts)) != 0 || 1852 (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0 || 1853 (ret = sshbuf_froms(b, &ca)) != 0) { 1854 /* XXX debug print error for ret */ 1855 ret = SSH_ERR_INVALID_FORMAT; 1856 goto out; 1857 } 1858 1859 /* Signature is left in the buffer so we can calculate this length */ 1860 signed_len = sshbuf_len(key->cert->certblob) - sshbuf_len(b); 1861 1862 if ((ret = sshbuf_get_string(b, &sig, &slen)) != 0) { 1863 ret = SSH_ERR_INVALID_FORMAT; 1864 goto out; 1865 } 1866 1867 if (key->cert->type != SSH2_CERT_TYPE_USER && 1868 key->cert->type != SSH2_CERT_TYPE_HOST) { 1869 ret = SSH_ERR_KEY_CERT_UNKNOWN_TYPE; 1870 goto out; 1871 } 1872 1873 /* Parse principals section */ 1874 while (sshbuf_len(principals) > 0) { 1875 char *principal = NULL; 1876 char **oprincipals = NULL; 1877 1878 if (key->cert->nprincipals >= SSHKEY_CERT_MAX_PRINCIPALS) { 1879 ret = SSH_ERR_INVALID_FORMAT; 1880 goto out; 1881 } 1882 if ((ret = sshbuf_get_cstring(principals, &principal, 1883 NULL)) != 0) { 1884 ret = SSH_ERR_INVALID_FORMAT; 1885 goto out; 1886 } 1887 oprincipals = key->cert->principals; 1888 key->cert->principals = reallocarray(key->cert->principals, 1889 key->cert->nprincipals + 1, sizeof(*key->cert->principals)); 1890 if (key->cert->principals == NULL) { 1891 free(principal); 1892 key->cert->principals = oprincipals; 1893 ret = SSH_ERR_ALLOC_FAIL; 1894 goto out; 1895 } 1896 key->cert->principals[key->cert->nprincipals++] = principal; 1897 } 1898 1899 /* 1900 * Stash a copies of the critical options and extensions sections 1901 * for later use. 1902 */ 1903 if ((ret = sshbuf_putb(key->cert->critical, crit)) != 0 || 1904 (exts != NULL && 1905 (ret = sshbuf_putb(key->cert->extensions, exts)) != 0)) 1906 goto out; 1907 1908 /* 1909 * Validate critical options and extensions sections format. 1910 */ 1911 while (sshbuf_len(crit) != 0) { 1912 if ((ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0 || 1913 (ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0) { 1914 sshbuf_reset(key->cert->critical); 1915 ret = SSH_ERR_INVALID_FORMAT; 1916 goto out; 1917 } 1918 } 1919 while (exts != NULL && sshbuf_len(exts) != 0) { 1920 if ((ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0 || 1921 (ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0) { 1922 sshbuf_reset(key->cert->extensions); 1923 ret = SSH_ERR_INVALID_FORMAT; 1924 goto out; 1925 } 1926 } 1927 1928 /* Parse CA key and check signature */ 1929 if (sshkey_from_blob_internal(ca, &key->cert->signature_key, 0) != 0) { 1930 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; 1931 goto out; 1932 } 1933 if (!sshkey_type_is_valid_ca(key->cert->signature_key->type)) { 1934 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; 1935 goto out; 1936 } 1937 if ((ret = sshkey_verify(key->cert->signature_key, sig, slen, 1938 sshbuf_ptr(key->cert->certblob), signed_len, 0)) != 0) 1939 goto out; 1940 1941 /* Success */ 1942 ret = 0; 1943 out: 1944 sshbuf_free(ca); 1945 sshbuf_free(crit); 1946 sshbuf_free(exts); 1947 sshbuf_free(principals); 1948 free(sig); 1949 return ret; 1950} 1951 1952static int 1953sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, 1954 int allow_cert) 1955{ 1956 int type, ret = SSH_ERR_INTERNAL_ERROR; 1957 char *ktype = NULL, *curve = NULL; 1958 struct sshkey *key = NULL; 1959 size_t len; 1960 u_char *pk = NULL; 1961 struct sshbuf *copy; 1962#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) 1963 EC_POINT *q = NULL; 1964#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ 1965 1966#ifdef DEBUG_PK /* XXX */ 1967 sshbuf_dump(b, stderr); 1968#endif 1969 *keyp = NULL; 1970 if ((copy = sshbuf_fromb(b)) == NULL) { 1971 ret = SSH_ERR_ALLOC_FAIL; 1972 goto out; 1973 } 1974 if (sshbuf_get_cstring(b, &ktype, NULL) != 0) { 1975 ret = SSH_ERR_INVALID_FORMAT; 1976 goto out; 1977 } 1978 1979 type = sshkey_type_from_name(ktype); 1980 if (!allow_cert && sshkey_type_is_cert(type)) { 1981 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; 1982 goto out; 1983 } 1984 switch (type) { 1985#ifdef WITH_OPENSSL 1986 case KEY_RSA_CERT: 1987 /* Skip nonce */ 1988 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { 1989 ret = SSH_ERR_INVALID_FORMAT; 1990 goto out; 1991 } 1992 /* FALLTHROUGH */ 1993 case KEY_RSA: 1994 if ((key = sshkey_new(type)) == NULL) { 1995 ret = SSH_ERR_ALLOC_FAIL; 1996 goto out; 1997 } 1998 if (sshbuf_get_bignum2(b, key->rsa->e) != 0 || 1999 sshbuf_get_bignum2(b, key->rsa->n) != 0) { 2000 ret = SSH_ERR_INVALID_FORMAT; 2001 goto out; 2002 } 2003#ifdef DEBUG_PK 2004 RSA_print_fp(stderr, key->rsa, 8); 2005#endif 2006 break; 2007 case KEY_DSA_CERT: 2008 /* Skip nonce */ 2009 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { 2010 ret = SSH_ERR_INVALID_FORMAT; 2011 goto out; 2012 } 2013 /* FALLTHROUGH */ 2014 case KEY_DSA: 2015 if ((key = sshkey_new(type)) == NULL) { 2016 ret = SSH_ERR_ALLOC_FAIL; 2017 goto out; 2018 } 2019 if (sshbuf_get_bignum2(b, key->dsa->p) != 0 || 2020 sshbuf_get_bignum2(b, key->dsa->q) != 0 || 2021 sshbuf_get_bignum2(b, key->dsa->g) != 0 || 2022 sshbuf_get_bignum2(b, key->dsa->pub_key) != 0) { 2023 ret = SSH_ERR_INVALID_FORMAT; 2024 goto out; 2025 } 2026#ifdef DEBUG_PK 2027 DSA_print_fp(stderr, key->dsa, 8); 2028#endif 2029 break; 2030 case KEY_ECDSA_CERT: 2031 /* Skip nonce */ 2032 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { 2033 ret = SSH_ERR_INVALID_FORMAT; 2034 goto out; 2035 } 2036 /* FALLTHROUGH */ 2037# ifdef OPENSSL_HAS_ECC 2038 case KEY_ECDSA: 2039 if ((key = sshkey_new(type)) == NULL) { 2040 ret = SSH_ERR_ALLOC_FAIL; 2041 goto out; 2042 } 2043 key->ecdsa_nid = sshkey_ecdsa_nid_from_name(ktype); 2044 if (sshbuf_get_cstring(b, &curve, NULL) != 0) { 2045 ret = SSH_ERR_INVALID_FORMAT; 2046 goto out; 2047 } 2048 if (key->ecdsa_nid != sshkey_curve_name_to_nid(curve)) { 2049 ret = SSH_ERR_EC_CURVE_MISMATCH; 2050 goto out; 2051 } 2052 if (key->ecdsa != NULL) 2053 EC_KEY_free(key->ecdsa); 2054 if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) 2055 == NULL) { 2056 ret = SSH_ERR_EC_CURVE_INVALID; 2057 goto out; 2058 } 2059 if ((q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL) { 2060 ret = SSH_ERR_ALLOC_FAIL; 2061 goto out; 2062 } 2063 if (sshbuf_get_ec(b, q, EC_KEY_get0_group(key->ecdsa)) != 0) { 2064 ret = SSH_ERR_INVALID_FORMAT; 2065 goto out; 2066 } 2067 if (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa), 2068 q) != 0) { 2069 ret = SSH_ERR_KEY_INVALID_EC_VALUE; 2070 goto out; 2071 } 2072 if (EC_KEY_set_public_key(key->ecdsa, q) != 1) { 2073 /* XXX assume it is a allocation error */ 2074 ret = SSH_ERR_ALLOC_FAIL; 2075 goto out; 2076 } 2077#ifdef DEBUG_PK 2078 sshkey_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q); 2079#endif 2080 break; 2081# endif /* OPENSSL_HAS_ECC */ 2082#endif /* WITH_OPENSSL */ 2083 case KEY_ED25519_CERT: 2084 /* Skip nonce */ 2085 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { 2086 ret = SSH_ERR_INVALID_FORMAT; 2087 goto out; 2088 } 2089 /* FALLTHROUGH */ 2090 case KEY_ED25519: 2091 if ((ret = sshbuf_get_string(b, &pk, &len)) != 0) 2092 goto out; 2093 if (len != ED25519_PK_SZ) { 2094 ret = SSH_ERR_INVALID_FORMAT; 2095 goto out; 2096 } 2097 if ((key = sshkey_new(type)) == NULL) { 2098 ret = SSH_ERR_ALLOC_FAIL; 2099 goto out; 2100 } 2101 key->ed25519_pk = pk; 2102 pk = NULL; 2103 break; 2104 case KEY_UNSPEC: 2105 if ((key = sshkey_new(type)) == NULL) { 2106 ret = SSH_ERR_ALLOC_FAIL; 2107 goto out; 2108 } 2109 break; 2110 default: 2111 ret = SSH_ERR_KEY_TYPE_UNKNOWN; 2112 goto out; 2113 } 2114 2115 /* Parse certificate potion */ 2116 if (sshkey_is_cert(key) && (ret = cert_parse(b, key, copy)) != 0) 2117 goto out; 2118 2119 if (key != NULL && sshbuf_len(b) != 0) { 2120 ret = SSH_ERR_INVALID_FORMAT; 2121 goto out; 2122 } 2123 ret = 0; 2124 *keyp = key; 2125 key = NULL; 2126 out: 2127 sshbuf_free(copy); 2128 sshkey_free(key); 2129 free(ktype); 2130 free(curve); 2131 free(pk); 2132#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) 2133 if (q != NULL) 2134 EC_POINT_free(q); 2135#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ 2136 return ret; 2137} 2138 2139int 2140sshkey_from_blob(const u_char *blob, size_t blen, struct sshkey **keyp) 2141{ 2142 struct sshbuf *b; 2143 int r; 2144 2145 if ((b = sshbuf_from(blob, blen)) == NULL) 2146 return SSH_ERR_ALLOC_FAIL; 2147 r = sshkey_from_blob_internal(b, keyp, 1); 2148 sshbuf_free(b); 2149 return r; 2150} 2151 2152int 2153sshkey_fromb(struct sshbuf *b, struct sshkey **keyp) 2154{ 2155 return sshkey_from_blob_internal(b, keyp, 1); 2156} 2157 2158int 2159sshkey_froms(struct sshbuf *buf, struct sshkey **keyp) 2160{ 2161 struct sshbuf *b; 2162 int r; 2163 2164 if ((r = sshbuf_froms(buf, &b)) != 0) 2165 return r; 2166 r = sshkey_from_blob_internal(b, keyp, 1); 2167 sshbuf_free(b); 2168 return r; 2169} 2170 2171int 2172sshkey_sign(const struct sshkey *key, 2173 u_char **sigp, size_t *lenp,
|
2177 const u_char *data, size_t datalen, u_int compat)
| 2174 const u_char *data, size_t datalen, const char *alg, u_int compat)
|
2178{ 2179 if (sigp != NULL) 2180 *sigp = NULL; 2181 if (lenp != NULL) 2182 *lenp = 0; 2183 if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE) 2184 return SSH_ERR_INVALID_ARGUMENT; 2185 switch (key->type) { 2186#ifdef WITH_OPENSSL 2187 case KEY_DSA_CERT: 2188 case KEY_DSA: 2189 return ssh_dss_sign(key, sigp, lenp, data, datalen, compat); 2190# ifdef OPENSSL_HAS_ECC 2191 case KEY_ECDSA_CERT: 2192 case KEY_ECDSA: 2193 return ssh_ecdsa_sign(key, sigp, lenp, data, datalen, compat); 2194# endif /* OPENSSL_HAS_ECC */ 2195 case KEY_RSA_CERT: 2196 case KEY_RSA:
| 2175{ 2176 if (sigp != NULL) 2177 *sigp = NULL; 2178 if (lenp != NULL) 2179 *lenp = 0; 2180 if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE) 2181 return SSH_ERR_INVALID_ARGUMENT; 2182 switch (key->type) { 2183#ifdef WITH_OPENSSL 2184 case KEY_DSA_CERT: 2185 case KEY_DSA: 2186 return ssh_dss_sign(key, sigp, lenp, data, datalen, compat); 2187# ifdef OPENSSL_HAS_ECC 2188 case KEY_ECDSA_CERT: 2189 case KEY_ECDSA: 2190 return ssh_ecdsa_sign(key, sigp, lenp, data, datalen, compat); 2191# endif /* OPENSSL_HAS_ECC */ 2192 case KEY_RSA_CERT: 2193 case KEY_RSA:
|
2197 return ssh_rsa_sign(key, sigp, lenp, data, datalen, compat);
| 2194 return ssh_rsa_sign(key, sigp, lenp, data, datalen, alg);
|
2198#endif /* WITH_OPENSSL */ 2199 case KEY_ED25519: 2200 case KEY_ED25519_CERT: 2201 return ssh_ed25519_sign(key, sigp, lenp, data, datalen, compat); 2202 default: 2203 return SSH_ERR_KEY_TYPE_UNKNOWN; 2204 } 2205} 2206 2207/* 2208 * ssh_key_verify returns 0 for a correct signature and < 0 on error. 2209 */ 2210int 2211sshkey_verify(const struct sshkey *key, 2212 const u_char *sig, size_t siglen, 2213 const u_char *data, size_t dlen, u_int compat) 2214{ 2215 if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE) 2216 return SSH_ERR_INVALID_ARGUMENT; 2217 switch (key->type) { 2218#ifdef WITH_OPENSSL 2219 case KEY_DSA_CERT: 2220 case KEY_DSA: 2221 return ssh_dss_verify(key, sig, siglen, data, dlen, compat); 2222# ifdef OPENSSL_HAS_ECC 2223 case KEY_ECDSA_CERT: 2224 case KEY_ECDSA: 2225 return ssh_ecdsa_verify(key, sig, siglen, data, dlen, compat); 2226# endif /* OPENSSL_HAS_ECC */ 2227 case KEY_RSA_CERT: 2228 case KEY_RSA:
| 2195#endif /* WITH_OPENSSL */ 2196 case KEY_ED25519: 2197 case KEY_ED25519_CERT: 2198 return ssh_ed25519_sign(key, sigp, lenp, data, datalen, compat); 2199 default: 2200 return SSH_ERR_KEY_TYPE_UNKNOWN; 2201 } 2202} 2203 2204/* 2205 * ssh_key_verify returns 0 for a correct signature and < 0 on error. 2206 */ 2207int 2208sshkey_verify(const struct sshkey *key, 2209 const u_char *sig, size_t siglen, 2210 const u_char *data, size_t dlen, u_int compat) 2211{ 2212 if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE) 2213 return SSH_ERR_INVALID_ARGUMENT; 2214 switch (key->type) { 2215#ifdef WITH_OPENSSL 2216 case KEY_DSA_CERT: 2217 case KEY_DSA: 2218 return ssh_dss_verify(key, sig, siglen, data, dlen, compat); 2219# ifdef OPENSSL_HAS_ECC 2220 case KEY_ECDSA_CERT: 2221 case KEY_ECDSA: 2222 return ssh_ecdsa_verify(key, sig, siglen, data, dlen, compat); 2223# endif /* OPENSSL_HAS_ECC */ 2224 case KEY_RSA_CERT: 2225 case KEY_RSA:
|
2229 return ssh_rsa_verify(key, sig, siglen, data, dlen, compat);
| 2226 return ssh_rsa_verify(key, sig, siglen, data, dlen);
|
2230#endif /* WITH_OPENSSL */ 2231 case KEY_ED25519: 2232 case KEY_ED25519_CERT: 2233 return ssh_ed25519_verify(key, sig, siglen, data, dlen, compat); 2234 default: 2235 return SSH_ERR_KEY_TYPE_UNKNOWN; 2236 } 2237} 2238 2239/* Converts a private to a public key */ 2240int 2241sshkey_demote(const struct sshkey *k, struct sshkey **dkp) 2242{ 2243 struct sshkey *pk; 2244 int ret = SSH_ERR_INTERNAL_ERROR; 2245
| 2227#endif /* WITH_OPENSSL */ 2228 case KEY_ED25519: 2229 case KEY_ED25519_CERT: 2230 return ssh_ed25519_verify(key, sig, siglen, data, dlen, compat); 2231 default: 2232 return SSH_ERR_KEY_TYPE_UNKNOWN; 2233 } 2234} 2235 2236/* Converts a private to a public key */ 2237int 2238sshkey_demote(const struct sshkey *k, struct sshkey **dkp) 2239{ 2240 struct sshkey *pk; 2241 int ret = SSH_ERR_INTERNAL_ERROR; 2242
|
2246 if (dkp != NULL) 2247 *dkp = NULL; 2248
| 2243 *dkp = NULL;
|
2249 if ((pk = calloc(1, sizeof(*pk))) == NULL) 2250 return SSH_ERR_ALLOC_FAIL; 2251 pk->type = k->type; 2252 pk->flags = k->flags; 2253 pk->ecdsa_nid = k->ecdsa_nid; 2254 pk->dsa = NULL; 2255 pk->ecdsa = NULL; 2256 pk->rsa = NULL; 2257 pk->ed25519_pk = NULL; 2258 pk->ed25519_sk = NULL; 2259 2260 switch (k->type) { 2261#ifdef WITH_OPENSSL 2262 case KEY_RSA_CERT: 2263 if ((ret = sshkey_cert_copy(k, pk)) != 0) 2264 goto fail; 2265 /* FALLTHROUGH */ 2266 case KEY_RSA1: 2267 case KEY_RSA: 2268 if ((pk->rsa = RSA_new()) == NULL || 2269 (pk->rsa->e = BN_dup(k->rsa->e)) == NULL || 2270 (pk->rsa->n = BN_dup(k->rsa->n)) == NULL) { 2271 ret = SSH_ERR_ALLOC_FAIL; 2272 goto fail; 2273 } 2274 break; 2275 case KEY_DSA_CERT: 2276 if ((ret = sshkey_cert_copy(k, pk)) != 0) 2277 goto fail; 2278 /* FALLTHROUGH */ 2279 case KEY_DSA: 2280 if ((pk->dsa = DSA_new()) == NULL || 2281 (pk->dsa->p = BN_dup(k->dsa->p)) == NULL || 2282 (pk->dsa->q = BN_dup(k->dsa->q)) == NULL || 2283 (pk->dsa->g = BN_dup(k->dsa->g)) == NULL || 2284 (pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) { 2285 ret = SSH_ERR_ALLOC_FAIL; 2286 goto fail; 2287 } 2288 break; 2289 case KEY_ECDSA_CERT: 2290 if ((ret = sshkey_cert_copy(k, pk)) != 0) 2291 goto fail; 2292 /* FALLTHROUGH */ 2293# ifdef OPENSSL_HAS_ECC 2294 case KEY_ECDSA: 2295 pk->ecdsa = EC_KEY_new_by_curve_name(pk->ecdsa_nid); 2296 if (pk->ecdsa == NULL) { 2297 ret = SSH_ERR_ALLOC_FAIL; 2298 goto fail; 2299 } 2300 if (EC_KEY_set_public_key(pk->ecdsa, 2301 EC_KEY_get0_public_key(k->ecdsa)) != 1) { 2302 ret = SSH_ERR_LIBCRYPTO_ERROR; 2303 goto fail; 2304 } 2305 break; 2306# endif /* OPENSSL_HAS_ECC */ 2307#endif /* WITH_OPENSSL */ 2308 case KEY_ED25519_CERT: 2309 if ((ret = sshkey_cert_copy(k, pk)) != 0) 2310 goto fail; 2311 /* FALLTHROUGH */ 2312 case KEY_ED25519: 2313 if (k->ed25519_pk != NULL) { 2314 if ((pk->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) { 2315 ret = SSH_ERR_ALLOC_FAIL; 2316 goto fail; 2317 } 2318 memcpy(pk->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ); 2319 } 2320 break; 2321 default: 2322 ret = SSH_ERR_KEY_TYPE_UNKNOWN; 2323 fail: 2324 sshkey_free(pk); 2325 return ret; 2326 } 2327 *dkp = pk; 2328 return 0; 2329} 2330 2331/* Convert a plain key to their _CERT equivalent */ 2332int 2333sshkey_to_certified(struct sshkey *k) 2334{ 2335 int newtype; 2336 2337 switch (k->type) { 2338#ifdef WITH_OPENSSL 2339 case KEY_RSA: 2340 newtype = KEY_RSA_CERT; 2341 break; 2342 case KEY_DSA: 2343 newtype = KEY_DSA_CERT; 2344 break; 2345 case KEY_ECDSA: 2346 newtype = KEY_ECDSA_CERT; 2347 break; 2348#endif /* WITH_OPENSSL */ 2349 case KEY_ED25519: 2350 newtype = KEY_ED25519_CERT; 2351 break; 2352 default: 2353 return SSH_ERR_INVALID_ARGUMENT; 2354 } 2355 if ((k->cert = cert_new()) == NULL) 2356 return SSH_ERR_ALLOC_FAIL; 2357 k->type = newtype; 2358 return 0; 2359} 2360 2361/* Convert a certificate to its raw key equivalent */ 2362int 2363sshkey_drop_cert(struct sshkey *k) 2364{ 2365 if (!sshkey_type_is_cert(k->type)) 2366 return SSH_ERR_KEY_TYPE_UNKNOWN; 2367 cert_free(k->cert); 2368 k->cert = NULL; 2369 k->type = sshkey_type_plain(k->type); 2370 return 0; 2371} 2372 2373/* Sign a certified key, (re-)generating the signed certblob. */ 2374int 2375sshkey_certify(struct sshkey *k, struct sshkey *ca) 2376{ 2377 struct sshbuf *principals = NULL; 2378 u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32]; 2379 size_t i, ca_len, sig_len; 2380 int ret = SSH_ERR_INTERNAL_ERROR; 2381 struct sshbuf *cert; 2382 2383 if (k == NULL || k->cert == NULL || 2384 k->cert->certblob == NULL || ca == NULL) 2385 return SSH_ERR_INVALID_ARGUMENT; 2386 if (!sshkey_is_cert(k)) 2387 return SSH_ERR_KEY_TYPE_UNKNOWN; 2388 if (!sshkey_type_is_valid_ca(ca->type)) 2389 return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; 2390 2391 if ((ret = sshkey_to_blob(ca, &ca_blob, &ca_len)) != 0) 2392 return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; 2393 2394 cert = k->cert->certblob; /* for readability */ 2395 sshbuf_reset(cert); 2396 if ((ret = sshbuf_put_cstring(cert, sshkey_ssh_name(k))) != 0) 2397 goto out; 2398 2399 /* -v01 certs put nonce first */ 2400 arc4random_buf(&nonce, sizeof(nonce)); 2401 if ((ret = sshbuf_put_string(cert, nonce, sizeof(nonce))) != 0) 2402 goto out; 2403 2404 /* XXX this substantially duplicates to_blob(); refactor */ 2405 switch (k->type) { 2406#ifdef WITH_OPENSSL 2407 case KEY_DSA_CERT: 2408 if ((ret = sshbuf_put_bignum2(cert, k->dsa->p)) != 0 || 2409 (ret = sshbuf_put_bignum2(cert, k->dsa->q)) != 0 || 2410 (ret = sshbuf_put_bignum2(cert, k->dsa->g)) != 0 || 2411 (ret = sshbuf_put_bignum2(cert, k->dsa->pub_key)) != 0) 2412 goto out; 2413 break; 2414# ifdef OPENSSL_HAS_ECC 2415 case KEY_ECDSA_CERT: 2416 if ((ret = sshbuf_put_cstring(cert, 2417 sshkey_curve_nid_to_name(k->ecdsa_nid))) != 0 || 2418 (ret = sshbuf_put_ec(cert, 2419 EC_KEY_get0_public_key(k->ecdsa), 2420 EC_KEY_get0_group(k->ecdsa))) != 0) 2421 goto out; 2422 break; 2423# endif /* OPENSSL_HAS_ECC */ 2424 case KEY_RSA_CERT: 2425 if ((ret = sshbuf_put_bignum2(cert, k->rsa->e)) != 0 || 2426 (ret = sshbuf_put_bignum2(cert, k->rsa->n)) != 0) 2427 goto out; 2428 break; 2429#endif /* WITH_OPENSSL */ 2430 case KEY_ED25519_CERT: 2431 if ((ret = sshbuf_put_string(cert, 2432 k->ed25519_pk, ED25519_PK_SZ)) != 0) 2433 goto out; 2434 break; 2435 default: 2436 ret = SSH_ERR_INVALID_ARGUMENT; 2437 goto out; 2438 } 2439 2440 if ((ret = sshbuf_put_u64(cert, k->cert->serial)) != 0 || 2441 (ret = sshbuf_put_u32(cert, k->cert->type)) != 0 || 2442 (ret = sshbuf_put_cstring(cert, k->cert->key_id)) != 0) 2443 goto out; 2444 2445 if ((principals = sshbuf_new()) == NULL) { 2446 ret = SSH_ERR_ALLOC_FAIL; 2447 goto out; 2448 } 2449 for (i = 0; i < k->cert->nprincipals; i++) { 2450 if ((ret = sshbuf_put_cstring(principals, 2451 k->cert->principals[i])) != 0) 2452 goto out; 2453 } 2454 if ((ret = sshbuf_put_stringb(cert, principals)) != 0 || 2455 (ret = sshbuf_put_u64(cert, k->cert->valid_after)) != 0 || 2456 (ret = sshbuf_put_u64(cert, k->cert->valid_before)) != 0 || 2457 (ret = sshbuf_put_stringb(cert, k->cert->critical)) != 0 || 2458 (ret = sshbuf_put_stringb(cert, k->cert->extensions)) != 0 || 2459 (ret = sshbuf_put_string(cert, NULL, 0)) != 0 || /* Reserved */ 2460 (ret = sshbuf_put_string(cert, ca_blob, ca_len)) != 0) 2461 goto out; 2462 2463 /* Sign the whole mess */ 2464 if ((ret = sshkey_sign(ca, &sig_blob, &sig_len, sshbuf_ptr(cert),
| 2244 if ((pk = calloc(1, sizeof(*pk))) == NULL) 2245 return SSH_ERR_ALLOC_FAIL; 2246 pk->type = k->type; 2247 pk->flags = k->flags; 2248 pk->ecdsa_nid = k->ecdsa_nid; 2249 pk->dsa = NULL; 2250 pk->ecdsa = NULL; 2251 pk->rsa = NULL; 2252 pk->ed25519_pk = NULL; 2253 pk->ed25519_sk = NULL; 2254 2255 switch (k->type) { 2256#ifdef WITH_OPENSSL 2257 case KEY_RSA_CERT: 2258 if ((ret = sshkey_cert_copy(k, pk)) != 0) 2259 goto fail; 2260 /* FALLTHROUGH */ 2261 case KEY_RSA1: 2262 case KEY_RSA: 2263 if ((pk->rsa = RSA_new()) == NULL || 2264 (pk->rsa->e = BN_dup(k->rsa->e)) == NULL || 2265 (pk->rsa->n = BN_dup(k->rsa->n)) == NULL) { 2266 ret = SSH_ERR_ALLOC_FAIL; 2267 goto fail; 2268 } 2269 break; 2270 case KEY_DSA_CERT: 2271 if ((ret = sshkey_cert_copy(k, pk)) != 0) 2272 goto fail; 2273 /* FALLTHROUGH */ 2274 case KEY_DSA: 2275 if ((pk->dsa = DSA_new()) == NULL || 2276 (pk->dsa->p = BN_dup(k->dsa->p)) == NULL || 2277 (pk->dsa->q = BN_dup(k->dsa->q)) == NULL || 2278 (pk->dsa->g = BN_dup(k->dsa->g)) == NULL || 2279 (pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) { 2280 ret = SSH_ERR_ALLOC_FAIL; 2281 goto fail; 2282 } 2283 break; 2284 case KEY_ECDSA_CERT: 2285 if ((ret = sshkey_cert_copy(k, pk)) != 0) 2286 goto fail; 2287 /* FALLTHROUGH */ 2288# ifdef OPENSSL_HAS_ECC 2289 case KEY_ECDSA: 2290 pk->ecdsa = EC_KEY_new_by_curve_name(pk->ecdsa_nid); 2291 if (pk->ecdsa == NULL) { 2292 ret = SSH_ERR_ALLOC_FAIL; 2293 goto fail; 2294 } 2295 if (EC_KEY_set_public_key(pk->ecdsa, 2296 EC_KEY_get0_public_key(k->ecdsa)) != 1) { 2297 ret = SSH_ERR_LIBCRYPTO_ERROR; 2298 goto fail; 2299 } 2300 break; 2301# endif /* OPENSSL_HAS_ECC */ 2302#endif /* WITH_OPENSSL */ 2303 case KEY_ED25519_CERT: 2304 if ((ret = sshkey_cert_copy(k, pk)) != 0) 2305 goto fail; 2306 /* FALLTHROUGH */ 2307 case KEY_ED25519: 2308 if (k->ed25519_pk != NULL) { 2309 if ((pk->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) { 2310 ret = SSH_ERR_ALLOC_FAIL; 2311 goto fail; 2312 } 2313 memcpy(pk->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ); 2314 } 2315 break; 2316 default: 2317 ret = SSH_ERR_KEY_TYPE_UNKNOWN; 2318 fail: 2319 sshkey_free(pk); 2320 return ret; 2321 } 2322 *dkp = pk; 2323 return 0; 2324} 2325 2326/* Convert a plain key to their _CERT equivalent */ 2327int 2328sshkey_to_certified(struct sshkey *k) 2329{ 2330 int newtype; 2331 2332 switch (k->type) { 2333#ifdef WITH_OPENSSL 2334 case KEY_RSA: 2335 newtype = KEY_RSA_CERT; 2336 break; 2337 case KEY_DSA: 2338 newtype = KEY_DSA_CERT; 2339 break; 2340 case KEY_ECDSA: 2341 newtype = KEY_ECDSA_CERT; 2342 break; 2343#endif /* WITH_OPENSSL */ 2344 case KEY_ED25519: 2345 newtype = KEY_ED25519_CERT; 2346 break; 2347 default: 2348 return SSH_ERR_INVALID_ARGUMENT; 2349 } 2350 if ((k->cert = cert_new()) == NULL) 2351 return SSH_ERR_ALLOC_FAIL; 2352 k->type = newtype; 2353 return 0; 2354} 2355 2356/* Convert a certificate to its raw key equivalent */ 2357int 2358sshkey_drop_cert(struct sshkey *k) 2359{ 2360 if (!sshkey_type_is_cert(k->type)) 2361 return SSH_ERR_KEY_TYPE_UNKNOWN; 2362 cert_free(k->cert); 2363 k->cert = NULL; 2364 k->type = sshkey_type_plain(k->type); 2365 return 0; 2366} 2367 2368/* Sign a certified key, (re-)generating the signed certblob. */ 2369int 2370sshkey_certify(struct sshkey *k, struct sshkey *ca) 2371{ 2372 struct sshbuf *principals = NULL; 2373 u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32]; 2374 size_t i, ca_len, sig_len; 2375 int ret = SSH_ERR_INTERNAL_ERROR; 2376 struct sshbuf *cert; 2377 2378 if (k == NULL || k->cert == NULL || 2379 k->cert->certblob == NULL || ca == NULL) 2380 return SSH_ERR_INVALID_ARGUMENT; 2381 if (!sshkey_is_cert(k)) 2382 return SSH_ERR_KEY_TYPE_UNKNOWN; 2383 if (!sshkey_type_is_valid_ca(ca->type)) 2384 return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; 2385 2386 if ((ret = sshkey_to_blob(ca, &ca_blob, &ca_len)) != 0) 2387 return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; 2388 2389 cert = k->cert->certblob; /* for readability */ 2390 sshbuf_reset(cert); 2391 if ((ret = sshbuf_put_cstring(cert, sshkey_ssh_name(k))) != 0) 2392 goto out; 2393 2394 /* -v01 certs put nonce first */ 2395 arc4random_buf(&nonce, sizeof(nonce)); 2396 if ((ret = sshbuf_put_string(cert, nonce, sizeof(nonce))) != 0) 2397 goto out; 2398 2399 /* XXX this substantially duplicates to_blob(); refactor */ 2400 switch (k->type) { 2401#ifdef WITH_OPENSSL 2402 case KEY_DSA_CERT: 2403 if ((ret = sshbuf_put_bignum2(cert, k->dsa->p)) != 0 || 2404 (ret = sshbuf_put_bignum2(cert, k->dsa->q)) != 0 || 2405 (ret = sshbuf_put_bignum2(cert, k->dsa->g)) != 0 || 2406 (ret = sshbuf_put_bignum2(cert, k->dsa->pub_key)) != 0) 2407 goto out; 2408 break; 2409# ifdef OPENSSL_HAS_ECC 2410 case KEY_ECDSA_CERT: 2411 if ((ret = sshbuf_put_cstring(cert, 2412 sshkey_curve_nid_to_name(k->ecdsa_nid))) != 0 || 2413 (ret = sshbuf_put_ec(cert, 2414 EC_KEY_get0_public_key(k->ecdsa), 2415 EC_KEY_get0_group(k->ecdsa))) != 0) 2416 goto out; 2417 break; 2418# endif /* OPENSSL_HAS_ECC */ 2419 case KEY_RSA_CERT: 2420 if ((ret = sshbuf_put_bignum2(cert, k->rsa->e)) != 0 || 2421 (ret = sshbuf_put_bignum2(cert, k->rsa->n)) != 0) 2422 goto out; 2423 break; 2424#endif /* WITH_OPENSSL */ 2425 case KEY_ED25519_CERT: 2426 if ((ret = sshbuf_put_string(cert, 2427 k->ed25519_pk, ED25519_PK_SZ)) != 0) 2428 goto out; 2429 break; 2430 default: 2431 ret = SSH_ERR_INVALID_ARGUMENT; 2432 goto out; 2433 } 2434 2435 if ((ret = sshbuf_put_u64(cert, k->cert->serial)) != 0 || 2436 (ret = sshbuf_put_u32(cert, k->cert->type)) != 0 || 2437 (ret = sshbuf_put_cstring(cert, k->cert->key_id)) != 0) 2438 goto out; 2439 2440 if ((principals = sshbuf_new()) == NULL) { 2441 ret = SSH_ERR_ALLOC_FAIL; 2442 goto out; 2443 } 2444 for (i = 0; i < k->cert->nprincipals; i++) { 2445 if ((ret = sshbuf_put_cstring(principals, 2446 k->cert->principals[i])) != 0) 2447 goto out; 2448 } 2449 if ((ret = sshbuf_put_stringb(cert, principals)) != 0 || 2450 (ret = sshbuf_put_u64(cert, k->cert->valid_after)) != 0 || 2451 (ret = sshbuf_put_u64(cert, k->cert->valid_before)) != 0 || 2452 (ret = sshbuf_put_stringb(cert, k->cert->critical)) != 0 || 2453 (ret = sshbuf_put_stringb(cert, k->cert->extensions)) != 0 || 2454 (ret = sshbuf_put_string(cert, NULL, 0)) != 0 || /* Reserved */ 2455 (ret = sshbuf_put_string(cert, ca_blob, ca_len)) != 0) 2456 goto out; 2457 2458 /* Sign the whole mess */ 2459 if ((ret = sshkey_sign(ca, &sig_blob, &sig_len, sshbuf_ptr(cert),
|
2465 sshbuf_len(cert), 0)) != 0)
| 2460 sshbuf_len(cert), NULL, 0)) != 0)
|
2466 goto out; 2467 2468 /* Append signature and we are done */ 2469 if ((ret = sshbuf_put_string(cert, sig_blob, sig_len)) != 0) 2470 goto out; 2471 ret = 0; 2472 out: 2473 if (ret != 0) 2474 sshbuf_reset(cert);
| 2461 goto out; 2462 2463 /* Append signature and we are done */ 2464 if ((ret = sshbuf_put_string(cert, sig_blob, sig_len)) != 0) 2465 goto out; 2466 ret = 0; 2467 out: 2468 if (ret != 0) 2469 sshbuf_reset(cert);
|
2475 if (sig_blob != NULL) 2476 free(sig_blob); 2477 if (ca_blob != NULL) 2478 free(ca_blob); 2479 if (principals != NULL) 2480 sshbuf_free(principals);
| 2470 free(sig_blob); 2471 free(ca_blob); 2472 sshbuf_free(principals);
|
2481 return ret; 2482} 2483 2484int 2485sshkey_cert_check_authority(const struct sshkey *k, 2486 int want_host, int require_principal, 2487 const char *name, const char **reason) 2488{ 2489 u_int i, principal_matches; 2490 time_t now = time(NULL); 2491 2492 if (reason != NULL) 2493 *reason = NULL; 2494 2495 if (want_host) { 2496 if (k->cert->type != SSH2_CERT_TYPE_HOST) { 2497 *reason = "Certificate invalid: not a host certificate"; 2498 return SSH_ERR_KEY_CERT_INVALID; 2499 } 2500 } else { 2501 if (k->cert->type != SSH2_CERT_TYPE_USER) { 2502 *reason = "Certificate invalid: not a user certificate"; 2503 return SSH_ERR_KEY_CERT_INVALID; 2504 } 2505 } 2506 if (now < 0) { 2507 /* yikes - system clock before epoch! */ 2508 *reason = "Certificate invalid: not yet valid"; 2509 return SSH_ERR_KEY_CERT_INVALID; 2510 } 2511 if ((u_int64_t)now < k->cert->valid_after) { 2512 *reason = "Certificate invalid: not yet valid"; 2513 return SSH_ERR_KEY_CERT_INVALID; 2514 } 2515 if ((u_int64_t)now >= k->cert->valid_before) { 2516 *reason = "Certificate invalid: expired"; 2517 return SSH_ERR_KEY_CERT_INVALID; 2518 } 2519 if (k->cert->nprincipals == 0) { 2520 if (require_principal) { 2521 *reason = "Certificate lacks principal list"; 2522 return SSH_ERR_KEY_CERT_INVALID; 2523 } 2524 } else if (name != NULL) { 2525 principal_matches = 0; 2526 for (i = 0; i < k->cert->nprincipals; i++) { 2527 if (strcmp(name, k->cert->principals[i]) == 0) { 2528 principal_matches = 1; 2529 break; 2530 } 2531 } 2532 if (!principal_matches) { 2533 *reason = "Certificate invalid: name is not a listed " 2534 "principal"; 2535 return SSH_ERR_KEY_CERT_INVALID; 2536 } 2537 } 2538 return 0; 2539} 2540
| 2473 return ret; 2474} 2475 2476int 2477sshkey_cert_check_authority(const struct sshkey *k, 2478 int want_host, int require_principal, 2479 const char *name, const char **reason) 2480{ 2481 u_int i, principal_matches; 2482 time_t now = time(NULL); 2483 2484 if (reason != NULL) 2485 *reason = NULL; 2486 2487 if (want_host) { 2488 if (k->cert->type != SSH2_CERT_TYPE_HOST) { 2489 *reason = "Certificate invalid: not a host certificate"; 2490 return SSH_ERR_KEY_CERT_INVALID; 2491 } 2492 } else { 2493 if (k->cert->type != SSH2_CERT_TYPE_USER) { 2494 *reason = "Certificate invalid: not a user certificate"; 2495 return SSH_ERR_KEY_CERT_INVALID; 2496 } 2497 } 2498 if (now < 0) { 2499 /* yikes - system clock before epoch! */ 2500 *reason = "Certificate invalid: not yet valid"; 2501 return SSH_ERR_KEY_CERT_INVALID; 2502 } 2503 if ((u_int64_t)now < k->cert->valid_after) { 2504 *reason = "Certificate invalid: not yet valid"; 2505 return SSH_ERR_KEY_CERT_INVALID; 2506 } 2507 if ((u_int64_t)now >= k->cert->valid_before) { 2508 *reason = "Certificate invalid: expired"; 2509 return SSH_ERR_KEY_CERT_INVALID; 2510 } 2511 if (k->cert->nprincipals == 0) { 2512 if (require_principal) { 2513 *reason = "Certificate lacks principal list"; 2514 return SSH_ERR_KEY_CERT_INVALID; 2515 } 2516 } else if (name != NULL) { 2517 principal_matches = 0; 2518 for (i = 0; i < k->cert->nprincipals; i++) { 2519 if (strcmp(name, k->cert->principals[i]) == 0) { 2520 principal_matches = 1; 2521 break; 2522 } 2523 } 2524 if (!principal_matches) { 2525 *reason = "Certificate invalid: name is not a listed " 2526 "principal"; 2527 return SSH_ERR_KEY_CERT_INVALID; 2528 } 2529 } 2530 return 0; 2531} 2532
|
| 2533size_t 2534sshkey_format_cert_validity(const struct sshkey_cert *cert, char *s, size_t l) 2535{ 2536 char from[32], to[32], ret[64]; 2537 time_t tt; 2538 struct tm *tm; 2539 2540 *from = *to = '\0'; 2541 if (cert->valid_after == 0 && 2542 cert->valid_before == 0xffffffffffffffffULL) 2543 return strlcpy(s, "forever", l); 2544 2545 if (cert->valid_after != 0) { 2546 /* XXX revisit INT_MAX in 2038 :) */ 2547 tt = cert->valid_after > INT_MAX ? 2548 INT_MAX : cert->valid_after; 2549 tm = localtime(&tt); 2550 strftime(from, sizeof(from), "%Y-%m-%dT%H:%M:%S", tm); 2551 } 2552 if (cert->valid_before != 0xffffffffffffffffULL) { 2553 /* XXX revisit INT_MAX in 2038 :) */ 2554 tt = cert->valid_before > INT_MAX ? 2555 INT_MAX : cert->valid_before; 2556 tm = localtime(&tt); 2557 strftime(to, sizeof(to), "%Y-%m-%dT%H:%M:%S", tm); 2558 } 2559 2560 if (cert->valid_after == 0) 2561 snprintf(ret, sizeof(ret), "before %s", to); 2562 else if (cert->valid_before == 0xffffffffffffffffULL) 2563 snprintf(ret, sizeof(ret), "after %s", from); 2564 else 2565 snprintf(ret, sizeof(ret), "from %s to %s", from, to); 2566 2567 return strlcpy(s, ret, l); 2568} 2569
|
2541int 2542sshkey_private_serialize(const struct sshkey *key, struct sshbuf *b) 2543{ 2544 int r = SSH_ERR_INTERNAL_ERROR; 2545 2546 if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0) 2547 goto out; 2548 switch (key->type) { 2549#ifdef WITH_OPENSSL 2550 case KEY_RSA: 2551 if ((r = sshbuf_put_bignum2(b, key->rsa->n)) != 0 || 2552 (r = sshbuf_put_bignum2(b, key->rsa->e)) != 0 || 2553 (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 || 2554 (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 || 2555 (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 || 2556 (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0) 2557 goto out; 2558 break; 2559 case KEY_RSA_CERT: 2560 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { 2561 r = SSH_ERR_INVALID_ARGUMENT; 2562 goto out; 2563 } 2564 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || 2565 (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 || 2566 (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 || 2567 (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 || 2568 (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0) 2569 goto out; 2570 break; 2571 case KEY_DSA: 2572 if ((r = sshbuf_put_bignum2(b, key->dsa->p)) != 0 || 2573 (r = sshbuf_put_bignum2(b, key->dsa->q)) != 0 || 2574 (r = sshbuf_put_bignum2(b, key->dsa->g)) != 0 || 2575 (r = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0 || 2576 (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0) 2577 goto out; 2578 break; 2579 case KEY_DSA_CERT: 2580 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { 2581 r = SSH_ERR_INVALID_ARGUMENT; 2582 goto out; 2583 } 2584 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || 2585 (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0) 2586 goto out; 2587 break; 2588# ifdef OPENSSL_HAS_ECC 2589 case KEY_ECDSA: 2590 if ((r = sshbuf_put_cstring(b, 2591 sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 || 2592 (r = sshbuf_put_eckey(b, key->ecdsa)) != 0 || 2593 (r = sshbuf_put_bignum2(b, 2594 EC_KEY_get0_private_key(key->ecdsa))) != 0) 2595 goto out; 2596 break; 2597 case KEY_ECDSA_CERT: 2598 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { 2599 r = SSH_ERR_INVALID_ARGUMENT; 2600 goto out; 2601 } 2602 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || 2603 (r = sshbuf_put_bignum2(b, 2604 EC_KEY_get0_private_key(key->ecdsa))) != 0) 2605 goto out; 2606 break; 2607# endif /* OPENSSL_HAS_ECC */ 2608#endif /* WITH_OPENSSL */ 2609 case KEY_ED25519: 2610 if ((r = sshbuf_put_string(b, key->ed25519_pk, 2611 ED25519_PK_SZ)) != 0 || 2612 (r = sshbuf_put_string(b, key->ed25519_sk, 2613 ED25519_SK_SZ)) != 0) 2614 goto out; 2615 break; 2616 case KEY_ED25519_CERT: 2617 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { 2618 r = SSH_ERR_INVALID_ARGUMENT; 2619 goto out; 2620 } 2621 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || 2622 (r = sshbuf_put_string(b, key->ed25519_pk, 2623 ED25519_PK_SZ)) != 0 || 2624 (r = sshbuf_put_string(b, key->ed25519_sk, 2625 ED25519_SK_SZ)) != 0) 2626 goto out; 2627 break; 2628 default: 2629 r = SSH_ERR_INVALID_ARGUMENT; 2630 goto out; 2631 } 2632 /* success */ 2633 r = 0; 2634 out: 2635 return r; 2636} 2637 2638int 2639sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) 2640{ 2641 char *tname = NULL, *curve = NULL; 2642 struct sshkey *k = NULL; 2643 size_t pklen = 0, sklen = 0; 2644 int type, r = SSH_ERR_INTERNAL_ERROR; 2645 u_char *ed25519_pk = NULL, *ed25519_sk = NULL; 2646#ifdef WITH_OPENSSL 2647 BIGNUM *exponent = NULL; 2648#endif /* WITH_OPENSSL */ 2649 2650 if (kp != NULL) 2651 *kp = NULL; 2652 if ((r = sshbuf_get_cstring(buf, &tname, NULL)) != 0) 2653 goto out; 2654 type = sshkey_type_from_name(tname); 2655 switch (type) { 2656#ifdef WITH_OPENSSL 2657 case KEY_DSA: 2658 if ((k = sshkey_new_private(type)) == NULL) { 2659 r = SSH_ERR_ALLOC_FAIL; 2660 goto out; 2661 } 2662 if ((r = sshbuf_get_bignum2(buf, k->dsa->p)) != 0 || 2663 (r = sshbuf_get_bignum2(buf, k->dsa->q)) != 0 || 2664 (r = sshbuf_get_bignum2(buf, k->dsa->g)) != 0 || 2665 (r = sshbuf_get_bignum2(buf, k->dsa->pub_key)) != 0 || 2666 (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0) 2667 goto out; 2668 break; 2669 case KEY_DSA_CERT: 2670 if ((r = sshkey_froms(buf, &k)) != 0 || 2671 (r = sshkey_add_private(k)) != 0 || 2672 (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0) 2673 goto out; 2674 break; 2675# ifdef OPENSSL_HAS_ECC 2676 case KEY_ECDSA: 2677 if ((k = sshkey_new_private(type)) == NULL) { 2678 r = SSH_ERR_ALLOC_FAIL; 2679 goto out; 2680 } 2681 if ((k->ecdsa_nid = sshkey_ecdsa_nid_from_name(tname)) == -1) { 2682 r = SSH_ERR_INVALID_ARGUMENT; 2683 goto out; 2684 } 2685 if ((r = sshbuf_get_cstring(buf, &curve, NULL)) != 0) 2686 goto out; 2687 if (k->ecdsa_nid != sshkey_curve_name_to_nid(curve)) { 2688 r = SSH_ERR_EC_CURVE_MISMATCH; 2689 goto out; 2690 } 2691 k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); 2692 if (k->ecdsa == NULL || (exponent = BN_new()) == NULL) { 2693 r = SSH_ERR_LIBCRYPTO_ERROR; 2694 goto out; 2695 } 2696 if ((r = sshbuf_get_eckey(buf, k->ecdsa)) != 0 || 2697 (r = sshbuf_get_bignum2(buf, exponent))) 2698 goto out; 2699 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) { 2700 r = SSH_ERR_LIBCRYPTO_ERROR; 2701 goto out; 2702 } 2703 if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
| 2570int 2571sshkey_private_serialize(const struct sshkey *key, struct sshbuf *b) 2572{ 2573 int r = SSH_ERR_INTERNAL_ERROR; 2574 2575 if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0) 2576 goto out; 2577 switch (key->type) { 2578#ifdef WITH_OPENSSL 2579 case KEY_RSA: 2580 if ((r = sshbuf_put_bignum2(b, key->rsa->n)) != 0 || 2581 (r = sshbuf_put_bignum2(b, key->rsa->e)) != 0 || 2582 (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 || 2583 (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 || 2584 (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 || 2585 (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0) 2586 goto out; 2587 break; 2588 case KEY_RSA_CERT: 2589 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { 2590 r = SSH_ERR_INVALID_ARGUMENT; 2591 goto out; 2592 } 2593 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || 2594 (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 || 2595 (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 || 2596 (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 || 2597 (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0) 2598 goto out; 2599 break; 2600 case KEY_DSA: 2601 if ((r = sshbuf_put_bignum2(b, key->dsa->p)) != 0 || 2602 (r = sshbuf_put_bignum2(b, key->dsa->q)) != 0 || 2603 (r = sshbuf_put_bignum2(b, key->dsa->g)) != 0 || 2604 (r = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0 || 2605 (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0) 2606 goto out; 2607 break; 2608 case KEY_DSA_CERT: 2609 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { 2610 r = SSH_ERR_INVALID_ARGUMENT; 2611 goto out; 2612 } 2613 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || 2614 (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0) 2615 goto out; 2616 break; 2617# ifdef OPENSSL_HAS_ECC 2618 case KEY_ECDSA: 2619 if ((r = sshbuf_put_cstring(b, 2620 sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 || 2621 (r = sshbuf_put_eckey(b, key->ecdsa)) != 0 || 2622 (r = sshbuf_put_bignum2(b, 2623 EC_KEY_get0_private_key(key->ecdsa))) != 0) 2624 goto out; 2625 break; 2626 case KEY_ECDSA_CERT: 2627 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { 2628 r = SSH_ERR_INVALID_ARGUMENT; 2629 goto out; 2630 } 2631 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || 2632 (r = sshbuf_put_bignum2(b, 2633 EC_KEY_get0_private_key(key->ecdsa))) != 0) 2634 goto out; 2635 break; 2636# endif /* OPENSSL_HAS_ECC */ 2637#endif /* WITH_OPENSSL */ 2638 case KEY_ED25519: 2639 if ((r = sshbuf_put_string(b, key->ed25519_pk, 2640 ED25519_PK_SZ)) != 0 || 2641 (r = sshbuf_put_string(b, key->ed25519_sk, 2642 ED25519_SK_SZ)) != 0) 2643 goto out; 2644 break; 2645 case KEY_ED25519_CERT: 2646 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { 2647 r = SSH_ERR_INVALID_ARGUMENT; 2648 goto out; 2649 } 2650 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || 2651 (r = sshbuf_put_string(b, key->ed25519_pk, 2652 ED25519_PK_SZ)) != 0 || 2653 (r = sshbuf_put_string(b, key->ed25519_sk, 2654 ED25519_SK_SZ)) != 0) 2655 goto out; 2656 break; 2657 default: 2658 r = SSH_ERR_INVALID_ARGUMENT; 2659 goto out; 2660 } 2661 /* success */ 2662 r = 0; 2663 out: 2664 return r; 2665} 2666 2667int 2668sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) 2669{ 2670 char *tname = NULL, *curve = NULL; 2671 struct sshkey *k = NULL; 2672 size_t pklen = 0, sklen = 0; 2673 int type, r = SSH_ERR_INTERNAL_ERROR; 2674 u_char *ed25519_pk = NULL, *ed25519_sk = NULL; 2675#ifdef WITH_OPENSSL 2676 BIGNUM *exponent = NULL; 2677#endif /* WITH_OPENSSL */ 2678 2679 if (kp != NULL) 2680 *kp = NULL; 2681 if ((r = sshbuf_get_cstring(buf, &tname, NULL)) != 0) 2682 goto out; 2683 type = sshkey_type_from_name(tname); 2684 switch (type) { 2685#ifdef WITH_OPENSSL 2686 case KEY_DSA: 2687 if ((k = sshkey_new_private(type)) == NULL) { 2688 r = SSH_ERR_ALLOC_FAIL; 2689 goto out; 2690 } 2691 if ((r = sshbuf_get_bignum2(buf, k->dsa->p)) != 0 || 2692 (r = sshbuf_get_bignum2(buf, k->dsa->q)) != 0 || 2693 (r = sshbuf_get_bignum2(buf, k->dsa->g)) != 0 || 2694 (r = sshbuf_get_bignum2(buf, k->dsa->pub_key)) != 0 || 2695 (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0) 2696 goto out; 2697 break; 2698 case KEY_DSA_CERT: 2699 if ((r = sshkey_froms(buf, &k)) != 0 || 2700 (r = sshkey_add_private(k)) != 0 || 2701 (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0) 2702 goto out; 2703 break; 2704# ifdef OPENSSL_HAS_ECC 2705 case KEY_ECDSA: 2706 if ((k = sshkey_new_private(type)) == NULL) { 2707 r = SSH_ERR_ALLOC_FAIL; 2708 goto out; 2709 } 2710 if ((k->ecdsa_nid = sshkey_ecdsa_nid_from_name(tname)) == -1) { 2711 r = SSH_ERR_INVALID_ARGUMENT; 2712 goto out; 2713 } 2714 if ((r = sshbuf_get_cstring(buf, &curve, NULL)) != 0) 2715 goto out; 2716 if (k->ecdsa_nid != sshkey_curve_name_to_nid(curve)) { 2717 r = SSH_ERR_EC_CURVE_MISMATCH; 2718 goto out; 2719 } 2720 k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); 2721 if (k->ecdsa == NULL || (exponent = BN_new()) == NULL) { 2722 r = SSH_ERR_LIBCRYPTO_ERROR; 2723 goto out; 2724 } 2725 if ((r = sshbuf_get_eckey(buf, k->ecdsa)) != 0 || 2726 (r = sshbuf_get_bignum2(buf, exponent))) 2727 goto out; 2728 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) { 2729 r = SSH_ERR_LIBCRYPTO_ERROR; 2730 goto out; 2731 } 2732 if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
|
2704 EC_KEY_get0_public_key(k->ecdsa)) != 0) ||
| 2733 EC_KEY_get0_public_key(k->ecdsa))) != 0 ||
|
2705 (r = sshkey_ec_validate_private(k->ecdsa)) != 0) 2706 goto out; 2707 break; 2708 case KEY_ECDSA_CERT: 2709 if ((exponent = BN_new()) == NULL) { 2710 r = SSH_ERR_LIBCRYPTO_ERROR; 2711 goto out; 2712 } 2713 if ((r = sshkey_froms(buf, &k)) != 0 || 2714 (r = sshkey_add_private(k)) != 0 || 2715 (r = sshbuf_get_bignum2(buf, exponent)) != 0) 2716 goto out; 2717 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) { 2718 r = SSH_ERR_LIBCRYPTO_ERROR; 2719 goto out; 2720 } 2721 if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
| 2734 (r = sshkey_ec_validate_private(k->ecdsa)) != 0) 2735 goto out; 2736 break; 2737 case KEY_ECDSA_CERT: 2738 if ((exponent = BN_new()) == NULL) { 2739 r = SSH_ERR_LIBCRYPTO_ERROR; 2740 goto out; 2741 } 2742 if ((r = sshkey_froms(buf, &k)) != 0 || 2743 (r = sshkey_add_private(k)) != 0 || 2744 (r = sshbuf_get_bignum2(buf, exponent)) != 0) 2745 goto out; 2746 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) { 2747 r = SSH_ERR_LIBCRYPTO_ERROR; 2748 goto out; 2749 } 2750 if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
|
2722 EC_KEY_get0_public_key(k->ecdsa)) != 0) ||
| 2751 EC_KEY_get0_public_key(k->ecdsa))) != 0 ||
|
2723 (r = sshkey_ec_validate_private(k->ecdsa)) != 0) 2724 goto out; 2725 break; 2726# endif /* OPENSSL_HAS_ECC */ 2727 case KEY_RSA: 2728 if ((k = sshkey_new_private(type)) == NULL) { 2729 r = SSH_ERR_ALLOC_FAIL; 2730 goto out; 2731 } 2732 if ((r = sshbuf_get_bignum2(buf, k->rsa->n)) != 0 || 2733 (r = sshbuf_get_bignum2(buf, k->rsa->e)) != 0 || 2734 (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 || 2735 (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || 2736 (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || 2737 (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || 2738 (r = rsa_generate_additional_parameters(k->rsa)) != 0) 2739 goto out; 2740 break; 2741 case KEY_RSA_CERT: 2742 if ((r = sshkey_froms(buf, &k)) != 0 || 2743 (r = sshkey_add_private(k)) != 0 ||
| 2752 (r = sshkey_ec_validate_private(k->ecdsa)) != 0) 2753 goto out; 2754 break; 2755# endif /* OPENSSL_HAS_ECC */ 2756 case KEY_RSA: 2757 if ((k = sshkey_new_private(type)) == NULL) { 2758 r = SSH_ERR_ALLOC_FAIL; 2759 goto out; 2760 } 2761 if ((r = sshbuf_get_bignum2(buf, k->rsa->n)) != 0 || 2762 (r = sshbuf_get_bignum2(buf, k->rsa->e)) != 0 || 2763 (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 || 2764 (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || 2765 (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || 2766 (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || 2767 (r = rsa_generate_additional_parameters(k->rsa)) != 0) 2768 goto out; 2769 break; 2770 case KEY_RSA_CERT: 2771 if ((r = sshkey_froms(buf, &k)) != 0 || 2772 (r = sshkey_add_private(k)) != 0 ||
|
2744 (r = sshbuf_get_bignum2(buf, k->rsa->d) != 0) || 2745 (r = sshbuf_get_bignum2(buf, k->rsa->iqmp) != 0) || 2746 (r = sshbuf_get_bignum2(buf, k->rsa->p) != 0) || 2747 (r = sshbuf_get_bignum2(buf, k->rsa->q) != 0) ||
| 2773 (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 || 2774 (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || 2775 (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || 2776 (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 ||
|
2748 (r = rsa_generate_additional_parameters(k->rsa)) != 0) 2749 goto out; 2750 break; 2751#endif /* WITH_OPENSSL */ 2752 case KEY_ED25519: 2753 if ((k = sshkey_new_private(type)) == NULL) { 2754 r = SSH_ERR_ALLOC_FAIL; 2755 goto out; 2756 } 2757 if ((r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 || 2758 (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0) 2759 goto out; 2760 if (pklen != ED25519_PK_SZ || sklen != ED25519_SK_SZ) { 2761 r = SSH_ERR_INVALID_FORMAT; 2762 goto out; 2763 } 2764 k->ed25519_pk = ed25519_pk; 2765 k->ed25519_sk = ed25519_sk; 2766 ed25519_pk = ed25519_sk = NULL; 2767 break; 2768 case KEY_ED25519_CERT: 2769 if ((r = sshkey_froms(buf, &k)) != 0 || 2770 (r = sshkey_add_private(k)) != 0 || 2771 (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 || 2772 (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0) 2773 goto out; 2774 if (pklen != ED25519_PK_SZ || sklen != ED25519_SK_SZ) { 2775 r = SSH_ERR_INVALID_FORMAT; 2776 goto out; 2777 } 2778 k->ed25519_pk = ed25519_pk; 2779 k->ed25519_sk = ed25519_sk; 2780 ed25519_pk = ed25519_sk = NULL; 2781 break; 2782 default: 2783 r = SSH_ERR_KEY_TYPE_UNKNOWN; 2784 goto out; 2785 } 2786#ifdef WITH_OPENSSL 2787 /* enable blinding */ 2788 switch (k->type) { 2789 case KEY_RSA: 2790 case KEY_RSA_CERT: 2791 case KEY_RSA1: 2792 if (RSA_blinding_on(k->rsa, NULL) != 1) { 2793 r = SSH_ERR_LIBCRYPTO_ERROR; 2794 goto out; 2795 } 2796 break; 2797 } 2798#endif /* WITH_OPENSSL */ 2799 /* success */ 2800 r = 0; 2801 if (kp != NULL) { 2802 *kp = k; 2803 k = NULL; 2804 } 2805 out: 2806 free(tname); 2807 free(curve); 2808#ifdef WITH_OPENSSL 2809 if (exponent != NULL) 2810 BN_clear_free(exponent); 2811#endif /* WITH_OPENSSL */ 2812 sshkey_free(k); 2813 if (ed25519_pk != NULL) { 2814 explicit_bzero(ed25519_pk, pklen); 2815 free(ed25519_pk); 2816 } 2817 if (ed25519_sk != NULL) { 2818 explicit_bzero(ed25519_sk, sklen); 2819 free(ed25519_sk); 2820 } 2821 return r; 2822} 2823 2824#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) 2825int 2826sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) 2827{ 2828 BN_CTX *bnctx; 2829 EC_POINT *nq = NULL; 2830 BIGNUM *order, *x, *y, *tmp; 2831 int ret = SSH_ERR_KEY_INVALID_EC_VALUE; 2832 2833 if ((bnctx = BN_CTX_new()) == NULL) 2834 return SSH_ERR_ALLOC_FAIL; 2835 BN_CTX_start(bnctx); 2836 2837 /* 2838 * We shouldn't ever hit this case because bignum_get_ecpoint() 2839 * refuses to load GF2m points. 2840 */ 2841 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != 2842 NID_X9_62_prime_field) 2843 goto out; 2844 2845 /* Q != infinity */ 2846 if (EC_POINT_is_at_infinity(group, public)) 2847 goto out; 2848 2849 if ((x = BN_CTX_get(bnctx)) == NULL || 2850 (y = BN_CTX_get(bnctx)) == NULL || 2851 (order = BN_CTX_get(bnctx)) == NULL || 2852 (tmp = BN_CTX_get(bnctx)) == NULL) { 2853 ret = SSH_ERR_ALLOC_FAIL; 2854 goto out; 2855 } 2856 2857 /* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */ 2858 if (EC_GROUP_get_order(group, order, bnctx) != 1 || 2859 EC_POINT_get_affine_coordinates_GFp(group, public, 2860 x, y, bnctx) != 1) { 2861 ret = SSH_ERR_LIBCRYPTO_ERROR; 2862 goto out; 2863 } 2864 if (BN_num_bits(x) <= BN_num_bits(order) / 2 || 2865 BN_num_bits(y) <= BN_num_bits(order) / 2) 2866 goto out; 2867 2868 /* nQ == infinity (n == order of subgroup) */ 2869 if ((nq = EC_POINT_new(group)) == NULL) { 2870 ret = SSH_ERR_ALLOC_FAIL; 2871 goto out; 2872 } 2873 if (EC_POINT_mul(group, nq, NULL, public, order, bnctx) != 1) { 2874 ret = SSH_ERR_LIBCRYPTO_ERROR; 2875 goto out; 2876 } 2877 if (EC_POINT_is_at_infinity(group, nq) != 1) 2878 goto out; 2879 2880 /* x < order - 1, y < order - 1 */ 2881 if (!BN_sub(tmp, order, BN_value_one())) { 2882 ret = SSH_ERR_LIBCRYPTO_ERROR; 2883 goto out; 2884 } 2885 if (BN_cmp(x, tmp) >= 0 || BN_cmp(y, tmp) >= 0) 2886 goto out; 2887 ret = 0; 2888 out: 2889 BN_CTX_free(bnctx); 2890 if (nq != NULL) 2891 EC_POINT_free(nq); 2892 return ret; 2893} 2894 2895int 2896sshkey_ec_validate_private(const EC_KEY *key) 2897{ 2898 BN_CTX *bnctx; 2899 BIGNUM *order, *tmp; 2900 int ret = SSH_ERR_KEY_INVALID_EC_VALUE; 2901 2902 if ((bnctx = BN_CTX_new()) == NULL) 2903 return SSH_ERR_ALLOC_FAIL; 2904 BN_CTX_start(bnctx); 2905 2906 if ((order = BN_CTX_get(bnctx)) == NULL || 2907 (tmp = BN_CTX_get(bnctx)) == NULL) { 2908 ret = SSH_ERR_ALLOC_FAIL; 2909 goto out; 2910 } 2911 2912 /* log2(private) > log2(order)/2 */ 2913 if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1) { 2914 ret = SSH_ERR_LIBCRYPTO_ERROR; 2915 goto out; 2916 } 2917 if (BN_num_bits(EC_KEY_get0_private_key(key)) <= 2918 BN_num_bits(order) / 2) 2919 goto out; 2920 2921 /* private < order - 1 */ 2922 if (!BN_sub(tmp, order, BN_value_one())) { 2923 ret = SSH_ERR_LIBCRYPTO_ERROR; 2924 goto out; 2925 } 2926 if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0) 2927 goto out; 2928 ret = 0; 2929 out: 2930 BN_CTX_free(bnctx); 2931 return ret; 2932} 2933 2934void 2935sshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point) 2936{ 2937 BIGNUM *x, *y; 2938 BN_CTX *bnctx; 2939 2940 if (point == NULL) { 2941 fputs("point=(NULL)\n", stderr); 2942 return; 2943 } 2944 if ((bnctx = BN_CTX_new()) == NULL) { 2945 fprintf(stderr, "%s: BN_CTX_new failed\n", __func__); 2946 return; 2947 } 2948 BN_CTX_start(bnctx); 2949 if ((x = BN_CTX_get(bnctx)) == NULL || 2950 (y = BN_CTX_get(bnctx)) == NULL) { 2951 fprintf(stderr, "%s: BN_CTX_get failed\n", __func__); 2952 return; 2953 } 2954 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != 2955 NID_X9_62_prime_field) { 2956 fprintf(stderr, "%s: group is not a prime field\n", __func__); 2957 return; 2958 } 2959 if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y, 2960 bnctx) != 1) { 2961 fprintf(stderr, "%s: EC_POINT_get_affine_coordinates_GFp\n", 2962 __func__); 2963 return; 2964 } 2965 fputs("x=", stderr); 2966 BN_print_fp(stderr, x); 2967 fputs("\ny=", stderr); 2968 BN_print_fp(stderr, y); 2969 fputs("\n", stderr); 2970 BN_CTX_free(bnctx); 2971} 2972 2973void 2974sshkey_dump_ec_key(const EC_KEY *key) 2975{ 2976 const BIGNUM *exponent; 2977 2978 sshkey_dump_ec_point(EC_KEY_get0_group(key), 2979 EC_KEY_get0_public_key(key)); 2980 fputs("exponent=", stderr); 2981 if ((exponent = EC_KEY_get0_private_key(key)) == NULL) 2982 fputs("(NULL)", stderr); 2983 else 2984 BN_print_fp(stderr, EC_KEY_get0_private_key(key)); 2985 fputs("\n", stderr); 2986} 2987#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ 2988 2989static int 2990sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob, 2991 const char *passphrase, const char *comment, const char *ciphername, 2992 int rounds) 2993{ 2994 u_char *cp, *key = NULL, *pubkeyblob = NULL; 2995 u_char salt[SALT_LEN]; 2996 char *b64 = NULL; 2997 size_t i, pubkeylen, keylen, ivlen, blocksize, authlen; 2998 u_int check; 2999 int r = SSH_ERR_INTERNAL_ERROR; 3000 struct sshcipher_ctx ciphercontext; 3001 const struct sshcipher *cipher; 3002 const char *kdfname = KDFNAME; 3003 struct sshbuf *encoded = NULL, *encrypted = NULL, *kdf = NULL; 3004 3005 memset(&ciphercontext, 0, sizeof(ciphercontext)); 3006 3007 if (rounds <= 0) 3008 rounds = DEFAULT_ROUNDS; 3009 if (passphrase == NULL || !strlen(passphrase)) { 3010 ciphername = "none"; 3011 kdfname = "none"; 3012 } else if (ciphername == NULL) 3013 ciphername = DEFAULT_CIPHERNAME; 3014 else if (cipher_number(ciphername) != SSH_CIPHER_SSH2) { 3015 r = SSH_ERR_INVALID_ARGUMENT; 3016 goto out; 3017 } 3018 if ((cipher = cipher_by_name(ciphername)) == NULL) { 3019 r = SSH_ERR_INTERNAL_ERROR; 3020 goto out; 3021 } 3022 3023 if ((kdf = sshbuf_new()) == NULL || 3024 (encoded = sshbuf_new()) == NULL || 3025 (encrypted = sshbuf_new()) == NULL) { 3026 r = SSH_ERR_ALLOC_FAIL; 3027 goto out; 3028 } 3029 blocksize = cipher_blocksize(cipher); 3030 keylen = cipher_keylen(cipher); 3031 ivlen = cipher_ivlen(cipher); 3032 authlen = cipher_authlen(cipher); 3033 if ((key = calloc(1, keylen + ivlen)) == NULL) { 3034 r = SSH_ERR_ALLOC_FAIL; 3035 goto out; 3036 } 3037 if (strcmp(kdfname, "bcrypt") == 0) { 3038 arc4random_buf(salt, SALT_LEN); 3039 if (bcrypt_pbkdf(passphrase, strlen(passphrase), 3040 salt, SALT_LEN, key, keylen + ivlen, rounds) < 0) { 3041 r = SSH_ERR_INVALID_ARGUMENT; 3042 goto out; 3043 } 3044 if ((r = sshbuf_put_string(kdf, salt, SALT_LEN)) != 0 || 3045 (r = sshbuf_put_u32(kdf, rounds)) != 0) 3046 goto out; 3047 } else if (strcmp(kdfname, "none") != 0) { 3048 /* Unsupported KDF type */ 3049 r = SSH_ERR_KEY_UNKNOWN_CIPHER; 3050 goto out; 3051 } 3052 if ((r = cipher_init(&ciphercontext, cipher, key, keylen, 3053 key + keylen, ivlen, 1)) != 0) 3054 goto out; 3055 3056 if ((r = sshbuf_put(encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC))) != 0 || 3057 (r = sshbuf_put_cstring(encoded, ciphername)) != 0 || 3058 (r = sshbuf_put_cstring(encoded, kdfname)) != 0 || 3059 (r = sshbuf_put_stringb(encoded, kdf)) != 0 || 3060 (r = sshbuf_put_u32(encoded, 1)) != 0 || /* number of keys */ 3061 (r = sshkey_to_blob(prv, &pubkeyblob, &pubkeylen)) != 0 || 3062 (r = sshbuf_put_string(encoded, pubkeyblob, pubkeylen)) != 0) 3063 goto out; 3064 3065 /* set up the buffer that will be encrypted */ 3066 3067 /* Random check bytes */ 3068 check = arc4random(); 3069 if ((r = sshbuf_put_u32(encrypted, check)) != 0 || 3070 (r = sshbuf_put_u32(encrypted, check)) != 0) 3071 goto out; 3072 3073 /* append private key and comment*/ 3074 if ((r = sshkey_private_serialize(prv, encrypted)) != 0 || 3075 (r = sshbuf_put_cstring(encrypted, comment)) != 0) 3076 goto out; 3077 3078 /* padding */ 3079 i = 0; 3080 while (sshbuf_len(encrypted) % blocksize) { 3081 if ((r = sshbuf_put_u8(encrypted, ++i & 0xff)) != 0) 3082 goto out; 3083 } 3084 3085 /* length in destination buffer */ 3086 if ((r = sshbuf_put_u32(encoded, sshbuf_len(encrypted))) != 0) 3087 goto out; 3088 3089 /* encrypt */ 3090 if ((r = sshbuf_reserve(encoded, 3091 sshbuf_len(encrypted) + authlen, &cp)) != 0) 3092 goto out; 3093 if ((r = cipher_crypt(&ciphercontext, 0, cp, 3094 sshbuf_ptr(encrypted), sshbuf_len(encrypted), 0, authlen)) != 0) 3095 goto out; 3096 3097 /* uuencode */ 3098 if ((b64 = sshbuf_dtob64(encoded)) == NULL) { 3099 r = SSH_ERR_ALLOC_FAIL; 3100 goto out; 3101 } 3102 3103 sshbuf_reset(blob); 3104 if ((r = sshbuf_put(blob, MARK_BEGIN, MARK_BEGIN_LEN)) != 0) 3105 goto out; 3106 for (i = 0; i < strlen(b64); i++) { 3107 if ((r = sshbuf_put_u8(blob, b64[i])) != 0) 3108 goto out; 3109 /* insert line breaks */ 3110 if (i % 70 == 69 && (r = sshbuf_put_u8(blob, '\n')) != 0) 3111 goto out; 3112 } 3113 if (i % 70 != 69 && (r = sshbuf_put_u8(blob, '\n')) != 0) 3114 goto out; 3115 if ((r = sshbuf_put(blob, MARK_END, MARK_END_LEN)) != 0) 3116 goto out; 3117 3118 /* success */ 3119 r = 0; 3120 3121 out: 3122 sshbuf_free(kdf); 3123 sshbuf_free(encoded); 3124 sshbuf_free(encrypted); 3125 cipher_cleanup(&ciphercontext); 3126 explicit_bzero(salt, sizeof(salt)); 3127 if (key != NULL) { 3128 explicit_bzero(key, keylen + ivlen); 3129 free(key); 3130 } 3131 if (pubkeyblob != NULL) { 3132 explicit_bzero(pubkeyblob, pubkeylen); 3133 free(pubkeyblob); 3134 } 3135 if (b64 != NULL) { 3136 explicit_bzero(b64, strlen(b64)); 3137 free(b64); 3138 } 3139 return r; 3140} 3141 3142static int 3143sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase, 3144 struct sshkey **keyp, char **commentp) 3145{ 3146 char *comment = NULL, *ciphername = NULL, *kdfname = NULL; 3147 const struct sshcipher *cipher = NULL; 3148 const u_char *cp; 3149 int r = SSH_ERR_INTERNAL_ERROR; 3150 size_t encoded_len; 3151 size_t i, keylen = 0, ivlen = 0, authlen = 0, slen = 0; 3152 struct sshbuf *encoded = NULL, *decoded = NULL; 3153 struct sshbuf *kdf = NULL, *decrypted = NULL; 3154 struct sshcipher_ctx ciphercontext; 3155 struct sshkey *k = NULL; 3156 u_char *key = NULL, *salt = NULL, *dp, pad, last; 3157 u_int blocksize, rounds, nkeys, encrypted_len, check1, check2; 3158 3159 memset(&ciphercontext, 0, sizeof(ciphercontext)); 3160 if (keyp != NULL) 3161 *keyp = NULL; 3162 if (commentp != NULL) 3163 *commentp = NULL; 3164 3165 if ((encoded = sshbuf_new()) == NULL || 3166 (decoded = sshbuf_new()) == NULL || 3167 (decrypted = sshbuf_new()) == NULL) { 3168 r = SSH_ERR_ALLOC_FAIL; 3169 goto out; 3170 } 3171 3172 /* check preamble */ 3173 cp = sshbuf_ptr(blob); 3174 encoded_len = sshbuf_len(blob); 3175 if (encoded_len < (MARK_BEGIN_LEN + MARK_END_LEN) || 3176 memcmp(cp, MARK_BEGIN, MARK_BEGIN_LEN) != 0) { 3177 r = SSH_ERR_INVALID_FORMAT; 3178 goto out; 3179 } 3180 cp += MARK_BEGIN_LEN; 3181 encoded_len -= MARK_BEGIN_LEN; 3182 3183 /* Look for end marker, removing whitespace as we go */ 3184 while (encoded_len > 0) { 3185 if (*cp != '\n' && *cp != '\r') { 3186 if ((r = sshbuf_put_u8(encoded, *cp)) != 0) 3187 goto out; 3188 } 3189 last = *cp; 3190 encoded_len--; 3191 cp++; 3192 if (last == '\n') { 3193 if (encoded_len >= MARK_END_LEN && 3194 memcmp(cp, MARK_END, MARK_END_LEN) == 0) { 3195 /* \0 terminate */ 3196 if ((r = sshbuf_put_u8(encoded, 0)) != 0) 3197 goto out; 3198 break; 3199 } 3200 } 3201 } 3202 if (encoded_len == 0) { 3203 r = SSH_ERR_INVALID_FORMAT; 3204 goto out; 3205 } 3206 3207 /* decode base64 */ 3208 if ((r = sshbuf_b64tod(decoded, (char *)sshbuf_ptr(encoded))) != 0) 3209 goto out; 3210 3211 /* check magic */ 3212 if (sshbuf_len(decoded) < sizeof(AUTH_MAGIC) || 3213 memcmp(sshbuf_ptr(decoded), AUTH_MAGIC, sizeof(AUTH_MAGIC))) { 3214 r = SSH_ERR_INVALID_FORMAT; 3215 goto out; 3216 } 3217 /* parse public portion of key */ 3218 if ((r = sshbuf_consume(decoded, sizeof(AUTH_MAGIC))) != 0 || 3219 (r = sshbuf_get_cstring(decoded, &ciphername, NULL)) != 0 || 3220 (r = sshbuf_get_cstring(decoded, &kdfname, NULL)) != 0 || 3221 (r = sshbuf_froms(decoded, &kdf)) != 0 || 3222 (r = sshbuf_get_u32(decoded, &nkeys)) != 0 || 3223 (r = sshbuf_skip_string(decoded)) != 0 || /* pubkey */ 3224 (r = sshbuf_get_u32(decoded, &encrypted_len)) != 0) 3225 goto out; 3226 3227 if ((cipher = cipher_by_name(ciphername)) == NULL) { 3228 r = SSH_ERR_KEY_UNKNOWN_CIPHER; 3229 goto out; 3230 } 3231 if ((passphrase == NULL || strlen(passphrase) == 0) && 3232 strcmp(ciphername, "none") != 0) { 3233 /* passphrase required */ 3234 r = SSH_ERR_KEY_WRONG_PASSPHRASE; 3235 goto out; 3236 } 3237 if (strcmp(kdfname, "none") != 0 && strcmp(kdfname, "bcrypt") != 0) { 3238 r = SSH_ERR_KEY_UNKNOWN_CIPHER; 3239 goto out; 3240 } 3241 if (!strcmp(kdfname, "none") && strcmp(ciphername, "none") != 0) { 3242 r = SSH_ERR_INVALID_FORMAT; 3243 goto out; 3244 } 3245 if (nkeys != 1) { 3246 /* XXX only one key supported */ 3247 r = SSH_ERR_INVALID_FORMAT; 3248 goto out; 3249 } 3250 3251 /* check size of encrypted key blob */ 3252 blocksize = cipher_blocksize(cipher); 3253 if (encrypted_len < blocksize || (encrypted_len % blocksize) != 0) { 3254 r = SSH_ERR_INVALID_FORMAT; 3255 goto out; 3256 } 3257 3258 /* setup key */ 3259 keylen = cipher_keylen(cipher); 3260 ivlen = cipher_ivlen(cipher); 3261 authlen = cipher_authlen(cipher); 3262 if ((key = calloc(1, keylen + ivlen)) == NULL) { 3263 r = SSH_ERR_ALLOC_FAIL; 3264 goto out; 3265 } 3266 if (strcmp(kdfname, "bcrypt") == 0) { 3267 if ((r = sshbuf_get_string(kdf, &salt, &slen)) != 0 || 3268 (r = sshbuf_get_u32(kdf, &rounds)) != 0) 3269 goto out; 3270 if (bcrypt_pbkdf(passphrase, strlen(passphrase), salt, slen, 3271 key, keylen + ivlen, rounds) < 0) { 3272 r = SSH_ERR_INVALID_FORMAT; 3273 goto out; 3274 } 3275 } 3276 3277 /* check that an appropriate amount of auth data is present */ 3278 if (sshbuf_len(decoded) < encrypted_len + authlen) { 3279 r = SSH_ERR_INVALID_FORMAT; 3280 goto out; 3281 } 3282 3283 /* decrypt private portion of key */ 3284 if ((r = sshbuf_reserve(decrypted, encrypted_len, &dp)) != 0 || 3285 (r = cipher_init(&ciphercontext, cipher, key, keylen, 3286 key + keylen, ivlen, 0)) != 0) 3287 goto out; 3288 if ((r = cipher_crypt(&ciphercontext, 0, dp, sshbuf_ptr(decoded), 3289 encrypted_len, 0, authlen)) != 0) { 3290 /* an integrity error here indicates an incorrect passphrase */ 3291 if (r == SSH_ERR_MAC_INVALID) 3292 r = SSH_ERR_KEY_WRONG_PASSPHRASE; 3293 goto out; 3294 } 3295 if ((r = sshbuf_consume(decoded, encrypted_len + authlen)) != 0) 3296 goto out; 3297 /* there should be no trailing data */ 3298 if (sshbuf_len(decoded) != 0) { 3299 r = SSH_ERR_INVALID_FORMAT; 3300 goto out; 3301 } 3302 3303 /* check check bytes */ 3304 if ((r = sshbuf_get_u32(decrypted, &check1)) != 0 || 3305 (r = sshbuf_get_u32(decrypted, &check2)) != 0) 3306 goto out; 3307 if (check1 != check2) { 3308 r = SSH_ERR_KEY_WRONG_PASSPHRASE; 3309 goto out; 3310 } 3311 3312 /* Load the private key and comment */ 3313 if ((r = sshkey_private_deserialize(decrypted, &k)) != 0 || 3314 (r = sshbuf_get_cstring(decrypted, &comment, NULL)) != 0) 3315 goto out; 3316 3317 /* Check deterministic padding */ 3318 i = 0; 3319 while (sshbuf_len(decrypted)) { 3320 if ((r = sshbuf_get_u8(decrypted, &pad)) != 0) 3321 goto out; 3322 if (pad != (++i & 0xff)) { 3323 r = SSH_ERR_INVALID_FORMAT; 3324 goto out; 3325 } 3326 } 3327 3328 /* XXX decode pubkey and check against private */ 3329 3330 /* success */ 3331 r = 0; 3332 if (keyp != NULL) { 3333 *keyp = k; 3334 k = NULL; 3335 } 3336 if (commentp != NULL) { 3337 *commentp = comment; 3338 comment = NULL; 3339 } 3340 out: 3341 pad = 0; 3342 cipher_cleanup(&ciphercontext); 3343 free(ciphername); 3344 free(kdfname); 3345 free(comment); 3346 if (salt != NULL) { 3347 explicit_bzero(salt, slen); 3348 free(salt); 3349 } 3350 if (key != NULL) { 3351 explicit_bzero(key, keylen + ivlen); 3352 free(key); 3353 } 3354 sshbuf_free(encoded); 3355 sshbuf_free(decoded); 3356 sshbuf_free(kdf); 3357 sshbuf_free(decrypted); 3358 sshkey_free(k); 3359 return r; 3360} 3361 3362#if WITH_SSH1 3363/* 3364 * Serialises the authentication (private) key to a blob, encrypting it with 3365 * passphrase. The identification of the blob (lowest 64 bits of n) will 3366 * precede the key to provide identification of the key without needing a 3367 * passphrase. 3368 */ 3369static int 3370sshkey_private_rsa1_to_blob(struct sshkey *key, struct sshbuf *blob, 3371 const char *passphrase, const char *comment) 3372{ 3373 struct sshbuf *buffer = NULL, *encrypted = NULL; 3374 u_char buf[8]; 3375 int r, cipher_num; 3376 struct sshcipher_ctx ciphercontext; 3377 const struct sshcipher *cipher; 3378 u_char *cp; 3379 3380 /* 3381 * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting 3382 * to another cipher; otherwise use SSH_AUTHFILE_CIPHER. 3383 */ 3384 cipher_num = (strcmp(passphrase, "") == 0) ? 3385 SSH_CIPHER_NONE : SSH_CIPHER_3DES; 3386 if ((cipher = cipher_by_number(cipher_num)) == NULL) 3387 return SSH_ERR_INTERNAL_ERROR; 3388 3389 /* This buffer is used to build the secret part of the private key. */ 3390 if ((buffer = sshbuf_new()) == NULL) 3391 return SSH_ERR_ALLOC_FAIL; 3392 3393 /* Put checkbytes for checking passphrase validity. */ 3394 if ((r = sshbuf_reserve(buffer, 4, &cp)) != 0) 3395 goto out; 3396 arc4random_buf(cp, 2); 3397 memcpy(cp + 2, cp, 2); 3398 3399 /* 3400 * Store the private key (n and e will not be stored because they 3401 * will be stored in plain text, and storing them also in encrypted 3402 * format would just give known plaintext). 3403 * Note: q and p are stored in reverse order to SSL. 3404 */ 3405 if ((r = sshbuf_put_bignum1(buffer, key->rsa->d)) != 0 || 3406 (r = sshbuf_put_bignum1(buffer, key->rsa->iqmp)) != 0 || 3407 (r = sshbuf_put_bignum1(buffer, key->rsa->q)) != 0 || 3408 (r = sshbuf_put_bignum1(buffer, key->rsa->p)) != 0) 3409 goto out; 3410 3411 /* Pad the part to be encrypted to a size that is a multiple of 8. */ 3412 explicit_bzero(buf, 8); 3413 if ((r = sshbuf_put(buffer, buf, 8 - (sshbuf_len(buffer) % 8))) != 0) 3414 goto out; 3415 3416 /* This buffer will be used to contain the data in the file. */ 3417 if ((encrypted = sshbuf_new()) == NULL) { 3418 r = SSH_ERR_ALLOC_FAIL; 3419 goto out; 3420 } 3421 3422 /* First store keyfile id string. */ 3423 if ((r = sshbuf_put(encrypted, LEGACY_BEGIN, 3424 sizeof(LEGACY_BEGIN))) != 0) 3425 goto out; 3426 3427 /* Store cipher type and "reserved" field. */ 3428 if ((r = sshbuf_put_u8(encrypted, cipher_num)) != 0 || 3429 (r = sshbuf_put_u32(encrypted, 0)) != 0) 3430 goto out; 3431 3432 /* Store public key. This will be in plain text. */ 3433 if ((r = sshbuf_put_u32(encrypted, BN_num_bits(key->rsa->n))) != 0 ||
| 2777 (r = rsa_generate_additional_parameters(k->rsa)) != 0) 2778 goto out; 2779 break; 2780#endif /* WITH_OPENSSL */ 2781 case KEY_ED25519: 2782 if ((k = sshkey_new_private(type)) == NULL) { 2783 r = SSH_ERR_ALLOC_FAIL; 2784 goto out; 2785 } 2786 if ((r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 || 2787 (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0) 2788 goto out; 2789 if (pklen != ED25519_PK_SZ || sklen != ED25519_SK_SZ) { 2790 r = SSH_ERR_INVALID_FORMAT; 2791 goto out; 2792 } 2793 k->ed25519_pk = ed25519_pk; 2794 k->ed25519_sk = ed25519_sk; 2795 ed25519_pk = ed25519_sk = NULL; 2796 break; 2797 case KEY_ED25519_CERT: 2798 if ((r = sshkey_froms(buf, &k)) != 0 || 2799 (r = sshkey_add_private(k)) != 0 || 2800 (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 || 2801 (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0) 2802 goto out; 2803 if (pklen != ED25519_PK_SZ || sklen != ED25519_SK_SZ) { 2804 r = SSH_ERR_INVALID_FORMAT; 2805 goto out; 2806 } 2807 k->ed25519_pk = ed25519_pk; 2808 k->ed25519_sk = ed25519_sk; 2809 ed25519_pk = ed25519_sk = NULL; 2810 break; 2811 default: 2812 r = SSH_ERR_KEY_TYPE_UNKNOWN; 2813 goto out; 2814 } 2815#ifdef WITH_OPENSSL 2816 /* enable blinding */ 2817 switch (k->type) { 2818 case KEY_RSA: 2819 case KEY_RSA_CERT: 2820 case KEY_RSA1: 2821 if (RSA_blinding_on(k->rsa, NULL) != 1) { 2822 r = SSH_ERR_LIBCRYPTO_ERROR; 2823 goto out; 2824 } 2825 break; 2826 } 2827#endif /* WITH_OPENSSL */ 2828 /* success */ 2829 r = 0; 2830 if (kp != NULL) { 2831 *kp = k; 2832 k = NULL; 2833 } 2834 out: 2835 free(tname); 2836 free(curve); 2837#ifdef WITH_OPENSSL 2838 if (exponent != NULL) 2839 BN_clear_free(exponent); 2840#endif /* WITH_OPENSSL */ 2841 sshkey_free(k); 2842 if (ed25519_pk != NULL) { 2843 explicit_bzero(ed25519_pk, pklen); 2844 free(ed25519_pk); 2845 } 2846 if (ed25519_sk != NULL) { 2847 explicit_bzero(ed25519_sk, sklen); 2848 free(ed25519_sk); 2849 } 2850 return r; 2851} 2852 2853#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) 2854int 2855sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) 2856{ 2857 BN_CTX *bnctx; 2858 EC_POINT *nq = NULL; 2859 BIGNUM *order, *x, *y, *tmp; 2860 int ret = SSH_ERR_KEY_INVALID_EC_VALUE; 2861 2862 if ((bnctx = BN_CTX_new()) == NULL) 2863 return SSH_ERR_ALLOC_FAIL; 2864 BN_CTX_start(bnctx); 2865 2866 /* 2867 * We shouldn't ever hit this case because bignum_get_ecpoint() 2868 * refuses to load GF2m points. 2869 */ 2870 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != 2871 NID_X9_62_prime_field) 2872 goto out; 2873 2874 /* Q != infinity */ 2875 if (EC_POINT_is_at_infinity(group, public)) 2876 goto out; 2877 2878 if ((x = BN_CTX_get(bnctx)) == NULL || 2879 (y = BN_CTX_get(bnctx)) == NULL || 2880 (order = BN_CTX_get(bnctx)) == NULL || 2881 (tmp = BN_CTX_get(bnctx)) == NULL) { 2882 ret = SSH_ERR_ALLOC_FAIL; 2883 goto out; 2884 } 2885 2886 /* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */ 2887 if (EC_GROUP_get_order(group, order, bnctx) != 1 || 2888 EC_POINT_get_affine_coordinates_GFp(group, public, 2889 x, y, bnctx) != 1) { 2890 ret = SSH_ERR_LIBCRYPTO_ERROR; 2891 goto out; 2892 } 2893 if (BN_num_bits(x) <= BN_num_bits(order) / 2 || 2894 BN_num_bits(y) <= BN_num_bits(order) / 2) 2895 goto out; 2896 2897 /* nQ == infinity (n == order of subgroup) */ 2898 if ((nq = EC_POINT_new(group)) == NULL) { 2899 ret = SSH_ERR_ALLOC_FAIL; 2900 goto out; 2901 } 2902 if (EC_POINT_mul(group, nq, NULL, public, order, bnctx) != 1) { 2903 ret = SSH_ERR_LIBCRYPTO_ERROR; 2904 goto out; 2905 } 2906 if (EC_POINT_is_at_infinity(group, nq) != 1) 2907 goto out; 2908 2909 /* x < order - 1, y < order - 1 */ 2910 if (!BN_sub(tmp, order, BN_value_one())) { 2911 ret = SSH_ERR_LIBCRYPTO_ERROR; 2912 goto out; 2913 } 2914 if (BN_cmp(x, tmp) >= 0 || BN_cmp(y, tmp) >= 0) 2915 goto out; 2916 ret = 0; 2917 out: 2918 BN_CTX_free(bnctx); 2919 if (nq != NULL) 2920 EC_POINT_free(nq); 2921 return ret; 2922} 2923 2924int 2925sshkey_ec_validate_private(const EC_KEY *key) 2926{ 2927 BN_CTX *bnctx; 2928 BIGNUM *order, *tmp; 2929 int ret = SSH_ERR_KEY_INVALID_EC_VALUE; 2930 2931 if ((bnctx = BN_CTX_new()) == NULL) 2932 return SSH_ERR_ALLOC_FAIL; 2933 BN_CTX_start(bnctx); 2934 2935 if ((order = BN_CTX_get(bnctx)) == NULL || 2936 (tmp = BN_CTX_get(bnctx)) == NULL) { 2937 ret = SSH_ERR_ALLOC_FAIL; 2938 goto out; 2939 } 2940 2941 /* log2(private) > log2(order)/2 */ 2942 if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1) { 2943 ret = SSH_ERR_LIBCRYPTO_ERROR; 2944 goto out; 2945 } 2946 if (BN_num_bits(EC_KEY_get0_private_key(key)) <= 2947 BN_num_bits(order) / 2) 2948 goto out; 2949 2950 /* private < order - 1 */ 2951 if (!BN_sub(tmp, order, BN_value_one())) { 2952 ret = SSH_ERR_LIBCRYPTO_ERROR; 2953 goto out; 2954 } 2955 if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0) 2956 goto out; 2957 ret = 0; 2958 out: 2959 BN_CTX_free(bnctx); 2960 return ret; 2961} 2962 2963void 2964sshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point) 2965{ 2966 BIGNUM *x, *y; 2967 BN_CTX *bnctx; 2968 2969 if (point == NULL) { 2970 fputs("point=(NULL)\n", stderr); 2971 return; 2972 } 2973 if ((bnctx = BN_CTX_new()) == NULL) { 2974 fprintf(stderr, "%s: BN_CTX_new failed\n", __func__); 2975 return; 2976 } 2977 BN_CTX_start(bnctx); 2978 if ((x = BN_CTX_get(bnctx)) == NULL || 2979 (y = BN_CTX_get(bnctx)) == NULL) { 2980 fprintf(stderr, "%s: BN_CTX_get failed\n", __func__); 2981 return; 2982 } 2983 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != 2984 NID_X9_62_prime_field) { 2985 fprintf(stderr, "%s: group is not a prime field\n", __func__); 2986 return; 2987 } 2988 if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y, 2989 bnctx) != 1) { 2990 fprintf(stderr, "%s: EC_POINT_get_affine_coordinates_GFp\n", 2991 __func__); 2992 return; 2993 } 2994 fputs("x=", stderr); 2995 BN_print_fp(stderr, x); 2996 fputs("\ny=", stderr); 2997 BN_print_fp(stderr, y); 2998 fputs("\n", stderr); 2999 BN_CTX_free(bnctx); 3000} 3001 3002void 3003sshkey_dump_ec_key(const EC_KEY *key) 3004{ 3005 const BIGNUM *exponent; 3006 3007 sshkey_dump_ec_point(EC_KEY_get0_group(key), 3008 EC_KEY_get0_public_key(key)); 3009 fputs("exponent=", stderr); 3010 if ((exponent = EC_KEY_get0_private_key(key)) == NULL) 3011 fputs("(NULL)", stderr); 3012 else 3013 BN_print_fp(stderr, EC_KEY_get0_private_key(key)); 3014 fputs("\n", stderr); 3015} 3016#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ 3017 3018static int 3019sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob, 3020 const char *passphrase, const char *comment, const char *ciphername, 3021 int rounds) 3022{ 3023 u_char *cp, *key = NULL, *pubkeyblob = NULL; 3024 u_char salt[SALT_LEN]; 3025 char *b64 = NULL; 3026 size_t i, pubkeylen, keylen, ivlen, blocksize, authlen; 3027 u_int check; 3028 int r = SSH_ERR_INTERNAL_ERROR; 3029 struct sshcipher_ctx ciphercontext; 3030 const struct sshcipher *cipher; 3031 const char *kdfname = KDFNAME; 3032 struct sshbuf *encoded = NULL, *encrypted = NULL, *kdf = NULL; 3033 3034 memset(&ciphercontext, 0, sizeof(ciphercontext)); 3035 3036 if (rounds <= 0) 3037 rounds = DEFAULT_ROUNDS; 3038 if (passphrase == NULL || !strlen(passphrase)) { 3039 ciphername = "none"; 3040 kdfname = "none"; 3041 } else if (ciphername == NULL) 3042 ciphername = DEFAULT_CIPHERNAME; 3043 else if (cipher_number(ciphername) != SSH_CIPHER_SSH2) { 3044 r = SSH_ERR_INVALID_ARGUMENT; 3045 goto out; 3046 } 3047 if ((cipher = cipher_by_name(ciphername)) == NULL) { 3048 r = SSH_ERR_INTERNAL_ERROR; 3049 goto out; 3050 } 3051 3052 if ((kdf = sshbuf_new()) == NULL || 3053 (encoded = sshbuf_new()) == NULL || 3054 (encrypted = sshbuf_new()) == NULL) { 3055 r = SSH_ERR_ALLOC_FAIL; 3056 goto out; 3057 } 3058 blocksize = cipher_blocksize(cipher); 3059 keylen = cipher_keylen(cipher); 3060 ivlen = cipher_ivlen(cipher); 3061 authlen = cipher_authlen(cipher); 3062 if ((key = calloc(1, keylen + ivlen)) == NULL) { 3063 r = SSH_ERR_ALLOC_FAIL; 3064 goto out; 3065 } 3066 if (strcmp(kdfname, "bcrypt") == 0) { 3067 arc4random_buf(salt, SALT_LEN); 3068 if (bcrypt_pbkdf(passphrase, strlen(passphrase), 3069 salt, SALT_LEN, key, keylen + ivlen, rounds) < 0) { 3070 r = SSH_ERR_INVALID_ARGUMENT; 3071 goto out; 3072 } 3073 if ((r = sshbuf_put_string(kdf, salt, SALT_LEN)) != 0 || 3074 (r = sshbuf_put_u32(kdf, rounds)) != 0) 3075 goto out; 3076 } else if (strcmp(kdfname, "none") != 0) { 3077 /* Unsupported KDF type */ 3078 r = SSH_ERR_KEY_UNKNOWN_CIPHER; 3079 goto out; 3080 } 3081 if ((r = cipher_init(&ciphercontext, cipher, key, keylen, 3082 key + keylen, ivlen, 1)) != 0) 3083 goto out; 3084 3085 if ((r = sshbuf_put(encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC))) != 0 || 3086 (r = sshbuf_put_cstring(encoded, ciphername)) != 0 || 3087 (r = sshbuf_put_cstring(encoded, kdfname)) != 0 || 3088 (r = sshbuf_put_stringb(encoded, kdf)) != 0 || 3089 (r = sshbuf_put_u32(encoded, 1)) != 0 || /* number of keys */ 3090 (r = sshkey_to_blob(prv, &pubkeyblob, &pubkeylen)) != 0 || 3091 (r = sshbuf_put_string(encoded, pubkeyblob, pubkeylen)) != 0) 3092 goto out; 3093 3094 /* set up the buffer that will be encrypted */ 3095 3096 /* Random check bytes */ 3097 check = arc4random(); 3098 if ((r = sshbuf_put_u32(encrypted, check)) != 0 || 3099 (r = sshbuf_put_u32(encrypted, check)) != 0) 3100 goto out; 3101 3102 /* append private key and comment*/ 3103 if ((r = sshkey_private_serialize(prv, encrypted)) != 0 || 3104 (r = sshbuf_put_cstring(encrypted, comment)) != 0) 3105 goto out; 3106 3107 /* padding */ 3108 i = 0; 3109 while (sshbuf_len(encrypted) % blocksize) { 3110 if ((r = sshbuf_put_u8(encrypted, ++i & 0xff)) != 0) 3111 goto out; 3112 } 3113 3114 /* length in destination buffer */ 3115 if ((r = sshbuf_put_u32(encoded, sshbuf_len(encrypted))) != 0) 3116 goto out; 3117 3118 /* encrypt */ 3119 if ((r = sshbuf_reserve(encoded, 3120 sshbuf_len(encrypted) + authlen, &cp)) != 0) 3121 goto out; 3122 if ((r = cipher_crypt(&ciphercontext, 0, cp, 3123 sshbuf_ptr(encrypted), sshbuf_len(encrypted), 0, authlen)) != 0) 3124 goto out; 3125 3126 /* uuencode */ 3127 if ((b64 = sshbuf_dtob64(encoded)) == NULL) { 3128 r = SSH_ERR_ALLOC_FAIL; 3129 goto out; 3130 } 3131 3132 sshbuf_reset(blob); 3133 if ((r = sshbuf_put(blob, MARK_BEGIN, MARK_BEGIN_LEN)) != 0) 3134 goto out; 3135 for (i = 0; i < strlen(b64); i++) { 3136 if ((r = sshbuf_put_u8(blob, b64[i])) != 0) 3137 goto out; 3138 /* insert line breaks */ 3139 if (i % 70 == 69 && (r = sshbuf_put_u8(blob, '\n')) != 0) 3140 goto out; 3141 } 3142 if (i % 70 != 69 && (r = sshbuf_put_u8(blob, '\n')) != 0) 3143 goto out; 3144 if ((r = sshbuf_put(blob, MARK_END, MARK_END_LEN)) != 0) 3145 goto out; 3146 3147 /* success */ 3148 r = 0; 3149 3150 out: 3151 sshbuf_free(kdf); 3152 sshbuf_free(encoded); 3153 sshbuf_free(encrypted); 3154 cipher_cleanup(&ciphercontext); 3155 explicit_bzero(salt, sizeof(salt)); 3156 if (key != NULL) { 3157 explicit_bzero(key, keylen + ivlen); 3158 free(key); 3159 } 3160 if (pubkeyblob != NULL) { 3161 explicit_bzero(pubkeyblob, pubkeylen); 3162 free(pubkeyblob); 3163 } 3164 if (b64 != NULL) { 3165 explicit_bzero(b64, strlen(b64)); 3166 free(b64); 3167 } 3168 return r; 3169} 3170 3171static int 3172sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase, 3173 struct sshkey **keyp, char **commentp) 3174{ 3175 char *comment = NULL, *ciphername = NULL, *kdfname = NULL; 3176 const struct sshcipher *cipher = NULL; 3177 const u_char *cp; 3178 int r = SSH_ERR_INTERNAL_ERROR; 3179 size_t encoded_len; 3180 size_t i, keylen = 0, ivlen = 0, authlen = 0, slen = 0; 3181 struct sshbuf *encoded = NULL, *decoded = NULL; 3182 struct sshbuf *kdf = NULL, *decrypted = NULL; 3183 struct sshcipher_ctx ciphercontext; 3184 struct sshkey *k = NULL; 3185 u_char *key = NULL, *salt = NULL, *dp, pad, last; 3186 u_int blocksize, rounds, nkeys, encrypted_len, check1, check2; 3187 3188 memset(&ciphercontext, 0, sizeof(ciphercontext)); 3189 if (keyp != NULL) 3190 *keyp = NULL; 3191 if (commentp != NULL) 3192 *commentp = NULL; 3193 3194 if ((encoded = sshbuf_new()) == NULL || 3195 (decoded = sshbuf_new()) == NULL || 3196 (decrypted = sshbuf_new()) == NULL) { 3197 r = SSH_ERR_ALLOC_FAIL; 3198 goto out; 3199 } 3200 3201 /* check preamble */ 3202 cp = sshbuf_ptr(blob); 3203 encoded_len = sshbuf_len(blob); 3204 if (encoded_len < (MARK_BEGIN_LEN + MARK_END_LEN) || 3205 memcmp(cp, MARK_BEGIN, MARK_BEGIN_LEN) != 0) { 3206 r = SSH_ERR_INVALID_FORMAT; 3207 goto out; 3208 } 3209 cp += MARK_BEGIN_LEN; 3210 encoded_len -= MARK_BEGIN_LEN; 3211 3212 /* Look for end marker, removing whitespace as we go */ 3213 while (encoded_len > 0) { 3214 if (*cp != '\n' && *cp != '\r') { 3215 if ((r = sshbuf_put_u8(encoded, *cp)) != 0) 3216 goto out; 3217 } 3218 last = *cp; 3219 encoded_len--; 3220 cp++; 3221 if (last == '\n') { 3222 if (encoded_len >= MARK_END_LEN && 3223 memcmp(cp, MARK_END, MARK_END_LEN) == 0) { 3224 /* \0 terminate */ 3225 if ((r = sshbuf_put_u8(encoded, 0)) != 0) 3226 goto out; 3227 break; 3228 } 3229 } 3230 } 3231 if (encoded_len == 0) { 3232 r = SSH_ERR_INVALID_FORMAT; 3233 goto out; 3234 } 3235 3236 /* decode base64 */ 3237 if ((r = sshbuf_b64tod(decoded, (char *)sshbuf_ptr(encoded))) != 0) 3238 goto out; 3239 3240 /* check magic */ 3241 if (sshbuf_len(decoded) < sizeof(AUTH_MAGIC) || 3242 memcmp(sshbuf_ptr(decoded), AUTH_MAGIC, sizeof(AUTH_MAGIC))) { 3243 r = SSH_ERR_INVALID_FORMAT; 3244 goto out; 3245 } 3246 /* parse public portion of key */ 3247 if ((r = sshbuf_consume(decoded, sizeof(AUTH_MAGIC))) != 0 || 3248 (r = sshbuf_get_cstring(decoded, &ciphername, NULL)) != 0 || 3249 (r = sshbuf_get_cstring(decoded, &kdfname, NULL)) != 0 || 3250 (r = sshbuf_froms(decoded, &kdf)) != 0 || 3251 (r = sshbuf_get_u32(decoded, &nkeys)) != 0 || 3252 (r = sshbuf_skip_string(decoded)) != 0 || /* pubkey */ 3253 (r = sshbuf_get_u32(decoded, &encrypted_len)) != 0) 3254 goto out; 3255 3256 if ((cipher = cipher_by_name(ciphername)) == NULL) { 3257 r = SSH_ERR_KEY_UNKNOWN_CIPHER; 3258 goto out; 3259 } 3260 if ((passphrase == NULL || strlen(passphrase) == 0) && 3261 strcmp(ciphername, "none") != 0) { 3262 /* passphrase required */ 3263 r = SSH_ERR_KEY_WRONG_PASSPHRASE; 3264 goto out; 3265 } 3266 if (strcmp(kdfname, "none") != 0 && strcmp(kdfname, "bcrypt") != 0) { 3267 r = SSH_ERR_KEY_UNKNOWN_CIPHER; 3268 goto out; 3269 } 3270 if (!strcmp(kdfname, "none") && strcmp(ciphername, "none") != 0) { 3271 r = SSH_ERR_INVALID_FORMAT; 3272 goto out; 3273 } 3274 if (nkeys != 1) { 3275 /* XXX only one key supported */ 3276 r = SSH_ERR_INVALID_FORMAT; 3277 goto out; 3278 } 3279 3280 /* check size of encrypted key blob */ 3281 blocksize = cipher_blocksize(cipher); 3282 if (encrypted_len < blocksize || (encrypted_len % blocksize) != 0) { 3283 r = SSH_ERR_INVALID_FORMAT; 3284 goto out; 3285 } 3286 3287 /* setup key */ 3288 keylen = cipher_keylen(cipher); 3289 ivlen = cipher_ivlen(cipher); 3290 authlen = cipher_authlen(cipher); 3291 if ((key = calloc(1, keylen + ivlen)) == NULL) { 3292 r = SSH_ERR_ALLOC_FAIL; 3293 goto out; 3294 } 3295 if (strcmp(kdfname, "bcrypt") == 0) { 3296 if ((r = sshbuf_get_string(kdf, &salt, &slen)) != 0 || 3297 (r = sshbuf_get_u32(kdf, &rounds)) != 0) 3298 goto out; 3299 if (bcrypt_pbkdf(passphrase, strlen(passphrase), salt, slen, 3300 key, keylen + ivlen, rounds) < 0) { 3301 r = SSH_ERR_INVALID_FORMAT; 3302 goto out; 3303 } 3304 } 3305 3306 /* check that an appropriate amount of auth data is present */ 3307 if (sshbuf_len(decoded) < encrypted_len + authlen) { 3308 r = SSH_ERR_INVALID_FORMAT; 3309 goto out; 3310 } 3311 3312 /* decrypt private portion of key */ 3313 if ((r = sshbuf_reserve(decrypted, encrypted_len, &dp)) != 0 || 3314 (r = cipher_init(&ciphercontext, cipher, key, keylen, 3315 key + keylen, ivlen, 0)) != 0) 3316 goto out; 3317 if ((r = cipher_crypt(&ciphercontext, 0, dp, sshbuf_ptr(decoded), 3318 encrypted_len, 0, authlen)) != 0) { 3319 /* an integrity error here indicates an incorrect passphrase */ 3320 if (r == SSH_ERR_MAC_INVALID) 3321 r = SSH_ERR_KEY_WRONG_PASSPHRASE; 3322 goto out; 3323 } 3324 if ((r = sshbuf_consume(decoded, encrypted_len + authlen)) != 0) 3325 goto out; 3326 /* there should be no trailing data */ 3327 if (sshbuf_len(decoded) != 0) { 3328 r = SSH_ERR_INVALID_FORMAT; 3329 goto out; 3330 } 3331 3332 /* check check bytes */ 3333 if ((r = sshbuf_get_u32(decrypted, &check1)) != 0 || 3334 (r = sshbuf_get_u32(decrypted, &check2)) != 0) 3335 goto out; 3336 if (check1 != check2) { 3337 r = SSH_ERR_KEY_WRONG_PASSPHRASE; 3338 goto out; 3339 } 3340 3341 /* Load the private key and comment */ 3342 if ((r = sshkey_private_deserialize(decrypted, &k)) != 0 || 3343 (r = sshbuf_get_cstring(decrypted, &comment, NULL)) != 0) 3344 goto out; 3345 3346 /* Check deterministic padding */ 3347 i = 0; 3348 while (sshbuf_len(decrypted)) { 3349 if ((r = sshbuf_get_u8(decrypted, &pad)) != 0) 3350 goto out; 3351 if (pad != (++i & 0xff)) { 3352 r = SSH_ERR_INVALID_FORMAT; 3353 goto out; 3354 } 3355 } 3356 3357 /* XXX decode pubkey and check against private */ 3358 3359 /* success */ 3360 r = 0; 3361 if (keyp != NULL) { 3362 *keyp = k; 3363 k = NULL; 3364 } 3365 if (commentp != NULL) { 3366 *commentp = comment; 3367 comment = NULL; 3368 } 3369 out: 3370 pad = 0; 3371 cipher_cleanup(&ciphercontext); 3372 free(ciphername); 3373 free(kdfname); 3374 free(comment); 3375 if (salt != NULL) { 3376 explicit_bzero(salt, slen); 3377 free(salt); 3378 } 3379 if (key != NULL) { 3380 explicit_bzero(key, keylen + ivlen); 3381 free(key); 3382 } 3383 sshbuf_free(encoded); 3384 sshbuf_free(decoded); 3385 sshbuf_free(kdf); 3386 sshbuf_free(decrypted); 3387 sshkey_free(k); 3388 return r; 3389} 3390 3391#if WITH_SSH1 3392/* 3393 * Serialises the authentication (private) key to a blob, encrypting it with 3394 * passphrase. The identification of the blob (lowest 64 bits of n) will 3395 * precede the key to provide identification of the key without needing a 3396 * passphrase. 3397 */ 3398static int 3399sshkey_private_rsa1_to_blob(struct sshkey *key, struct sshbuf *blob, 3400 const char *passphrase, const char *comment) 3401{ 3402 struct sshbuf *buffer = NULL, *encrypted = NULL; 3403 u_char buf[8]; 3404 int r, cipher_num; 3405 struct sshcipher_ctx ciphercontext; 3406 const struct sshcipher *cipher; 3407 u_char *cp; 3408 3409 /* 3410 * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting 3411 * to another cipher; otherwise use SSH_AUTHFILE_CIPHER. 3412 */ 3413 cipher_num = (strcmp(passphrase, "") == 0) ? 3414 SSH_CIPHER_NONE : SSH_CIPHER_3DES; 3415 if ((cipher = cipher_by_number(cipher_num)) == NULL) 3416 return SSH_ERR_INTERNAL_ERROR; 3417 3418 /* This buffer is used to build the secret part of the private key. */ 3419 if ((buffer = sshbuf_new()) == NULL) 3420 return SSH_ERR_ALLOC_FAIL; 3421 3422 /* Put checkbytes for checking passphrase validity. */ 3423 if ((r = sshbuf_reserve(buffer, 4, &cp)) != 0) 3424 goto out; 3425 arc4random_buf(cp, 2); 3426 memcpy(cp + 2, cp, 2); 3427 3428 /* 3429 * Store the private key (n and e will not be stored because they 3430 * will be stored in plain text, and storing them also in encrypted 3431 * format would just give known plaintext). 3432 * Note: q and p are stored in reverse order to SSL. 3433 */ 3434 if ((r = sshbuf_put_bignum1(buffer, key->rsa->d)) != 0 || 3435 (r = sshbuf_put_bignum1(buffer, key->rsa->iqmp)) != 0 || 3436 (r = sshbuf_put_bignum1(buffer, key->rsa->q)) != 0 || 3437 (r = sshbuf_put_bignum1(buffer, key->rsa->p)) != 0) 3438 goto out; 3439 3440 /* Pad the part to be encrypted to a size that is a multiple of 8. */ 3441 explicit_bzero(buf, 8); 3442 if ((r = sshbuf_put(buffer, buf, 8 - (sshbuf_len(buffer) % 8))) != 0) 3443 goto out; 3444 3445 /* This buffer will be used to contain the data in the file. */ 3446 if ((encrypted = sshbuf_new()) == NULL) { 3447 r = SSH_ERR_ALLOC_FAIL; 3448 goto out; 3449 } 3450 3451 /* First store keyfile id string. */ 3452 if ((r = sshbuf_put(encrypted, LEGACY_BEGIN, 3453 sizeof(LEGACY_BEGIN))) != 0) 3454 goto out; 3455 3456 /* Store cipher type and "reserved" field. */ 3457 if ((r = sshbuf_put_u8(encrypted, cipher_num)) != 0 || 3458 (r = sshbuf_put_u32(encrypted, 0)) != 0) 3459 goto out; 3460 3461 /* Store public key. This will be in plain text. */ 3462 if ((r = sshbuf_put_u32(encrypted, BN_num_bits(key->rsa->n))) != 0 ||
|
3434 (r = sshbuf_put_bignum1(encrypted, key->rsa->n) != 0) || 3435 (r = sshbuf_put_bignum1(encrypted, key->rsa->e) != 0) || 3436 (r = sshbuf_put_cstring(encrypted, comment) != 0))
| 3463 (r = sshbuf_put_bignum1(encrypted, key->rsa->n)) != 0 || 3464 (r = sshbuf_put_bignum1(encrypted, key->rsa->e)) != 0 || 3465 (r = sshbuf_put_cstring(encrypted, comment)) != 0)
|
3437 goto out; 3438 3439 /* Allocate space for the private part of the key in the buffer. */ 3440 if ((r = sshbuf_reserve(encrypted, sshbuf_len(buffer), &cp)) != 0) 3441 goto out; 3442 3443 if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase, 3444 CIPHER_ENCRYPT)) != 0) 3445 goto out; 3446 if ((r = cipher_crypt(&ciphercontext, 0, cp, 3447 sshbuf_ptr(buffer), sshbuf_len(buffer), 0, 0)) != 0) 3448 goto out; 3449 if ((r = cipher_cleanup(&ciphercontext)) != 0) 3450 goto out; 3451 3452 r = sshbuf_putb(blob, encrypted); 3453 3454 out: 3455 explicit_bzero(&ciphercontext, sizeof(ciphercontext)); 3456 explicit_bzero(buf, sizeof(buf));
| 3466 goto out; 3467 3468 /* Allocate space for the private part of the key in the buffer. */ 3469 if ((r = sshbuf_reserve(encrypted, sshbuf_len(buffer), &cp)) != 0) 3470 goto out; 3471 3472 if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase, 3473 CIPHER_ENCRYPT)) != 0) 3474 goto out; 3475 if ((r = cipher_crypt(&ciphercontext, 0, cp, 3476 sshbuf_ptr(buffer), sshbuf_len(buffer), 0, 0)) != 0) 3477 goto out; 3478 if ((r = cipher_cleanup(&ciphercontext)) != 0) 3479 goto out; 3480 3481 r = sshbuf_putb(blob, encrypted); 3482 3483 out: 3484 explicit_bzero(&ciphercontext, sizeof(ciphercontext)); 3485 explicit_bzero(buf, sizeof(buf));
|
3457 if (buffer != NULL) 3458 sshbuf_free(buffer); 3459 if (encrypted != NULL) 3460 sshbuf_free(encrypted);
| 3486 sshbuf_free(buffer); 3487 sshbuf_free(encrypted);
|
3461 3462 return r; 3463} 3464#endif /* WITH_SSH1 */ 3465 3466#ifdef WITH_OPENSSL 3467/* convert SSH v2 key in OpenSSL PEM format */ 3468static int 3469sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob, 3470 const char *_passphrase, const char *comment) 3471{ 3472 int success, r; 3473 int blen, len = strlen(_passphrase); 3474 u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL; 3475#if (OPENSSL_VERSION_NUMBER < 0x00907000L) 3476 const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL; 3477#else 3478 const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL; 3479#endif 3480 const u_char *bptr; 3481 BIO *bio = NULL; 3482 3483 if (len > 0 && len <= 4) 3484 return SSH_ERR_PASSPHRASE_TOO_SHORT; 3485 if ((bio = BIO_new(BIO_s_mem())) == NULL) 3486 return SSH_ERR_ALLOC_FAIL; 3487 3488 switch (key->type) { 3489 case KEY_DSA: 3490 success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, 3491 cipher, passphrase, len, NULL, NULL); 3492 break; 3493#ifdef OPENSSL_HAS_ECC 3494 case KEY_ECDSA: 3495 success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa, 3496 cipher, passphrase, len, NULL, NULL); 3497 break; 3498#endif 3499 case KEY_RSA: 3500 success = PEM_write_bio_RSAPrivateKey(bio, key->rsa, 3501 cipher, passphrase, len, NULL, NULL); 3502 break; 3503 default: 3504 success = 0; 3505 break; 3506 } 3507 if (success == 0) { 3508 r = SSH_ERR_LIBCRYPTO_ERROR; 3509 goto out; 3510 } 3511 if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) { 3512 r = SSH_ERR_INTERNAL_ERROR; 3513 goto out; 3514 } 3515 if ((r = sshbuf_put(blob, bptr, blen)) != 0) 3516 goto out; 3517 r = 0; 3518 out: 3519 BIO_free(bio); 3520 return r; 3521} 3522#endif /* WITH_OPENSSL */ 3523 3524/* Serialise "key" to buffer "blob" */ 3525int 3526sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, 3527 const char *passphrase, const char *comment, 3528 int force_new_format, const char *new_format_cipher, int new_format_rounds) 3529{ 3530 switch (key->type) { 3531#ifdef WITH_SSH1 3532 case KEY_RSA1: 3533 return sshkey_private_rsa1_to_blob(key, blob, 3534 passphrase, comment); 3535#endif /* WITH_SSH1 */ 3536#ifdef WITH_OPENSSL 3537 case KEY_DSA: 3538 case KEY_ECDSA: 3539 case KEY_RSA: 3540 if (force_new_format) { 3541 return sshkey_private_to_blob2(key, blob, passphrase, 3542 comment, new_format_cipher, new_format_rounds); 3543 } 3544 return sshkey_private_pem_to_blob(key, blob, 3545 passphrase, comment); 3546#endif /* WITH_OPENSSL */ 3547 case KEY_ED25519: 3548 return sshkey_private_to_blob2(key, blob, passphrase, 3549 comment, new_format_cipher, new_format_rounds); 3550 default: 3551 return SSH_ERR_KEY_TYPE_UNKNOWN; 3552 } 3553} 3554 3555#ifdef WITH_SSH1 3556/* 3557 * Parse the public, unencrypted portion of a RSA1 key. 3558 */ 3559int 3560sshkey_parse_public_rsa1_fileblob(struct sshbuf *blob, 3561 struct sshkey **keyp, char **commentp) 3562{ 3563 int r; 3564 struct sshkey *pub = NULL; 3565 struct sshbuf *copy = NULL; 3566 3567 if (keyp != NULL) 3568 *keyp = NULL; 3569 if (commentp != NULL) 3570 *commentp = NULL; 3571 3572 /* Check that it is at least big enough to contain the ID string. */ 3573 if (sshbuf_len(blob) < sizeof(LEGACY_BEGIN)) 3574 return SSH_ERR_INVALID_FORMAT; 3575 3576 /* 3577 * Make sure it begins with the id string. Consume the id string 3578 * from the buffer. 3579 */ 3580 if (memcmp(sshbuf_ptr(blob), LEGACY_BEGIN, sizeof(LEGACY_BEGIN)) != 0) 3581 return SSH_ERR_INVALID_FORMAT; 3582 /* Make a working copy of the keyblob and skip past the magic */ 3583 if ((copy = sshbuf_fromb(blob)) == NULL) 3584 return SSH_ERR_ALLOC_FAIL; 3585 if ((r = sshbuf_consume(copy, sizeof(LEGACY_BEGIN))) != 0) 3586 goto out; 3587 3588 /* Skip cipher type, reserved data and key bits. */ 3589 if ((r = sshbuf_get_u8(copy, NULL)) != 0 || /* cipher type */ 3590 (r = sshbuf_get_u32(copy, NULL)) != 0 || /* reserved */ 3591 (r = sshbuf_get_u32(copy, NULL)) != 0) /* key bits */ 3592 goto out; 3593 3594 /* Read the public key from the buffer. */ 3595 if ((pub = sshkey_new(KEY_RSA1)) == NULL || 3596 (r = sshbuf_get_bignum1(copy, pub->rsa->n)) != 0 || 3597 (r = sshbuf_get_bignum1(copy, pub->rsa->e)) != 0) 3598 goto out; 3599 3600 /* Finally, the comment */ 3601 if ((r = sshbuf_get_string(copy, (u_char**)commentp, NULL)) != 0) 3602 goto out; 3603 3604 /* The encrypted private part is not parsed by this function. */ 3605 3606 r = 0; 3607 if (keyp != NULL) 3608 *keyp = pub; 3609 else 3610 sshkey_free(pub); 3611 pub = NULL; 3612 3613 out:
| 3488 3489 return r; 3490} 3491#endif /* WITH_SSH1 */ 3492 3493#ifdef WITH_OPENSSL 3494/* convert SSH v2 key in OpenSSL PEM format */ 3495static int 3496sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob, 3497 const char *_passphrase, const char *comment) 3498{ 3499 int success, r; 3500 int blen, len = strlen(_passphrase); 3501 u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL; 3502#if (OPENSSL_VERSION_NUMBER < 0x00907000L) 3503 const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL; 3504#else 3505 const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL; 3506#endif 3507 const u_char *bptr; 3508 BIO *bio = NULL; 3509 3510 if (len > 0 && len <= 4) 3511 return SSH_ERR_PASSPHRASE_TOO_SHORT; 3512 if ((bio = BIO_new(BIO_s_mem())) == NULL) 3513 return SSH_ERR_ALLOC_FAIL; 3514 3515 switch (key->type) { 3516 case KEY_DSA: 3517 success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, 3518 cipher, passphrase, len, NULL, NULL); 3519 break; 3520#ifdef OPENSSL_HAS_ECC 3521 case KEY_ECDSA: 3522 success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa, 3523 cipher, passphrase, len, NULL, NULL); 3524 break; 3525#endif 3526 case KEY_RSA: 3527 success = PEM_write_bio_RSAPrivateKey(bio, key->rsa, 3528 cipher, passphrase, len, NULL, NULL); 3529 break; 3530 default: 3531 success = 0; 3532 break; 3533 } 3534 if (success == 0) { 3535 r = SSH_ERR_LIBCRYPTO_ERROR; 3536 goto out; 3537 } 3538 if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) { 3539 r = SSH_ERR_INTERNAL_ERROR; 3540 goto out; 3541 } 3542 if ((r = sshbuf_put(blob, bptr, blen)) != 0) 3543 goto out; 3544 r = 0; 3545 out: 3546 BIO_free(bio); 3547 return r; 3548} 3549#endif /* WITH_OPENSSL */ 3550 3551/* Serialise "key" to buffer "blob" */ 3552int 3553sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, 3554 const char *passphrase, const char *comment, 3555 int force_new_format, const char *new_format_cipher, int new_format_rounds) 3556{ 3557 switch (key->type) { 3558#ifdef WITH_SSH1 3559 case KEY_RSA1: 3560 return sshkey_private_rsa1_to_blob(key, blob, 3561 passphrase, comment); 3562#endif /* WITH_SSH1 */ 3563#ifdef WITH_OPENSSL 3564 case KEY_DSA: 3565 case KEY_ECDSA: 3566 case KEY_RSA: 3567 if (force_new_format) { 3568 return sshkey_private_to_blob2(key, blob, passphrase, 3569 comment, new_format_cipher, new_format_rounds); 3570 } 3571 return sshkey_private_pem_to_blob(key, blob, 3572 passphrase, comment); 3573#endif /* WITH_OPENSSL */ 3574 case KEY_ED25519: 3575 return sshkey_private_to_blob2(key, blob, passphrase, 3576 comment, new_format_cipher, new_format_rounds); 3577 default: 3578 return SSH_ERR_KEY_TYPE_UNKNOWN; 3579 } 3580} 3581 3582#ifdef WITH_SSH1 3583/* 3584 * Parse the public, unencrypted portion of a RSA1 key. 3585 */ 3586int 3587sshkey_parse_public_rsa1_fileblob(struct sshbuf *blob, 3588 struct sshkey **keyp, char **commentp) 3589{ 3590 int r; 3591 struct sshkey *pub = NULL; 3592 struct sshbuf *copy = NULL; 3593 3594 if (keyp != NULL) 3595 *keyp = NULL; 3596 if (commentp != NULL) 3597 *commentp = NULL; 3598 3599 /* Check that it is at least big enough to contain the ID string. */ 3600 if (sshbuf_len(blob) < sizeof(LEGACY_BEGIN)) 3601 return SSH_ERR_INVALID_FORMAT; 3602 3603 /* 3604 * Make sure it begins with the id string. Consume the id string 3605 * from the buffer. 3606 */ 3607 if (memcmp(sshbuf_ptr(blob), LEGACY_BEGIN, sizeof(LEGACY_BEGIN)) != 0) 3608 return SSH_ERR_INVALID_FORMAT; 3609 /* Make a working copy of the keyblob and skip past the magic */ 3610 if ((copy = sshbuf_fromb(blob)) == NULL) 3611 return SSH_ERR_ALLOC_FAIL; 3612 if ((r = sshbuf_consume(copy, sizeof(LEGACY_BEGIN))) != 0) 3613 goto out; 3614 3615 /* Skip cipher type, reserved data and key bits. */ 3616 if ((r = sshbuf_get_u8(copy, NULL)) != 0 || /* cipher type */ 3617 (r = sshbuf_get_u32(copy, NULL)) != 0 || /* reserved */ 3618 (r = sshbuf_get_u32(copy, NULL)) != 0) /* key bits */ 3619 goto out; 3620 3621 /* Read the public key from the buffer. */ 3622 if ((pub = sshkey_new(KEY_RSA1)) == NULL || 3623 (r = sshbuf_get_bignum1(copy, pub->rsa->n)) != 0 || 3624 (r = sshbuf_get_bignum1(copy, pub->rsa->e)) != 0) 3625 goto out; 3626 3627 /* Finally, the comment */ 3628 if ((r = sshbuf_get_string(copy, (u_char**)commentp, NULL)) != 0) 3629 goto out; 3630 3631 /* The encrypted private part is not parsed by this function. */ 3632 3633 r = 0; 3634 if (keyp != NULL) 3635 *keyp = pub; 3636 else 3637 sshkey_free(pub); 3638 pub = NULL; 3639 3640 out:
|
3614 if (copy != NULL) 3615 sshbuf_free(copy); 3616 if (pub != NULL) 3617 sshkey_free(pub);
| 3641 sshbuf_free(copy); 3642 sshkey_free(pub);
|
3618 return r; 3619} 3620 3621static int 3622sshkey_parse_private_rsa1(struct sshbuf *blob, const char *passphrase, 3623 struct sshkey **keyp, char **commentp) 3624{ 3625 int r; 3626 u_int16_t check1, check2; 3627 u_int8_t cipher_type; 3628 struct sshbuf *decrypted = NULL, *copy = NULL; 3629 u_char *cp; 3630 char *comment = NULL; 3631 struct sshcipher_ctx ciphercontext; 3632 const struct sshcipher *cipher; 3633 struct sshkey *prv = NULL; 3634 3635 *keyp = NULL; 3636 if (commentp != NULL) 3637 *commentp = NULL; 3638 3639 /* Check that it is at least big enough to contain the ID string. */ 3640 if (sshbuf_len(blob) < sizeof(LEGACY_BEGIN)) 3641 return SSH_ERR_INVALID_FORMAT; 3642 3643 /* 3644 * Make sure it begins with the id string. Consume the id string 3645 * from the buffer. 3646 */ 3647 if (memcmp(sshbuf_ptr(blob), LEGACY_BEGIN, sizeof(LEGACY_BEGIN)) != 0) 3648 return SSH_ERR_INVALID_FORMAT; 3649 3650 if ((prv = sshkey_new_private(KEY_RSA1)) == NULL) { 3651 r = SSH_ERR_ALLOC_FAIL; 3652 goto out; 3653 } 3654 if ((copy = sshbuf_fromb(blob)) == NULL || 3655 (decrypted = sshbuf_new()) == NULL) { 3656 r = SSH_ERR_ALLOC_FAIL; 3657 goto out; 3658 } 3659 if ((r = sshbuf_consume(copy, sizeof(LEGACY_BEGIN))) != 0) 3660 goto out; 3661 3662 /* Read cipher type. */ 3663 if ((r = sshbuf_get_u8(copy, &cipher_type)) != 0 || 3664 (r = sshbuf_get_u32(copy, NULL)) != 0) /* reserved */ 3665 goto out; 3666 3667 /* Read the public key and comment from the buffer. */ 3668 if ((r = sshbuf_get_u32(copy, NULL)) != 0 || /* key bits */ 3669 (r = sshbuf_get_bignum1(copy, prv->rsa->n)) != 0 || 3670 (r = sshbuf_get_bignum1(copy, prv->rsa->e)) != 0 || 3671 (r = sshbuf_get_cstring(copy, &comment, NULL)) != 0) 3672 goto out; 3673 3674 /* Check that it is a supported cipher. */ 3675 cipher = cipher_by_number(cipher_type); 3676 if (cipher == NULL) { 3677 r = SSH_ERR_KEY_UNKNOWN_CIPHER; 3678 goto out; 3679 } 3680 /* Initialize space for decrypted data. */ 3681 if ((r = sshbuf_reserve(decrypted, sshbuf_len(copy), &cp)) != 0) 3682 goto out; 3683 3684 /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ 3685 if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase, 3686 CIPHER_DECRYPT)) != 0) 3687 goto out; 3688 if ((r = cipher_crypt(&ciphercontext, 0, cp, 3689 sshbuf_ptr(copy), sshbuf_len(copy), 0, 0)) != 0) { 3690 cipher_cleanup(&ciphercontext); 3691 goto out; 3692 } 3693 if ((r = cipher_cleanup(&ciphercontext)) != 0) 3694 goto out; 3695 3696 if ((r = sshbuf_get_u16(decrypted, &check1)) != 0 || 3697 (r = sshbuf_get_u16(decrypted, &check2)) != 0) 3698 goto out; 3699 if (check1 != check2) { 3700 r = SSH_ERR_KEY_WRONG_PASSPHRASE; 3701 goto out; 3702 } 3703 3704 /* Read the rest of the private key. */ 3705 if ((r = sshbuf_get_bignum1(decrypted, prv->rsa->d)) != 0 || 3706 (r = sshbuf_get_bignum1(decrypted, prv->rsa->iqmp)) != 0 || 3707 (r = sshbuf_get_bignum1(decrypted, prv->rsa->q)) != 0 || 3708 (r = sshbuf_get_bignum1(decrypted, prv->rsa->p)) != 0) 3709 goto out; 3710 3711 /* calculate p-1 and q-1 */ 3712 if ((r = rsa_generate_additional_parameters(prv->rsa)) != 0) 3713 goto out; 3714 3715 /* enable blinding */ 3716 if (RSA_blinding_on(prv->rsa, NULL) != 1) { 3717 r = SSH_ERR_LIBCRYPTO_ERROR; 3718 goto out; 3719 } 3720 r = 0; 3721 *keyp = prv; 3722 prv = NULL; 3723 if (commentp != NULL) { 3724 *commentp = comment; 3725 comment = NULL; 3726 } 3727 out: 3728 explicit_bzero(&ciphercontext, sizeof(ciphercontext));
| 3643 return r; 3644} 3645 3646static int 3647sshkey_parse_private_rsa1(struct sshbuf *blob, const char *passphrase, 3648 struct sshkey **keyp, char **commentp) 3649{ 3650 int r; 3651 u_int16_t check1, check2; 3652 u_int8_t cipher_type; 3653 struct sshbuf *decrypted = NULL, *copy = NULL; 3654 u_char *cp; 3655 char *comment = NULL; 3656 struct sshcipher_ctx ciphercontext; 3657 const struct sshcipher *cipher; 3658 struct sshkey *prv = NULL; 3659 3660 *keyp = NULL; 3661 if (commentp != NULL) 3662 *commentp = NULL; 3663 3664 /* Check that it is at least big enough to contain the ID string. */ 3665 if (sshbuf_len(blob) < sizeof(LEGACY_BEGIN)) 3666 return SSH_ERR_INVALID_FORMAT; 3667 3668 /* 3669 * Make sure it begins with the id string. Consume the id string 3670 * from the buffer. 3671 */ 3672 if (memcmp(sshbuf_ptr(blob), LEGACY_BEGIN, sizeof(LEGACY_BEGIN)) != 0) 3673 return SSH_ERR_INVALID_FORMAT; 3674 3675 if ((prv = sshkey_new_private(KEY_RSA1)) == NULL) { 3676 r = SSH_ERR_ALLOC_FAIL; 3677 goto out; 3678 } 3679 if ((copy = sshbuf_fromb(blob)) == NULL || 3680 (decrypted = sshbuf_new()) == NULL) { 3681 r = SSH_ERR_ALLOC_FAIL; 3682 goto out; 3683 } 3684 if ((r = sshbuf_consume(copy, sizeof(LEGACY_BEGIN))) != 0) 3685 goto out; 3686 3687 /* Read cipher type. */ 3688 if ((r = sshbuf_get_u8(copy, &cipher_type)) != 0 || 3689 (r = sshbuf_get_u32(copy, NULL)) != 0) /* reserved */ 3690 goto out; 3691 3692 /* Read the public key and comment from the buffer. */ 3693 if ((r = sshbuf_get_u32(copy, NULL)) != 0 || /* key bits */ 3694 (r = sshbuf_get_bignum1(copy, prv->rsa->n)) != 0 || 3695 (r = sshbuf_get_bignum1(copy, prv->rsa->e)) != 0 || 3696 (r = sshbuf_get_cstring(copy, &comment, NULL)) != 0) 3697 goto out; 3698 3699 /* Check that it is a supported cipher. */ 3700 cipher = cipher_by_number(cipher_type); 3701 if (cipher == NULL) { 3702 r = SSH_ERR_KEY_UNKNOWN_CIPHER; 3703 goto out; 3704 } 3705 /* Initialize space for decrypted data. */ 3706 if ((r = sshbuf_reserve(decrypted, sshbuf_len(copy), &cp)) != 0) 3707 goto out; 3708 3709 /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ 3710 if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase, 3711 CIPHER_DECRYPT)) != 0) 3712 goto out; 3713 if ((r = cipher_crypt(&ciphercontext, 0, cp, 3714 sshbuf_ptr(copy), sshbuf_len(copy), 0, 0)) != 0) { 3715 cipher_cleanup(&ciphercontext); 3716 goto out; 3717 } 3718 if ((r = cipher_cleanup(&ciphercontext)) != 0) 3719 goto out; 3720 3721 if ((r = sshbuf_get_u16(decrypted, &check1)) != 0 || 3722 (r = sshbuf_get_u16(decrypted, &check2)) != 0) 3723 goto out; 3724 if (check1 != check2) { 3725 r = SSH_ERR_KEY_WRONG_PASSPHRASE; 3726 goto out; 3727 } 3728 3729 /* Read the rest of the private key. */ 3730 if ((r = sshbuf_get_bignum1(decrypted, prv->rsa->d)) != 0 || 3731 (r = sshbuf_get_bignum1(decrypted, prv->rsa->iqmp)) != 0 || 3732 (r = sshbuf_get_bignum1(decrypted, prv->rsa->q)) != 0 || 3733 (r = sshbuf_get_bignum1(decrypted, prv->rsa->p)) != 0) 3734 goto out; 3735 3736 /* calculate p-1 and q-1 */ 3737 if ((r = rsa_generate_additional_parameters(prv->rsa)) != 0) 3738 goto out; 3739 3740 /* enable blinding */ 3741 if (RSA_blinding_on(prv->rsa, NULL) != 1) { 3742 r = SSH_ERR_LIBCRYPTO_ERROR; 3743 goto out; 3744 } 3745 r = 0; 3746 *keyp = prv; 3747 prv = NULL; 3748 if (commentp != NULL) { 3749 *commentp = comment; 3750 comment = NULL; 3751 } 3752 out: 3753 explicit_bzero(&ciphercontext, sizeof(ciphercontext));
|
3729 if (comment != NULL) 3730 free(comment); 3731 if (prv != NULL) 3732 sshkey_free(prv); 3733 if (copy != NULL) 3734 sshbuf_free(copy); 3735 if (decrypted != NULL) 3736 sshbuf_free(decrypted);
| 3754 free(comment); 3755 sshkey_free(prv); 3756 sshbuf_free(copy); 3757 sshbuf_free(decrypted);
|
3737 return r; 3738} 3739#endif /* WITH_SSH1 */ 3740 3741#ifdef WITH_OPENSSL 3742static int 3743sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, 3744 const char *passphrase, struct sshkey **keyp) 3745{ 3746 EVP_PKEY *pk = NULL; 3747 struct sshkey *prv = NULL; 3748 BIO *bio = NULL; 3749 int r; 3750 3751 *keyp = NULL; 3752 3753 if ((bio = BIO_new(BIO_s_mem())) == NULL || sshbuf_len(blob) > INT_MAX) 3754 return SSH_ERR_ALLOC_FAIL; 3755 if (BIO_write(bio, sshbuf_ptr(blob), sshbuf_len(blob)) != 3756 (int)sshbuf_len(blob)) { 3757 r = SSH_ERR_ALLOC_FAIL; 3758 goto out; 3759 } 3760 3761 if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, 3762 (char *)passphrase)) == NULL) { 3763 r = SSH_ERR_KEY_WRONG_PASSPHRASE; 3764 goto out; 3765 } 3766 if (pk->type == EVP_PKEY_RSA && 3767 (type == KEY_UNSPEC || type == KEY_RSA)) { 3768 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { 3769 r = SSH_ERR_ALLOC_FAIL; 3770 goto out; 3771 } 3772 prv->rsa = EVP_PKEY_get1_RSA(pk); 3773 prv->type = KEY_RSA; 3774#ifdef DEBUG_PK 3775 RSA_print_fp(stderr, prv->rsa, 8); 3776#endif 3777 if (RSA_blinding_on(prv->rsa, NULL) != 1) { 3778 r = SSH_ERR_LIBCRYPTO_ERROR; 3779 goto out; 3780 } 3781 } else if (pk->type == EVP_PKEY_DSA && 3782 (type == KEY_UNSPEC || type == KEY_DSA)) { 3783 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { 3784 r = SSH_ERR_ALLOC_FAIL; 3785 goto out; 3786 } 3787 prv->dsa = EVP_PKEY_get1_DSA(pk); 3788 prv->type = KEY_DSA; 3789#ifdef DEBUG_PK 3790 DSA_print_fp(stderr, prv->dsa, 8); 3791#endif 3792#ifdef OPENSSL_HAS_ECC 3793 } else if (pk->type == EVP_PKEY_EC && 3794 (type == KEY_UNSPEC || type == KEY_ECDSA)) { 3795 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { 3796 r = SSH_ERR_ALLOC_FAIL; 3797 goto out; 3798 } 3799 prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk); 3800 prv->type = KEY_ECDSA; 3801 prv->ecdsa_nid = sshkey_ecdsa_key_to_nid(prv->ecdsa); 3802 if (prv->ecdsa_nid == -1 || 3803 sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL || 3804 sshkey_ec_validate_public(EC_KEY_get0_group(prv->ecdsa), 3805 EC_KEY_get0_public_key(prv->ecdsa)) != 0 || 3806 sshkey_ec_validate_private(prv->ecdsa) != 0) { 3807 r = SSH_ERR_INVALID_FORMAT; 3808 goto out; 3809 } 3810# ifdef DEBUG_PK 3811 if (prv != NULL && prv->ecdsa != NULL) 3812 sshkey_dump_ec_key(prv->ecdsa); 3813# endif 3814#endif /* OPENSSL_HAS_ECC */ 3815 } else { 3816 r = SSH_ERR_INVALID_FORMAT; 3817 goto out; 3818 } 3819 r = 0; 3820 *keyp = prv; 3821 prv = NULL; 3822 out: 3823 BIO_free(bio); 3824 if (pk != NULL) 3825 EVP_PKEY_free(pk);
| 3758 return r; 3759} 3760#endif /* WITH_SSH1 */ 3761 3762#ifdef WITH_OPENSSL 3763static int 3764sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, 3765 const char *passphrase, struct sshkey **keyp) 3766{ 3767 EVP_PKEY *pk = NULL; 3768 struct sshkey *prv = NULL; 3769 BIO *bio = NULL; 3770 int r; 3771 3772 *keyp = NULL; 3773 3774 if ((bio = BIO_new(BIO_s_mem())) == NULL || sshbuf_len(blob) > INT_MAX) 3775 return SSH_ERR_ALLOC_FAIL; 3776 if (BIO_write(bio, sshbuf_ptr(blob), sshbuf_len(blob)) != 3777 (int)sshbuf_len(blob)) { 3778 r = SSH_ERR_ALLOC_FAIL; 3779 goto out; 3780 } 3781 3782 if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, 3783 (char *)passphrase)) == NULL) { 3784 r = SSH_ERR_KEY_WRONG_PASSPHRASE; 3785 goto out; 3786 } 3787 if (pk->type == EVP_PKEY_RSA && 3788 (type == KEY_UNSPEC || type == KEY_RSA)) { 3789 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { 3790 r = SSH_ERR_ALLOC_FAIL; 3791 goto out; 3792 } 3793 prv->rsa = EVP_PKEY_get1_RSA(pk); 3794 prv->type = KEY_RSA; 3795#ifdef DEBUG_PK 3796 RSA_print_fp(stderr, prv->rsa, 8); 3797#endif 3798 if (RSA_blinding_on(prv->rsa, NULL) != 1) { 3799 r = SSH_ERR_LIBCRYPTO_ERROR; 3800 goto out; 3801 } 3802 } else if (pk->type == EVP_PKEY_DSA && 3803 (type == KEY_UNSPEC || type == KEY_DSA)) { 3804 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { 3805 r = SSH_ERR_ALLOC_FAIL; 3806 goto out; 3807 } 3808 prv->dsa = EVP_PKEY_get1_DSA(pk); 3809 prv->type = KEY_DSA; 3810#ifdef DEBUG_PK 3811 DSA_print_fp(stderr, prv->dsa, 8); 3812#endif 3813#ifdef OPENSSL_HAS_ECC 3814 } else if (pk->type == EVP_PKEY_EC && 3815 (type == KEY_UNSPEC || type == KEY_ECDSA)) { 3816 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { 3817 r = SSH_ERR_ALLOC_FAIL; 3818 goto out; 3819 } 3820 prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk); 3821 prv->type = KEY_ECDSA; 3822 prv->ecdsa_nid = sshkey_ecdsa_key_to_nid(prv->ecdsa); 3823 if (prv->ecdsa_nid == -1 || 3824 sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL || 3825 sshkey_ec_validate_public(EC_KEY_get0_group(prv->ecdsa), 3826 EC_KEY_get0_public_key(prv->ecdsa)) != 0 || 3827 sshkey_ec_validate_private(prv->ecdsa) != 0) { 3828 r = SSH_ERR_INVALID_FORMAT; 3829 goto out; 3830 } 3831# ifdef DEBUG_PK 3832 if (prv != NULL && prv->ecdsa != NULL) 3833 sshkey_dump_ec_key(prv->ecdsa); 3834# endif 3835#endif /* OPENSSL_HAS_ECC */ 3836 } else { 3837 r = SSH_ERR_INVALID_FORMAT; 3838 goto out; 3839 } 3840 r = 0; 3841 *keyp = prv; 3842 prv = NULL; 3843 out: 3844 BIO_free(bio); 3845 if (pk != NULL) 3846 EVP_PKEY_free(pk);
|
3826 if (prv != NULL) 3827 sshkey_free(prv);
| 3847 sshkey_free(prv);
|
3828 return r; 3829} 3830#endif /* WITH_OPENSSL */ 3831 3832int 3833sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, 3834 const char *passphrase, struct sshkey **keyp, char **commentp) 3835{
| 3848 return r; 3849} 3850#endif /* WITH_OPENSSL */ 3851 3852int 3853sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, 3854 const char *passphrase, struct sshkey **keyp, char **commentp) 3855{
|
3836 int r; 3837
| |
3838 *keyp = NULL; 3839 if (commentp != NULL) 3840 *commentp = NULL; 3841 3842 switch (type) { 3843#ifdef WITH_SSH1 3844 case KEY_RSA1: 3845 return sshkey_parse_private_rsa1(blob, passphrase, 3846 keyp, commentp); 3847#endif /* WITH_SSH1 */ 3848#ifdef WITH_OPENSSL 3849 case KEY_DSA: 3850 case KEY_ECDSA: 3851 case KEY_RSA: 3852 return sshkey_parse_private_pem_fileblob(blob, type, 3853 passphrase, keyp); 3854#endif /* WITH_OPENSSL */ 3855 case KEY_ED25519: 3856 return sshkey_parse_private2(blob, type, passphrase, 3857 keyp, commentp); 3858 case KEY_UNSPEC:
| 3856 *keyp = NULL; 3857 if (commentp != NULL) 3858 *commentp = NULL; 3859 3860 switch (type) { 3861#ifdef WITH_SSH1 3862 case KEY_RSA1: 3863 return sshkey_parse_private_rsa1(blob, passphrase, 3864 keyp, commentp); 3865#endif /* WITH_SSH1 */ 3866#ifdef WITH_OPENSSL 3867 case KEY_DSA: 3868 case KEY_ECDSA: 3869 case KEY_RSA: 3870 return sshkey_parse_private_pem_fileblob(blob, type, 3871 passphrase, keyp); 3872#endif /* WITH_OPENSSL */ 3873 case KEY_ED25519: 3874 return sshkey_parse_private2(blob, type, passphrase, 3875 keyp, commentp); 3876 case KEY_UNSPEC:
|
3859 if ((r = sshkey_parse_private2(blob, type, passphrase, keyp, 3860 commentp)) == 0)
| 3877 if (sshkey_parse_private2(blob, type, passphrase, keyp, 3878 commentp) == 0)
|
3861 return 0; 3862#ifdef WITH_OPENSSL 3863 return sshkey_parse_private_pem_fileblob(blob, type, 3864 passphrase, keyp); 3865#else 3866 return SSH_ERR_INVALID_FORMAT; 3867#endif /* WITH_OPENSSL */ 3868 default: 3869 return SSH_ERR_KEY_TYPE_UNKNOWN; 3870 } 3871} 3872 3873int 3874sshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase,
| 3879 return 0; 3880#ifdef WITH_OPENSSL 3881 return sshkey_parse_private_pem_fileblob(blob, type, 3882 passphrase, keyp); 3883#else 3884 return SSH_ERR_INVALID_FORMAT; 3885#endif /* WITH_OPENSSL */ 3886 default: 3887 return SSH_ERR_KEY_TYPE_UNKNOWN; 3888 } 3889} 3890 3891int 3892sshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase,
|
3875 const char *filename, struct sshkey **keyp, char **commentp)
| 3893 struct sshkey **keyp, char **commentp)
|
3876{
| 3894{
|
3877 int r; 3878
| |
3879 if (keyp != NULL) 3880 *keyp = NULL; 3881 if (commentp != NULL) 3882 *commentp = NULL; 3883 3884#ifdef WITH_SSH1 3885 /* it's a SSH v1 key if the public key part is readable */
| 3895 if (keyp != NULL) 3896 *keyp = NULL; 3897 if (commentp != NULL) 3898 *commentp = NULL; 3899 3900#ifdef WITH_SSH1 3901 /* it's a SSH v1 key if the public key part is readable */
|
3886 if ((r = sshkey_parse_public_rsa1_fileblob(buffer, NULL, NULL)) == 0) {
| 3902 if (sshkey_parse_public_rsa1_fileblob(buffer, NULL, NULL) == 0) {
|
3887 return sshkey_parse_private_fileblob_type(buffer, KEY_RSA1, 3888 passphrase, keyp, commentp); 3889 } 3890#endif /* WITH_SSH1 */
| 3903 return sshkey_parse_private_fileblob_type(buffer, KEY_RSA1, 3904 passphrase, keyp, commentp); 3905 } 3906#endif /* WITH_SSH1 */
|
3891 if ((r = sshkey_parse_private_fileblob_type(buffer, KEY_UNSPEC, 3892 passphrase, keyp, commentp)) == 0) 3893 return 0; 3894 return r;
| 3907 return sshkey_parse_private_fileblob_type(buffer, KEY_UNSPEC, 3908 passphrase, keyp, commentp);
|
3895}
| 3909}
|