summaryrefslogtreecommitdiff
path: root/sshkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshkey.c')
-rw-r--r--sshkey.c299
1 files changed, 282 insertions, 17 deletions
diff --git a/sshkey.c b/sshkey.c
index 379a579cf..7aa7e772c 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshkey.c,v 1.75 2019/05/20 00:20:35 djm Exp $ */ 1/* $OpenBSD: sshkey.c,v 1.76 2019/06/21 04:21:05 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.
@@ -78,7 +78,15 @@
78/* Version identification string for SSH v1 identity files. */ 78/* Version identification string for SSH v1 identity files. */
79#define LEGACY_BEGIN "SSH PRIVATE KEY FILE FORMAT 1.1\n" 79#define LEGACY_BEGIN "SSH PRIVATE KEY FILE FORMAT 1.1\n"
80 80
81int sshkey_private_serialize_opt(const struct sshkey *key, 81/*
82 * Constants relating to "shielding" support; protection of keys expected
83 * to remain in memory for long durations
84 */
85#define SSHKEY_SHIELD_PREKEY_LEN (16 * 1024)
86#define SSHKEY_SHIELD_CIPHER "aes256-ctr" /* XXX want AES-EME* */
87#define SSHKEY_SHIELD_PREKEY_HASH SSH_DIGEST_SHA512
88
89int sshkey_private_serialize_opt(struct sshkey *key,
82 struct sshbuf *buf, enum sshkey_serialize_rep); 90 struct sshbuf *buf, enum sshkey_serialize_rep);
83static int sshkey_from_blob_internal(struct sshbuf *buf, 91static int sshkey_from_blob_internal(struct sshbuf *buf,
84 struct sshkey **keyp, int allow_cert); 92 struct sshkey **keyp, int allow_cert);
@@ -604,6 +612,8 @@ sshkey_free(struct sshkey *k)
604 } 612 }
605 if (sshkey_is_cert(k)) 613 if (sshkey_is_cert(k))
606 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);
607 freezero(k, sizeof(*k)); 617 freezero(k, sizeof(*k));
608} 618}
609 619
@@ -1869,6 +1879,218 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
1869 return r; 1879 return r;
1870} 1880}
1871 1881
1882int
1883sshkey_is_shielded(struct sshkey *k)
1884{
1885 return k != NULL && k->shielded_private != NULL;
1886}
1887
1888int
1889sshkey_shield_private(struct sshkey *k)
1890{
1891 struct sshbuf *prvbuf = NULL;
1892 u_char *prekey = NULL, *enc = NULL, keyiv[SSH_DIGEST_MAX_LENGTH];
1893 struct sshcipher_ctx *cctx = NULL;
1894 const struct sshcipher *cipher;
1895 size_t i, enclen = 0;
1896 struct sshkey *kswap = NULL, tmp;
1897 int r = SSH_ERR_INTERNAL_ERROR;
1898
1899#ifdef DEBUG_PK
1900 fprintf(stderr, "%s: entering for %s\n", __func__, sshkey_ssh_name(k));
1901#endif
1902 if ((cipher = cipher_by_name(SSHKEY_SHIELD_CIPHER)) == NULL) {
1903 r = SSH_ERR_INVALID_ARGUMENT;
1904 goto out;
1905 }
1906 if (cipher_keylen(cipher) + cipher_ivlen(cipher) >
1907 ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH)) {
1908 r = SSH_ERR_INTERNAL_ERROR;
1909 goto out;
1910 }
1911
1912 /* Prepare a random pre-key, and from it an ephemeral key */
1913 if ((prekey = malloc(SSHKEY_SHIELD_PREKEY_LEN)) == NULL) {
1914 r = SSH_ERR_ALLOC_FAIL;
1915 goto out;
1916 }
1917 arc4random_buf(prekey, SSHKEY_SHIELD_PREKEY_LEN);
1918 if ((r = ssh_digest_memory(SSHKEY_SHIELD_PREKEY_HASH,
1919 prekey, SSHKEY_SHIELD_PREKEY_LEN,
1920 keyiv, SSH_DIGEST_MAX_LENGTH)) != 0)
1921 goto out;
1922#ifdef DEBUG_PK
1923 fprintf(stderr, "%s: key+iv\n", __func__);
1924 sshbuf_dump_data(keyiv, ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH),
1925 stderr);
1926#endif
1927 if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher),
1928 keyiv + cipher_keylen(cipher), cipher_ivlen(cipher), 1)) != 0)
1929 goto out;
1930
1931 /* Serialise and encrypt the private key using the ephemeral key */
1932 if ((prvbuf = sshbuf_new()) == NULL) {
1933 r = SSH_ERR_ALLOC_FAIL;
1934 goto out;
1935 }
1936 if (sshkey_is_shielded(k) && (r = sshkey_unshield_private(k)) != 0)
1937 goto out;
1938 if ((r = sshkey_private_serialize_opt(k, prvbuf,
1939 SSHKEY_SERIALIZE_FULL)) != 0)
1940 goto out;
1941 /* pad to cipher blocksize */
1942 i = 0;
1943 while (sshbuf_len(prvbuf) % cipher_blocksize(cipher)) {
1944 if ((r = sshbuf_put_u8(prvbuf, ++i & 0xff)) != 0)
1945 goto out;
1946 }
1947#ifdef DEBUG_PK
1948 fprintf(stderr, "%s: serialised\n", __func__);
1949 sshbuf_dump(prvbuf, stderr);
1950#endif
1951 /* encrypt */
1952 enclen = sshbuf_len(prvbuf);
1953 if ((enc = malloc(enclen)) == NULL) {
1954 r = SSH_ERR_ALLOC_FAIL;
1955 goto out;
1956 }
1957 if ((r = cipher_crypt(cctx, 0, enc,
1958 sshbuf_ptr(prvbuf), sshbuf_len(prvbuf), 0, 0)) != 0)
1959 goto out;
1960#ifdef DEBUG_PK
1961 fprintf(stderr, "%s: encrypted\n", __func__);
1962 sshbuf_dump_data(enc, enclen, stderr);
1963#endif
1964
1965 /* Make a scrubbed, public-only copy of our private key argument */
1966 if ((r = sshkey_from_private(k, &kswap)) != 0)
1967 goto out;
1968
1969 /* Swap the private key out (it will be destroyed below) */
1970 tmp = *kswap;
1971 *kswap = *k;
1972 *k = tmp;
1973
1974 /* Insert the shielded key into our argument */
1975 k->shielded_private = enc;
1976 k->shielded_len = enclen;
1977 k->shield_prekey = prekey;
1978 k->shield_prekey_len = SSHKEY_SHIELD_PREKEY_LEN;
1979 enc = prekey = NULL; /* transferred */
1980 enclen = 0;
1981
1982 /* success */
1983 r = 0;
1984
1985 out:
1986 /* XXX behaviour on error - invalidate original private key? */
1987 cipher_free(cctx);
1988 explicit_bzero(enc, enclen);
1989 explicit_bzero(keyiv, sizeof(keyiv));
1990 explicit_bzero(&tmp, sizeof(tmp));
1991 freezero(prekey, SSHKEY_SHIELD_PREKEY_LEN);
1992 sshkey_free(kswap);
1993 sshbuf_free(prvbuf);
1994 return r;
1995}
1996
1997int
1998sshkey_unshield_private(struct sshkey *k)
1999{
2000 struct sshbuf *prvbuf = NULL;
2001 u_char pad, *cp, keyiv[SSH_DIGEST_MAX_LENGTH];
2002 struct sshcipher_ctx *cctx = NULL;
2003 const struct sshcipher *cipher;
2004 size_t i;
2005 struct sshkey *kswap = NULL, tmp;
2006 int r = SSH_ERR_INTERNAL_ERROR;
2007
2008#ifdef DEBUG_PK
2009 fprintf(stderr, "%s: entering for %s\n", __func__, sshkey_ssh_name(k));
2010#endif
2011 if (!sshkey_is_shielded(k))
2012 return 0; /* nothing to do */
2013
2014 if ((cipher = cipher_by_name(SSHKEY_SHIELD_CIPHER)) == NULL) {
2015 r = SSH_ERR_INVALID_ARGUMENT;
2016 goto out;
2017 }
2018 if (cipher_keylen(cipher) + cipher_ivlen(cipher) >
2019 ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH)) {
2020 r = SSH_ERR_INTERNAL_ERROR;
2021 goto out;
2022 }
2023 /* check size of shielded key blob */
2024 if (k->shielded_len < cipher_blocksize(cipher) ||
2025 (k->shielded_len % cipher_blocksize(cipher)) != 0) {
2026 r = SSH_ERR_INVALID_FORMAT;
2027 goto out;
2028 }
2029
2030 /* Calculate the ephemeral key from the prekey */
2031 if ((r = ssh_digest_memory(SSHKEY_SHIELD_PREKEY_HASH,
2032 k->shield_prekey, k->shield_prekey_len,
2033 keyiv, SSH_DIGEST_MAX_LENGTH)) != 0)
2034 goto out;
2035 if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher),
2036 keyiv + cipher_keylen(cipher), cipher_ivlen(cipher), 0)) != 0)
2037 goto out;
2038#ifdef DEBUG_PK
2039 fprintf(stderr, "%s: key+iv\n", __func__);
2040 sshbuf_dump_data(keyiv, ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH),
2041 stderr);
2042#endif
2043
2044 /* Decrypt and parse the shielded private key using the ephemeral key */
2045 if ((prvbuf = sshbuf_new()) == NULL) {
2046 r = SSH_ERR_ALLOC_FAIL;
2047 goto out;
2048 }
2049 if ((r = sshbuf_reserve(prvbuf, k->shielded_len, &cp)) != 0)
2050 goto out;
2051 /* decrypt */
2052#ifdef DEBUG_PK
2053 fprintf(stderr, "%s: encrypted\n", __func__);
2054 sshbuf_dump_data(k->shielded_private, k->shielded_len, stderr);
2055#endif
2056 if ((r = cipher_crypt(cctx, 0, cp,
2057 k->shielded_private, k->shielded_len, 0, 0)) != 0)
2058 goto out;
2059#ifdef DEBUG_PK
2060 fprintf(stderr, "%s: serialised\n", __func__);
2061 sshbuf_dump(prvbuf, stderr);
2062#endif
2063 /* Parse private key */
2064 if ((r = sshkey_private_deserialize(prvbuf, &kswap)) != 0)
2065 goto out;
2066 /* Check deterministic padding */
2067 i = 0;
2068 while (sshbuf_len(prvbuf)) {
2069 if ((r = sshbuf_get_u8(prvbuf, &pad)) != 0)
2070 goto out;
2071 if (pad != (++i & 0xff)) {
2072 r = SSH_ERR_INVALID_FORMAT;
2073 goto out;
2074 }
2075 }
2076
2077 /* Swap the parsed key back into place */
2078 tmp = *kswap;
2079 *kswap = *k;
2080 *k = tmp;
2081
2082 /* success */
2083 r = 0;
2084
2085 out:
2086 cipher_free(cctx);
2087 explicit_bzero(keyiv, sizeof(keyiv));
2088 explicit_bzero(&tmp, sizeof(tmp));
2089 sshkey_free(kswap);
2090 sshbuf_free(prvbuf);
2091 return r;
2092}
2093
1872static int 2094static int
1873cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf) 2095cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
1874{ 2096{
@@ -2373,41 +2595,55 @@ sshkey_check_sigtype(const u_char *sig, size_t siglen,
2373} 2595}
2374 2596
2375int 2597int
2376sshkey_sign(const struct sshkey *key, 2598sshkey_sign(struct sshkey *key,
2377 u_char **sigp, size_t *lenp, 2599 u_char **sigp, size_t *lenp,
2378 const u_char *data, size_t datalen, const char *alg, u_int compat) 2600 const u_char *data, size_t datalen, const char *alg, u_int compat)
2379{ 2601{
2602 int was_shielded = sshkey_is_shielded(key);
2603 int r2, r = SSH_ERR_INTERNAL_ERROR;
2604
2380 if (sigp != NULL) 2605 if (sigp != NULL)
2381 *sigp = NULL; 2606 *sigp = NULL;
2382 if (lenp != NULL) 2607 if (lenp != NULL)
2383 *lenp = 0; 2608 *lenp = 0;
2384 if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE) 2609 if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)
2385 return SSH_ERR_INVALID_ARGUMENT; 2610 return SSH_ERR_INVALID_ARGUMENT;
2611 if ((r = sshkey_unshield_private(key)) != 0)
2612 return r;
2386 switch (key->type) { 2613 switch (key->type) {
2387#ifdef WITH_OPENSSL 2614#ifdef WITH_OPENSSL
2388 case KEY_DSA_CERT: 2615 case KEY_DSA_CERT:
2389 case KEY_DSA: 2616 case KEY_DSA:
2390 return ssh_dss_sign(key, sigp, lenp, data, datalen, compat); 2617 r = ssh_dss_sign(key, sigp, lenp, data, datalen, compat);
2618 break;
2391# ifdef OPENSSL_HAS_ECC 2619# ifdef OPENSSL_HAS_ECC
2392 case KEY_ECDSA_CERT: 2620 case KEY_ECDSA_CERT:
2393 case KEY_ECDSA: 2621 case KEY_ECDSA:
2394 return ssh_ecdsa_sign(key, sigp, lenp, data, datalen, compat); 2622 r = ssh_ecdsa_sign(key, sigp, lenp, data, datalen, compat);
2623 break;
2395# endif /* OPENSSL_HAS_ECC */ 2624# endif /* OPENSSL_HAS_ECC */
2396 case KEY_RSA_CERT: 2625 case KEY_RSA_CERT:
2397 case KEY_RSA: 2626 case KEY_RSA:
2398 return ssh_rsa_sign(key, sigp, lenp, data, datalen, alg); 2627 r = ssh_rsa_sign(key, sigp, lenp, data, datalen, alg);
2628 break;
2399#endif /* WITH_OPENSSL */ 2629#endif /* WITH_OPENSSL */
2400 case KEY_ED25519: 2630 case KEY_ED25519:
2401 case KEY_ED25519_CERT: 2631 case KEY_ED25519_CERT:
2402 return ssh_ed25519_sign(key, sigp, lenp, data, datalen, compat); 2632 r = ssh_ed25519_sign(key, sigp, lenp, data, datalen, compat);
2633 break;
2403#ifdef WITH_XMSS 2634#ifdef WITH_XMSS
2404 case KEY_XMSS: 2635 case KEY_XMSS:
2405 case KEY_XMSS_CERT: 2636 case KEY_XMSS_CERT:
2406 return ssh_xmss_sign(key, sigp, lenp, data, datalen, compat); 2637 r = ssh_xmss_sign(key, sigp, lenp, data, datalen, compat);
2638 break;
2407#endif /* WITH_XMSS */ 2639#endif /* WITH_XMSS */
2408 default: 2640 default:
2409 return SSH_ERR_KEY_TYPE_UNKNOWN; 2641 r = SSH_ERR_KEY_TYPE_UNKNOWN;
2642 break;
2410 } 2643 }
2644 if (was_shielded && (r2 = sshkey_shield_private(key)) != 0)
2645 return r2;
2646 return r;
2411} 2647}
2412 2648
2413/* 2649/*
@@ -2652,7 +2888,7 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
2652} 2888}
2653 2889
2654static int 2890static int
2655default_key_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, 2891default_key_sign(struct sshkey *key, u_char **sigp, size_t *lenp,
2656 const u_char *data, size_t datalen, 2892 const u_char *data, size_t datalen,
2657 const char *alg, u_int compat, void *ctx) 2893 const char *alg, u_int compat, void *ctx)
2658{ 2894{
@@ -2762,15 +2998,21 @@ sshkey_format_cert_validity(const struct sshkey_cert *cert, char *s, size_t l)
2762} 2998}
2763 2999
2764int 3000int
2765sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b, 3001sshkey_private_serialize_opt(struct sshkey *key, struct sshbuf *buf,
2766 enum sshkey_serialize_rep opts) 3002 enum sshkey_serialize_rep opts)
2767{ 3003{
2768 int r = SSH_ERR_INTERNAL_ERROR; 3004 int r = SSH_ERR_INTERNAL_ERROR;
3005 int was_shielded = sshkey_is_shielded(key);
3006 struct sshbuf *b = NULL;
2769#ifdef WITH_OPENSSL 3007#ifdef WITH_OPENSSL
2770 const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_iqmp, *rsa_p, *rsa_q; 3008 const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_iqmp, *rsa_p, *rsa_q;
2771 const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key, *dsa_priv_key; 3009 const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key, *dsa_priv_key;
2772#endif /* WITH_OPENSSL */ 3010#endif /* WITH_OPENSSL */
2773 3011
3012 if ((r = sshkey_unshield_private(key)) != 0)
3013 return r;
3014 if ((b = sshbuf_new()) == NULL)
3015 return SSH_ERR_ALLOC_FAIL;
2774 if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0) 3016 if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0)
2775 goto out; 3017 goto out;
2776 switch (key->type) { 3018 switch (key->type) {
@@ -2896,14 +3138,23 @@ sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b,
2896 r = SSH_ERR_INVALID_ARGUMENT; 3138 r = SSH_ERR_INVALID_ARGUMENT;
2897 goto out; 3139 goto out;
2898 } 3140 }
2899 /* success */ 3141 /*
3142 * success (but we still need to append the output to buf after
3143 * possibly re-shielding the private key)
3144 */
2900 r = 0; 3145 r = 0;
2901 out: 3146 out:
3147 if (was_shielded)
3148 r = sshkey_shield_private(key);
3149 if (r == 0)
3150 r = sshbuf_putb(buf, b);
3151 sshbuf_free(b);
3152
2902 return r; 3153 return r;
2903} 3154}
2904 3155
2905int 3156int
2906sshkey_private_serialize(const struct sshkey *key, struct sshbuf *b) 3157sshkey_private_serialize(struct sshkey *key, struct sshbuf *b)
2907{ 3158{
2908 return sshkey_private_serialize_opt(key, b, 3159 return sshkey_private_serialize_opt(key, b,
2909 SSHKEY_SERIALIZE_DEFAULT); 3160 SSHKEY_SERIALIZE_DEFAULT);
@@ -3358,7 +3609,7 @@ sshkey_dump_ec_key(const EC_KEY *key)
3358#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ 3609#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */
3359 3610
3360static int 3611static int
3361sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob, 3612sshkey_private_to_blob2(struct sshkey *prv, struct sshbuf *blob,
3362 const char *passphrase, const char *comment, const char *ciphername, 3613 const char *passphrase, const char *comment, const char *ciphername,
3363 int rounds) 3614 int rounds)
3364{ 3615{
@@ -3728,20 +3979,28 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
3728#ifdef WITH_OPENSSL 3979#ifdef WITH_OPENSSL
3729/* convert SSH v2 key in OpenSSL PEM format */ 3980/* convert SSH v2 key in OpenSSL PEM format */
3730static int 3981static int
3731sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob, 3982sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf,
3732 const char *_passphrase, const char *comment) 3983 const char *_passphrase, const char *comment)
3733{ 3984{
3985 int was_shielded = sshkey_is_shielded(key);
3734 int success, r; 3986 int success, r;
3735 int blen, len = strlen(_passphrase); 3987 int blen, len = strlen(_passphrase);
3736 u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL; 3988 u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;
3737 const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL; 3989 const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
3738 char *bptr; 3990 char *bptr;
3739 BIO *bio = NULL; 3991 BIO *bio = NULL;
3992 struct sshbuf *blob;
3740 3993
3741 if (len > 0 && len <= 4) 3994 if (len > 0 && len <= 4)
3742 return SSH_ERR_PASSPHRASE_TOO_SHORT; 3995 return SSH_ERR_PASSPHRASE_TOO_SHORT;
3743 if ((bio = BIO_new(BIO_s_mem())) == NULL) 3996 if ((blob = sshbuf_new()) == NULL)
3744 return SSH_ERR_ALLOC_FAIL; 3997 return SSH_ERR_ALLOC_FAIL;
3998 if ((bio = BIO_new(BIO_s_mem())) == NULL) {
3999 sshbuf_free(blob);
4000 return SSH_ERR_ALLOC_FAIL;
4001 }
4002 if ((r = sshkey_unshield_private(key)) != 0)
4003 goto out;
3745 4004
3746 switch (key->type) { 4005 switch (key->type) {
3747 case KEY_DSA: 4006 case KEY_DSA:
@@ -3774,6 +4033,12 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob,
3774 goto out; 4033 goto out;
3775 r = 0; 4034 r = 0;
3776 out: 4035 out:
4036 if (was_shielded)
4037 r = sshkey_shield_private(key);
4038 if (r == 0)
4039 r = sshbuf_putb(buf, blob);
4040 sshbuf_free(blob);
4041
3777 BIO_free(bio); 4042 BIO_free(bio);
3778 return r; 4043 return r;
3779} 4044}
@@ -4102,7 +4367,7 @@ sshkey_set_filename(struct sshkey *k, const char *filename)
4102} 4367}
4103#else 4368#else
4104int 4369int
4105sshkey_private_serialize_maxsign(const struct sshkey *k, struct sshbuf *b, 4370sshkey_private_serialize_maxsign(struct sshkey *k, struct sshbuf *b,
4106 u_int32_t maxsign, sshkey_printfn *pr) 4371 u_int32_t maxsign, sshkey_printfn *pr)
4107{ 4372{
4108 return sshkey_private_serialize_opt(k, b, SSHKEY_SERIALIZE_DEFAULT); 4373 return sshkey_private_serialize_opt(k, b, SSHKEY_SERIALIZE_DEFAULT);