diff options
-rw-r--r-- | authfd.c | 4 | ||||
-rw-r--r-- | authfd.h | 4 | ||||
-rw-r--r-- | krl.c | 4 | ||||
-rw-r--r-- | krl.h | 4 | ||||
-rw-r--r-- | ssh-agent.c | 7 | ||||
-rw-r--r-- | ssh-keygen.c | 4 | ||||
-rw-r--r-- | sshconnect.c | 4 | ||||
-rw-r--r-- | sshconnect.h | 4 | ||||
-rw-r--r-- | sshd.c | 10 | ||||
-rw-r--r-- | sshkey.c | 299 | ||||
-rw-r--r-- | sshkey.h | 21 |
11 files changed, 324 insertions, 41 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: authfd.c,v 1.113 2018/12/27 23:02:11 djm Exp $ */ | 1 | /* $OpenBSD: authfd.c,v 1.114 2019/06/21 04:21:04 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -423,7 +423,7 @@ encode_constraints(struct sshbuf *m, u_int life, u_int confirm, u_int maxsign) | |||
423 | * This call is intended only for use by ssh-add(1) and like applications. | 423 | * This call is intended only for use by ssh-add(1) and like applications. |
424 | */ | 424 | */ |
425 | int | 425 | int |
426 | ssh_add_identity_constrained(int sock, const struct sshkey *key, | 426 | ssh_add_identity_constrained(int sock, struct sshkey *key, |
427 | const char *comment, u_int life, u_int confirm, u_int maxsign) | 427 | const char *comment, u_int life, u_int confirm, u_int maxsign) |
428 | { | 428 | { |
429 | struct sshbuf *msg; | 429 | struct sshbuf *msg; |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: authfd.h,v 1.44 2018/07/12 04:35:25 djm Exp $ */ | 1 | /* $OpenBSD: authfd.h,v 1.45 2019/06/21 04:21:04 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -29,7 +29,7 @@ void ssh_close_authentication_socket(int sock); | |||
29 | int ssh_lock_agent(int sock, int lock, const char *password); | 29 | int ssh_lock_agent(int sock, int lock, const char *password); |
30 | int ssh_fetch_identitylist(int sock, struct ssh_identitylist **idlp); | 30 | int ssh_fetch_identitylist(int sock, struct ssh_identitylist **idlp); |
31 | void ssh_free_identitylist(struct ssh_identitylist *idl); | 31 | void ssh_free_identitylist(struct ssh_identitylist *idl); |
32 | int ssh_add_identity_constrained(int sock, const struct sshkey *key, | 32 | int ssh_add_identity_constrained(int sock, struct sshkey *key, |
33 | const char *comment, u_int life, u_int confirm, u_int maxsign); | 33 | const char *comment, u_int life, u_int confirm, u_int maxsign); |
34 | int ssh_remove_identity(int sock, struct sshkey *key); | 34 | int ssh_remove_identity(int sock, struct sshkey *key); |
35 | int ssh_update_card(int sock, int add, const char *reader_id, | 35 | int ssh_update_card(int sock, int add, const char *reader_id, |
@@ -14,7 +14,7 @@ | |||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | /* $OpenBSD: krl.c,v 1.42 2018/09/12 01:21:34 djm Exp $ */ | 17 | /* $OpenBSD: krl.c,v 1.43 2019/06/21 04:21:04 djm Exp $ */ |
18 | 18 | ||
19 | #include "includes.h" | 19 | #include "includes.h" |
20 | 20 | ||
@@ -732,7 +732,7 @@ revoked_certs_generate(struct revoked_certs *rc, struct sshbuf *buf) | |||
732 | 732 | ||
733 | int | 733 | int |
734 | ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf, | 734 | ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf, |
735 | const struct sshkey **sign_keys, u_int nsign_keys) | 735 | struct sshkey **sign_keys, u_int nsign_keys) |
736 | { | 736 | { |
737 | int r = SSH_ERR_INTERNAL_ERROR; | 737 | int r = SSH_ERR_INTERNAL_ERROR; |
738 | struct revoked_certs *rc; | 738 | struct revoked_certs *rc; |
@@ -14,7 +14,7 @@ | |||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | /* $OpenBSD: krl.h,v 1.6 2018/09/12 01:21:34 djm Exp $ */ | 17 | /* $OpenBSD: krl.h,v 1.7 2019/06/21 04:21:04 djm Exp $ */ |
18 | 18 | ||
19 | #ifndef _KRL_H | 19 | #ifndef _KRL_H |
20 | #define _KRL_H | 20 | #define _KRL_H |
@@ -56,7 +56,7 @@ int ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const u_char *p, size_t len); | |||
56 | int ssh_krl_revoke_key_sha256(struct ssh_krl *krl, const u_char *p, size_t len); | 56 | int ssh_krl_revoke_key_sha256(struct ssh_krl *krl, const u_char *p, size_t len); |
57 | int ssh_krl_revoke_key(struct ssh_krl *krl, const struct sshkey *key); | 57 | int ssh_krl_revoke_key(struct ssh_krl *krl, const struct sshkey *key); |
58 | int ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf, | 58 | int ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf, |
59 | const struct sshkey **sign_keys, u_int nsign_keys); | 59 | struct sshkey **sign_keys, u_int nsign_keys); |
60 | int ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp, | 60 | int ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp, |
61 | const struct sshkey **sign_ca_keys, size_t nsign_ca_keys); | 61 | const struct sshkey **sign_ca_keys, size_t nsign_ca_keys); |
62 | int ssh_krl_check_key(struct ssh_krl *krl, const struct sshkey *key); | 62 | int ssh_krl_check_key(struct ssh_krl *krl, const struct sshkey *key); |
diff --git a/ssh-agent.c b/ssh-agent.c index 4669b679c..4d7ab225f 100644 --- a/ssh-agent.c +++ b/ssh-agent.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-agent.c,v 1.235 2019/06/14 03:51:47 djm Exp $ */ | 1 | /* $OpenBSD: ssh-agent.c,v 1.236 2019/06/21 04:21:04 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -423,7 +423,10 @@ process_add_identity(SocketEntry *e) | |||
423 | error("%s: decode private key: %s", __func__, ssh_err(r)); | 423 | error("%s: decode private key: %s", __func__, ssh_err(r)); |
424 | goto err; | 424 | goto err; |
425 | } | 425 | } |
426 | 426 | if ((r = sshkey_shield_private(k)) != 0) { | |
427 | error("%s: shield private key: %s", __func__, ssh_err(r)); | ||
428 | goto err; | ||
429 | } | ||
427 | while (sshbuf_len(e->request)) { | 430 | while (sshbuf_len(e->request)) { |
428 | if ((r = sshbuf_get_u8(e->request, &ctype)) != 0) { | 431 | if ((r = sshbuf_get_u8(e->request, &ctype)) != 0) { |
429 | error("%s: buffer error: %s", __func__, ssh_err(r)); | 432 | error("%s: buffer error: %s", __func__, ssh_err(r)); |
diff --git a/ssh-keygen.c b/ssh-keygen.c index 010667157..c95bc15cf 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-keygen.c,v 1.331 2019/06/06 05:13:13 otto Exp $ */ | 1 | /* $OpenBSD: ssh-keygen.c,v 1.332 2019/06/21 04:21:04 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -1654,7 +1654,7 @@ load_pkcs11_key(char *path) | |||
1654 | 1654 | ||
1655 | /* Signer for sshkey_certify_custom that uses the agent */ | 1655 | /* Signer for sshkey_certify_custom that uses the agent */ |
1656 | static int | 1656 | static int |
1657 | agent_signer(const struct sshkey *key, u_char **sigp, size_t *lenp, | 1657 | agent_signer(struct sshkey *key, u_char **sigp, size_t *lenp, |
1658 | const u_char *data, size_t datalen, | 1658 | const u_char *data, size_t datalen, |
1659 | const char *alg, u_int compat, void *ctx) | 1659 | const char *alg, u_int compat, void *ctx) |
1660 | { | 1660 | { |
diff --git a/sshconnect.c b/sshconnect.c index c57f1a0ff..2dc500b47 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect.c,v 1.315 2019/05/03 03:27:38 dtucker Exp $ */ | 1 | /* $OpenBSD: sshconnect.c,v 1.316 2019/06/21 04:21:04 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -1401,7 +1401,7 @@ ssh_local_cmd(const char *args) | |||
1401 | } | 1401 | } |
1402 | 1402 | ||
1403 | void | 1403 | void |
1404 | maybe_add_key_to_agent(char *authfile, const struct sshkey *private, | 1404 | maybe_add_key_to_agent(char *authfile, struct sshkey *private, |
1405 | char *comment, char *passphrase) | 1405 | char *comment, char *passphrase) |
1406 | { | 1406 | { |
1407 | int auth_sock = -1, r; | 1407 | int auth_sock = -1, r; |
diff --git a/sshconnect.h b/sshconnect.h index 6e8989b27..b455d7c20 100644 --- a/sshconnect.h +++ b/sshconnect.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect.h,v 1.37 2019/01/19 21:36:38 djm Exp $ */ | 1 | /* $OpenBSD: sshconnect.h,v 1.38 2019/06/21 04:21:05 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
@@ -52,4 +52,4 @@ void ssh_userauth2(struct ssh *ssh, const char *, const char *, | |||
52 | 52 | ||
53 | int ssh_local_cmd(const char *); | 53 | int ssh_local_cmd(const char *); |
54 | 54 | ||
55 | void maybe_add_key_to_agent(char *, const struct sshkey *, char *, char *); | 55 | void maybe_add_key_to_agent(char *, struct sshkey *, char *, char *); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.535 2019/06/06 05:13:13 otto Exp $ */ | 1 | /* $OpenBSD: sshd.c,v 1.536 2019/06/21 04:21:05 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -1375,7 +1375,7 @@ set_process_rdomain(struct ssh *ssh, const char *name) | |||
1375 | 1375 | ||
1376 | static void | 1376 | static void |
1377 | accumulate_host_timing_secret(struct sshbuf *server_cfg, | 1377 | accumulate_host_timing_secret(struct sshbuf *server_cfg, |
1378 | const struct sshkey *key) | 1378 | struct sshkey *key) |
1379 | { | 1379 | { |
1380 | static struct ssh_digest_ctx *ctx; | 1380 | static struct ssh_digest_ctx *ctx; |
1381 | u_char *hash; | 1381 | u_char *hash; |
@@ -1723,6 +1723,12 @@ main(int ac, char **av) | |||
1723 | &key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR) | 1723 | &key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR) |
1724 | do_log2(ll, "Unable to load host key \"%s\": %s", | 1724 | do_log2(ll, "Unable to load host key \"%s\": %s", |
1725 | options.host_key_files[i], ssh_err(r)); | 1725 | options.host_key_files[i], ssh_err(r)); |
1726 | if (r == 0 && (r = sshkey_shield_private(key)) != 0) { | ||
1727 | do_log2(ll, "Unable to shield host key \"%s\": %s", | ||
1728 | options.host_key_files[i], ssh_err(r)); | ||
1729 | sshkey_free(key); | ||
1730 | key = NULL; | ||
1731 | } | ||
1726 | if ((r = sshkey_load_public(options.host_key_files[i], | 1732 | if ((r = sshkey_load_public(options.host_key_files[i], |
1727 | &pubkey, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR) | 1733 | &pubkey, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR) |
1728 | do_log2(ll, "Unable to load host key \"%s\": %s", | 1734 | do_log2(ll, "Unable to load host key \"%s\": %s", |
@@ -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 | ||
81 | int 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 | |||
89 | int sshkey_private_serialize_opt(struct sshkey *key, | ||
82 | struct sshbuf *buf, enum sshkey_serialize_rep); | 90 | struct sshbuf *buf, enum sshkey_serialize_rep); |
83 | static int sshkey_from_blob_internal(struct sshbuf *buf, | 91 | static 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 | ||
1882 | int | ||
1883 | sshkey_is_shielded(struct sshkey *k) | ||
1884 | { | ||
1885 | return k != NULL && k->shielded_private != NULL; | ||
1886 | } | ||
1887 | |||
1888 | int | ||
1889 | sshkey_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 | |||
1997 | int | ||
1998 | sshkey_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 | |||
1872 | static int | 2094 | static int |
1873 | cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf) | 2095 | cert_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 | ||
2375 | int | 2597 | int |
2376 | sshkey_sign(const struct sshkey *key, | 2598 | sshkey_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 | ||
2654 | static int | 2890 | static int |
2655 | default_key_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, | 2891 | default_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 | ||
2764 | int | 3000 | int |
2765 | sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b, | 3001 | sshkey_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 | ||
2905 | int | 3156 | int |
2906 | sshkey_private_serialize(const struct sshkey *key, struct sshbuf *b) | 3157 | sshkey_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 | ||
3360 | static int | 3611 | static int |
3361 | sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob, | 3612 | sshkey_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 */ |
3730 | static int | 3981 | static int |
3731 | sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob, | 3982 | sshkey_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 |
4104 | int | 4369 | int |
4105 | sshkey_private_serialize_maxsign(const struct sshkey *k, struct sshbuf *b, | 4370 | sshkey_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); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshkey.h,v 1.31 2019/01/20 22:51:37 djm Exp $ */ | 1 | /* $OpenBSD: sshkey.h,v 1.32 2019/06/21 04:21:05 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
@@ -123,6 +123,10 @@ struct sshkey { | |||
123 | u_char *xmss_sk; | 123 | u_char *xmss_sk; |
124 | u_char *xmss_pk; | 124 | u_char *xmss_pk; |
125 | struct sshkey_cert *cert; | 125 | struct sshkey_cert *cert; |
126 | u_char *shielded_private; | ||
127 | size_t shielded_len; | ||
128 | u_char *shield_prekey; | ||
129 | size_t shield_prekey_len; | ||
126 | }; | 130 | }; |
127 | 131 | ||
128 | #define ED25519_SK_SZ crypto_sign_ed25519_SECRETKEYBYTES | 132 | #define ED25519_SK_SZ crypto_sign_ed25519_SECRETKEYBYTES |
@@ -146,6 +150,11 @@ u_int sshkey_size(const struct sshkey *); | |||
146 | 150 | ||
147 | int sshkey_generate(int type, u_int bits, struct sshkey **keyp); | 151 | int sshkey_generate(int type, u_int bits, struct sshkey **keyp); |
148 | int sshkey_from_private(const struct sshkey *, struct sshkey **); | 152 | int sshkey_from_private(const struct sshkey *, struct sshkey **); |
153 | |||
154 | int sshkey_is_shielded(struct sshkey *); | ||
155 | int sshkey_shield_private(struct sshkey *); | ||
156 | int sshkey_unshield_private(struct sshkey *); | ||
157 | |||
149 | int sshkey_type_from_name(const char *); | 158 | int sshkey_type_from_name(const char *); |
150 | int sshkey_is_cert(const struct sshkey *); | 159 | int sshkey_is_cert(const struct sshkey *); |
151 | int sshkey_type_is_cert(int); | 160 | int sshkey_type_is_cert(int); |
@@ -161,7 +170,7 @@ int sshkey_check_cert_sigtype(const struct sshkey *, const char *); | |||
161 | 170 | ||
162 | int sshkey_certify(struct sshkey *, struct sshkey *, const char *); | 171 | int sshkey_certify(struct sshkey *, struct sshkey *, const char *); |
163 | /* Variant allowing use of a custom signature function (e.g. for ssh-agent) */ | 172 | /* Variant allowing use of a custom signature function (e.g. for ssh-agent) */ |
164 | typedef int sshkey_certify_signer(const struct sshkey *, u_char **, size_t *, | 173 | typedef int sshkey_certify_signer(struct sshkey *, u_char **, size_t *, |
165 | const u_char *, size_t, const char *, u_int, void *); | 174 | const u_char *, size_t, const char *, u_int, void *); |
166 | int sshkey_certify_custom(struct sshkey *, struct sshkey *, const char *, | 175 | int sshkey_certify_custom(struct sshkey *, struct sshkey *, const char *, |
167 | sshkey_certify_signer *, void *); | 176 | sshkey_certify_signer *, void *); |
@@ -192,7 +201,7 @@ int sshkey_puts_opts(const struct sshkey *, struct sshbuf *, | |||
192 | int sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *); | 201 | int sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *); |
193 | int sshkey_putb_plain(const struct sshkey *, struct sshbuf *); | 202 | int sshkey_putb_plain(const struct sshkey *, struct sshbuf *); |
194 | 203 | ||
195 | int sshkey_sign(const struct sshkey *, u_char **, size_t *, | 204 | int sshkey_sign(struct sshkey *, u_char **, size_t *, |
196 | const u_char *, size_t, const char *, u_int); | 205 | const u_char *, size_t, const char *, u_int); |
197 | int sshkey_verify(const struct sshkey *, const u_char *, size_t, | 206 | int sshkey_verify(const struct sshkey *, const u_char *, size_t, |
198 | const u_char *, size_t, const char *, u_int); | 207 | const u_char *, size_t, const char *, u_int); |
@@ -204,8 +213,8 @@ void sshkey_dump_ec_point(const EC_GROUP *, const EC_POINT *); | |||
204 | void sshkey_dump_ec_key(const EC_KEY *); | 213 | void sshkey_dump_ec_key(const EC_KEY *); |
205 | 214 | ||
206 | /* private key parsing and serialisation */ | 215 | /* private key parsing and serialisation */ |
207 | int sshkey_private_serialize(const struct sshkey *key, struct sshbuf *buf); | 216 | int sshkey_private_serialize(struct sshkey *key, struct sshbuf *buf); |
208 | int sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *buf, | 217 | int sshkey_private_serialize_opt(struct sshkey *key, struct sshbuf *buf, |
209 | enum sshkey_serialize_rep); | 218 | enum sshkey_serialize_rep); |
210 | int sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **keyp); | 219 | int sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **keyp); |
211 | 220 | ||
@@ -231,7 +240,7 @@ int sshkey_set_filename(struct sshkey *, const char *); | |||
231 | int sshkey_enable_maxsign(struct sshkey *, u_int32_t); | 240 | int sshkey_enable_maxsign(struct sshkey *, u_int32_t); |
232 | u_int32_t sshkey_signatures_left(const struct sshkey *); | 241 | u_int32_t sshkey_signatures_left(const struct sshkey *); |
233 | int sshkey_forward_state(const struct sshkey *, u_int32_t, sshkey_printfn *); | 242 | int sshkey_forward_state(const struct sshkey *, u_int32_t, sshkey_printfn *); |
234 | int sshkey_private_serialize_maxsign(const struct sshkey *key, struct sshbuf *buf, | 243 | int sshkey_private_serialize_maxsign(struct sshkey *key, struct sshbuf *buf, |
235 | u_int32_t maxsign, sshkey_printfn *pr); | 244 | u_int32_t maxsign, sshkey_printfn *pr); |
236 | 245 | ||
237 | #ifdef SSHKEY_INTERNAL | 246 | #ifdef SSHKEY_INTERNAL |