summaryrefslogtreecommitdiff
path: root/sshkey.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2019-10-09 22:59:48 +0100
committerColin Watson <cjwatson@debian.org>2019-10-09 22:59:48 +0100
commit4213eec74e74de6310c27a40c3e9759a08a73996 (patch)
treee97a6dcafc6763aea7c804e4e113c2750cb1400d /sshkey.c
parent102062f825fb26a74295a1c089c00c4c4c76b68a (diff)
parentcdf1d0a9f5d18535e0a18ff34860e81a6d83aa5c (diff)
Import openssh_8.1p1.orig.tar.gz
Diffstat (limited to 'sshkey.c')
-rw-r--r--sshkey.c444
1 files changed, 378 insertions, 66 deletions
diff --git a/sshkey.c b/sshkey.c
index ad1957762..ef90563b3 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshkey.c,v 1.73 2019/01/21 09:54:11 djm Exp $ */ 1/* $OpenBSD: sshkey.c,v 1.84 2019/10/09 00:04:42 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Alexander von Gernler. All rights reserved. 4 * Copyright (c) 2008 Alexander von Gernler. All rights reserved.
@@ -43,6 +43,7 @@
43#include <stdio.h> 43#include <stdio.h>
44#include <string.h> 44#include <string.h>
45#include <resolv.h> 45#include <resolv.h>
46#include <time.h>
46#ifdef HAVE_UTIL_H 47#ifdef HAVE_UTIL_H
47#include <util.h> 48#include <util.h>
48#endif /* HAVE_UTIL_H */ 49#endif /* HAVE_UTIL_H */
@@ -55,10 +56,12 @@
55#include "digest.h" 56#include "digest.h"
56#define SSHKEY_INTERNAL 57#define SSHKEY_INTERNAL
57#include "sshkey.h" 58#include "sshkey.h"
58#include "sshkey-xmss.h"
59#include "match.h" 59#include "match.h"
60 60
61#ifdef WITH_XMSS
62#include "sshkey-xmss.h"
61#include "xmss_fast.h" 63#include "xmss_fast.h"
64#endif
62 65
63#include "openbsd-compat/openssl-compat.h" 66#include "openbsd-compat/openssl-compat.h"
64 67
@@ -76,11 +79,18 @@
76/* Version identification string for SSH v1 identity files. */ 79/* Version identification string for SSH v1 identity files. */
77#define LEGACY_BEGIN "SSH PRIVATE KEY FILE FORMAT 1.1\n" 80#define LEGACY_BEGIN "SSH PRIVATE KEY FILE FORMAT 1.1\n"
78 81
79int sshkey_private_serialize_opt(const struct sshkey *key, 82/*
83 * Constants relating to "shielding" support; protection of keys expected
84 * to remain in memory for long durations
85 */
86#define SSHKEY_SHIELD_PREKEY_LEN (16 * 1024)
87#define SSHKEY_SHIELD_CIPHER "aes256-ctr" /* XXX want AES-EME* */
88#define SSHKEY_SHIELD_PREKEY_HASH SSH_DIGEST_SHA512
89
90int sshkey_private_serialize_opt(struct sshkey *key,
80 struct sshbuf *buf, enum sshkey_serialize_rep); 91 struct sshbuf *buf, enum sshkey_serialize_rep);
81static int sshkey_from_blob_internal(struct sshbuf *buf, 92static int sshkey_from_blob_internal(struct sshbuf *buf,
82 struct sshkey **keyp, int allow_cert); 93 struct sshkey **keyp, int allow_cert);
83static int get_sigtype(const u_char *sig, size_t siglen, char **sigtypep);
84 94
85/* Supported key types */ 95/* Supported key types */
86struct keytype { 96struct keytype {
@@ -602,6 +612,8 @@ sshkey_free(struct sshkey *k)
602 } 612 }
603 if (sshkey_is_cert(k)) 613 if (sshkey_is_cert(k))
604 cert_free(k->cert); 614 cert_free(k->cert);
615 freezero(k->shielded_private, k->shielded_len);
616 freezero(k->shield_prekey, k->shield_prekey_len);
605 freezero(k, sizeof(*k)); 617 freezero(k, sizeof(*k));
606} 618}
607 619
@@ -938,7 +950,6 @@ fingerprint_b64(const char *alg, u_char *dgst_raw, size_t dgst_raw_len)
938 char *ret; 950 char *ret;
939 size_t plen = strlen(alg) + 1; 951 size_t plen = strlen(alg) + 1;
940 size_t rlen = ((dgst_raw_len + 2) / 3) * 4 + plen + 1; 952 size_t rlen = ((dgst_raw_len + 2) / 3) * 4 + plen + 1;
941 int r;
942 953
943 if (dgst_raw_len > 65536 || (ret = calloc(1, rlen)) == NULL) 954 if (dgst_raw_len > 65536 || (ret = calloc(1, rlen)) == NULL)
944 return NULL; 955 return NULL;
@@ -946,8 +957,7 @@ fingerprint_b64(const char *alg, u_char *dgst_raw, size_t dgst_raw_len)
946 strlcat(ret, ":", rlen); 957 strlcat(ret, ":", rlen);
947 if (dgst_raw_len == 0) 958 if (dgst_raw_len == 0)
948 return ret; 959 return ret;
949 if ((r = b64_ntop(dgst_raw, dgst_raw_len, 960 if (b64_ntop(dgst_raw, dgst_raw_len, ret + plen, rlen - plen) == -1) {
950 ret + plen, rlen - plen)) == -1) {
951 freezero(ret, rlen); 961 freezero(ret, rlen);
952 return NULL; 962 return NULL;
953 } 963 }
@@ -1392,7 +1402,7 @@ sshkey_to_base64(const struct sshkey *key, char **b64p)
1392 return SSH_ERR_ALLOC_FAIL; 1402 return SSH_ERR_ALLOC_FAIL;
1393 if ((r = sshkey_putb(key, b)) != 0) 1403 if ((r = sshkey_putb(key, b)) != 0)
1394 goto out; 1404 goto out;
1395 if ((uu = sshbuf_dtob64(b)) == NULL) { 1405 if ((uu = sshbuf_dtob64_string(b, 0)) == NULL) {
1396 r = SSH_ERR_ALLOC_FAIL; 1406 r = SSH_ERR_ALLOC_FAIL;
1397 goto out; 1407 goto out;
1398 } 1408 }
@@ -1867,6 +1877,218 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
1867 return r; 1877 return r;
1868} 1878}
1869 1879
1880int
1881sshkey_is_shielded(struct sshkey *k)
1882{
1883 return k != NULL && k->shielded_private != NULL;
1884}
1885
1886int
1887sshkey_shield_private(struct sshkey *k)
1888{
1889 struct sshbuf *prvbuf = NULL;
1890 u_char *prekey = NULL, *enc = NULL, keyiv[SSH_DIGEST_MAX_LENGTH];
1891 struct sshcipher_ctx *cctx = NULL;
1892 const struct sshcipher *cipher;
1893 size_t i, enclen = 0;
1894 struct sshkey *kswap = NULL, tmp;
1895 int r = SSH_ERR_INTERNAL_ERROR;
1896
1897#ifdef DEBUG_PK
1898 fprintf(stderr, "%s: entering for %s\n", __func__, sshkey_ssh_name(k));
1899#endif
1900 if ((cipher = cipher_by_name(SSHKEY_SHIELD_CIPHER)) == NULL) {
1901 r = SSH_ERR_INVALID_ARGUMENT;
1902 goto out;
1903 }
1904 if (cipher_keylen(cipher) + cipher_ivlen(cipher) >
1905 ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH)) {
1906 r = SSH_ERR_INTERNAL_ERROR;
1907 goto out;
1908 }
1909
1910 /* Prepare a random pre-key, and from it an ephemeral key */
1911 if ((prekey = malloc(SSHKEY_SHIELD_PREKEY_LEN)) == NULL) {
1912 r = SSH_ERR_ALLOC_FAIL;
1913 goto out;
1914 }
1915 arc4random_buf(prekey, SSHKEY_SHIELD_PREKEY_LEN);
1916 if ((r = ssh_digest_memory(SSHKEY_SHIELD_PREKEY_HASH,
1917 prekey, SSHKEY_SHIELD_PREKEY_LEN,
1918 keyiv, SSH_DIGEST_MAX_LENGTH)) != 0)
1919 goto out;
1920#ifdef DEBUG_PK
1921 fprintf(stderr, "%s: key+iv\n", __func__);
1922 sshbuf_dump_data(keyiv, ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH),
1923 stderr);
1924#endif
1925 if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher),
1926 keyiv + cipher_keylen(cipher), cipher_ivlen(cipher), 1)) != 0)
1927 goto out;
1928
1929 /* Serialise and encrypt the private key using the ephemeral key */
1930 if ((prvbuf = sshbuf_new()) == NULL) {
1931 r = SSH_ERR_ALLOC_FAIL;
1932 goto out;
1933 }
1934 if (sshkey_is_shielded(k) && (r = sshkey_unshield_private(k)) != 0)
1935 goto out;
1936 if ((r = sshkey_private_serialize_opt(k, prvbuf,
1937 SSHKEY_SERIALIZE_FULL)) != 0)
1938 goto out;
1939 /* pad to cipher blocksize */
1940 i = 0;
1941 while (sshbuf_len(prvbuf) % cipher_blocksize(cipher)) {
1942 if ((r = sshbuf_put_u8(prvbuf, ++i & 0xff)) != 0)
1943 goto out;
1944 }
1945#ifdef DEBUG_PK
1946 fprintf(stderr, "%s: serialised\n", __func__);
1947 sshbuf_dump(prvbuf, stderr);
1948#endif
1949 /* encrypt */
1950 enclen = sshbuf_len(prvbuf);
1951 if ((enc = malloc(enclen)) == NULL) {
1952 r = SSH_ERR_ALLOC_FAIL;
1953 goto out;
1954 }
1955 if ((r = cipher_crypt(cctx, 0, enc,
1956 sshbuf_ptr(prvbuf), sshbuf_len(prvbuf), 0, 0)) != 0)
1957 goto out;
1958#ifdef DEBUG_PK
1959 fprintf(stderr, "%s: encrypted\n", __func__);
1960 sshbuf_dump_data(enc, enclen, stderr);
1961#endif
1962
1963 /* Make a scrubbed, public-only copy of our private key argument */
1964 if ((r = sshkey_from_private(k, &kswap)) != 0)
1965 goto out;
1966
1967 /* Swap the private key out (it will be destroyed below) */
1968 tmp = *kswap;
1969 *kswap = *k;
1970 *k = tmp;
1971
1972 /* Insert the shielded key into our argument */
1973 k->shielded_private = enc;
1974 k->shielded_len = enclen;
1975 k->shield_prekey = prekey;
1976 k->shield_prekey_len = SSHKEY_SHIELD_PREKEY_LEN;
1977 enc = prekey = NULL; /* transferred */
1978 enclen = 0;
1979
1980 /* success */
1981 r = 0;
1982
1983 out:
1984 /* XXX behaviour on error - invalidate original private key? */
1985 cipher_free(cctx);
1986 explicit_bzero(keyiv, sizeof(keyiv));
1987 explicit_bzero(&tmp, sizeof(tmp));
1988 freezero(enc, enclen);
1989 freezero(prekey, SSHKEY_SHIELD_PREKEY_LEN);
1990 sshkey_free(kswap);
1991 sshbuf_free(prvbuf);
1992 return r;
1993}
1994
1995int
1996sshkey_unshield_private(struct sshkey *k)
1997{
1998 struct sshbuf *prvbuf = NULL;
1999 u_char pad, *cp, keyiv[SSH_DIGEST_MAX_LENGTH];
2000 struct sshcipher_ctx *cctx = NULL;
2001 const struct sshcipher *cipher;
2002 size_t i;
2003 struct sshkey *kswap = NULL, tmp;
2004 int r = SSH_ERR_INTERNAL_ERROR;
2005
2006#ifdef DEBUG_PK
2007 fprintf(stderr, "%s: entering for %s\n", __func__, sshkey_ssh_name(k));
2008#endif
2009 if (!sshkey_is_shielded(k))
2010 return 0; /* nothing to do */
2011
2012 if ((cipher = cipher_by_name(SSHKEY_SHIELD_CIPHER)) == NULL) {
2013 r = SSH_ERR_INVALID_ARGUMENT;
2014 goto out;
2015 }
2016 if (cipher_keylen(cipher) + cipher_ivlen(cipher) >
2017 ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH)) {
2018 r = SSH_ERR_INTERNAL_ERROR;
2019 goto out;
2020 }
2021 /* check size of shielded key blob */
2022 if (k->shielded_len < cipher_blocksize(cipher) ||
2023 (k->shielded_len % cipher_blocksize(cipher)) != 0) {
2024 r = SSH_ERR_INVALID_FORMAT;
2025 goto out;
2026 }
2027
2028 /* Calculate the ephemeral key from the prekey */
2029 if ((r = ssh_digest_memory(SSHKEY_SHIELD_PREKEY_HASH,
2030 k->shield_prekey, k->shield_prekey_len,
2031 keyiv, SSH_DIGEST_MAX_LENGTH)) != 0)
2032 goto out;
2033 if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher),
2034 keyiv + cipher_keylen(cipher), cipher_ivlen(cipher), 0)) != 0)
2035 goto out;
2036#ifdef DEBUG_PK
2037 fprintf(stderr, "%s: key+iv\n", __func__);
2038 sshbuf_dump_data(keyiv, ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH),
2039 stderr);
2040#endif
2041
2042 /* Decrypt and parse the shielded private key using the ephemeral key */
2043 if ((prvbuf = sshbuf_new()) == NULL) {
2044 r = SSH_ERR_ALLOC_FAIL;
2045 goto out;
2046 }
2047 if ((r = sshbuf_reserve(prvbuf, k->shielded_len, &cp)) != 0)
2048 goto out;
2049 /* decrypt */
2050#ifdef DEBUG_PK
2051 fprintf(stderr, "%s: encrypted\n", __func__);
2052 sshbuf_dump_data(k->shielded_private, k->shielded_len, stderr);
2053#endif
2054 if ((r = cipher_crypt(cctx, 0, cp,
2055 k->shielded_private, k->shielded_len, 0, 0)) != 0)
2056 goto out;
2057#ifdef DEBUG_PK
2058 fprintf(stderr, "%s: serialised\n", __func__);
2059 sshbuf_dump(prvbuf, stderr);
2060#endif
2061 /* Parse private key */
2062 if ((r = sshkey_private_deserialize(prvbuf, &kswap)) != 0)
2063 goto out;
2064 /* Check deterministic padding */
2065 i = 0;
2066 while (sshbuf_len(prvbuf)) {
2067 if ((r = sshbuf_get_u8(prvbuf, &pad)) != 0)
2068 goto out;
2069 if (pad != (++i & 0xff)) {
2070 r = SSH_ERR_INVALID_FORMAT;
2071 goto out;
2072 }
2073 }
2074
2075 /* Swap the parsed key back into place */
2076 tmp = *kswap;
2077 *kswap = *k;
2078 *k = tmp;
2079
2080 /* success */
2081 r = 0;
2082
2083 out:
2084 cipher_free(cctx);
2085 explicit_bzero(keyiv, sizeof(keyiv));
2086 explicit_bzero(&tmp, sizeof(tmp));
2087 sshkey_free(kswap);
2088 sshbuf_free(prvbuf);
2089 return r;
2090}
2091
1870static int 2092static int
1871cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf) 2093cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
1872{ 2094{
@@ -1978,7 +2200,8 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
1978 if ((ret = sshkey_verify(key->cert->signature_key, sig, slen, 2200 if ((ret = sshkey_verify(key->cert->signature_key, sig, slen,
1979 sshbuf_ptr(key->cert->certblob), signed_len, NULL, 0)) != 0) 2201 sshbuf_ptr(key->cert->certblob), signed_len, NULL, 0)) != 0)
1980 goto out; 2202 goto out;
1981 if ((ret = get_sigtype(sig, slen, &key->cert->signature_type)) != 0) 2203 if ((ret = sshkey_get_sigtype(sig, slen,
2204 &key->cert->signature_type)) != 0)
1982 goto out; 2205 goto out;
1983 2206
1984 /* Success */ 2207 /* Success */
@@ -2280,8 +2503,8 @@ sshkey_froms(struct sshbuf *buf, struct sshkey **keyp)
2280 return r; 2503 return r;
2281} 2504}
2282 2505
2283static int 2506int
2284get_sigtype(const u_char *sig, size_t siglen, char **sigtypep) 2507sshkey_get_sigtype(const u_char *sig, size_t siglen, char **sigtypep)
2285{ 2508{
2286 int r; 2509 int r;
2287 struct sshbuf *b = NULL; 2510 struct sshbuf *b = NULL;
@@ -2363,7 +2586,7 @@ sshkey_check_sigtype(const u_char *sig, size_t siglen,
2363 return 0; 2586 return 0;
2364 if ((expected_alg = sshkey_sigalg_by_name(requested_alg)) == NULL) 2587 if ((expected_alg = sshkey_sigalg_by_name(requested_alg)) == NULL)
2365 return SSH_ERR_INVALID_ARGUMENT; 2588 return SSH_ERR_INVALID_ARGUMENT;
2366 if ((r = get_sigtype(sig, siglen, &sigtype)) != 0) 2589 if ((r = sshkey_get_sigtype(sig, siglen, &sigtype)) != 0)
2367 return r; 2590 return r;
2368 r = strcmp(expected_alg, sigtype) == 0; 2591 r = strcmp(expected_alg, sigtype) == 0;
2369 free(sigtype); 2592 free(sigtype);
@@ -2371,41 +2594,55 @@ sshkey_check_sigtype(const u_char *sig, size_t siglen,
2371} 2594}
2372 2595
2373int 2596int
2374sshkey_sign(const struct sshkey *key, 2597sshkey_sign(struct sshkey *key,
2375 u_char **sigp, size_t *lenp, 2598 u_char **sigp, size_t *lenp,
2376 const u_char *data, size_t datalen, const char *alg, u_int compat) 2599 const u_char *data, size_t datalen, const char *alg, u_int compat)
2377{ 2600{
2601 int was_shielded = sshkey_is_shielded(key);
2602 int r2, r = SSH_ERR_INTERNAL_ERROR;
2603
2378 if (sigp != NULL) 2604 if (sigp != NULL)
2379 *sigp = NULL; 2605 *sigp = NULL;
2380 if (lenp != NULL) 2606 if (lenp != NULL)
2381 *lenp = 0; 2607 *lenp = 0;
2382 if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE) 2608 if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)
2383 return SSH_ERR_INVALID_ARGUMENT; 2609 return SSH_ERR_INVALID_ARGUMENT;
2610 if ((r = sshkey_unshield_private(key)) != 0)
2611 return r;
2384 switch (key->type) { 2612 switch (key->type) {
2385#ifdef WITH_OPENSSL 2613#ifdef WITH_OPENSSL
2386 case KEY_DSA_CERT: 2614 case KEY_DSA_CERT:
2387 case KEY_DSA: 2615 case KEY_DSA:
2388 return ssh_dss_sign(key, sigp, lenp, data, datalen, compat); 2616 r = ssh_dss_sign(key, sigp, lenp, data, datalen, compat);
2617 break;
2389# ifdef OPENSSL_HAS_ECC 2618# ifdef OPENSSL_HAS_ECC
2390 case KEY_ECDSA_CERT: 2619 case KEY_ECDSA_CERT:
2391 case KEY_ECDSA: 2620 case KEY_ECDSA:
2392 return ssh_ecdsa_sign(key, sigp, lenp, data, datalen, compat); 2621 r = ssh_ecdsa_sign(key, sigp, lenp, data, datalen, compat);
2622 break;
2393# endif /* OPENSSL_HAS_ECC */ 2623# endif /* OPENSSL_HAS_ECC */
2394 case KEY_RSA_CERT: 2624 case KEY_RSA_CERT:
2395 case KEY_RSA: 2625 case KEY_RSA:
2396 return ssh_rsa_sign(key, sigp, lenp, data, datalen, alg); 2626 r = ssh_rsa_sign(key, sigp, lenp, data, datalen, alg);
2627 break;
2397#endif /* WITH_OPENSSL */ 2628#endif /* WITH_OPENSSL */
2398 case KEY_ED25519: 2629 case KEY_ED25519:
2399 case KEY_ED25519_CERT: 2630 case KEY_ED25519_CERT:
2400 return ssh_ed25519_sign(key, sigp, lenp, data, datalen, compat); 2631 r = ssh_ed25519_sign(key, sigp, lenp, data, datalen, compat);
2632 break;
2401#ifdef WITH_XMSS 2633#ifdef WITH_XMSS
2402 case KEY_XMSS: 2634 case KEY_XMSS:
2403 case KEY_XMSS_CERT: 2635 case KEY_XMSS_CERT:
2404 return ssh_xmss_sign(key, sigp, lenp, data, datalen, compat); 2636 r = ssh_xmss_sign(key, sigp, lenp, data, datalen, compat);
2637 break;
2405#endif /* WITH_XMSS */ 2638#endif /* WITH_XMSS */
2406 default: 2639 default:
2407 return SSH_ERR_KEY_TYPE_UNKNOWN; 2640 r = SSH_ERR_KEY_TYPE_UNKNOWN;
2641 break;
2408 } 2642 }
2643 if (was_shielded && (r2 = sshkey_shield_private(key)) != 0)
2644 return r2;
2645 return r;
2409} 2646}
2410 2647
2411/* 2648/*
@@ -2526,6 +2763,13 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
2526 strcmp(alg, k->cert->signature_type) != 0) 2763 strcmp(alg, k->cert->signature_type) != 0)
2527 return SSH_ERR_INVALID_ARGUMENT; 2764 return SSH_ERR_INVALID_ARGUMENT;
2528 2765
2766 /*
2767 * If no signing algorithm or signature_type was specified and we're
2768 * using a RSA key, then default to a good signature algorithm.
2769 */
2770 if (alg == NULL && ca->type == KEY_RSA)
2771 alg = "rsa-sha2-512";
2772
2529 if ((ret = sshkey_to_blob(ca, &ca_blob, &ca_len)) != 0) 2773 if ((ret = sshkey_to_blob(ca, &ca_blob, &ca_len)) != 0)
2530 return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; 2774 return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
2531 2775
@@ -2618,7 +2862,7 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
2618 sshbuf_len(cert), alg, 0, signer_ctx)) != 0) 2862 sshbuf_len(cert), alg, 0, signer_ctx)) != 0)
2619 goto out; 2863 goto out;
2620 /* Check and update signature_type against what was actually used */ 2864 /* Check and update signature_type against what was actually used */
2621 if ((ret = get_sigtype(sig_blob, sig_len, &sigtype)) != 0) 2865 if ((ret = sshkey_get_sigtype(sig_blob, sig_len, &sigtype)) != 0)
2622 goto out; 2866 goto out;
2623 if (alg != NULL && strcmp(alg, sigtype) != 0) { 2867 if (alg != NULL && strcmp(alg, sigtype) != 0) {
2624 ret = SSH_ERR_SIGN_ALG_UNSUPPORTED; 2868 ret = SSH_ERR_SIGN_ALG_UNSUPPORTED;
@@ -2643,7 +2887,7 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
2643} 2887}
2644 2888
2645static int 2889static int
2646default_key_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, 2890default_key_sign(struct sshkey *key, u_char **sigp, size_t *lenp,
2647 const u_char *data, size_t datalen, 2891 const u_char *data, size_t datalen,
2648 const char *alg, u_int compat, void *ctx) 2892 const char *alg, u_int compat, void *ctx)
2649{ 2893{
@@ -2753,15 +2997,21 @@ sshkey_format_cert_validity(const struct sshkey_cert *cert, char *s, size_t l)
2753} 2997}
2754 2998
2755int 2999int
2756sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b, 3000sshkey_private_serialize_opt(struct sshkey *key, struct sshbuf *buf,
2757 enum sshkey_serialize_rep opts) 3001 enum sshkey_serialize_rep opts)
2758{ 3002{
2759 int r = SSH_ERR_INTERNAL_ERROR; 3003 int r = SSH_ERR_INTERNAL_ERROR;
3004 int was_shielded = sshkey_is_shielded(key);
3005 struct sshbuf *b = NULL;
2760#ifdef WITH_OPENSSL 3006#ifdef WITH_OPENSSL
2761 const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_iqmp, *rsa_p, *rsa_q; 3007 const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_iqmp, *rsa_p, *rsa_q;
2762 const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key, *dsa_priv_key; 3008 const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key, *dsa_priv_key;
2763#endif /* WITH_OPENSSL */ 3009#endif /* WITH_OPENSSL */
2764 3010
3011 if ((r = sshkey_unshield_private(key)) != 0)
3012 return r;
3013 if ((b = sshbuf_new()) == NULL)
3014 return SSH_ERR_ALLOC_FAIL;
2765 if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0) 3015 if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0)
2766 goto out; 3016 goto out;
2767 switch (key->type) { 3017 switch (key->type) {
@@ -2887,14 +3137,23 @@ sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b,
2887 r = SSH_ERR_INVALID_ARGUMENT; 3137 r = SSH_ERR_INVALID_ARGUMENT;
2888 goto out; 3138 goto out;
2889 } 3139 }
2890 /* success */ 3140 /*
3141 * success (but we still need to append the output to buf after
3142 * possibly re-shielding the private key)
3143 */
2891 r = 0; 3144 r = 0;
2892 out: 3145 out:
3146 if (was_shielded)
3147 r = sshkey_shield_private(key);
3148 if (r == 0)
3149 r = sshbuf_putb(buf, b);
3150 sshbuf_free(b);
3151
2893 return r; 3152 return r;
2894} 3153}
2895 3154
2896int 3155int
2897sshkey_private_serialize(const struct sshkey *key, struct sshbuf *b) 3156sshkey_private_serialize(struct sshkey *key, struct sshbuf *b)
2898{ 3157{
2899 return sshkey_private_serialize_opt(key, b, 3158 return sshkey_private_serialize_opt(key, b,
2900 SSHKEY_SERIALIZE_DEFAULT); 3159 SSHKEY_SERIALIZE_DEFAULT);
@@ -2950,6 +3209,10 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2950 if ((r = sshkey_froms(buf, &k)) != 0 || 3209 if ((r = sshkey_froms(buf, &k)) != 0 ||
2951 (r = sshbuf_get_bignum2(buf, &dsa_priv_key)) != 0) 3210 (r = sshbuf_get_bignum2(buf, &dsa_priv_key)) != 0)
2952 goto out; 3211 goto out;
3212 if (k->type != type) {
3213 r = SSH_ERR_INVALID_FORMAT;
3214 goto out;
3215 }
2953 if (!DSA_set0_key(k->dsa, NULL, dsa_priv_key)) { 3216 if (!DSA_set0_key(k->dsa, NULL, dsa_priv_key)) {
2954 r = SSH_ERR_LIBCRYPTO_ERROR; 3217 r = SSH_ERR_LIBCRYPTO_ERROR;
2955 goto out; 3218 goto out;
@@ -2993,6 +3256,11 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2993 if ((r = sshkey_froms(buf, &k)) != 0 || 3256 if ((r = sshkey_froms(buf, &k)) != 0 ||
2994 (r = sshbuf_get_bignum2(buf, &exponent)) != 0) 3257 (r = sshbuf_get_bignum2(buf, &exponent)) != 0)
2995 goto out; 3258 goto out;
3259 if (k->type != type ||
3260 k->ecdsa_nid != sshkey_ecdsa_nid_from_name(tname)) {
3261 r = SSH_ERR_INVALID_FORMAT;
3262 goto out;
3263 }
2996 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) { 3264 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) {
2997 r = SSH_ERR_LIBCRYPTO_ERROR; 3265 r = SSH_ERR_LIBCRYPTO_ERROR;
2998 goto out; 3266 goto out;
@@ -3037,6 +3305,10 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
3037 (r = sshbuf_get_bignum2(buf, &rsa_p)) != 0 || 3305 (r = sshbuf_get_bignum2(buf, &rsa_p)) != 0 ||
3038 (r = sshbuf_get_bignum2(buf, &rsa_q)) != 0) 3306 (r = sshbuf_get_bignum2(buf, &rsa_q)) != 0)
3039 goto out; 3307 goto out;
3308 if (k->type != type) {
3309 r = SSH_ERR_INVALID_FORMAT;
3310 goto out;
3311 }
3040 if (!RSA_set0_key(k->rsa, NULL, NULL, rsa_d)) { 3312 if (!RSA_set0_key(k->rsa, NULL, NULL, rsa_d)) {
3041 r = SSH_ERR_LIBCRYPTO_ERROR; 3313 r = SSH_ERR_LIBCRYPTO_ERROR;
3042 goto out; 3314 goto out;
@@ -3074,13 +3346,17 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
3074 (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 || 3346 (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 ||
3075 (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0) 3347 (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0)
3076 goto out; 3348 goto out;
3349 if (k->type != type) {
3350 r = SSH_ERR_INVALID_FORMAT;
3351 goto out;
3352 }
3077 if (pklen != ED25519_PK_SZ || sklen != ED25519_SK_SZ) { 3353 if (pklen != ED25519_PK_SZ || sklen != ED25519_SK_SZ) {
3078 r = SSH_ERR_INVALID_FORMAT; 3354 r = SSH_ERR_INVALID_FORMAT;
3079 goto out; 3355 goto out;
3080 } 3356 }
3081 k->ed25519_pk = ed25519_pk; 3357 k->ed25519_pk = ed25519_pk;
3082 k->ed25519_sk = ed25519_sk; 3358 k->ed25519_sk = ed25519_sk;
3083 ed25519_pk = ed25519_sk = NULL; 3359 ed25519_pk = ed25519_sk = NULL; /* transferred */
3084 break; 3360 break;
3085#ifdef WITH_XMSS 3361#ifdef WITH_XMSS
3086 case KEY_XMSS: 3362 case KEY_XMSS:
@@ -3111,7 +3387,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
3111 (r = sshbuf_get_string(buf, &xmss_pk, &pklen)) != 0 || 3387 (r = sshbuf_get_string(buf, &xmss_pk, &pklen)) != 0 ||
3112 (r = sshbuf_get_string(buf, &xmss_sk, &sklen)) != 0) 3388 (r = sshbuf_get_string(buf, &xmss_sk, &sklen)) != 0)
3113 goto out; 3389 goto out;
3114 if (strcmp(xmss_name, k->xmss_name)) { 3390 if (k->type != type || strcmp(xmss_name, k->xmss_name) != 0) {
3115 r = SSH_ERR_INVALID_FORMAT; 3391 r = SSH_ERR_INVALID_FORMAT;
3116 goto out; 3392 goto out;
3117 } 3393 }
@@ -3349,7 +3625,7 @@ sshkey_dump_ec_key(const EC_KEY *key)
3349#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ 3625#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */
3350 3626
3351static int 3627static int
3352sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob, 3628sshkey_private_to_blob2(struct sshkey *prv, struct sshbuf *blob,
3353 const char *passphrase, const char *comment, const char *ciphername, 3629 const char *passphrase, const char *comment, const char *ciphername,
3354 int rounds) 3630 int rounds)
3355{ 3631{
@@ -3451,25 +3727,12 @@ sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob,
3451 sshbuf_ptr(encrypted), sshbuf_len(encrypted), 0, authlen)) != 0) 3727 sshbuf_ptr(encrypted), sshbuf_len(encrypted), 0, authlen)) != 0)
3452 goto out; 3728 goto out;
3453 3729
3454 /* uuencode */
3455 if ((b64 = sshbuf_dtob64(encoded)) == NULL) {
3456 r = SSH_ERR_ALLOC_FAIL;
3457 goto out;
3458 }
3459
3460 sshbuf_reset(blob); 3730 sshbuf_reset(blob);
3461 if ((r = sshbuf_put(blob, MARK_BEGIN, MARK_BEGIN_LEN)) != 0) 3731
3462 goto out; 3732 /* assemble uuencoded key */
3463 for (i = 0; i < strlen(b64); i++) { 3733 if ((r = sshbuf_put(blob, MARK_BEGIN, MARK_BEGIN_LEN)) != 0 ||
3464 if ((r = sshbuf_put_u8(blob, b64[i])) != 0) 3734 (r = sshbuf_dtob64(encoded, blob, 1)) != 0 ||
3465 goto out; 3735 (r = sshbuf_put(blob, MARK_END, MARK_END_LEN)) != 0)
3466 /* insert line breaks */
3467 if (i % 70 == 69 && (r = sshbuf_put_u8(blob, '\n')) != 0)
3468 goto out;
3469 }
3470 if (i % 70 != 69 && (r = sshbuf_put_u8(blob, '\n')) != 0)
3471 goto out;
3472 if ((r = sshbuf_put(blob, MARK_END, MARK_END_LEN)) != 0)
3473 goto out; 3736 goto out;
3474 3737
3475 /* success */ 3738 /* success */
@@ -3631,7 +3894,8 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
3631 } 3894 }
3632 3895
3633 /* check that an appropriate amount of auth data is present */ 3896 /* check that an appropriate amount of auth data is present */
3634 if (sshbuf_len(decoded) < encrypted_len + authlen) { 3897 if (sshbuf_len(decoded) < authlen ||
3898 sshbuf_len(decoded) - authlen < encrypted_len) {
3635 r = SSH_ERR_INVALID_FORMAT; 3899 r = SSH_ERR_INVALID_FORMAT;
3636 goto out; 3900 goto out;
3637 } 3901 }
@@ -3717,37 +3981,62 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
3717 3981
3718 3982
3719#ifdef WITH_OPENSSL 3983#ifdef WITH_OPENSSL
3720/* convert SSH v2 key in OpenSSL PEM format */ 3984/* convert SSH v2 key to PEM or PKCS#8 format */
3721static int 3985static int
3722sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob, 3986sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *buf,
3723 const char *_passphrase, const char *comment) 3987 int format, const char *_passphrase, const char *comment)
3724{ 3988{
3989 int was_shielded = sshkey_is_shielded(key);
3725 int success, r; 3990 int success, r;
3726 int blen, len = strlen(_passphrase); 3991 int blen, len = strlen(_passphrase);
3727 u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL; 3992 u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;
3728 const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL; 3993 const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
3729 char *bptr; 3994 char *bptr;
3730 BIO *bio = NULL; 3995 BIO *bio = NULL;
3996 struct sshbuf *blob;
3997 EVP_PKEY *pkey = NULL;
3731 3998
3732 if (len > 0 && len <= 4) 3999 if (len > 0 && len <= 4)
3733 return SSH_ERR_PASSPHRASE_TOO_SHORT; 4000 return SSH_ERR_PASSPHRASE_TOO_SHORT;
3734 if ((bio = BIO_new(BIO_s_mem())) == NULL) 4001 if ((blob = sshbuf_new()) == NULL)
3735 return SSH_ERR_ALLOC_FAIL; 4002 return SSH_ERR_ALLOC_FAIL;
4003 if ((bio = BIO_new(BIO_s_mem())) == NULL) {
4004 r = SSH_ERR_ALLOC_FAIL;
4005 goto out;
4006 }
4007 if (format == SSHKEY_PRIVATE_PKCS8 && (pkey = EVP_PKEY_new()) == NULL) {
4008 r = SSH_ERR_ALLOC_FAIL;
4009 goto out;
4010 }
4011 if ((r = sshkey_unshield_private(key)) != 0)
4012 goto out;
3736 4013
3737 switch (key->type) { 4014 switch (key->type) {
3738 case KEY_DSA: 4015 case KEY_DSA:
3739 success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, 4016 if (format == SSHKEY_PRIVATE_PEM) {
3740 cipher, passphrase, len, NULL, NULL); 4017 success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
4018 cipher, passphrase, len, NULL, NULL);
4019 } else {
4020 success = EVP_PKEY_set1_DSA(pkey, key->dsa);
4021 }
3741 break; 4022 break;
3742#ifdef OPENSSL_HAS_ECC 4023#ifdef OPENSSL_HAS_ECC
3743 case KEY_ECDSA: 4024 case KEY_ECDSA:
3744 success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa, 4025 if (format == SSHKEY_PRIVATE_PEM) {
3745 cipher, passphrase, len, NULL, NULL); 4026 success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
4027 cipher, passphrase, len, NULL, NULL);
4028 } else {
4029 success = EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa);
4030 }
3746 break; 4031 break;
3747#endif 4032#endif
3748 case KEY_RSA: 4033 case KEY_RSA:
3749 success = PEM_write_bio_RSAPrivateKey(bio, key->rsa, 4034 if (format == SSHKEY_PRIVATE_PEM) {
3750 cipher, passphrase, len, NULL, NULL); 4035 success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
4036 cipher, passphrase, len, NULL, NULL);
4037 } else {
4038 success = EVP_PKEY_set1_RSA(pkey, key->rsa);
4039 }
3751 break; 4040 break;
3752 default: 4041 default:
3753 success = 0; 4042 success = 0;
@@ -3757,6 +4046,13 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob,
3757 r = SSH_ERR_LIBCRYPTO_ERROR; 4046 r = SSH_ERR_LIBCRYPTO_ERROR;
3758 goto out; 4047 goto out;
3759 } 4048 }
4049 if (format == SSHKEY_PRIVATE_PKCS8) {
4050 if ((success = PEM_write_bio_PrivateKey(bio, pkey, cipher,
4051 passphrase, len, NULL, NULL)) == 0) {
4052 r = SSH_ERR_LIBCRYPTO_ERROR;
4053 goto out;
4054 }
4055 }
3760 if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) { 4056 if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) {
3761 r = SSH_ERR_INTERNAL_ERROR; 4057 r = SSH_ERR_INTERNAL_ERROR;
3762 goto out; 4058 goto out;
@@ -3765,6 +4061,13 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob,
3765 goto out; 4061 goto out;
3766 r = 0; 4062 r = 0;
3767 out: 4063 out:
4064 if (was_shielded)
4065 r = sshkey_shield_private(key);
4066 if (r == 0)
4067 r = sshbuf_putb(buf, blob);
4068
4069 EVP_PKEY_free(pkey);
4070 sshbuf_free(blob);
3768 BIO_free(bio); 4071 BIO_free(bio);
3769 return r; 4072 return r;
3770} 4073}
@@ -3774,29 +4077,38 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob,
3774int 4077int
3775sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, 4078sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
3776 const char *passphrase, const char *comment, 4079 const char *passphrase, const char *comment,
3777 int force_new_format, const char *new_format_cipher, int new_format_rounds) 4080 int format, const char *openssh_format_cipher, int openssh_format_rounds)
3778{ 4081{
3779 switch (key->type) { 4082 switch (key->type) {
3780#ifdef WITH_OPENSSL 4083#ifdef WITH_OPENSSL
3781 case KEY_DSA: 4084 case KEY_DSA:
3782 case KEY_ECDSA: 4085 case KEY_ECDSA:
3783 case KEY_RSA: 4086 case KEY_RSA:
3784 if (force_new_format) { 4087 break; /* see below */
3785 return sshkey_private_to_blob2(key, blob, passphrase,
3786 comment, new_format_cipher, new_format_rounds);
3787 }
3788 return sshkey_private_pem_to_blob(key, blob,
3789 passphrase, comment);
3790#endif /* WITH_OPENSSL */ 4088#endif /* WITH_OPENSSL */
3791 case KEY_ED25519: 4089 case KEY_ED25519:
3792#ifdef WITH_XMSS 4090#ifdef WITH_XMSS
3793 case KEY_XMSS: 4091 case KEY_XMSS:
3794#endif /* WITH_XMSS */ 4092#endif /* WITH_XMSS */
3795 return sshkey_private_to_blob2(key, blob, passphrase, 4093 return sshkey_private_to_blob2(key, blob, passphrase,
3796 comment, new_format_cipher, new_format_rounds); 4094 comment, openssh_format_cipher, openssh_format_rounds);
3797 default: 4095 default:
3798 return SSH_ERR_KEY_TYPE_UNKNOWN; 4096 return SSH_ERR_KEY_TYPE_UNKNOWN;
3799 } 4097 }
4098
4099#ifdef WITH_OPENSSL
4100 switch (format) {
4101 case SSHKEY_PRIVATE_OPENSSH:
4102 return sshkey_private_to_blob2(key, blob, passphrase,
4103 comment, openssh_format_cipher, openssh_format_rounds);
4104 case SSHKEY_PRIVATE_PEM:
4105 case SSHKEY_PRIVATE_PKCS8:
4106 return sshkey_private_to_blob_pem_pkcs8(key, blob,
4107 format, passphrase, comment);
4108 default:
4109 return SSH_ERR_INVALID_ARGUMENT;
4110 }
4111#endif /* WITH_OPENSSL */
3800} 4112}
3801 4113
3802 4114
@@ -4039,7 +4351,7 @@ sshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase,
4039 * maxsign times. 4351 * maxsign times.
4040 */ 4352 */
4041int 4353int
4042sshkey_private_serialize_maxsign(const struct sshkey *k, struct sshbuf *b, 4354sshkey_private_serialize_maxsign(struct sshkey *k, struct sshbuf *b,
4043 u_int32_t maxsign, sshkey_printfn *pr) 4355 u_int32_t maxsign, sshkey_printfn *pr)
4044{ 4356{
4045 int r, rupdate; 4357 int r, rupdate;
@@ -4093,7 +4405,7 @@ sshkey_set_filename(struct sshkey *k, const char *filename)
4093} 4405}
4094#else 4406#else
4095int 4407int
4096sshkey_private_serialize_maxsign(const struct sshkey *k, struct sshbuf *b, 4408sshkey_private_serialize_maxsign(struct sshkey *k, struct sshbuf *b,
4097 u_int32_t maxsign, sshkey_printfn *pr) 4409 u_int32_t maxsign, sshkey_printfn *pr)
4098{ 4410{
4099 return sshkey_private_serialize_opt(k, b, SSHKEY_SERIALIZE_DEFAULT); 4411 return sshkey_private_serialize_opt(k, b, SSHKEY_SERIALIZE_DEFAULT);