summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2014-07-02 15:28:02 +1000
committerDamien Miller <djm@mindrot.org>2014-07-02 15:28:02 +1000
commit8668706d0f52654fe64c0ca41a96113aeab8d2b8 (patch)
tree73e78e1ea3d39206e39870bbe0af17d6c430fb51
parent2cd7929250cf9e9f658d70dcd452f529ba08c942 (diff)
- djm@cvs.openbsd.org 2014/06/24 01:13:21
[Makefile.in auth-bsdauth.c auth-chall.c auth-options.c auth-rsa.c [auth2-none.c auth2-pubkey.c authfile.c authfile.h cipher-3des1.c [cipher-chachapoly.c cipher-chachapoly.h cipher.c cipher.h [digest-libc.c digest-openssl.c digest.h dns.c entropy.c hmac.h [hostfile.c key.c key.h krl.c monitor.c packet.c rsa.c rsa.h [ssh-add.c ssh-agent.c ssh-dss.c ssh-ecdsa.c ssh-ed25519.c [ssh-keygen.c ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c [ssh-rsa.c sshbuf-misc.c sshbuf.h sshconnect.c sshconnect1.c [sshconnect2.c sshd.c sshkey.c sshkey.h [openbsd-compat/openssl-compat.c openbsd-compat/openssl-compat.h] New key API: refactor key-related functions to be more library-like, existing API is offered as a set of wrappers. with and ok markus@ Thanks also to Ben Hawkes, David Tomaschik, Ivan Fratric, Matthew Dempsky and Ron Bowes for a detailed review a few months ago. NB. This commit also removes portable OpenSSH support for OpenSSL <0.9.8e.
-rw-r--r--ChangeLog20
-rw-r--r--Makefile.in5
-rw-r--r--auth-bsdauth.c4
-rw-r--r--auth-chall.c5
-rw-r--r--auth-options.c14
-rw-r--r--auth-rsa.c5
-rw-r--r--auth2-none.c5
-rw-r--r--auth2-pubkey.c6
-rw-r--r--authfile.c1421
-rw-r--r--authfile.h63
-rw-r--r--cipher-3des1.c55
-rw-r--r--cipher-chachapoly.c25
-rw-r--r--cipher-chachapoly.h4
-rw-r--r--cipher.c363
-rw-r--r--cipher.h57
-rw-r--r--digest-libc.c27
-rw-r--r--digest-openssl.c36
-rw-r--r--digest.h7
-rw-r--r--dns.c4
-rw-r--r--entropy.c2
-rw-r--r--hmac.h5
-rw-r--r--hostfile.c3
-rw-r--r--key.c2803
-rw-r--r--key.h187
-rw-r--r--krl.c8
-rw-r--r--monitor.c5
-rw-r--r--openbsd-compat/openssl-compat.c141
-rw-r--r--openbsd-compat/openssl-compat.h118
-rw-r--r--packet.c38
-rw-r--r--rsa.c113
-rw-r--r--rsa.h6
-rw-r--r--ssh-add.c24
-rw-r--r--ssh-agent.c24
-rw-r--r--ssh-dss.c237
-rw-r--r--ssh-ecdsa.c232
-rw-r--r--ssh-ed25519.c183
-rw-r--r--ssh-keygen.c20
-rw-r--r--ssh-pkcs11-client.c4
-rw-r--r--ssh-pkcs11-helper.c8
-rw-r--r--ssh-pkcs11.c4
-rw-r--r--ssh-rsa.c260
-rw-r--r--sshbuf-misc.c16
-rw-r--r--sshbuf.h7
-rw-r--r--sshconnect.c4
-rw-r--r--sshconnect1.c18
-rw-r--r--sshconnect2.c8
-rw-r--r--sshd.c16
-rw-r--r--sshkey.c3843
-rw-r--r--sshkey.h222
49 files changed, 5812 insertions, 4873 deletions
diff --git a/ChangeLog b/ChangeLog
index 8f24fc6bc..e821f6de2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -24,6 +24,26 @@
24 24
25 Readers of a broken KRL caused by this bug will fail closed, so no 25 Readers of a broken KRL caused by this bug will fail closed, so no
26 should-have-been-revoked key will be accepted. 26 should-have-been-revoked key will be accepted.
27 - djm@cvs.openbsd.org 2014/06/24 01:13:21
28 [Makefile.in auth-bsdauth.c auth-chall.c auth-options.c auth-rsa.c
29 [auth2-none.c auth2-pubkey.c authfile.c authfile.h cipher-3des1.c
30 [cipher-chachapoly.c cipher-chachapoly.h cipher.c cipher.h
31 [digest-libc.c digest-openssl.c digest.h dns.c entropy.c hmac.h
32 [hostfile.c key.c key.h krl.c monitor.c packet.c rsa.c rsa.h
33 [ssh-add.c ssh-agent.c ssh-dss.c ssh-ecdsa.c ssh-ed25519.c
34 [ssh-keygen.c ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c
35 [ssh-rsa.c sshbuf-misc.c sshbuf.h sshconnect.c sshconnect1.c
36 [sshconnect2.c sshd.c sshkey.c sshkey.h
37 [openbsd-compat/openssl-compat.c openbsd-compat/openssl-compat.h]
38 New key API: refactor key-related functions to be more library-like,
39 existing API is offered as a set of wrappers.
40
41 with and ok markus@
42
43 Thanks also to Ben Hawkes, David Tomaschik, Ivan Fratric, Matthew
44 Dempsky and Ron Bowes for a detailed review a few months ago.
45 NB. This commit also removes portable OpenSSH support for OpenSSL
46 <0.9.8e.
27 47
2820140618 4820140618
29 - (tim) [openssh/session.c] Work around to get chroot sftp working on UnixWare 49 - (tim) [openssh/session.c] Work around to get chroot sftp working on UnixWare
diff --git a/Makefile.in b/Makefile.in
index 6bca5b51e..16659c0b1 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,4 +1,4 @@
1# $Id: Makefile.in,v 1.359 2014/05/21 22:23:59 djm Exp $ 1# $Id: Makefile.in,v 1.360 2014/07/02 05:28:03 djm Exp $
2 2
3# uncomment if you run a non bourne compatable shell. Ie. csh 3# uncomment if you run a non bourne compatable shell. Ie. csh
4#SHELL = @SH@ 4#SHELL = @SH@
@@ -68,7 +68,8 @@ LIBOPENSSH_OBJS=\
68 sshbuf.o \ 68 sshbuf.o \
69 sshbuf-getput-basic.o \ 69 sshbuf-getput-basic.o \
70 sshbuf-misc.o \ 70 sshbuf-misc.o \
71 sshbuf-getput-crypto.o 71 sshbuf-getput-crypto.o \
72 sshkey.o
72 73
73LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ 74LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
74 authfd.o authfile.o bufaux.o bufbn.o buffer.o \ 75 authfd.o authfile.o bufaux.o bufbn.o buffer.o \
diff --git a/auth-bsdauth.c b/auth-bsdauth.c
index f4209c22a..37ff893e6 100644
--- a/auth-bsdauth.c
+++ b/auth-bsdauth.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth-bsdauth.c,v 1.12 2014/03/12 04:50:32 djm Exp $ */ 1/* $OpenBSD: auth-bsdauth.c,v 1.13 2014/06/24 01:13:21 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -26,6 +26,8 @@
26#include "includes.h" 26#include "includes.h"
27 27
28#include <sys/types.h> 28#include <sys/types.h>
29#include <stdarg.h>
30#include <stdio.h>
29 31
30#include <stdarg.h> 32#include <stdarg.h>
31 33
diff --git a/auth-chall.c b/auth-chall.c
index 0005aa88b..cb3d522d9 100644
--- a/auth-chall.c
+++ b/auth-chall.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth-chall.c,v 1.13 2013/05/17 00:13:13 djm Exp $ */ 1/* $OpenBSD: auth-chall.c,v 1.14 2014/06/24 01:13:21 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -26,6 +26,9 @@
26#include "includes.h" 26#include "includes.h"
27 27
28#include <sys/types.h> 28#include <sys/types.h>
29#include <stdarg.h>
30#include <stdlib.h>
31#include <stdio.h>
29 32
30#include <stdarg.h> 33#include <stdarg.h>
31 34
diff --git a/auth-options.c b/auth-options.c
index fa209eaab..9a3c270e9 100644
--- a/auth-options.c
+++ b/auth-options.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth-options.c,v 1.62 2013/12/19 00:27:57 djm Exp $ */ 1/* $OpenBSD: auth-options.c,v 1.63 2014/06/24 01:13:21 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
@@ -586,8 +586,8 @@ auth_cert_options(Key *k, struct passwd *pw)
586 586
587 if (key_cert_is_legacy(k)) { 587 if (key_cert_is_legacy(k)) {
588 /* All options are in the one field for v00 certs */ 588 /* All options are in the one field for v00 certs */
589 if (parse_option_list(buffer_ptr(&k->cert->critical), 589 if (parse_option_list(buffer_ptr(k->cert->critical),
590 buffer_len(&k->cert->critical), pw, 590 buffer_len(k->cert->critical), pw,
591 OPTIONS_CRITICAL|OPTIONS_EXTENSIONS, 1, 591 OPTIONS_CRITICAL|OPTIONS_EXTENSIONS, 1,
592 &cert_no_port_forwarding_flag, 592 &cert_no_port_forwarding_flag,
593 &cert_no_agent_forwarding_flag, 593 &cert_no_agent_forwarding_flag,
@@ -599,14 +599,14 @@ auth_cert_options(Key *k, struct passwd *pw)
599 return -1; 599 return -1;
600 } else { 600 } else {
601 /* Separate options and extensions for v01 certs */ 601 /* Separate options and extensions for v01 certs */
602 if (parse_option_list(buffer_ptr(&k->cert->critical), 602 if (parse_option_list(buffer_ptr(k->cert->critical),
603 buffer_len(&k->cert->critical), pw, 603 buffer_len(k->cert->critical), pw,
604 OPTIONS_CRITICAL, 1, NULL, NULL, NULL, NULL, NULL, 604 OPTIONS_CRITICAL, 1, NULL, NULL, NULL, NULL, NULL,
605 &cert_forced_command, 605 &cert_forced_command,
606 &cert_source_address_done) == -1) 606 &cert_source_address_done) == -1)
607 return -1; 607 return -1;
608 if (parse_option_list(buffer_ptr(&k->cert->extensions), 608 if (parse_option_list(buffer_ptr(k->cert->extensions),
609 buffer_len(&k->cert->extensions), pw, 609 buffer_len(k->cert->extensions), pw,
610 OPTIONS_EXTENSIONS, 1, 610 OPTIONS_EXTENSIONS, 1,
611 &cert_no_port_forwarding_flag, 611 &cert_no_port_forwarding_flag,
612 &cert_no_agent_forwarding_flag, 612 &cert_no_agent_forwarding_flag,
diff --git a/auth-rsa.c b/auth-rsa.c
index 5dad6c3dc..1bddfa02f 100644
--- a/auth-rsa.c
+++ b/auth-rsa.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth-rsa.c,v 1.86 2014/01/27 19:18:54 markus Exp $ */ 1/* $OpenBSD: auth-rsa.c,v 1.87 2014/06/24 01:13:21 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
@@ -144,7 +144,8 @@ auth_rsa_challenge_dialog(Key *key)
144 challenge = PRIVSEP(auth_rsa_generate_challenge(key)); 144 challenge = PRIVSEP(auth_rsa_generate_challenge(key));
145 145
146 /* Encrypt the challenge with the public key. */ 146 /* Encrypt the challenge with the public key. */
147 rsa_public_encrypt(encrypted_challenge, challenge, key->rsa); 147 if (rsa_public_encrypt(encrypted_challenge, challenge, key->rsa) != 0)
148 fatal("%s: rsa_public_encrypt failed", __func__);
148 149
149 /* Send the encrypted challenge to the client. */ 150 /* Send the encrypted challenge to the client. */
150 packet_start(SSH_SMSG_AUTH_RSA_CHALLENGE); 151 packet_start(SSH_SMSG_AUTH_RSA_CHALLENGE);
diff --git a/auth2-none.c b/auth2-none.c
index c8c6c74a9..5501b9d64 100644
--- a/auth2-none.c
+++ b/auth2-none.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-none.c,v 1.16 2010/06/25 08:46:17 djm Exp $ */ 1/* $OpenBSD: auth2-none.c,v 1.17 2014/06/24 01:13:21 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -30,9 +30,10 @@
30#include <sys/uio.h> 30#include <sys/uio.h>
31 31
32#include <fcntl.h> 32#include <fcntl.h>
33#include <stdarg.h>
34#include <string.h> 33#include <string.h>
35#include <unistd.h> 34#include <unistd.h>
35#include <stdarg.h>
36#include <stdio.h>
36 37
37#include "atomicio.h" 38#include "atomicio.h"
38#include "xmalloc.h" 39#include "xmalloc.h"
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index 0fd27bb92..b2fd07a61 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-pubkey.c,v 1.39 2013/12/30 23:52:27 djm Exp $ */ 1/* $OpenBSD: auth2-pubkey.c,v 1.40 2014/06/24 01:13:21 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -230,7 +230,7 @@ pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...)
230} 230}
231 231
232static int 232static int
233match_principals_option(const char *principal_list, struct KeyCert *cert) 233match_principals_option(const char *principal_list, struct sshkey_cert *cert)
234{ 234{
235 char *result; 235 char *result;
236 u_int i; 236 u_int i;
@@ -250,7 +250,7 @@ match_principals_option(const char *principal_list, struct KeyCert *cert)
250} 250}
251 251
252static int 252static int
253match_principals_file(char *file, struct passwd *pw, struct KeyCert *cert) 253match_principals_file(char *file, struct passwd *pw, struct sshkey_cert *cert)
254{ 254{
255 FILE *f; 255 FILE *f;
256 char line[SSH_MAX_PUBKEY_BYTES], *cp, *ep, *line_opts; 256 char line[SSH_MAX_PUBKEY_BYTES], *cp, *ep, *line_opts;
diff --git a/authfile.c b/authfile.c
index 7cb901133..e93d86738 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,18 +1,5 @@
1/* $OpenBSD: authfile.c,v 1.106 2014/04/29 18:01:49 markus Exp $ */ 1/* $OpenBSD: authfile.c,v 1.107 2014/06/24 01:13:21 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * All rights reserved
6 * This file contains functions for reading and writing identity files, and
7 * for reading the passphrase from the user.
8 *
9 * As far as I am concerned, the code I have written for this software
10 * can be used freely for any purpose. Any derived versions of this
11 * software must be clearly marked as such, and if the derived work is
12 * incompatible with the protocol description in the RFC file, it must be
13 * called by a name other than "ssh" or "Secure Shell".
14 *
15 *
16 * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
17 * 4 *
18 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
@@ -43,32 +30,15 @@
43#include <sys/param.h> 30#include <sys/param.h>
44#include <sys/uio.h> 31#include <sys/uio.h>
45 32
46#ifdef WITH_OPENSSL
47#include <openssl/err.h>
48#include <openssl/evp.h>
49#include <openssl/pem.h>
50#endif
51
52/* compatibility with old or broken OpenSSL versions */
53#include "openbsd-compat/openssl-compat.h"
54
55#include "crypto_api.h"
56
57#include <errno.h> 33#include <errno.h>
58#include <fcntl.h> 34#include <fcntl.h>
59#include <stdarg.h>
60#include <stdio.h> 35#include <stdio.h>
36#include <stdarg.h>
61#include <stdlib.h> 37#include <stdlib.h>
62#include <string.h> 38#include <string.h>
63#include <unistd.h> 39#include <unistd.h>
64 40
65#ifdef HAVE_UTIL_H
66#include <util.h>
67#endif
68
69#include "xmalloc.h"
70#include "cipher.h" 41#include "cipher.h"
71#include "buffer.h"
72#include "key.h" 42#include "key.h"
73#include "ssh.h" 43#include "ssh.h"
74#include "log.h" 44#include "log.h"
@@ -76,667 +46,92 @@
76#include "rsa.h" 46#include "rsa.h"
77#include "misc.h" 47#include "misc.h"
78#include "atomicio.h" 48#include "atomicio.h"
79#include "uuencode.h" 49#include "sshbuf.h"
80 50#include "ssherr.h"
81/* openssh private key file format */
82#define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n"
83#define MARK_END "-----END OPENSSH PRIVATE KEY-----\n"
84#define KDFNAME "bcrypt"
85#define AUTH_MAGIC "openssh-key-v1"
86#define SALT_LEN 16
87#define DEFAULT_CIPHERNAME "aes256-cbc"
88#define DEFAULT_ROUNDS 16
89 51
90#define MAX_KEY_FILE_SIZE (1024 * 1024) 52#define MAX_KEY_FILE_SIZE (1024 * 1024)
91 53
92/* Version identification string for SSH v1 identity files. */
93static const char authfile_id_string[] =
94 "SSH PRIVATE KEY FILE FORMAT 1.1\n";
95
96static int
97key_private_to_blob2(Key *prv, Buffer *blob, const char *passphrase,
98 const char *comment, const char *ciphername, int rounds)
99{
100 u_char *key, *cp, salt[SALT_LEN];
101 size_t keylen, ivlen, blocksize, authlen;
102 u_int len, check;
103 int i, n;
104 const Cipher *c;
105 Buffer encoded, b, kdf;
106 CipherContext ctx;
107 const char *kdfname = KDFNAME;
108
109 if (rounds <= 0)
110 rounds = DEFAULT_ROUNDS;
111 if (passphrase == NULL || !strlen(passphrase)) {
112 ciphername = "none";
113 kdfname = "none";
114 } else if (ciphername == NULL)
115 ciphername = DEFAULT_CIPHERNAME;
116 else if (cipher_number(ciphername) != SSH_CIPHER_SSH2)
117 fatal("invalid cipher");
118
119 if ((c = cipher_by_name(ciphername)) == NULL)
120 fatal("unknown cipher name");
121 buffer_init(&kdf);
122 blocksize = cipher_blocksize(c);
123 keylen = cipher_keylen(c);
124 ivlen = cipher_ivlen(c);
125 authlen = cipher_authlen(c);
126 key = xcalloc(1, keylen + ivlen);
127 if (strcmp(kdfname, "none") != 0) {
128 arc4random_buf(salt, SALT_LEN);
129 if (bcrypt_pbkdf(passphrase, strlen(passphrase),
130 salt, SALT_LEN, key, keylen + ivlen, rounds) < 0)
131 fatal("bcrypt_pbkdf failed");
132 buffer_put_string(&kdf, salt, SALT_LEN);
133 buffer_put_int(&kdf, rounds);
134 }
135 cipher_init(&ctx, c, key, keylen, key + keylen , ivlen, 1);
136 explicit_bzero(key, keylen + ivlen);
137 free(key);
138
139 buffer_init(&encoded);
140 buffer_append(&encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC));
141 buffer_put_cstring(&encoded, ciphername);
142 buffer_put_cstring(&encoded, kdfname);
143 buffer_put_string(&encoded, buffer_ptr(&kdf), buffer_len(&kdf));
144 buffer_put_int(&encoded, 1); /* number of keys */
145 key_to_blob(prv, &cp, &len); /* public key */
146 buffer_put_string(&encoded, cp, len);
147
148 explicit_bzero(cp, len);
149 free(cp);
150
151 buffer_free(&kdf);
152
153 /* set up the buffer that will be encrypted */
154 buffer_init(&b);
155
156 /* Random check bytes */
157 check = arc4random();
158 buffer_put_int(&b, check);
159 buffer_put_int(&b, check);
160
161 /* append private key and comment*/
162 key_private_serialize(prv, &b);
163 buffer_put_cstring(&b, comment);
164
165 /* padding */
166 i = 0;
167 while (buffer_len(&b) % blocksize)
168 buffer_put_char(&b, ++i & 0xff);
169
170 /* length */
171 buffer_put_int(&encoded, buffer_len(&b));
172
173 /* encrypt */
174 cp = buffer_append_space(&encoded, buffer_len(&b) + authlen);
175 if (cipher_crypt(&ctx, 0, cp, buffer_ptr(&b), buffer_len(&b), 0,
176 authlen) != 0)
177 fatal("%s: cipher_crypt failed", __func__);
178 buffer_free(&b);
179 cipher_cleanup(&ctx);
180
181 /* uuencode */
182 len = 2 * buffer_len(&encoded);
183 cp = xmalloc(len);
184 n = uuencode(buffer_ptr(&encoded), buffer_len(&encoded),
185 (char *)cp, len);
186 if (n < 0)
187 fatal("%s: uuencode", __func__);
188
189 buffer_clear(blob);
190 buffer_append(blob, MARK_BEGIN, sizeof(MARK_BEGIN) - 1);
191 for (i = 0; i < n; i++) {
192 buffer_put_char(blob, cp[i]);
193 if (i % 70 == 69)
194 buffer_put_char(blob, '\n');
195 }
196 if (i % 70 != 69)
197 buffer_put_char(blob, '\n');
198 buffer_append(blob, MARK_END, sizeof(MARK_END) - 1);
199 free(cp);
200
201 return buffer_len(blob);
202}
203
204static Key *
205key_parse_private2(Buffer *blob, int type, const char *passphrase,
206 char **commentp)
207{
208 u_char *key = NULL, *cp, *salt = NULL, pad, last;
209 char *comment = NULL, *ciphername = NULL, *kdfname = NULL;
210 const u_char *kdfp;
211 u_int keylen = 0, ivlen, blocksize, slen, klen, len, rounds, nkeys;
212 u_int check1, check2, m1len, m2len;
213 size_t authlen;
214 const Cipher *c;
215 Buffer b, encoded, copy, kdf;
216 CipherContext ctx;
217 Key *k = NULL;
218 int dlen, ret, i;
219
220 buffer_init(&b);
221 buffer_init(&kdf);
222 buffer_init(&encoded);
223 buffer_init(&copy);
224
225 /* uudecode */
226 m1len = sizeof(MARK_BEGIN) - 1;
227 m2len = sizeof(MARK_END) - 1;
228 cp = buffer_ptr(blob);
229 len = buffer_len(blob);
230 if (len < m1len || memcmp(cp, MARK_BEGIN, m1len)) {
231 debug("%s: missing begin marker", __func__);
232 goto out;
233 }
234 cp += m1len;
235 len -= m1len;
236 while (len) {
237 if (*cp != '\n' && *cp != '\r')
238 buffer_put_char(&encoded, *cp);
239 last = *cp;
240 len--;
241 cp++;
242 if (last == '\n') {
243 if (len >= m2len && !memcmp(cp, MARK_END, m2len)) {
244 buffer_put_char(&encoded, '\0');
245 break;
246 }
247 }
248 }
249 if (!len) {
250 debug("%s: no end marker", __func__);
251 goto out;
252 }
253 len = buffer_len(&encoded);
254 if ((cp = buffer_append_space(&copy, len)) == NULL) {
255 error("%s: buffer_append_space", __func__);
256 goto out;
257 }
258 if ((dlen = uudecode(buffer_ptr(&encoded), cp, len)) < 0) {
259 error("%s: uudecode failed", __func__);
260 goto out;
261 }
262 if ((u_int)dlen > len) {
263 error("%s: crazy uudecode length %d > %u", __func__, dlen, len);
264 goto out;
265 }
266 buffer_consume_end(&copy, len - dlen);
267 if (buffer_len(&copy) < sizeof(AUTH_MAGIC) ||
268 memcmp(buffer_ptr(&copy), AUTH_MAGIC, sizeof(AUTH_MAGIC))) {
269 error("%s: bad magic", __func__);
270 goto out;
271 }
272 buffer_consume(&copy, sizeof(AUTH_MAGIC));
273
274 ciphername = buffer_get_cstring_ret(&copy, NULL);
275 if (ciphername == NULL ||
276 (c = cipher_by_name(ciphername)) == NULL) {
277 error("%s: unknown cipher name", __func__);
278 goto out;
279 }
280 if ((passphrase == NULL || !strlen(passphrase)) &&
281 strcmp(ciphername, "none") != 0) {
282 /* passphrase required */
283 goto out;
284 }
285 kdfname = buffer_get_cstring_ret(&copy, NULL);
286 if (kdfname == NULL ||
287 (strcmp(kdfname, "none") != 0 && strcmp(kdfname, "bcrypt") != 0)) {
288 error("%s: unknown kdf name", __func__);
289 goto out;
290 }
291 if (!strcmp(kdfname, "none") && strcmp(ciphername, "none") != 0) {
292 error("%s: cipher %s requires kdf", __func__, ciphername);
293 goto out;
294 }
295 /* kdf options */
296 kdfp = buffer_get_string_ptr_ret(&copy, &klen);
297 if (kdfp == NULL) {
298 error("%s: kdf options not set", __func__);
299 goto out;
300 }
301 if (klen > 0) {
302 if ((cp = buffer_append_space(&kdf, klen)) == NULL) {
303 error("%s: kdf alloc failed", __func__);
304 goto out;
305 }
306 memcpy(cp, kdfp, klen);
307 }
308 /* number of keys */
309 if (buffer_get_int_ret(&nkeys, &copy) < 0) {
310 error("%s: key counter missing", __func__);
311 goto out;
312 }
313 if (nkeys != 1) {
314 error("%s: only one key supported", __func__);
315 goto out;
316 }
317 /* pubkey */
318 if ((cp = buffer_get_string_ret(&copy, &len)) == NULL) {
319 error("%s: pubkey not found", __func__);
320 goto out;
321 }
322 free(cp); /* XXX check pubkey against decrypted private key */
323
324 /* size of encrypted key blob */
325 len = buffer_get_int(&copy);
326 blocksize = cipher_blocksize(c);
327 authlen = cipher_authlen(c);
328 if (len < blocksize) {
329 error("%s: encrypted data too small", __func__);
330 goto out;
331 }
332 if (len % blocksize) {
333 error("%s: length not multiple of blocksize", __func__);
334 goto out;
335 }
336
337 /* setup key */
338 keylen = cipher_keylen(c);
339 ivlen = cipher_ivlen(c);
340 key = xcalloc(1, keylen + ivlen);
341 if (!strcmp(kdfname, "bcrypt")) {
342 if ((salt = buffer_get_string_ret(&kdf, &slen)) == NULL) {
343 error("%s: salt not set", __func__);
344 goto out;
345 }
346 if (buffer_get_int_ret(&rounds, &kdf) < 0) {
347 error("%s: rounds not set", __func__);
348 goto out;
349 }
350 if (bcrypt_pbkdf(passphrase, strlen(passphrase), salt, slen,
351 key, keylen + ivlen, rounds) < 0) {
352 error("%s: bcrypt_pbkdf failed", __func__);
353 goto out;
354 }
355 }
356
357 cp = buffer_append_space(&b, len);
358 cipher_init(&ctx, c, key, keylen, key + keylen, ivlen, 0);
359 ret = cipher_crypt(&ctx, 0, cp, buffer_ptr(&copy), len, 0, authlen);
360 cipher_cleanup(&ctx);
361 buffer_consume(&copy, len);
362
363 /* fail silently on decryption errors */
364 if (ret != 0) {
365 debug("%s: decrypt failed", __func__);
366 goto out;
367 }
368
369 if (buffer_len(&copy) != 0) {
370 error("%s: key blob has trailing data (len = %u)", __func__,
371 buffer_len(&copy));
372 goto out;
373 }
374
375 /* check bytes */
376 if (buffer_get_int_ret(&check1, &b) < 0 ||
377 buffer_get_int_ret(&check2, &b) < 0) {
378 error("check bytes missing");
379 goto out;
380 }
381 if (check1 != check2) {
382 debug("%s: decrypt failed: 0x%08x != 0x%08x", __func__,
383 check1, check2);
384 goto out;
385 }
386
387 k = key_private_deserialize(&b);
388
389 /* comment */
390 comment = buffer_get_cstring_ret(&b, NULL);
391
392 i = 0;
393 while (buffer_len(&b)) {
394 if (buffer_get_char_ret(&pad, &b) == -1 ||
395 pad != (++i & 0xff)) {
396 error("%s: bad padding", __func__);
397 key_free(k);
398 k = NULL;
399 goto out;
400 }
401 }
402
403 if (k && commentp) {
404 *commentp = comment;
405 comment = NULL;
406 }
407
408 /* XXX decode pubkey and check against private */
409 out:
410 free(ciphername);
411 free(kdfname);
412 free(salt);
413 free(comment);
414 if (key)
415 explicit_bzero(key, keylen + ivlen);
416 free(key);
417 buffer_free(&encoded);
418 buffer_free(&copy);
419 buffer_free(&kdf);
420 buffer_free(&b);
421 return k;
422}
423
424#ifdef WITH_SSH1
425/*
426 * Serialises the authentication (private) key to a blob, encrypting it with
427 * passphrase. The identification of the blob (lowest 64 bits of n) will
428 * precede the key to provide identification of the key without needing a
429 * passphrase.
430 */
431static int
432key_private_rsa1_to_blob(Key *key, Buffer *blob, const char *passphrase,
433 const char *comment)
434{
435 Buffer buffer, encrypted;
436 u_char buf[100], *cp;
437 int i, cipher_num;
438 CipherContext ciphercontext;
439 const Cipher *cipher;
440 u_int32_t rnd;
441
442 /*
443 * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting
444 * to another cipher; otherwise use SSH_AUTHFILE_CIPHER.
445 */
446 cipher_num = (strcmp(passphrase, "") == 0) ?
447 SSH_CIPHER_NONE : SSH_AUTHFILE_CIPHER;
448 if ((cipher = cipher_by_number(cipher_num)) == NULL)
449 fatal("save_private_key_rsa: bad cipher");
450
451 /* This buffer is used to built the secret part of the private key. */
452 buffer_init(&buffer);
453
454 /* Put checkbytes for checking passphrase validity. */
455 rnd = arc4random();
456 buf[0] = rnd & 0xff;
457 buf[1] = (rnd >> 8) & 0xff;
458 buf[2] = buf[0];
459 buf[3] = buf[1];
460 buffer_append(&buffer, buf, 4);
461
462 /*
463 * Store the private key (n and e will not be stored because they
464 * will be stored in plain text, and storing them also in encrypted
465 * format would just give known plaintext).
466 */
467 buffer_put_bignum(&buffer, key->rsa->d);
468 buffer_put_bignum(&buffer, key->rsa->iqmp);
469 buffer_put_bignum(&buffer, key->rsa->q); /* reverse from SSL p */
470 buffer_put_bignum(&buffer, key->rsa->p); /* reverse from SSL q */
471
472 /* Pad the part to be encrypted until its size is a multiple of 8. */
473 while (buffer_len(&buffer) % 8 != 0)
474 buffer_put_char(&buffer, 0);
475
476 /* This buffer will be used to contain the data in the file. */
477 buffer_init(&encrypted);
478
479 /* First store keyfile id string. */
480 for (i = 0; authfile_id_string[i]; i++)
481 buffer_put_char(&encrypted, authfile_id_string[i]);
482 buffer_put_char(&encrypted, 0);
483
484 /* Store cipher type. */
485 buffer_put_char(&encrypted, cipher_num);
486 buffer_put_int(&encrypted, 0); /* For future extension */
487
488 /* Store public key. This will be in plain text. */
489 buffer_put_int(&encrypted, BN_num_bits(key->rsa->n));
490 buffer_put_bignum(&encrypted, key->rsa->n);
491 buffer_put_bignum(&encrypted, key->rsa->e);
492 buffer_put_cstring(&encrypted, comment);
493
494 /* Allocate space for the private part of the key in the buffer. */
495 cp = buffer_append_space(&encrypted, buffer_len(&buffer));
496
497 cipher_set_key_string(&ciphercontext, cipher, passphrase,
498 CIPHER_ENCRYPT);
499 if (cipher_crypt(&ciphercontext, 0, cp,
500 buffer_ptr(&buffer), buffer_len(&buffer), 0, 0) != 0)
501 fatal("%s: cipher_crypt failed", __func__);
502 cipher_cleanup(&ciphercontext);
503 explicit_bzero(&ciphercontext, sizeof(ciphercontext));
504
505 /* Destroy temporary data. */
506 explicit_bzero(buf, sizeof(buf));
507 buffer_free(&buffer);
508
509 buffer_append(blob, buffer_ptr(&encrypted), buffer_len(&encrypted));
510 buffer_free(&encrypted);
511
512 return 1;
513}
514#endif
515
516#ifdef WITH_OPENSSL
517/* convert SSH v2 key in OpenSSL PEM format */
518static int
519key_private_pem_to_blob(Key *key, Buffer *blob, const char *_passphrase,
520 const char *comment)
521{
522 int success = 0;
523 int blen, len = strlen(_passphrase);
524 u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;
525#if (OPENSSL_VERSION_NUMBER < 0x00907000L)
526 const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL;
527#else
528 const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
529#endif
530 const u_char *bptr;
531 BIO *bio;
532
533 if (len > 0 && len <= 4) {
534 error("passphrase too short: have %d bytes, need > 4", len);
535 return 0;
536 }
537 if ((bio = BIO_new(BIO_s_mem())) == NULL) {
538 error("%s: BIO_new failed", __func__);
539 return 0;
540 }
541 switch (key->type) {
542 case KEY_DSA:
543 success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
544 cipher, passphrase, len, NULL, NULL);
545 break;
546#ifdef OPENSSL_HAS_ECC
547 case KEY_ECDSA:
548 success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
549 cipher, passphrase, len, NULL, NULL);
550 break;
551#endif
552 case KEY_RSA:
553 success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
554 cipher, passphrase, len, NULL, NULL);
555 break;
556 }
557 if (success) {
558 if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0)
559 success = 0;
560 else
561 buffer_append(blob, bptr, blen);
562 }
563 BIO_free(bio);
564 return success;
565}
566#endif
567
568/* Save a key blob to a file */ 54/* Save a key blob to a file */
569static int 55static int
570key_save_private_blob(Buffer *keybuf, const char *filename) 56sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename)
571{ 57{
572 int fd; 58 int fd, oerrno;
573 59
574 if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0) { 60 if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0)
575 error("open %s failed: %s.", filename, strerror(errno)); 61 return SSH_ERR_SYSTEM_ERROR;
576 return 0; 62 if (atomicio(vwrite, fd, (u_char *)sshbuf_ptr(keybuf),
577 } 63 sshbuf_len(keybuf)) != sshbuf_len(keybuf)) {
578 if (atomicio(vwrite, fd, buffer_ptr(keybuf), 64 oerrno = errno;
579 buffer_len(keybuf)) != buffer_len(keybuf)) {
580 error("write to key file %s failed: %s", filename,
581 strerror(errno));
582 close(fd); 65 close(fd);
583 unlink(filename); 66 unlink(filename);
584 return 0; 67 errno = oerrno;
68 return SSH_ERR_SYSTEM_ERROR;
585 } 69 }
586 close(fd); 70 close(fd);
587 return 1; 71 return 0;
588}
589
590/* Serialise "key" to buffer "blob" */
591static int
592key_private_to_blob(Key *key, Buffer *blob, const char *passphrase,
593 const char *comment, int force_new_format, const char *new_format_cipher,
594 int new_format_rounds)
595{
596 switch (key->type) {
597#ifdef WITH_SSH1
598 case KEY_RSA1:
599 return key_private_rsa1_to_blob(key, blob, passphrase, comment);
600#endif
601#ifdef WITH_OPENSSL
602 case KEY_DSA:
603 case KEY_ECDSA:
604 case KEY_RSA:
605 if (force_new_format) {
606 return key_private_to_blob2(key, blob, passphrase,
607 comment, new_format_cipher, new_format_rounds);
608 }
609 return key_private_pem_to_blob(key, blob, passphrase, comment);
610#endif
611 case KEY_ED25519:
612 return key_private_to_blob2(key, blob, passphrase,
613 comment, new_format_cipher, new_format_rounds);
614 default:
615 error("%s: cannot save key type %d", __func__, key->type);
616 return 0;
617 }
618} 72}
619 73
620int 74int
621key_save_private(Key *key, const char *filename, const char *passphrase, 75sshkey_save_private(struct sshkey *key, const char *filename,
622 const char *comment, int force_new_format, const char *new_format_cipher, 76 const char *passphrase, const char *comment,
623 int new_format_rounds) 77 int force_new_format, const char *new_format_cipher, int new_format_rounds)
624{ 78{
625 Buffer keyblob; 79 struct sshbuf *keyblob = NULL;
626 int success = 0; 80 int r;
627 81
628 buffer_init(&keyblob); 82 if ((keyblob = sshbuf_new()) == NULL)
629 if (!key_private_to_blob(key, &keyblob, passphrase, comment, 83 return SSH_ERR_ALLOC_FAIL;
630 force_new_format, new_format_cipher, new_format_rounds)) 84 if ((r = sshkey_private_to_fileblob(key, keyblob, passphrase, comment,
85 force_new_format, new_format_cipher, new_format_rounds)) != 0)
631 goto out; 86 goto out;
632 if (!key_save_private_blob(&keyblob, filename)) 87 if ((r = sshkey_save_private_blob(keyblob, filename)) != 0)
633 goto out; 88 goto out;
634 success = 1; 89 r = 0;
635 out: 90 out:
636 buffer_free(&keyblob); 91 sshbuf_free(keyblob);
637 return success; 92 return r;
638}
639
640#ifdef WITH_SSH1
641/*
642 * Parse the public, unencrypted portion of a RSA1 key.
643 */
644static Key *
645key_parse_public_rsa1(Buffer *blob, char **commentp)
646{
647 Key *pub;
648 Buffer copy;
649
650 /* Check that it is at least big enough to contain the ID string. */
651 if (buffer_len(blob) < sizeof(authfile_id_string)) {
652 debug3("Truncated RSA1 identifier");
653 return NULL;
654 }
655
656 /*
657 * Make sure it begins with the id string. Consume the id string
658 * from the buffer.
659 */
660 if (memcmp(buffer_ptr(blob), authfile_id_string,
661 sizeof(authfile_id_string)) != 0) {
662 debug3("Incorrect RSA1 identifier");
663 return NULL;
664 }
665 buffer_init(&copy);
666 buffer_append(&copy, buffer_ptr(blob), buffer_len(blob));
667 buffer_consume(&copy, sizeof(authfile_id_string));
668
669 /* Skip cipher type and reserved data. */
670 (void) buffer_get_char(&copy); /* cipher type */
671 (void) buffer_get_int(&copy); /* reserved */
672
673 /* Read the public key from the buffer. */
674 (void) buffer_get_int(&copy);
675 pub = key_new(KEY_RSA1);
676 buffer_get_bignum(&copy, pub->rsa->n);
677 buffer_get_bignum(&copy, pub->rsa->e);
678 if (commentp)
679 *commentp = buffer_get_string(&copy, NULL);
680 /* The encrypted private part is not parsed by this function. */
681 buffer_free(&copy);
682
683 return pub;
684} 93}
685#endif
686 94
687/* Load a key from a fd into a buffer */ 95/* Load a key from a fd into a buffer */
688int 96int
689key_load_file(int fd, const char *filename, Buffer *blob) 97sshkey_load_file(int fd, const char *filename, struct sshbuf *blob)
690{ 98{
691 u_char buf[1024]; 99 u_char buf[1024];
692 size_t len; 100 size_t len;
693 struct stat st; 101 struct stat st;
102 int r;
694 103
695 if (fstat(fd, &st) < 0) { 104 if (fstat(fd, &st) < 0)
696 error("%s: fstat of key file %.200s%sfailed: %.100s", __func__, 105 return SSH_ERR_SYSTEM_ERROR;
697 filename == NULL ? "" : filename,
698 filename == NULL ? "" : " ",
699 strerror(errno));
700 return 0;
701 }
702 if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 && 106 if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
703 st.st_size > MAX_KEY_FILE_SIZE) { 107 st.st_size > MAX_KEY_FILE_SIZE)
704 toobig: 108 return SSH_ERR_INVALID_FORMAT;
705 error("%s: key file %.200s%stoo large", __func__,
706 filename == NULL ? "" : filename,
707 filename == NULL ? "" : " ");
708 return 0;
709 }
710 buffer_clear(blob);
711 for (;;) { 109 for (;;) {
712 if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) { 110 if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {
713 if (errno == EPIPE) 111 if (errno == EPIPE)
714 break; 112 break;
715 debug("%s: read from key file %.200s%sfailed: %.100s", 113 r = SSH_ERR_SYSTEM_ERROR;
716 __func__, filename == NULL ? "" : filename, 114 goto out;
717 filename == NULL ? "" : " ", strerror(errno));
718 buffer_clear(blob);
719 explicit_bzero(buf, sizeof(buf));
720 return 0;
721 } 115 }
722 buffer_append(blob, buf, len); 116 if ((r = sshbuf_put(blob, buf, len)) != 0)
723 if (buffer_len(blob) > MAX_KEY_FILE_SIZE) { 117 goto out;
724 buffer_clear(blob); 118 if (sshbuf_len(blob) > MAX_KEY_FILE_SIZE) {
725 explicit_bzero(buf, sizeof(buf)); 119 r = SSH_ERR_INVALID_FORMAT;
726 goto toobig; 120 goto out;
727 } 121 }
728 } 122 }
729 explicit_bzero(buf, sizeof(buf));
730 if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 && 123 if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
731 st.st_size != buffer_len(blob)) { 124 st.st_size != (off_t)sshbuf_len(blob)) {
732 debug("%s: key file %.200s%schanged size while reading", 125 r = SSH_ERR_FILE_CHANGED;
733 __func__, filename == NULL ? "" : filename, 126 goto out;
734 filename == NULL ? "" : " ");
735 buffer_clear(blob);
736 return 0;
737 } 127 }
128 r = 0;
738 129
739 return 1; 130 out:
131 explicit_bzero(buf, sizeof(buf));
132 if (r != 0)
133 sshbuf_reset(blob);
134 return r;
740} 135}
741 136
742#ifdef WITH_SSH1 137#ifdef WITH_SSH1
@@ -745,249 +140,65 @@ key_load_file(int fd, const char *filename, Buffer *blob)
745 * encountered (the file does not exist or is not readable), and the key 140 * encountered (the file does not exist or is not readable), and the key
746 * otherwise. 141 * otherwise.
747 */ 142 */
748static Key * 143static int
749key_load_public_rsa1(int fd, const char *filename, char **commentp) 144sshkey_load_public_rsa1(int fd, const char *filename,
750{ 145 struct sshkey **keyp, char **commentp)
751 Buffer buffer;
752 Key *pub;
753
754 buffer_init(&buffer);
755 if (!key_load_file(fd, filename, &buffer)) {
756 buffer_free(&buffer);
757 return NULL;
758 }
759
760 pub = key_parse_public_rsa1(&buffer, commentp);
761 if (pub == NULL)
762 debug3("Could not load \"%s\" as a RSA1 public key", filename);
763 buffer_free(&buffer);
764 return pub;
765}
766
767/* load public key from private-key file, works only for SSH v1 */
768Key *
769key_load_public_type(int type, const char *filename, char **commentp)
770{
771 Key *pub;
772 int fd;
773
774 if (type == KEY_RSA1) {
775 fd = open(filename, O_RDONLY);
776 if (fd < 0)
777 return NULL;
778 pub = key_load_public_rsa1(fd, filename, commentp);
779 close(fd);
780 return pub;
781 }
782 return NULL;
783}
784
785static Key *
786key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp)
787{ 146{
788 int check1, check2, cipher_type; 147 struct sshbuf *b = NULL;
789 Buffer decrypted; 148 int r;
790 u_char *cp;
791 CipherContext ciphercontext;
792 const Cipher *cipher;
793 Key *prv = NULL;
794 Buffer copy;
795
796 /* Check that it is at least big enough to contain the ID string. */
797 if (buffer_len(blob) < sizeof(authfile_id_string)) {
798 debug3("Truncated RSA1 identifier");
799 return NULL;
800 }
801
802 /*
803 * Make sure it begins with the id string. Consume the id string
804 * from the buffer.
805 */
806 if (memcmp(buffer_ptr(blob), authfile_id_string,
807 sizeof(authfile_id_string)) != 0) {
808 debug3("Incorrect RSA1 identifier");
809 return NULL;
810 }
811 buffer_init(&copy);
812 buffer_append(&copy, buffer_ptr(blob), buffer_len(blob));
813 buffer_consume(&copy, sizeof(authfile_id_string));
814
815 /* Read cipher type. */
816 cipher_type = buffer_get_char(&copy);
817 (void) buffer_get_int(&copy); /* Reserved data. */
818
819 /* Read the public key from the buffer. */
820 (void) buffer_get_int(&copy);
821 prv = key_new_private(KEY_RSA1);
822
823 buffer_get_bignum(&copy, prv->rsa->n);
824 buffer_get_bignum(&copy, prv->rsa->e);
825 if (commentp)
826 *commentp = buffer_get_string(&copy, NULL);
827 else
828 (void)buffer_get_string_ptr(&copy, NULL);
829
830 /* Check that it is a supported cipher. */
831 cipher = cipher_by_number(cipher_type);
832 if (cipher == NULL) {
833 debug("Unsupported RSA1 cipher %d", cipher_type);
834 buffer_free(&copy);
835 goto fail;
836 }
837 /* Initialize space for decrypted data. */
838 buffer_init(&decrypted);
839 cp = buffer_append_space(&decrypted, buffer_len(&copy));
840
841 /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */
842 cipher_set_key_string(&ciphercontext, cipher, passphrase,
843 CIPHER_DECRYPT);
844 if (cipher_crypt(&ciphercontext, 0, cp,
845 buffer_ptr(&copy), buffer_len(&copy), 0, 0) != 0)
846 fatal("%s: cipher_crypt failed", __func__);
847 cipher_cleanup(&ciphercontext);
848 explicit_bzero(&ciphercontext, sizeof(ciphercontext));
849 buffer_free(&copy);
850
851 check1 = buffer_get_char(&decrypted);
852 check2 = buffer_get_char(&decrypted);
853 if (check1 != buffer_get_char(&decrypted) ||
854 check2 != buffer_get_char(&decrypted)) {
855 if (strcmp(passphrase, "") != 0)
856 debug("Bad passphrase supplied for RSA1 key");
857 /* Bad passphrase. */
858 buffer_free(&decrypted);
859 goto fail;
860 }
861 /* Read the rest of the private key. */
862 buffer_get_bignum(&decrypted, prv->rsa->d);
863 buffer_get_bignum(&decrypted, prv->rsa->iqmp); /* u */
864 /* in SSL and SSH v1 p and q are exchanged */
865 buffer_get_bignum(&decrypted, prv->rsa->q); /* p */
866 buffer_get_bignum(&decrypted, prv->rsa->p); /* q */
867
868 /* calculate p-1 and q-1 */
869 rsa_generate_additional_parameters(prv->rsa);
870
871 buffer_free(&decrypted);
872 149
873 /* enable blinding */ 150 *keyp = NULL;
874 if (RSA_blinding_on(prv->rsa, NULL) != 1) {
875 error("%s: RSA_blinding_on failed", __func__);
876 goto fail;
877 }
878 return prv;
879
880fail:
881 if (commentp != NULL) 151 if (commentp != NULL)
882 free(*commentp); 152 *commentp = NULL;
883 key_free(prv); 153
884 return NULL; 154 if ((b = sshbuf_new()) == NULL)
155 return SSH_ERR_ALLOC_FAIL;
156 if ((r = sshkey_load_file(fd, filename, b)) != 0)
157 goto out;
158 if ((r = sshkey_parse_public_rsa1_fileblob(b, keyp, commentp)) != 0)
159 goto out;
160 r = 0;
161 out:
162 sshbuf_free(b);
163 return r;
885} 164}
886#endif 165#endif /* WITH_SSH1 */
887 166
888#ifdef WITH_OPENSSL 167#ifdef WITH_OPENSSL
889static Key * 168/* XXX Deprecate? */
890key_parse_private_pem(Buffer *blob, int type, const char *passphrase, 169int
891 char **commentp) 170sshkey_load_private_pem(int fd, int type, const char *passphrase,
171 struct sshkey **keyp, char **commentp)
892{ 172{
893 EVP_PKEY *pk = NULL; 173 struct sshbuf *buffer = NULL;
894 Key *prv = NULL; 174 int r;
895 char *name = "<no key>";
896 BIO *bio;
897
898 if ((bio = BIO_new_mem_buf(buffer_ptr(blob),
899 buffer_len(blob))) == NULL) {
900 error("%s: BIO_new_mem_buf failed", __func__);
901 return NULL;
902 }
903
904 pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, (char *)passphrase);
905 BIO_free(bio);
906 if (pk == NULL) {
907 debug("%s: PEM_read_PrivateKey failed", __func__);
908 (void)ERR_get_error();
909 } else if (pk->type == EVP_PKEY_RSA &&
910 (type == KEY_UNSPEC||type==KEY_RSA)) {
911 prv = key_new(KEY_UNSPEC);
912 prv->rsa = EVP_PKEY_get1_RSA(pk);
913 prv->type = KEY_RSA;
914 name = "rsa w/o comment";
915#ifdef DEBUG_PK
916 RSA_print_fp(stderr, prv->rsa, 8);
917#endif
918 if (RSA_blinding_on(prv->rsa, NULL) != 1) {
919 error("%s: RSA_blinding_on failed", __func__);
920 key_free(prv);
921 prv = NULL;
922 }
923 } else if (pk->type == EVP_PKEY_DSA &&
924 (type == KEY_UNSPEC||type==KEY_DSA)) {
925 prv = key_new(KEY_UNSPEC);
926 prv->dsa = EVP_PKEY_get1_DSA(pk);
927 prv->type = KEY_DSA;
928 name = "dsa w/o comment";
929#ifdef DEBUG_PK
930 DSA_print_fp(stderr, prv->dsa, 8);
931#endif
932#ifdef OPENSSL_HAS_ECC
933 } else if (pk->type == EVP_PKEY_EC &&
934 (type == KEY_UNSPEC||type==KEY_ECDSA)) {
935 prv = key_new(KEY_UNSPEC);
936 prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk);
937 prv->type = KEY_ECDSA;
938 if ((prv->ecdsa_nid = key_ecdsa_key_to_nid(prv->ecdsa)) == -1 ||
939 key_curve_nid_to_name(prv->ecdsa_nid) == NULL ||
940 key_ec_validate_public(EC_KEY_get0_group(prv->ecdsa),
941 EC_KEY_get0_public_key(prv->ecdsa)) != 0 ||
942 key_ec_validate_private(prv->ecdsa) != 0) {
943 error("%s: bad ECDSA key", __func__);
944 key_free(prv);
945 prv = NULL;
946 }
947 name = "ecdsa w/o comment";
948#ifdef DEBUG_PK
949 if (prv != NULL && prv->ecdsa != NULL)
950 key_dump_ec_key(prv->ecdsa);
951#endif
952#endif /* OPENSSL_HAS_ECC */
953 } else {
954 error("%s: PEM_read_PrivateKey: mismatch or "
955 "unknown EVP_PKEY save_type %d", __func__, pk->save_type);
956 }
957 if (pk != NULL)
958 EVP_PKEY_free(pk);
959 if (prv != NULL && commentp)
960 *commentp = xstrdup(name);
961 debug("read PEM private key done: type %s",
962 prv ? key_type(prv) : "<unknown>");
963 return prv;
964}
965 175
966Key * 176 *keyp = NULL;
967key_load_private_pem(int fd, int type, const char *passphrase, 177 if (commentp != NULL)
968 char **commentp) 178 *commentp = NULL;
969{
970 Buffer buffer;
971 Key *prv;
972 179
973 buffer_init(&buffer); 180 if ((buffer = sshbuf_new()) == NULL)
974 if (!key_load_file(fd, NULL, &buffer)) { 181 return SSH_ERR_ALLOC_FAIL;
975 buffer_free(&buffer); 182 if ((r = sshkey_load_file(fd, NULL, buffer)) != 0)
976 return NULL; 183 goto out;
977 } 184 if ((r = sshkey_parse_private_pem_fileblob(buffer, type, passphrase,
978 prv = key_parse_private_pem(&buffer, type, passphrase, commentp); 185 keyp, commentp)) != 0)
979 buffer_free(&buffer); 186 goto out;
980 return prv; 187 r = 0;
188 out:
189 sshbuf_free(buffer);
190 return r;
981} 191}
982#endif 192#endif /* WITH_OPENSSL */
983 193
194/* XXX remove error() calls from here? */
984int 195int
985key_perm_ok(int fd, const char *filename) 196sshkey_perm_ok(int fd, const char *filename)
986{ 197{
987 struct stat st; 198 struct stat st;
988 199
989 if (fstat(fd, &st) < 0) 200 if (fstat(fd, &st) < 0)
990 return 0; 201 return SSH_ERR_SYSTEM_ERROR;
991 /* 202 /*
992 * if a key owned by the user is accessed, then we check the 203 * if a key owned by the user is accessed, then we check the
993 * permissions of the file. if the key owned by a different user, 204 * permissions of the file. if the key owned by a different user,
@@ -1002,313 +213,311 @@ key_perm_ok(int fd, const char *filename)
1002 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 213 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
1003 error("Permissions 0%3.3o for '%s' are too open.", 214 error("Permissions 0%3.3o for '%s' are too open.",
1004 (u_int)st.st_mode & 0777, filename); 215 (u_int)st.st_mode & 0777, filename);
1005 error("It is required that your private key files are NOT accessible by others."); 216 error("It is recommended that your private key files are NOT accessible by others.");
1006 error("This private key will be ignored."); 217 error("This private key will be ignored.");
1007 return 0; 218 return SSH_ERR_KEY_BAD_PERMISSIONS;
1008 } 219 }
1009 return 1; 220 return 0;
1010} 221}
1011 222
1012static Key * 223/* XXX kill perm_ok now that we have SSH_ERR_KEY_BAD_PERMISSIONS? */
1013key_parse_private_type(Buffer *blob, int type, const char *passphrase, 224int
1014 char **commentp) 225sshkey_load_private_type(int type, const char *filename, const char *passphrase,
226 struct sshkey **keyp, char **commentp, int *perm_ok)
1015{ 227{
1016 Key *k; 228 int fd, r;
229 struct sshbuf *buffer = NULL;
1017 230
1018 switch (type) { 231 *keyp = NULL;
1019#ifdef WITH_SSH1 232 if (commentp != NULL)
1020 case KEY_RSA1: 233 *commentp = NULL;
1021 return key_parse_private_rsa1(blob, passphrase, commentp);
1022#endif
1023#ifdef WITH_OPENSSL
1024 case KEY_DSA:
1025 case KEY_ECDSA:
1026 case KEY_RSA:
1027 return key_parse_private_pem(blob, type, passphrase, commentp);
1028#endif
1029 case KEY_ED25519:
1030 return key_parse_private2(blob, type, passphrase, commentp);
1031 case KEY_UNSPEC:
1032 if ((k = key_parse_private2(blob, type, passphrase, commentp)))
1033 return k;
1034#ifdef WITH_OPENSSL
1035 return key_parse_private_pem(blob, type, passphrase, commentp);
1036#endif
1037 default:
1038 error("%s: cannot parse key type %d", __func__, type);
1039 break;
1040 }
1041 return NULL;
1042}
1043
1044Key *
1045key_load_private_type(int type, const char *filename, const char *passphrase,
1046 char **commentp, int *perm_ok)
1047{
1048 int fd;
1049 Key *ret;
1050 Buffer buffer;
1051 234
1052 fd = open(filename, O_RDONLY); 235 if ((fd = open(filename, O_RDONLY)) < 0) {
1053 if (fd < 0) {
1054 debug("could not open key file '%s': %s", filename,
1055 strerror(errno));
1056 if (perm_ok != NULL) 236 if (perm_ok != NULL)
1057 *perm_ok = 0; 237 *perm_ok = 0;
1058 return NULL; 238 return SSH_ERR_SYSTEM_ERROR;
1059 } 239 }
1060 if (!key_perm_ok(fd, filename)) { 240 if (sshkey_perm_ok(fd, filename) != 0) {
1061 if (perm_ok != NULL) 241 if (perm_ok != NULL)
1062 *perm_ok = 0; 242 *perm_ok = 0;
1063 error("bad permissions: ignore key: %s", filename); 243 r = SSH_ERR_KEY_BAD_PERMISSIONS;
1064 close(fd); 244 goto out;
1065 return NULL;
1066 } 245 }
1067 if (perm_ok != NULL) 246 if (perm_ok != NULL)
1068 *perm_ok = 1; 247 *perm_ok = 1;
1069 248
1070 buffer_init(&buffer); 249 if ((buffer = sshbuf_new()) == NULL) {
1071 if (!key_load_file(fd, filename, &buffer)) { 250 r = SSH_ERR_ALLOC_FAIL;
1072 buffer_free(&buffer); 251 goto out;
1073 close(fd);
1074 return NULL;
1075 } 252 }
253 if ((r = sshkey_load_file(fd, filename, buffer)) != 0)
254 goto out;
255 if ((r = sshkey_parse_private_fileblob_type(buffer, type, passphrase,
256 keyp, commentp)) != 0)
257 goto out;
258 r = 0;
259 out:
1076 close(fd); 260 close(fd);
1077 ret = key_parse_private_type(&buffer, type, passphrase, commentp); 261 if (buffer != NULL)
1078 buffer_free(&buffer); 262 sshbuf_free(buffer);
1079 return ret; 263 return r;
1080} 264}
1081 265
1082Key * 266/* XXX this is almost identical to sshkey_load_private_type() */
1083key_parse_private(Buffer *buffer, const char *filename, 267int
1084 const char *passphrase, char **commentp) 268sshkey_load_private(const char *filename, const char *passphrase,
269 struct sshkey **keyp, char **commentp)
1085{ 270{
1086#ifdef WITH_SSH1 271 struct sshbuf *buffer = NULL;
1087 Key *pub, *prv; 272 int r, fd;
1088 273
1089 /* it's a SSH v1 key if the public key part is readable */ 274 *keyp = NULL;
1090 pub = key_parse_public_rsa1(buffer, commentp); 275 if (commentp != NULL)
1091 if (pub == NULL) { 276 *commentp = NULL;
1092 prv = key_parse_private_type(buffer, KEY_UNSPEC,
1093 passphrase, NULL);
1094 /* use the filename as a comment for PEM */
1095 if (commentp && prv)
1096 *commentp = xstrdup(filename);
1097 } else {
1098 key_free(pub);
1099 /* key_parse_public_rsa1() has already loaded the comment */
1100 prv = key_parse_private_type(buffer, KEY_RSA1, passphrase,
1101 NULL);
1102 }
1103 return prv;
1104#else
1105 return key_parse_private_type(buffer, KEY_UNSPEC,
1106 passphrase, commentp);
1107#endif
1108}
1109
1110Key *
1111key_load_private(const char *filename, const char *passphrase,
1112 char **commentp)
1113{
1114 Key *prv;
1115 Buffer buffer;
1116 int fd;
1117 277
1118 fd = open(filename, O_RDONLY); 278 if ((fd = open(filename, O_RDONLY)) < 0)
1119 if (fd < 0) { 279 return SSH_ERR_SYSTEM_ERROR;
1120 debug("could not open key file '%s': %s", filename, 280 if (sshkey_perm_ok(fd, filename) != 0) {
1121 strerror(errno)); 281 r = SSH_ERR_KEY_BAD_PERMISSIONS;
1122 return NULL; 282 goto out;
1123 }
1124 if (!key_perm_ok(fd, filename)) {
1125 error("bad permissions: ignore key: %s", filename);
1126 close(fd);
1127 return NULL;
1128 } 283 }
1129 284
1130 buffer_init(&buffer); 285 if ((buffer = sshbuf_new()) == NULL) {
1131 if (!key_load_file(fd, filename, &buffer)) { 286 r = SSH_ERR_ALLOC_FAIL;
1132 buffer_free(&buffer); 287 goto out;
1133 close(fd);
1134 return NULL;
1135 } 288 }
289 if ((r = sshkey_load_file(fd, filename, buffer)) != 0 ||
290 (r = sshkey_parse_private_fileblob(buffer, passphrase, filename,
291 keyp, commentp)) != 0)
292 goto out;
293 r = 0;
294 out:
1136 close(fd); 295 close(fd);
1137 296 if (buffer != NULL)
1138 prv = key_parse_private(&buffer, filename, passphrase, commentp); 297 sshbuf_free(buffer);
1139 buffer_free(&buffer); 298 return r;
1140 return prv;
1141} 299}
1142 300
1143static int 301static int
1144key_try_load_public(Key *k, const char *filename, char **commentp) 302sshkey_try_load_public(struct sshkey *k, const char *filename, char **commentp)
1145{ 303{
1146 FILE *f; 304 FILE *f;
1147 char line[SSH_MAX_PUBKEY_BYTES]; 305 char line[SSH_MAX_PUBKEY_BYTES];
1148 char *cp; 306 char *cp;
1149 u_long linenum = 0; 307 u_long linenum = 0;
308 int r;
1150 309
1151 f = fopen(filename, "r"); 310 if (commentp != NULL)
1152 if (f != NULL) { 311 *commentp = NULL;
1153 while (read_keyfile_line(f, filename, line, sizeof(line), 312 if ((f = fopen(filename, "r")) == NULL)
1154 &linenum) != -1) { 313 return SSH_ERR_SYSTEM_ERROR;
1155 cp = line; 314 while (read_keyfile_line(f, filename, line, sizeof(line),
1156 switch (*cp) { 315 &linenum) != -1) {
1157 case '#': 316 cp = line;
1158 case '\n': 317 switch (*cp) {
1159 case '\0': 318 case '#':
1160 continue; 319 case '\n':
1161 } 320 case '\0':
1162 /* Abort loading if this looks like a private key */ 321 continue;
1163 if (strncmp(cp, "-----BEGIN", 10) == 0) 322 }
1164 break; 323 /* Abort loading if this looks like a private key */
1165 /* Skip leading whitespace. */ 324 if (strncmp(cp, "-----BEGIN", 10) == 0 ||
1166 for (; *cp && (*cp == ' ' || *cp == '\t'); cp++) 325 strcmp(cp, "SSH PRIVATE KEY FILE") == 0)
1167 ; 326 break;
1168 if (*cp) { 327 /* Skip leading whitespace. */
1169 if (key_read(k, &cp) == 1) { 328 for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
1170 cp[strcspn(cp, "\r\n")] = '\0'; 329 ;
1171 if (commentp) { 330 if (*cp) {
1172 *commentp = xstrdup(*cp ? 331 if ((r = sshkey_read(k, &cp)) == 0) {
1173 cp : filename); 332 cp[strcspn(cp, "\r\n")] = '\0';
1174 } 333 if (commentp) {
1175 fclose(f); 334 *commentp = strdup(*cp ?
1176 return 1; 335 cp : filename);
336 if (*commentp == NULL)
337 r = SSH_ERR_ALLOC_FAIL;
1177 } 338 }
339 fclose(f);
340 return r;
1178 } 341 }
1179 } 342 }
1180 fclose(f);
1181 } 343 }
1182 return 0; 344 fclose(f);
345 return SSH_ERR_INVALID_FORMAT;
1183} 346}
1184 347
1185/* load public key from ssh v1 private or any pubkey file */ 348/* load public key from ssh v1 private or any pubkey file */
1186Key * 349int
1187key_load_public(const char *filename, char **commentp) 350sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
1188{ 351{
1189 Key *pub; 352 struct sshkey *pub = NULL;
1190 char file[MAXPATHLEN]; 353 char file[MAXPATHLEN];
354 int r, fd;
355
356 if (keyp != NULL)
357 *keyp = NULL;
358 if (commentp != NULL)
359 *commentp = NULL;
1191 360
361 if ((fd = open(filename, O_RDONLY)) < 0)
362 goto skip;
1192#ifdef WITH_SSH1 363#ifdef WITH_SSH1
1193 /* try rsa1 private key */ 364 /* try rsa1 private key */
1194 pub = key_load_public_type(KEY_RSA1, filename, commentp); 365 r = sshkey_load_public_rsa1(fd, filename, keyp, commentp);
1195 if (pub != NULL) 366 close(fd);
1196 return pub; 367 switch (r) {
368 case SSH_ERR_INTERNAL_ERROR:
369 case SSH_ERR_ALLOC_FAIL:
370 case SSH_ERR_INVALID_ARGUMENT:
371 case SSH_ERR_SYSTEM_ERROR:
372 case 0:
373 return r;
374 }
375#endif /* WITH_SSH1 */
376
377 /* try ssh2 public key */
378 if ((pub = sshkey_new(KEY_UNSPEC)) == NULL)
379 return SSH_ERR_ALLOC_FAIL;
380 if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) {
381 if (keyp != NULL)
382 *keyp = pub;
383 return 0;
384 }
385 sshkey_free(pub);
1197 386
387#ifdef WITH_SSH1
1198 /* try rsa1 public key */ 388 /* try rsa1 public key */
1199 pub = key_new(KEY_RSA1); 389 if ((pub = sshkey_new(KEY_RSA1)) == NULL)
1200 if (key_try_load_public(pub, filename, commentp) == 1) 390 return SSH_ERR_ALLOC_FAIL;
1201 return pub; 391 if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) {
1202 key_free(pub); 392 if (keyp != NULL)
1203#endif 393 *keyp = pub;
394 return 0;
395 }
396 sshkey_free(pub);
397#endif /* WITH_SSH1 */
1204 398
1205 /* try ssh2 public key */ 399 skip:
1206 pub = key_new(KEY_UNSPEC); 400 /* try .pub suffix */
1207 if (key_try_load_public(pub, filename, commentp) == 1) 401 if ((pub = sshkey_new(KEY_UNSPEC)) == NULL)
1208 return pub; 402 return SSH_ERR_ALLOC_FAIL;
403 r = SSH_ERR_ALLOC_FAIL; /* in case strlcpy or strlcat fail */
1209 if ((strlcpy(file, filename, sizeof file) < sizeof(file)) && 404 if ((strlcpy(file, filename, sizeof file) < sizeof(file)) &&
1210 (strlcat(file, ".pub", sizeof file) < sizeof(file)) && 405 (strlcat(file, ".pub", sizeof file) < sizeof(file)) &&
1211 (key_try_load_public(pub, file, commentp) == 1)) 406 (r = sshkey_try_load_public(pub, file, commentp)) == 0) {
1212 return pub; 407 if (keyp != NULL)
1213 key_free(pub); 408 *keyp = pub;
1214 return NULL; 409 return 0;
410 }
411 sshkey_free(pub);
412 return r;
1215} 413}
1216 414
1217/* Load the certificate associated with the named private key */ 415/* Load the certificate associated with the named private key */
1218Key * 416int
1219key_load_cert(const char *filename) 417sshkey_load_cert(const char *filename, struct sshkey **keyp)
1220{ 418{
1221 Key *pub; 419 struct sshkey *pub = NULL;
1222 char *file; 420 char *file = NULL;
421 int r = SSH_ERR_INTERNAL_ERROR;
1223 422
1224 pub = key_new(KEY_UNSPEC); 423 *keyp = NULL;
1225 xasprintf(&file, "%s-cert.pub", filename); 424
1226 if (key_try_load_public(pub, file, NULL) == 1) { 425 if (asprintf(&file, "%s-cert.pub", filename) == -1)
1227 free(file); 426 return SSH_ERR_ALLOC_FAIL;
1228 return pub; 427
428 if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) {
429 goto out;
1229 } 430 }
1230 free(file); 431 if ((r = sshkey_try_load_public(pub, file, NULL)) != 0)
1231 key_free(pub); 432 goto out;
1232 return NULL; 433
434 *keyp = pub;
435 pub = NULL;
436 r = 0;
437
438 out:
439 if (file != NULL)
440 free(file);
441 if (pub != NULL)
442 sshkey_free(pub);
443 return r;
1233} 444}
1234 445
1235/* Load private key and certificate */ 446/* Load private key and certificate */
1236Key * 447int
1237key_load_private_cert(int type, const char *filename, const char *passphrase, 448sshkey_load_private_cert(int type, const char *filename, const char *passphrase,
1238 int *perm_ok) 449 struct sshkey **keyp, int *perm_ok)
1239{ 450{
1240 Key *key, *pub; 451 struct sshkey *key = NULL, *cert = NULL;
452 int r;
453
454 *keyp = NULL;
1241 455
1242 switch (type) { 456 switch (type) {
1243#ifdef WITH_OPENSSL 457#ifdef WITH_OPENSSL
1244 case KEY_RSA: 458 case KEY_RSA:
1245 case KEY_DSA: 459 case KEY_DSA:
1246 case KEY_ECDSA: 460 case KEY_ECDSA:
1247#endif
1248 case KEY_ED25519: 461 case KEY_ED25519:
462#endif /* WITH_OPENSSL */
463 case KEY_UNSPEC:
1249 break; 464 break;
1250 default: 465 default:
1251 error("%s: unsupported key type", __func__); 466 return SSH_ERR_KEY_TYPE_UNKNOWN;
1252 return NULL;
1253 } 467 }
1254 468
1255 if ((key = key_load_private_type(type, filename, 469 if ((r = sshkey_load_private_type(type, filename,
1256 passphrase, NULL, perm_ok)) == NULL) 470 passphrase, &key, NULL, perm_ok)) != 0 ||
1257 return NULL; 471 (r = sshkey_load_cert(filename, &cert)) != 0)
1258 472 goto out;
1259 if ((pub = key_load_cert(filename)) == NULL) {
1260 key_free(key);
1261 return NULL;
1262 }
1263 473
1264 /* Make sure the private key matches the certificate */ 474 /* Make sure the private key matches the certificate */
1265 if (key_equal_public(key, pub) == 0) { 475 if (sshkey_equal_public(key, cert) == 0) {
1266 error("%s: certificate does not match private key %s", 476 r = SSH_ERR_KEY_CERT_MISMATCH;
1267 __func__, filename); 477 goto out;
1268 } else if (key_to_certified(key, key_cert_is_legacy(pub)) != 0) {
1269 error("%s: key_to_certified failed", __func__);
1270 } else {
1271 key_cert_copy(pub, key);
1272 key_free(pub);
1273 return key;
1274 } 478 }
1275 479
1276 key_free(key); 480 if ((r = sshkey_to_certified(key, sshkey_cert_is_legacy(cert))) != 0 ||
1277 key_free(pub); 481 (r = sshkey_cert_copy(cert, key)) != 0)
1278 return NULL; 482 goto out;
483 r = 0;
484 *keyp = key;
485 key = NULL;
486 out:
487 if (key != NULL)
488 sshkey_free(key);
489 if (cert != NULL)
490 sshkey_free(cert);
491 return r;
1279} 492}
1280 493
1281/* 494/*
1282 * Returns 1 if the specified "key" is listed in the file "filename", 495 * Returns success if the specified "key" is listed in the file "filename",
1283 * 0 if the key is not listed or -1 on error. 496 * SSH_ERR_KEY_NOT_FOUND: if the key is not listed or another error.
1284 * If strict_type is set then the key type must match exactly, 497 * If strict_type is set then the key type must match exactly,
1285 * otherwise a comparison that ignores certficiate data is performed. 498 * otherwise a comparison that ignores certficiate data is performed.
1286 */ 499 */
1287int 500int
1288key_in_file(Key *key, const char *filename, int strict_type) 501sshkey_in_file(struct sshkey *key, const char *filename, int strict_type)
1289{ 502{
1290 FILE *f; 503 FILE *f;
1291 char line[SSH_MAX_PUBKEY_BYTES]; 504 char line[SSH_MAX_PUBKEY_BYTES];
1292 char *cp; 505 char *cp;
1293 u_long linenum = 0; 506 u_long linenum = 0;
1294 int ret = 0; 507 int r = 0;
1295 Key *pub; 508 struct sshkey *pub = NULL;
1296 int (*key_compare)(const Key *, const Key *) = strict_type ? 509 int (*sshkey_compare)(const struct sshkey *, const struct sshkey *) =
1297 key_equal : key_equal_public; 510 strict_type ? sshkey_equal : sshkey_equal_public;
1298 511
1299 if ((f = fopen(filename, "r")) == NULL) { 512 if ((f = fopen(filename, "r")) == NULL) {
1300 if (errno == ENOENT) { 513 if (errno == ENOENT)
1301 debug("%s: keyfile \"%s\" missing", __func__, filename); 514 return SSH_ERR_KEY_NOT_FOUND;
1302 return 0; 515 else
1303 } else { 516 return SSH_ERR_SYSTEM_ERROR;
1304 error("%s: could not open keyfile \"%s\": %s", __func__,
1305 filename, strerror(errno));
1306 return -1;
1307 }
1308 } 517 }
1309 518
1310 while (read_keyfile_line(f, filename, line, sizeof(line), 519 while (read_keyfile_line(f, filename, line, sizeof(line),
1311 &linenum) != -1) { 520 &linenum) != -1) {
1312 cp = line; 521 cp = line;
1313 522
1314 /* Skip leading whitespace. */ 523 /* Skip leading whitespace. */
@@ -1323,18 +532,24 @@ key_in_file(Key *key, const char *filename, int strict_type)
1323 continue; 532 continue;
1324 } 533 }
1325 534
1326 pub = key_new(KEY_UNSPEC); 535 if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) {
1327 if (key_read(pub, &cp) != 1) { 536 r = SSH_ERR_ALLOC_FAIL;
1328 key_free(pub); 537 goto out;
1329 continue;
1330 } 538 }
1331 if (key_compare(key, pub)) { 539 if ((r = sshkey_read(pub, &cp)) != 0)
1332 ret = 1; 540 goto out;
1333 key_free(pub); 541 if (sshkey_compare(key, pub)) {
1334 break; 542 r = 0;
543 goto out;
1335 } 544 }
1336 key_free(pub); 545 sshkey_free(pub);
546 pub = NULL;
1337 } 547 }
548 r = SSH_ERR_KEY_NOT_FOUND;
549 out:
550 if (pub != NULL)
551 sshkey_free(pub);
1338 fclose(f); 552 fclose(f);
1339 return ret; 553 return r;
1340} 554}
555
diff --git a/authfile.h b/authfile.h
index 8ba1c2dbe..223101202 100644
--- a/authfile.h
+++ b/authfile.h
@@ -1,32 +1,51 @@
1/* $OpenBSD: authfile.h,v 1.17 2013/12/06 13:34:54 markus Exp $ */ 1/* $OpenBSD: authfile.h,v 1.18 2014/06/24 01:13:21 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
5 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
6 * All rights reserved
7 * 5 *
8 * As far as I am concerned, the code I have written for this software 6 * Redistribution and use in source and binary forms, with or without
9 * can be used freely for any purpose. Any derived versions of this 7 * modification, are permitted provided that the following conditions
10 * software must be clearly marked as such, and if the derived work is 8 * are met:
11 * incompatible with the protocol description in the RFC file, it must be 9 * 1. Redistributions of source code must retain the above copyright
12 * called by a name other than "ssh" or "Secure Shell". 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13 */ 25 */
14 26
15#ifndef AUTHFILE_H 27#ifndef AUTHFILE_H
16#define AUTHFILE_H 28#define AUTHFILE_H
17 29
18int key_save_private(Key *, const char *, const char *, const char *, 30#ifdef WITH_LEAKMALLOC
19 int, const char *, int); 31#include "leakmalloc.h"
20int key_load_file(int, const char *, Buffer *); 32#endif
21Key *key_load_cert(const char *); 33
22Key *key_load_public(const char *, char **); 34struct sshbuf;
23Key *key_load_public_type(int, const char *, char **); 35struct sshkey;
24Key *key_parse_private(Buffer *, const char *, const char *, char **); 36
25Key *key_load_private(const char *, const char *, char **); 37int sshkey_save_private(struct sshkey *, const char *,
26Key *key_load_private_cert(int, const char *, const char *, int *); 38 const char *, const char *, int, const char *, int);
27Key *key_load_private_type(int, const char *, const char *, char **, int *); 39int sshkey_load_file(int, const char *, struct sshbuf *);
28Key *key_load_private_pem(int, int, const char *, char **); 40int sshkey_load_cert(const char *, struct sshkey **);
29int key_perm_ok(int, const char *); 41int sshkey_load_public(const char *, struct sshkey **, char **);
30int key_in_file(Key *, const char *, int); 42int sshkey_load_private(const char *, const char *, struct sshkey **, char **);
43int sshkey_load_private_cert(int, const char *, const char *,
44 struct sshkey **, int *);
45int sshkey_load_private_type(int, const char *, const char *,
46 struct sshkey **, char **, int *);
47int sshkey_load_private_pem(int, int, const char *, struct sshkey **, char **);
48int sshkey_perm_ok(int, const char *);
49int sshkey_in_file(struct sshkey *, const char *, int);
31 50
32#endif 51#endif
diff --git a/cipher-3des1.c b/cipher-3des1.c
index b2823592b..5361f517d 100644
--- a/cipher-3des1.c
+++ b/cipher-3des1.c
@@ -29,13 +29,11 @@
29 29
30#include <openssl/evp.h> 30#include <openssl/evp.h>
31 31
32#include <stdarg.h>
33#include <string.h> 32#include <string.h>
34 33
35#include "xmalloc.h" 34#include "xmalloc.h"
36#include "log.h" 35#include "log.h"
37 36#include "ssherr.h"
38#include "openbsd-compat/openssl-compat.h"
39 37
40/* 38/*
41 * This is used by SSH1: 39 * This is used by SSH1:
@@ -57,7 +55,7 @@ struct ssh1_3des_ctx
57}; 55};
58 56
59const EVP_CIPHER * evp_ssh1_3des(void); 57const EVP_CIPHER * evp_ssh1_3des(void);
60void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); 58int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
61 59
62static int 60static int
63ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, 61ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
@@ -67,11 +65,12 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
67 u_char *k1, *k2, *k3; 65 u_char *k1, *k2, *k3;
68 66
69 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { 67 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
70 c = xcalloc(1, sizeof(*c)); 68 if ((c = calloc(1, sizeof(*c))) == NULL)
69 return 0;
71 EVP_CIPHER_CTX_set_app_data(ctx, c); 70 EVP_CIPHER_CTX_set_app_data(ctx, c);
72 } 71 }
73 if (key == NULL) 72 if (key == NULL)
74 return (1); 73 return 1;
75 if (enc == -1) 74 if (enc == -1)
76 enc = ctx->encrypt; 75 enc = ctx->encrypt;
77 k1 = k2 = k3 = (u_char *) key; 76 k1 = k2 = k3 = (u_char *) key;
@@ -85,44 +84,29 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
85 EVP_CIPHER_CTX_init(&c->k1); 84 EVP_CIPHER_CTX_init(&c->k1);
86 EVP_CIPHER_CTX_init(&c->k2); 85 EVP_CIPHER_CTX_init(&c->k2);
87 EVP_CIPHER_CTX_init(&c->k3); 86 EVP_CIPHER_CTX_init(&c->k3);
88#ifdef SSH_OLD_EVP
89 EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc);
90 EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc);
91 EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc);
92#else
93 if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 || 87 if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
94 EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 || 88 EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
95 EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) { 89 EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
96 explicit_bzero(c, sizeof(*c)); 90 explicit_bzero(c, sizeof(*c));
97 free(c); 91 free(c);
98 EVP_CIPHER_CTX_set_app_data(ctx, NULL); 92 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
99 return (0); 93 return 0;
100 } 94 }
101#endif 95 return 1;
102 return (1);
103} 96}
104 97
105static int 98static int
106ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, 99ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, size_t len)
107 LIBCRYPTO_EVP_INL_TYPE len)
108{ 100{
109 struct ssh1_3des_ctx *c; 101 struct ssh1_3des_ctx *c;
110 102
111 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { 103 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
112 error("ssh1_3des_cbc: no context"); 104 return 0;
113 return (0);
114 }
115#ifdef SSH_OLD_EVP
116 EVP_Cipher(&c->k1, dest, (u_char *)src, len);
117 EVP_Cipher(&c->k2, dest, dest, len);
118 EVP_Cipher(&c->k3, dest, dest, len);
119#else
120 if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 || 105 if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 ||
121 EVP_Cipher(&c->k2, dest, dest, len) == 0 || 106 EVP_Cipher(&c->k2, dest, dest, len) == 0 ||
122 EVP_Cipher(&c->k3, dest, dest, len) == 0) 107 EVP_Cipher(&c->k3, dest, dest, len) == 0)
123 return (0); 108 return 0;
124#endif 109 return 1;
125 return (1);
126} 110}
127 111
128static int 112static int
@@ -138,29 +122,28 @@ ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx)
138 free(c); 122 free(c);
139 EVP_CIPHER_CTX_set_app_data(ctx, NULL); 123 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
140 } 124 }
141 return (1); 125 return 1;
142} 126}
143 127
144void 128int
145ssh1_3des_iv(EVP_CIPHER_CTX *evp, int doset, u_char *iv, int len) 129ssh1_3des_iv(EVP_CIPHER_CTX *evp, int doset, u_char *iv, int len)
146{ 130{
147 struct ssh1_3des_ctx *c; 131 struct ssh1_3des_ctx *c;
148 132
149 if (len != 24) 133 if (len != 24)
150 fatal("%s: bad 3des iv length: %d", __func__, len); 134 return SSH_ERR_INVALID_ARGUMENT;
151 if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL) 135 if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL)
152 fatal("%s: no 3des context", __func__); 136 return SSH_ERR_INTERNAL_ERROR;
153 if (doset) { 137 if (doset) {
154 debug3("%s: Installed 3DES IV", __func__);
155 memcpy(c->k1.iv, iv, 8); 138 memcpy(c->k1.iv, iv, 8);
156 memcpy(c->k2.iv, iv + 8, 8); 139 memcpy(c->k2.iv, iv + 8, 8);
157 memcpy(c->k3.iv, iv + 16, 8); 140 memcpy(c->k3.iv, iv + 16, 8);
158 } else { 141 } else {
159 debug3("%s: Copying 3DES IV", __func__);
160 memcpy(iv, c->k1.iv, 8); 142 memcpy(iv, c->k1.iv, 8);
161 memcpy(iv + 8, c->k2.iv, 8); 143 memcpy(iv + 8, c->k2.iv, 8);
162 memcpy(iv + 16, c->k3.iv, 8); 144 memcpy(iv + 16, c->k3.iv, 8);
163 } 145 }
146 return 0;
164} 147}
165 148
166const EVP_CIPHER * 149const EVP_CIPHER *
@@ -176,8 +159,6 @@ evp_ssh1_3des(void)
176 ssh1_3des.init = ssh1_3des_init; 159 ssh1_3des.init = ssh1_3des_init;
177 ssh1_3des.cleanup = ssh1_3des_cleanup; 160 ssh1_3des.cleanup = ssh1_3des_cleanup;
178 ssh1_3des.do_cipher = ssh1_3des_cbc; 161 ssh1_3des.do_cipher = ssh1_3des_cbc;
179#ifndef SSH_OLD_EVP
180 ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH; 162 ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH;
181#endif 163 return &ssh1_3des;
182 return (&ssh1_3des);
183} 164}
diff --git a/cipher-chachapoly.c b/cipher-chachapoly.c
index 251b94ec8..0caccd297 100644
--- a/cipher-chachapoly.c
+++ b/cipher-chachapoly.c
@@ -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: cipher-chachapoly.c,v 1.4 2014/01/31 16:39:19 tedu Exp $ */ 17/* $OpenBSD: cipher-chachapoly.c,v 1.5 2014/06/24 01:13:21 djm Exp $ */
18 18
19#include "includes.h" 19#include "includes.h"
20 20
@@ -24,16 +24,18 @@
24#include <stdio.h> /* needed for misc.h */ 24#include <stdio.h> /* needed for misc.h */
25 25
26#include "log.h" 26#include "log.h"
27#include "misc.h" 27#include "sshbuf.h"
28#include "ssherr.h"
28#include "cipher-chachapoly.h" 29#include "cipher-chachapoly.h"
29 30
30void chachapoly_init(struct chachapoly_ctx *ctx, 31int chachapoly_init(struct chachapoly_ctx *ctx,
31 const u_char *key, u_int keylen) 32 const u_char *key, u_int keylen)
32{ 33{
33 if (keylen != (32 + 32)) /* 2 x 256 bit keys */ 34 if (keylen != (32 + 32)) /* 2 x 256 bit keys */
34 fatal("%s: invalid keylen %u", __func__, keylen); 35 return SSH_ERR_INVALID_ARGUMENT;
35 chacha_keysetup(&ctx->main_ctx, key, 256); 36 chacha_keysetup(&ctx->main_ctx, key, 256);
36 chacha_keysetup(&ctx->header_ctx, key + 32, 256); 37 chacha_keysetup(&ctx->header_ctx, key + 32, 256);
38 return 0;
37} 39}
38 40
39/* 41/*
@@ -52,14 +54,14 @@ chachapoly_crypt(struct chachapoly_ctx *ctx, u_int seqnr, u_char *dest,
52 u_char seqbuf[8]; 54 u_char seqbuf[8];
53 const u_char one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */ 55 const u_char one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */
54 u_char expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN]; 56 u_char expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN];
55 int r = -1; 57 int r = SSH_ERR_INTERNAL_ERROR;
56 58
57 /* 59 /*
58 * Run ChaCha20 once to generate the Poly1305 key. The IV is the 60 * Run ChaCha20 once to generate the Poly1305 key. The IV is the
59 * packet sequence number. 61 * packet sequence number.
60 */ 62 */
61 memset(poly_key, 0, sizeof(poly_key)); 63 memset(poly_key, 0, sizeof(poly_key));
62 put_u64(seqbuf, seqnr); 64 POKE_U64(seqbuf, seqnr);
63 chacha_ivsetup(&ctx->main_ctx, seqbuf, NULL); 65 chacha_ivsetup(&ctx->main_ctx, seqbuf, NULL);
64 chacha_encrypt_bytes(&ctx->main_ctx, 66 chacha_encrypt_bytes(&ctx->main_ctx,
65 poly_key, poly_key, sizeof(poly_key)); 67 poly_key, poly_key, sizeof(poly_key));
@@ -71,8 +73,10 @@ chachapoly_crypt(struct chachapoly_ctx *ctx, u_int seqnr, u_char *dest,
71 const u_char *tag = src + aadlen + len; 73 const u_char *tag = src + aadlen + len;
72 74
73 poly1305_auth(expected_tag, src, aadlen + len, poly_key); 75 poly1305_auth(expected_tag, src, aadlen + len, poly_key);
74 if (timingsafe_bcmp(expected_tag, tag, POLY1305_TAGLEN) != 0) 76 if (timingsafe_bcmp(expected_tag, tag, POLY1305_TAGLEN) != 0) {
77 r = SSH_ERR_MAC_INVALID;
75 goto out; 78 goto out;
79 }
76 } 80 }
77 /* Crypt additional data */ 81 /* Crypt additional data */
78 if (aadlen) { 82 if (aadlen) {
@@ -88,7 +92,6 @@ chachapoly_crypt(struct chachapoly_ctx *ctx, u_int seqnr, u_char *dest,
88 poly_key); 92 poly_key);
89 } 93 }
90 r = 0; 94 r = 0;
91
92 out: 95 out:
93 explicit_bzero(expected_tag, sizeof(expected_tag)); 96 explicit_bzero(expected_tag, sizeof(expected_tag));
94 explicit_bzero(seqbuf, sizeof(seqbuf)); 97 explicit_bzero(seqbuf, sizeof(seqbuf));
@@ -104,11 +107,11 @@ chachapoly_get_length(struct chachapoly_ctx *ctx,
104 u_char buf[4], seqbuf[8]; 107 u_char buf[4], seqbuf[8];
105 108
106 if (len < 4) 109 if (len < 4)
107 return -1; /* Insufficient length */ 110 return SSH_ERR_MESSAGE_INCOMPLETE;
108 put_u64(seqbuf, seqnr); 111 POKE_U64(seqbuf, seqnr);
109 chacha_ivsetup(&ctx->header_ctx, seqbuf, NULL); 112 chacha_ivsetup(&ctx->header_ctx, seqbuf, NULL);
110 chacha_encrypt_bytes(&ctx->header_ctx, cp, buf, 4); 113 chacha_encrypt_bytes(&ctx->header_ctx, cp, buf, 4);
111 *plenp = get_u32(buf); 114 *plenp = PEEK_U32(buf);
112 return 0; 115 return 0;
113} 116}
114 117
diff --git a/cipher-chachapoly.h b/cipher-chachapoly.h
index 7948dcdcd..b7072be7d 100644
--- a/cipher-chachapoly.h
+++ b/cipher-chachapoly.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: cipher-chachapoly.h,v 1.3 2014/05/02 03:27:54 djm Exp $ */ 1/* $OpenBSD: cipher-chachapoly.h,v 1.4 2014/06/24 01:13:21 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) Damien Miller 2013 <djm@mindrot.org> 4 * Copyright (c) Damien Miller 2013 <djm@mindrot.org>
@@ -28,7 +28,7 @@ struct chachapoly_ctx {
28 struct chacha_ctx main_ctx, header_ctx; 28 struct chacha_ctx main_ctx, header_ctx;
29}; 29};
30 30
31void chachapoly_init(struct chachapoly_ctx *cpctx, 31int chachapoly_init(struct chachapoly_ctx *cpctx,
32 const u_char *key, u_int keylen) 32 const u_char *key, u_int keylen)
33 __attribute__((__bounded__(__buffer__, 2, 3))); 33 __attribute__((__bounded__(__buffer__, 2, 3)));
34int chachapoly_crypt(struct chachapoly_ctx *cpctx, u_int seqnr, 34int chachapoly_crypt(struct chachapoly_ctx *cpctx, u_int seqnr,
diff --git a/cipher.c b/cipher.c
index 5569d2455..48ef105ca 100644
--- a/cipher.c
+++ b/cipher.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: cipher.c,v 1.98 2014/04/29 18:01:49 markus Exp $ */ 1/* $OpenBSD: cipher.c,v 1.99 2014/06/24 01:13:21 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
@@ -43,23 +43,19 @@
43#include <stdarg.h> 43#include <stdarg.h>
44#include <stdio.h> 44#include <stdio.h>
45 45
46#include "xmalloc.h"
47#include "log.h"
48#include "misc.h"
49#include "cipher.h" 46#include "cipher.h"
50#include "buffer.h" 47#include "misc.h"
48#include "sshbuf.h"
49#include "ssherr.h"
51#include "digest.h" 50#include "digest.h"
52 51
53/* compatibility with old or broken OpenSSL versions */
54#include "openbsd-compat/openssl-compat.h"
55
56#ifdef WITH_SSH1 52#ifdef WITH_SSH1
57extern const EVP_CIPHER *evp_ssh1_bf(void); 53extern const EVP_CIPHER *evp_ssh1_bf(void);
58extern const EVP_CIPHER *evp_ssh1_3des(void); 54extern const EVP_CIPHER *evp_ssh1_3des(void);
59extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); 55extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
60#endif 56#endif
61 57
62struct Cipher { 58struct sshcipher {
63 char *name; 59 char *name;
64 int number; /* for ssh1 only */ 60 int number; /* for ssh1 only */
65 u_int block_size; 61 u_int block_size;
@@ -79,12 +75,12 @@ struct Cipher {
79#endif 75#endif
80}; 76};
81 77
82static const struct Cipher ciphers[] = { 78static const struct sshcipher ciphers[] = {
83#ifdef WITH_SSH1 79#ifdef WITH_SSH1
84 { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, 80 { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc },
85 { "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des }, 81 { "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des },
86 { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf }, 82 { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf },
87#endif 83#endif /* WITH_SSH1 */
88#ifdef WITH_OPENSSL 84#ifdef WITH_OPENSSL
89 { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, 85 { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null },
90 { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, 86 { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc },
@@ -103,12 +99,12 @@ static const struct Cipher ciphers[] = {
103 { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, 99 { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr },
104 { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, 100 { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr },
105 { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, 101 { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr },
106#ifdef OPENSSL_HAVE_EVPGCM 102# ifdef OPENSSL_HAVE_EVPGCM
107 { "aes128-gcm@openssh.com", 103 { "aes128-gcm@openssh.com",
108 SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, 104 SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm },
109 { "aes256-gcm@openssh.com", 105 { "aes256-gcm@openssh.com",
110 SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, 106 SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm },
111#endif 107# endif /* OPENSSL_HAVE_EVPGCM */
112#else /* WITH_OPENSSL */ 108#else /* WITH_OPENSSL */
113 { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, CFLAG_AESCTR, NULL }, 109 { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, CFLAG_AESCTR, NULL },
114 { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, CFLAG_AESCTR, NULL }, 110 { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, CFLAG_AESCTR, NULL },
@@ -117,18 +113,19 @@ static const struct Cipher ciphers[] = {
117#endif /* WITH_OPENSSL */ 113#endif /* WITH_OPENSSL */
118 { "chacha20-poly1305@openssh.com", 114 { "chacha20-poly1305@openssh.com",
119 SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL }, 115 SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL },
116
120 { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } 117 { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL }
121}; 118};
122 119
123/*--*/ 120/*--*/
124 121
125/* Returns a list of supported ciphers separated by the specified char. */ 122/* Returns a comma-separated list of supported ciphers. */
126char * 123char *
127cipher_alg_list(char sep, int auth_only) 124cipher_alg_list(char sep, int auth_only)
128{ 125{
129 char *ret = NULL; 126 char *tmp, *ret = NULL;
130 size_t nlen, rlen = 0; 127 size_t nlen, rlen = 0;
131 const Cipher *c; 128 const struct sshcipher *c;
132 129
133 for (c = ciphers; c->name != NULL; c++) { 130 for (c = ciphers; c->name != NULL; c++) {
134 if (c->number != SSH_CIPHER_SSH2) 131 if (c->number != SSH_CIPHER_SSH2)
@@ -138,7 +135,11 @@ cipher_alg_list(char sep, int auth_only)
138 if (ret != NULL) 135 if (ret != NULL)
139 ret[rlen++] = sep; 136 ret[rlen++] = sep;
140 nlen = strlen(c->name); 137 nlen = strlen(c->name);
141 ret = xrealloc(ret, 1, rlen + nlen + 2); 138 if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {
139 free(ret);
140 return NULL;
141 }
142 ret = tmp;
142 memcpy(ret + rlen, c->name, nlen + 1); 143 memcpy(ret + rlen, c->name, nlen + 1);
143 rlen += nlen; 144 rlen += nlen;
144 } 145 }
@@ -146,19 +147,19 @@ cipher_alg_list(char sep, int auth_only)
146} 147}
147 148
148u_int 149u_int
149cipher_blocksize(const Cipher *c) 150cipher_blocksize(const struct sshcipher *c)
150{ 151{
151 return (c->block_size); 152 return (c->block_size);
152} 153}
153 154
154u_int 155u_int
155cipher_keylen(const Cipher *c) 156cipher_keylen(const struct sshcipher *c)
156{ 157{
157 return (c->key_len); 158 return (c->key_len);
158} 159}
159 160
160u_int 161u_int
161cipher_seclen(const Cipher *c) 162cipher_seclen(const struct sshcipher *c)
162{ 163{
163 if (strcmp("3des-cbc", c->name) == 0) 164 if (strcmp("3des-cbc", c->name) == 0)
164 return 14; 165 return 14;
@@ -166,13 +167,13 @@ cipher_seclen(const Cipher *c)
166} 167}
167 168
168u_int 169u_int
169cipher_authlen(const Cipher *c) 170cipher_authlen(const struct sshcipher *c)
170{ 171{
171 return (c->auth_len); 172 return (c->auth_len);
172} 173}
173 174
174u_int 175u_int
175cipher_ivlen(const Cipher *c) 176cipher_ivlen(const struct sshcipher *c)
176{ 177{
177 /* 178 /*
178 * Default is cipher block size, except for chacha20+poly1305 that 179 * Default is cipher block size, except for chacha20+poly1305 that
@@ -183,13 +184,13 @@ cipher_ivlen(const Cipher *c)
183} 184}
184 185
185u_int 186u_int
186cipher_get_number(const Cipher *c) 187cipher_get_number(const struct sshcipher *c)
187{ 188{
188 return (c->number); 189 return (c->number);
189} 190}
190 191
191u_int 192u_int
192cipher_is_cbc(const Cipher *c) 193cipher_is_cbc(const struct sshcipher *c)
193{ 194{
194 return (c->flags & CFLAG_CBC) != 0; 195 return (c->flags & CFLAG_CBC) != 0;
195} 196}
@@ -206,20 +207,20 @@ cipher_mask_ssh1(int client)
206 return mask; 207 return mask;
207} 208}
208 209
209const Cipher * 210const struct sshcipher *
210cipher_by_name(const char *name) 211cipher_by_name(const char *name)
211{ 212{
212 const Cipher *c; 213 const struct sshcipher *c;
213 for (c = ciphers; c->name != NULL; c++) 214 for (c = ciphers; c->name != NULL; c++)
214 if (strcmp(c->name, name) == 0) 215 if (strcmp(c->name, name) == 0)
215 return c; 216 return c;
216 return NULL; 217 return NULL;
217} 218}
218 219
219const Cipher * 220const struct sshcipher *
220cipher_by_number(int id) 221cipher_by_number(int id)
221{ 222{
222 const Cipher *c; 223 const struct sshcipher *c;
223 for (c = ciphers; c->name != NULL; c++) 224 for (c = ciphers; c->name != NULL; c++)
224 if (c->number == id) 225 if (c->number == id)
225 return c; 226 return c;
@@ -230,23 +231,22 @@ cipher_by_number(int id)
230int 231int
231ciphers_valid(const char *names) 232ciphers_valid(const char *names)
232{ 233{
233 const Cipher *c; 234 const struct sshcipher *c;
234 char *cipher_list, *cp; 235 char *cipher_list, *cp;
235 char *p; 236 char *p;
236 237
237 if (names == NULL || strcmp(names, "") == 0) 238 if (names == NULL || strcmp(names, "") == 0)
238 return 0; 239 return 0;
239 cipher_list = cp = xstrdup(names); 240 if ((cipher_list = cp = strdup(names)) == NULL)
241 return 0;
240 for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; 242 for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
241 (p = strsep(&cp, CIPHER_SEP))) { 243 (p = strsep(&cp, CIPHER_SEP))) {
242 c = cipher_by_name(p); 244 c = cipher_by_name(p);
243 if (c == NULL || c->number != SSH_CIPHER_SSH2) { 245 if (c == NULL || c->number != SSH_CIPHER_SSH2) {
244 debug("bad cipher %s [%s]", p, names);
245 free(cipher_list); 246 free(cipher_list);
246 return 0; 247 return 0;
247 } 248 }
248 } 249 }
249 debug3("ciphers ok: [%s]", names);
250 free(cipher_list); 250 free(cipher_list);
251 return 1; 251 return 1;
252} 252}
@@ -259,7 +259,7 @@ ciphers_valid(const char *names)
259int 259int
260cipher_number(const char *name) 260cipher_number(const char *name)
261{ 261{
262 const Cipher *c; 262 const struct sshcipher *c;
263 if (name == NULL) 263 if (name == NULL)
264 return -1; 264 return -1;
265 for (c = ciphers; c->name != NULL; c++) 265 for (c = ciphers; c->name != NULL; c++)
@@ -271,31 +271,33 @@ cipher_number(const char *name)
271char * 271char *
272cipher_name(int id) 272cipher_name(int id)
273{ 273{
274 const Cipher *c = cipher_by_number(id); 274 const struct sshcipher *c = cipher_by_number(id);
275 return (c==NULL) ? "<unknown>" : c->name; 275 return (c==NULL) ? "<unknown>" : c->name;
276} 276}
277 277
278void 278const char *
279cipher_init(CipherContext *cc, const Cipher *cipher, 279cipher_warning_message(const struct sshcipher_ctx *cc)
280{
281 if (cc == NULL || cc->cipher == NULL)
282 return NULL;
283 if (cc->cipher->number == SSH_CIPHER_DES)
284 return "use of DES is strongly discouraged due to "
285 "cryptographic weaknesses";
286 return NULL;
287}
288
289int
290cipher_init(struct sshcipher_ctx *cc, const struct sshcipher *cipher,
280 const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, 291 const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
281 int do_encrypt) 292 int do_encrypt)
282{ 293{
283#ifdef WITH_OPENSSL 294#ifdef WITH_OPENSSL
284 static int dowarn = 1; 295 int ret = SSH_ERR_INTERNAL_ERROR;
285#ifdef SSH_OLD_EVP
286 EVP_CIPHER *type;
287#else
288 const EVP_CIPHER *type; 296 const EVP_CIPHER *type;
289 int klen; 297 int klen;
290#endif
291 u_char *junk, *discard; 298 u_char *junk, *discard;
292 299
293 if (cipher->number == SSH_CIPHER_DES) { 300 if (cipher->number == SSH_CIPHER_DES) {
294 if (dowarn) {
295 error("Warning: use of DES is strongly discouraged "
296 "due to cryptographic weaknesses");
297 dowarn = 0;
298 }
299 if (keylen > 8) 301 if (keylen > 8)
300 keylen = 8; 302 keylen = 8;
301 } 303 }
@@ -303,71 +305,70 @@ cipher_init(CipherContext *cc, const Cipher *cipher,
303 cc->plaintext = (cipher->number == SSH_CIPHER_NONE); 305 cc->plaintext = (cipher->number == SSH_CIPHER_NONE);
304 cc->encrypt = do_encrypt; 306 cc->encrypt = do_encrypt;
305 307
306 if (keylen < cipher->key_len) 308 if (keylen < cipher->key_len ||
307 fatal("cipher_init: key length %d is insufficient for %s.", 309 (iv != NULL && ivlen < cipher_ivlen(cipher)))
308 keylen, cipher->name); 310 return SSH_ERR_INVALID_ARGUMENT;
309 if (iv != NULL && ivlen < cipher_ivlen(cipher))
310 fatal("cipher_init: iv length %d is insufficient for %s.",
311 ivlen, cipher->name);
312 cc->cipher = cipher;
313 311
312 cc->cipher = cipher;
314 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { 313 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
315 chachapoly_init(&cc->cp_ctx, key, keylen); 314 return chachapoly_init(&cc->cp_ctx, key, keylen);
316 return;
317 } 315 }
318#ifndef WITH_OPENSSL 316#ifndef WITH_OPENSSL
319 if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { 317 if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
320 aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen); 318 aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen);
321 aesctr_ivsetup(&cc->ac_ctx, iv); 319 aesctr_ivsetup(&cc->ac_ctx, iv);
322 return; 320 return 0;
323 } 321 }
324 if ((cc->cipher->flags & CFLAG_NONE) != 0) 322 if ((cc->cipher->flags & CFLAG_NONE) != 0)
325 return; 323 return 0;
326 fatal("unsupported cipher"); 324 return SSH_ERR_INVALID_ARGUMENT;
327#else 325#else
328 type = (*cipher->evptype)(); 326 type = (*cipher->evptype)();
329 EVP_CIPHER_CTX_init(&cc->evp); 327 EVP_CIPHER_CTX_init(&cc->evp);
330#ifdef SSH_OLD_EVP
331 if (type->key_len > 0 && type->key_len != keylen) {
332 debug("cipher_init: set keylen (%d -> %d)",
333 type->key_len, keylen);
334 type->key_len = keylen;
335 }
336 EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv,
337 (do_encrypt == CIPHER_ENCRYPT));
338#else
339 if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv, 328 if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv,
340 (do_encrypt == CIPHER_ENCRYPT)) == 0) 329 (do_encrypt == CIPHER_ENCRYPT)) == 0) {
341 fatal("cipher_init: EVP_CipherInit failed for %s", 330 ret = SSH_ERR_LIBCRYPTO_ERROR;
342 cipher->name); 331 goto bad;
332 }
343 if (cipher_authlen(cipher) && 333 if (cipher_authlen(cipher) &&
344 !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, 334 !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED,
345 -1, (u_char *)iv)) 335 -1, (u_char *)iv)) {
346 fatal("cipher_init: EVP_CTRL_GCM_SET_IV_FIXED failed for %s", 336 ret = SSH_ERR_LIBCRYPTO_ERROR;
347 cipher->name); 337 goto bad;
338 }
348 klen = EVP_CIPHER_CTX_key_length(&cc->evp); 339 klen = EVP_CIPHER_CTX_key_length(&cc->evp);
349 if (klen > 0 && keylen != (u_int)klen) { 340 if (klen > 0 && keylen != (u_int)klen) {
350 debug2("cipher_init: set keylen (%d -> %d)", klen, keylen); 341 if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) {
351 if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) 342 ret = SSH_ERR_LIBCRYPTO_ERROR;
352 fatal("cipher_init: set keylen failed (%d -> %d)", 343 goto bad;
353 klen, keylen); 344 }
345 }
346 if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0) {
347 ret = SSH_ERR_LIBCRYPTO_ERROR;
348 goto bad;
354 } 349 }
355 if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0)
356 fatal("cipher_init: EVP_CipherInit: set key failed for %s",
357 cipher->name);
358#endif
359 350
360 if (cipher->discard_len > 0) { 351 if (cipher->discard_len > 0) {
361 junk = xmalloc(cipher->discard_len); 352 if ((junk = malloc(cipher->discard_len)) == NULL ||
362 discard = xmalloc(cipher->discard_len); 353 (discard = malloc(cipher->discard_len)) == NULL) {
363 if (EVP_Cipher(&cc->evp, discard, junk, 354 if (junk != NULL)
364 cipher->discard_len) == 0) 355 free(junk);
365 fatal("evp_crypt: EVP_Cipher failed during discard"); 356 ret = SSH_ERR_ALLOC_FAIL;
357 goto bad;
358 }
359 ret = EVP_Cipher(&cc->evp, discard, junk, cipher->discard_len);
366 explicit_bzero(discard, cipher->discard_len); 360 explicit_bzero(discard, cipher->discard_len);
367 free(junk); 361 free(junk);
368 free(discard); 362 free(discard);
363 if (ret != 1) {
364 ret = SSH_ERR_LIBCRYPTO_ERROR;
365 bad:
366 EVP_CIPHER_CTX_cleanup(&cc->evp);
367 return ret;
368 }
369 } 369 }
370#endif 370#endif
371 return 0;
371} 372}
372 373
373/* 374/*
@@ -379,16 +380,15 @@ cipher_init(CipherContext *cc, const Cipher *cipher,
379 * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag. 380 * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag.
380 * This tag is written on encryption and verified on decryption. 381 * This tag is written on encryption and verified on decryption.
381 * Both 'aadlen' and 'authlen' can be set to 0. 382 * Both 'aadlen' and 'authlen' can be set to 0.
382 * cipher_crypt() returns 0 on success and -1 if the decryption integrity
383 * check fails.
384 */ 383 */
385int 384int
386cipher_crypt(CipherContext *cc, u_int seqnr, u_char *dest, const u_char *src, 385cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest,
387 u_int len, u_int aadlen, u_int authlen) 386 const u_char *src, u_int len, u_int aadlen, u_int authlen)
388{ 387{
389 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 388 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
390 return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, len, 389 return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src,
391 aadlen, authlen, cc->encrypt); 390 len, aadlen, authlen, cc->encrypt);
391 }
392#ifndef WITH_OPENSSL 392#ifndef WITH_OPENSSL
393 if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { 393 if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
394 if (aadlen) 394 if (aadlen)
@@ -401,46 +401,43 @@ cipher_crypt(CipherContext *cc, u_int seqnr, u_char *dest, const u_char *src,
401 memcpy(dest, src, aadlen + len); 401 memcpy(dest, src, aadlen + len);
402 return 0; 402 return 0;
403 } 403 }
404 fatal("unsupported cipher"); 404 return SSH_ERR_INVALID_ARGUMENT;
405#else 405#else
406 if (authlen) { 406 if (authlen) {
407 u_char lastiv[1]; 407 u_char lastiv[1];
408 408
409 if (authlen != cipher_authlen(cc->cipher)) 409 if (authlen != cipher_authlen(cc->cipher))
410 fatal("%s: authlen mismatch %d", __func__, authlen); 410 return SSH_ERR_INVALID_ARGUMENT;
411 /* increment IV */ 411 /* increment IV */
412 if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN, 412 if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN,
413 1, lastiv)) 413 1, lastiv))
414 fatal("%s: EVP_CTRL_GCM_IV_GEN", __func__); 414 return SSH_ERR_LIBCRYPTO_ERROR;
415 /* set tag on decyption */ 415 /* set tag on decyption */
416 if (!cc->encrypt && 416 if (!cc->encrypt &&
417 !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG, 417 !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG,
418 authlen, (u_char *)src + aadlen + len)) 418 authlen, (u_char *)src + aadlen + len))
419 fatal("%s: EVP_CTRL_GCM_SET_TAG", __func__); 419 return SSH_ERR_LIBCRYPTO_ERROR;
420 } 420 }
421 if (aadlen) { 421 if (aadlen) {
422 if (authlen && 422 if (authlen &&
423 EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0) 423 EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0)
424 fatal("%s: EVP_Cipher(aad) failed", __func__); 424 return SSH_ERR_LIBCRYPTO_ERROR;
425 memcpy(dest, src, aadlen); 425 memcpy(dest, src, aadlen);
426 } 426 }
427 if (len % cc->cipher->block_size) 427 if (len % cc->cipher->block_size)
428 fatal("%s: bad plaintext length %d", __func__, len); 428 return SSH_ERR_INVALID_ARGUMENT;
429 if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen, 429 if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen,
430 len) < 0) 430 len) < 0)
431 fatal("%s: EVP_Cipher failed", __func__); 431 return SSH_ERR_LIBCRYPTO_ERROR;
432 if (authlen) { 432 if (authlen) {
433 /* compute tag (on encrypt) or verify tag (on decrypt) */ 433 /* compute tag (on encrypt) or verify tag (on decrypt) */
434 if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0) { 434 if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0)
435 if (cc->encrypt) 435 return cc->encrypt ?
436 fatal("%s: EVP_Cipher(final) failed", __func__); 436 SSH_ERR_LIBCRYPTO_ERROR : SSH_ERR_MAC_INVALID;
437 else
438 return -1;
439 }
440 if (cc->encrypt && 437 if (cc->encrypt &&
441 !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG, 438 !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG,
442 authlen, dest + aadlen + len)) 439 authlen, dest + aadlen + len))
443 fatal("%s: EVP_CTRL_GCM_GET_TAG", __func__); 440 return SSH_ERR_LIBCRYPTO_ERROR;
444 } 441 }
445 return 0; 442 return 0;
446#endif 443#endif
@@ -448,61 +445,65 @@ cipher_crypt(CipherContext *cc, u_int seqnr, u_char *dest, const u_char *src,
448 445
449/* Extract the packet length, including any decryption necessary beforehand */ 446/* Extract the packet length, including any decryption necessary beforehand */
450int 447int
451cipher_get_length(CipherContext *cc, u_int *plenp, u_int seqnr, 448cipher_get_length(struct sshcipher_ctx *cc, u_int *plenp, u_int seqnr,
452 const u_char *cp, u_int len) 449 const u_char *cp, u_int len)
453{ 450{
454 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 451 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
455 return chachapoly_get_length(&cc->cp_ctx, plenp, seqnr, 452 return chachapoly_get_length(&cc->cp_ctx, plenp, seqnr,
456 cp, len); 453 cp, len);
457 if (len < 4) 454 if (len < 4)
458 return -1; 455 return SSH_ERR_MESSAGE_INCOMPLETE;
459 *plenp = get_u32(cp); 456 *plenp = get_u32(cp);
460 return 0; 457 return 0;
461} 458}
462 459
463void 460int
464cipher_cleanup(CipherContext *cc) 461cipher_cleanup(struct sshcipher_ctx *cc)
465{ 462{
463 if (cc == NULL || cc->cipher == NULL)
464 return 0;
466 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 465 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
467 explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx)); 466 explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx));
468 else if ((cc->cipher->flags & CFLAG_AESCTR) != 0) 467 else if ((cc->cipher->flags & CFLAG_AESCTR) != 0)
469 explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx)); 468 explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx));
470#ifdef WITH_OPENSSL 469#ifdef WITH_OPENSSL
471 else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) 470 else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
472 error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed"); 471 return SSH_ERR_LIBCRYPTO_ERROR;
473#endif 472#endif
473 return 0;
474} 474}
475 475
476/* 476/*
477 * Selects the cipher, and keys if by computing the MD5 checksum of the 477 * Selects the cipher, and keys if by computing the MD5 checksum of the
478 * passphrase and using the resulting 16 bytes as the key. 478 * passphrase and using the resulting 16 bytes as the key.
479 */ 479 */
480 480int
481void 481cipher_set_key_string(struct sshcipher_ctx *cc, const struct sshcipher *cipher,
482cipher_set_key_string(CipherContext *cc, const Cipher *cipher,
483 const char *passphrase, int do_encrypt) 482 const char *passphrase, int do_encrypt)
484{ 483{
485 u_char digest[16]; 484 u_char digest[16];
485 int r = SSH_ERR_INTERNAL_ERROR;
486 486
487 if (ssh_digest_memory(SSH_DIGEST_MD5, passphrase, strlen(passphrase), 487 if ((r = ssh_digest_memory(SSH_DIGEST_MD5,
488 digest, sizeof(digest)) < 0) 488 passphrase, strlen(passphrase),
489 fatal("%s: md5 failed", __func__); 489 digest, sizeof(digest))) != 0)
490 490 goto out;
491 cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt);
492 491
492 r = cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt);
493 out:
493 explicit_bzero(digest, sizeof(digest)); 494 explicit_bzero(digest, sizeof(digest));
495 return r;
494} 496}
495 497
496/* 498/*
497 * Exports an IV from the CipherContext required to export the key 499 * Exports an IV from the sshcipher_ctx required to export the key
498 * state back from the unprivileged child to the privileged parent 500 * state back from the unprivileged child to the privileged parent
499 * process. 501 * process.
500 */ 502 */
501
502int 503int
503cipher_get_keyiv_len(const CipherContext *cc) 504cipher_get_keyiv_len(const struct sshcipher_ctx *cc)
504{ 505{
505 const Cipher *c = cc->cipher; 506 const struct sshcipher *c = cc->cipher;
506 int ivlen = 0; 507 int ivlen = 0;
507 508
508 if (c->number == SSH_CIPHER_3DES) 509 if (c->number == SSH_CIPHER_3DES)
@@ -512,25 +513,25 @@ cipher_get_keyiv_len(const CipherContext *cc)
512#ifdef WITH_OPENSSL 513#ifdef WITH_OPENSSL
513 else 514 else
514 ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp); 515 ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp);
515#endif 516#endif /* WITH_OPENSSL */
516 return (ivlen); 517 return (ivlen);
517} 518}
518 519
519void 520int
520cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) 521cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len)
521{ 522{
522 const Cipher *c = cc->cipher; 523 const struct sshcipher *c = cc->cipher;
523#ifdef WITH_OPENSSL 524#ifdef WITH_OPENSSL
524 int evplen; 525 int evplen;
525#endif 526#endif
526 527
527 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { 528 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
528 if (len != 0) 529 if (len != 0)
529 fatal("%s: wrong iv length %d != %d", __func__, len, 0); 530 return SSH_ERR_INVALID_ARGUMENT;
530 return; 531 return 0;
531 } 532 }
532 if ((cc->cipher->flags & CFLAG_NONE) != 0) 533 if ((cc->cipher->flags & CFLAG_NONE) != 0)
533 return; 534 return 0;
534 535
535 switch (c->number) { 536 switch (c->number) {
536#ifdef WITH_OPENSSL 537#ifdef WITH_OPENSSL
@@ -538,51 +539,42 @@ cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len)
538 case SSH_CIPHER_DES: 539 case SSH_CIPHER_DES:
539 case SSH_CIPHER_BLOWFISH: 540 case SSH_CIPHER_BLOWFISH:
540 evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); 541 evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
541 if (evplen <= 0) 542 if (evplen == 0)
542 return; 543 return 0;
544 else if (evplen < 0)
545 return SSH_ERR_LIBCRYPTO_ERROR;
543 if ((u_int)evplen != len) 546 if ((u_int)evplen != len)
544 fatal("%s: wrong iv length %d != %d", __func__, 547 return SSH_ERR_INVALID_ARGUMENT;
545 evplen, len);
546#ifdef USE_BUILTIN_RIJNDAEL
547 if (c->evptype == evp_rijndael)
548 ssh_rijndael_iv(&cc->evp, 0, iv, len);
549 else
550#endif /* USE_BUILTIN_RIJNDAEL */
551#ifndef OPENSSL_HAVE_EVPCTR
552 if (c->evptype == evp_aes_128_ctr)
553 ssh_aes_ctr_iv(&cc->evp, 0, iv, len);
554 else
555#endif /* OPENSSL_HAVE_EVPCTR */
556 if (cipher_authlen(c)) { 548 if (cipher_authlen(c)) {
557 if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN, 549 if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN,
558 len, iv)) 550 len, iv))
559 fatal("%s: EVP_CTRL_GCM_IV_GEN", __func__); 551 return SSH_ERR_LIBCRYPTO_ERROR;
560 } else 552 } else
561 memcpy(iv, cc->evp.iv, len); 553 memcpy(iv, cc->evp.iv, len);
562 break; 554 break;
563#endif /* WITH_OPENSSL */ 555#endif
564#ifdef WITH_SSH1 556#ifdef WITH_SSH1
565 case SSH_CIPHER_3DES: 557 case SSH_CIPHER_3DES:
566 ssh1_3des_iv(&cc->evp, 0, iv, 24); 558 return ssh1_3des_iv(&cc->evp, 0, iv, 24);
567 break; 559#endif
568#endif /* WITH_SSH1 */
569 default: 560 default:
570 fatal("%s: bad cipher %d", __func__, c->number); 561 return SSH_ERR_INVALID_ARGUMENT;
571 } 562 }
563 return 0;
572} 564}
573 565
574void 566int
575cipher_set_keyiv(CipherContext *cc, u_char *iv) 567cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv)
576{ 568{
577 const Cipher *c = cc->cipher; 569 const struct sshcipher *c = cc->cipher;
578#ifdef WITH_OPENSSL 570#ifdef WITH_OPENSSL
579 int evplen = 0; 571 int evplen = 0;
580#endif 572#endif
581 573
582 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 574 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
583 return; 575 return 0;
584 if ((cc->cipher->flags & CFLAG_NONE) != 0) 576 if ((cc->cipher->flags & CFLAG_NONE) != 0)
585 return; 577 return 0;
586 578
587 switch (c->number) { 579 switch (c->number) {
588#ifdef WITH_OPENSSL 580#ifdef WITH_OPENSSL
@@ -590,42 +582,37 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv)
590 case SSH_CIPHER_DES: 582 case SSH_CIPHER_DES:
591 case SSH_CIPHER_BLOWFISH: 583 case SSH_CIPHER_BLOWFISH:
592 evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); 584 evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
593 if (evplen == 0) 585 if (evplen <= 0)
594 return; 586 return SSH_ERR_LIBCRYPTO_ERROR;
595#ifdef USE_BUILTIN_RIJNDAEL
596 if (c->evptype == evp_rijndael)
597 ssh_rijndael_iv(&cc->evp, 1, iv, evplen);
598 else
599#endif /* USE_BUILTIN_RIJNDAEL */
600#ifndef OPENSSL_HAVE_EVPCTR
601 if (c->evptype == evp_aes_128_ctr)
602 ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen);
603 else
604#endif /* OPENSSL_HAVE_EVPCTR */
605 if (cipher_authlen(c)) { 587 if (cipher_authlen(c)) {
588 /* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */
606 if (!EVP_CIPHER_CTX_ctrl(&cc->evp, 589 if (!EVP_CIPHER_CTX_ctrl(&cc->evp,
607 EVP_CTRL_GCM_SET_IV_FIXED, -1, iv)) 590 EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv))
608 fatal("%s: EVP_CTRL_GCM_SET_IV_FIXED failed", 591 return SSH_ERR_LIBCRYPTO_ERROR;
609 __func__); 592 } else
610 } else 593 memcpy(cc->evp.iv, iv, evplen);
611 memcpy(cc->evp.iv, iv, evplen);
612 break; 594 break;
613#endif /* WITH_OPENSSL */ 595#endif
614#ifdef WITH_SSH1 596#ifdef WITH_SSH1
615 case SSH_CIPHER_3DES: 597 case SSH_CIPHER_3DES:
616 ssh1_3des_iv(&cc->evp, 1, iv, 24); 598 return ssh1_3des_iv(&cc->evp, 1, (u_char *)iv, 24);
617 break; 599#endif
618#endif /* WITH_SSH1 */
619 default: 600 default:
620 fatal("%s: bad cipher %d", __func__, c->number); 601 return SSH_ERR_INVALID_ARGUMENT;
621 } 602 }
603 return 0;
622} 604}
623 605
606#ifdef WITH_OPENSSL
607#define EVP_X_STATE(evp) (evp).cipher_data
608#define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size
609#endif
610
624int 611int
625cipher_get_keycontext(const CipherContext *cc, u_char *dat) 612cipher_get_keycontext(const struct sshcipher_ctx *cc, u_char *dat)
626{ 613{
627#ifdef WITH_OPENSSL 614#ifdef WITH_OPENSSL
628 const Cipher *c = cc->cipher; 615 const struct sshcipher *c = cc->cipher;
629 int plen = 0; 616 int plen = 0;
630 617
631 if (c->evptype == EVP_rc4) { 618 if (c->evptype == EVP_rc4) {
@@ -636,15 +623,15 @@ cipher_get_keycontext(const CipherContext *cc, u_char *dat)
636 } 623 }
637 return (plen); 624 return (plen);
638#else 625#else
639 return (0); 626 return 0;
640#endif 627#endif
641} 628}
642 629
643void 630void
644cipher_set_keycontext(CipherContext *cc, u_char *dat) 631cipher_set_keycontext(struct sshcipher_ctx *cc, const u_char *dat)
645{ 632{
646#ifdef WITH_OPENSSL 633#ifdef WITH_OPENSSL
647 const Cipher *c = cc->cipher; 634 const struct sshcipher *c = cc->cipher;
648 int plen; 635 int plen;
649 636
650 if (c->evptype == EVP_rc4) { 637 if (c->evptype == EVP_rc4) {
diff --git a/cipher.h b/cipher.h
index 5aa778f14..de74c1e3b 100644
--- a/cipher.h
+++ b/cipher.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: cipher.h,v 1.45 2014/04/29 18:01:49 markus Exp $ */ 1/* $OpenBSD: cipher.h,v 1.46 2014/06/24 01:13:21 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -37,6 +37,7 @@
37#ifndef CIPHER_H 37#ifndef CIPHER_H
38#define CIPHER_H 38#define CIPHER_H
39 39
40#include <sys/types.h>
40#include <openssl/evp.h> 41#include <openssl/evp.h>
41#include "cipher-chachapoly.h" 42#include "cipher-chachapoly.h"
42#include "cipher-aesctr.h" 43#include "cipher-aesctr.h"
@@ -61,45 +62,47 @@
61#define CIPHER_ENCRYPT 1 62#define CIPHER_ENCRYPT 1
62#define CIPHER_DECRYPT 0 63#define CIPHER_DECRYPT 0
63 64
64typedef struct Cipher Cipher; 65struct sshcipher;
65typedef struct CipherContext CipherContext; 66struct sshcipher_ctx {
66
67struct Cipher;
68struct CipherContext {
69 int plaintext; 67 int plaintext;
70 int encrypt; 68 int encrypt;
71 EVP_CIPHER_CTX evp; 69 EVP_CIPHER_CTX evp;
72 struct chachapoly_ctx cp_ctx; /* XXX union with evp? */ 70 struct chachapoly_ctx cp_ctx; /* XXX union with evp? */
73 struct aesctr_ctx ac_ctx; /* XXX union with evp? */ 71 struct aesctr_ctx ac_ctx; /* XXX union with evp? */
74 const Cipher *cipher; 72 const struct sshcipher *cipher;
75}; 73};
76 74
75typedef struct sshcipher Cipher ;
76typedef struct sshcipher_ctx CipherContext ;
77
77u_int cipher_mask_ssh1(int); 78u_int cipher_mask_ssh1(int);
78const Cipher *cipher_by_name(const char *); 79const struct sshcipher *cipher_by_name(const char *);
79const Cipher *cipher_by_number(int); 80const struct sshcipher *cipher_by_number(int);
80int cipher_number(const char *); 81int cipher_number(const char *);
81char *cipher_name(int); 82char *cipher_name(int);
82int ciphers_valid(const char *); 83int ciphers_valid(const char *);
83char *cipher_alg_list(char, int); 84char *cipher_alg_list(char, int);
84void cipher_init(CipherContext *, const Cipher *, const u_char *, u_int, 85int cipher_init(struct sshcipher_ctx *, const struct sshcipher *,
85 const u_char *, u_int, int); 86 const u_char *, u_int, const u_char *, u_int, int);
86int cipher_crypt(CipherContext *, u_int, u_char *, const u_char *, 87const char* cipher_warning_message(const struct sshcipher_ctx *);
88int cipher_crypt(struct sshcipher_ctx *, u_int, u_char *, const u_char *,
87 u_int, u_int, u_int); 89 u_int, u_int, u_int);
88int cipher_get_length(CipherContext *, u_int *, u_int, 90int cipher_get_length(struct sshcipher_ctx *, u_int *, u_int,
89 const u_char *, u_int); 91 const u_char *, u_int);
90void cipher_cleanup(CipherContext *); 92int cipher_cleanup(struct sshcipher_ctx *);
91void cipher_set_key_string(CipherContext *, const Cipher *, const char *, int); 93int cipher_set_key_string(struct sshcipher_ctx *, const struct sshcipher *,
92u_int cipher_blocksize(const Cipher *); 94 const char *, int);
93u_int cipher_keylen(const Cipher *); 95u_int cipher_blocksize(const struct sshcipher *);
94u_int cipher_seclen(const Cipher *); 96u_int cipher_keylen(const struct sshcipher *);
95u_int cipher_authlen(const Cipher *); 97u_int cipher_seclen(const struct sshcipher *);
96u_int cipher_ivlen(const Cipher *); 98u_int cipher_authlen(const struct sshcipher *);
97u_int cipher_is_cbc(const Cipher *); 99u_int cipher_ivlen(const struct sshcipher *);
100u_int cipher_is_cbc(const struct sshcipher *);
98 101
99u_int cipher_get_number(const Cipher *); 102u_int cipher_get_number(const struct sshcipher *);
100void cipher_get_keyiv(CipherContext *, u_char *, u_int); 103int cipher_get_keyiv(struct sshcipher_ctx *, u_char *, u_int);
101void cipher_set_keyiv(CipherContext *, u_char *); 104int cipher_set_keyiv(struct sshcipher_ctx *, const u_char *);
102int cipher_get_keyiv_len(const CipherContext *); 105int cipher_get_keyiv_len(const struct sshcipher_ctx *);
103int cipher_get_keycontext(const CipherContext *, u_char *); 106int cipher_get_keycontext(const struct sshcipher_ctx *, u_char *);
104void cipher_set_keycontext(CipherContext *, u_char *); 107void cipher_set_keycontext(struct sshcipher_ctx *, const u_char *);
105#endif /* CIPHER_H */ 108#endif /* CIPHER_H */
diff --git a/digest-libc.c b/digest-libc.c
index 1804b0698..1b4423a05 100644
--- a/digest-libc.c
+++ b/digest-libc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: digest-libc.c,v 1.2 2014/02/02 03:44:31 djm Exp $ */ 1/* $OpenBSD: digest-libc.c,v 1.3 2014/06/24 01:13:21 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2013 Damien Miller <djm@mindrot.org> 3 * Copyright (c) 2013 Damien Miller <djm@mindrot.org>
4 * Copyright (c) 2014 Markus Friedl. All rights reserved. 4 * Copyright (c) 2014 Markus Friedl. All rights reserved.
@@ -28,7 +28,8 @@
28#include <sha1.h> 28#include <sha1.h>
29#include <sha2.h> 29#include <sha2.h>
30 30
31#include "buffer.h" 31#include "ssherr.h"
32#include "sshbuf.h"
32#include "digest.h" 33#include "digest.h"
33 34
34typedef void md_init_fn(void *mdctx); 35typedef void md_init_fn(void *mdctx);
@@ -164,7 +165,7 @@ ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to)
164 const struct ssh_digest *digest = ssh_digest_by_alg(from->alg); 165 const struct ssh_digest *digest = ssh_digest_by_alg(from->alg);
165 166
166 if (digest == NULL || from->alg != to->alg) 167 if (digest == NULL || from->alg != to->alg)
167 return -1; 168 return SSH_ERR_INVALID_ARGUMENT;
168 memcpy(to->mdctx, from->mdctx, digest->ctx_len); 169 memcpy(to->mdctx, from->mdctx, digest->ctx_len);
169 return 0; 170 return 0;
170} 171}
@@ -175,15 +176,15 @@ ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
175 const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg); 176 const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg);
176 177
177 if (digest == NULL) 178 if (digest == NULL)
178 return -1; 179 return SSH_ERR_INVALID_ARGUMENT;
179 digest->md_update(ctx->mdctx, m, mlen); 180 digest->md_update(ctx->mdctx, m, mlen);
180 return 0; 181 return 0;
181} 182}
182 183
183int 184int
184ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const Buffer *b) 185ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const struct sshbuf *b)
185{ 186{
186 return ssh_digest_update(ctx, buffer_ptr(b), buffer_len(b)); 187 return ssh_digest_update(ctx, sshbuf_ptr(b), sshbuf_len(b));
187} 188}
188 189
189int 190int
@@ -192,11 +193,11 @@ ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
192 const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg); 193 const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg);
193 194
194 if (digest == NULL) 195 if (digest == NULL)
195 return -1; 196 return SSH_ERR_INVALID_ARGUMENT;
196 if (dlen > UINT_MAX) 197 if (dlen > UINT_MAX)
197 return -1; 198 return SSH_ERR_INVALID_ARGUMENT;
198 if (dlen < digest->digest_len) /* No truncation allowed */ 199 if (dlen < digest->digest_len) /* No truncation allowed */
199 return -1; 200 return SSH_ERR_INVALID_ARGUMENT;
200 digest->md_final(d, ctx->mdctx); 201 digest->md_final(d, ctx->mdctx);
201 return 0; 202 return 0;
202} 203}
@@ -223,16 +224,16 @@ ssh_digest_memory(int alg, const void *m, size_t mlen, u_char *d, size_t dlen)
223 struct ssh_digest_ctx *ctx = ssh_digest_start(alg); 224 struct ssh_digest_ctx *ctx = ssh_digest_start(alg);
224 225
225 if (ctx == NULL) 226 if (ctx == NULL)
226 return -1; 227 return SSH_ERR_INVALID_ARGUMENT;
227 if (ssh_digest_update(ctx, m, mlen) != 0 || 228 if (ssh_digest_update(ctx, m, mlen) != 0 ||
228 ssh_digest_final(ctx, d, dlen) != 0) 229 ssh_digest_final(ctx, d, dlen) != 0)
229 return -1; 230 return SSH_ERR_INVALID_ARGUMENT;
230 ssh_digest_free(ctx); 231 ssh_digest_free(ctx);
231 return 0; 232 return 0;
232} 233}
233 234
234int 235int
235ssh_digest_buffer(int alg, const Buffer *b, u_char *d, size_t dlen) 236ssh_digest_buffer(int alg, const struct sshbuf *b, u_char *d, size_t dlen)
236{ 237{
237 return ssh_digest_memory(alg, buffer_ptr(b), buffer_len(b), d, dlen); 238 return ssh_digest_memory(alg, sshbuf_ptr(b), sshbuf_len(b), d, dlen);
238} 239}
diff --git a/digest-openssl.c b/digest-openssl.c
index 863d37d03..de0380135 100644
--- a/digest-openssl.c
+++ b/digest-openssl.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: digest-openssl.c,v 1.2 2014/02/02 03:44:31 djm Exp $ */ 1/* $OpenBSD: digest-openssl.c,v 1.3 2014/06/24 01:13:21 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2013 Damien Miller <djm@mindrot.org> 3 * Copyright (c) 2013 Damien Miller <djm@mindrot.org>
4 * 4 *
@@ -26,8 +26,9 @@
26 26
27#include "openbsd-compat/openssl-compat.h" 27#include "openbsd-compat/openssl-compat.h"
28 28
29#include "buffer.h" 29#include "sshbuf.h"
30#include "digest.h" 30#include "digest.h"
31#include "ssherr.h"
31 32
32struct ssh_digest_ctx { 33struct ssh_digest_ctx {
33 int alg; 34 int alg;
@@ -98,9 +99,11 @@ ssh_digest_start(int alg)
98int 99int
99ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to) 100ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to)
100{ 101{
102 if (from->alg != to->alg)
103 return SSH_ERR_INVALID_ARGUMENT;
101 /* we have bcopy-style order while openssl has memcpy-style */ 104 /* we have bcopy-style order while openssl has memcpy-style */
102 if (!EVP_MD_CTX_copy_ex(&to->mdctx, &from->mdctx)) 105 if (!EVP_MD_CTX_copy_ex(&to->mdctx, &from->mdctx))
103 return -1; 106 return SSH_ERR_LIBCRYPTO_ERROR;
104 return 0; 107 return 0;
105} 108}
106 109
@@ -108,14 +111,14 @@ int
108ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) 111ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
109{ 112{
110 if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1) 113 if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1)
111 return -1; 114 return SSH_ERR_LIBCRYPTO_ERROR;
112 return 0; 115 return 0;
113} 116}
114 117
115int 118int
116ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const Buffer *b) 119ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const struct sshbuf *b)
117{ 120{
118 return ssh_digest_update(ctx, buffer_ptr(b), buffer_len(b)); 121 return ssh_digest_update(ctx, sshbuf_ptr(b), sshbuf_len(b));
119} 122}
120 123
121int 124int
@@ -125,13 +128,13 @@ ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
125 u_int l = dlen; 128 u_int l = dlen;
126 129
127 if (dlen > UINT_MAX) 130 if (dlen > UINT_MAX)
128 return -1; 131 return SSH_ERR_INVALID_ARGUMENT;
129 if (dlen < digest->digest_len) /* No truncation allowed */ 132 if (dlen < digest->digest_len) /* No truncation allowed */
130 return -1; 133 return SSH_ERR_INVALID_ARGUMENT;
131 if (EVP_DigestFinal_ex(&ctx->mdctx, d, &l) != 1) 134 if (EVP_DigestFinal_ex(&ctx->mdctx, d, &l) != 1)
132 return -1; 135 return SSH_ERR_LIBCRYPTO_ERROR;
133 if (l != digest->digest_len) /* sanity */ 136 if (l != digest->digest_len) /* sanity */
134 return -1; 137 return SSH_ERR_INTERNAL_ERROR;
135 return 0; 138 return 0;
136} 139}
137 140
@@ -149,18 +152,19 @@ int
149ssh_digest_memory(int alg, const void *m, size_t mlen, u_char *d, size_t dlen) 152ssh_digest_memory(int alg, const void *m, size_t mlen, u_char *d, size_t dlen)
150{ 153{
151 struct ssh_digest_ctx *ctx = ssh_digest_start(alg); 154 struct ssh_digest_ctx *ctx = ssh_digest_start(alg);
155 int r;
152 156
153 if (ctx == NULL) 157 if (ctx == NULL)
154 return -1; 158 return SSH_ERR_INVALID_ARGUMENT;
155 if (ssh_digest_update(ctx, m, mlen) != 0 || 159 if ((r = ssh_digest_update(ctx, m, mlen) != 0) ||
156 ssh_digest_final(ctx, d, dlen) != 0) 160 (r = ssh_digest_final(ctx, d, dlen) != 0))
157 return -1; 161 return r;
158 ssh_digest_free(ctx); 162 ssh_digest_free(ctx);
159 return 0; 163 return 0;
160} 164}
161 165
162int 166int
163ssh_digest_buffer(int alg, const Buffer *b, u_char *d, size_t dlen) 167ssh_digest_buffer(int alg, const struct sshbuf *b, u_char *d, size_t dlen)
164{ 168{
165 return ssh_digest_memory(alg, buffer_ptr(b), buffer_len(b), d, dlen); 169 return ssh_digest_memory(alg, sshbuf_ptr(b), sshbuf_len(b), d, dlen);
166} 170}
diff --git a/digest.h b/digest.h
index 04295e277..edf6c87da 100644
--- a/digest.h
+++ b/digest.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: digest.h,v 1.4 2014/05/02 03:27:54 djm Exp $ */ 1/* $OpenBSD: digest.h,v 1.5 2014/06/24 01:13:21 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2013 Damien Miller <djm@mindrot.org> 3 * Copyright (c) 2013 Damien Miller <djm@mindrot.org>
4 * 4 *
@@ -47,14 +47,15 @@ int ssh_digest_memory(int alg, const void *m, size_t mlen,
47 u_char *d, size_t dlen) 47 u_char *d, size_t dlen)
48 __attribute__((__bounded__(__buffer__, 2, 3))) 48 __attribute__((__bounded__(__buffer__, 2, 3)))
49 __attribute__((__bounded__(__buffer__, 4, 5))); 49 __attribute__((__bounded__(__buffer__, 4, 5)));
50int ssh_digest_buffer(int alg, const Buffer *b, u_char *d, size_t dlen) 50int ssh_digest_buffer(int alg, const struct sshbuf *b, u_char *d, size_t dlen)
51 __attribute__((__bounded__(__buffer__, 3, 4))); 51 __attribute__((__bounded__(__buffer__, 3, 4)));
52 52
53/* Update API */ 53/* Update API */
54struct ssh_digest_ctx *ssh_digest_start(int alg); 54struct ssh_digest_ctx *ssh_digest_start(int alg);
55int ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) 55int ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
56 __attribute__((__bounded__(__buffer__, 2, 3))); 56 __attribute__((__bounded__(__buffer__, 2, 3)));
57int ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const Buffer *b); 57int ssh_digest_update_buffer(struct ssh_digest_ctx *ctx,
58 const struct sshbuf *b);
58int ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen) 59int ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
59 __attribute__((__bounded__(__buffer__, 2, 3))); 60 __attribute__((__bounded__(__buffer__, 2, 3)));
60void ssh_digest_free(struct ssh_digest_ctx *ctx); 61void ssh_digest_free(struct ssh_digest_ctx *ctx);
diff --git a/dns.c b/dns.c
index c780f8ba7..c4d073cf5 100644
--- a/dns.c
+++ b/dns.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: dns.c,v 1.30 2014/04/20 09:24:26 logan Exp $ */ 1/* $OpenBSD: dns.c,v 1.31 2014/06/24 01:13:21 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2003 Wesley Griffin. All rights reserved. 4 * Copyright (c) 2003 Wesley Griffin. All rights reserved.
@@ -34,6 +34,8 @@
34#include <stdarg.h> 34#include <stdarg.h>
35#include <stdio.h> 35#include <stdio.h>
36#include <string.h> 36#include <string.h>
37#include <stdarg.h>
38#include <stdlib.h>
37 39
38#include "xmalloc.h" 40#include "xmalloc.h"
39#include "key.h" 41#include "key.h"
diff --git a/entropy.c b/entropy.c
index e1a8e142b..1e9d52ac4 100644
--- a/entropy.c
+++ b/entropy.c
@@ -43,6 +43,8 @@
43#include <openssl/crypto.h> 43#include <openssl/crypto.h>
44#include <openssl/err.h> 44#include <openssl/err.h>
45 45
46#include "openbsd-compat/openssl-compat.h"
47
46#include "ssh.h" 48#include "ssh.h"
47#include "misc.h" 49#include "misc.h"
48#include "xmalloc.h" 50#include "xmalloc.h"
diff --git a/hmac.h b/hmac.h
index 05813906e..42b33d002 100644
--- a/hmac.h
+++ b/hmac.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: hmac.h,v 1.8 2014/05/02 03:27:54 djm Exp $ */ 1/* $OpenBSD: hmac.h,v 1.9 2014/06/24 01:13:21 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Markus Friedl. All rights reserved. 3 * Copyright (c) 2014 Markus Friedl. All rights reserved.
4 * 4 *
@@ -21,6 +21,7 @@
21/* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */ 21/* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */
22size_t ssh_hmac_bytes(int alg); 22size_t ssh_hmac_bytes(int alg);
23 23
24struct sshbuf;
24struct ssh_hmac_ctx; 25struct ssh_hmac_ctx;
25struct ssh_hmac_ctx *ssh_hmac_start(int alg); 26struct ssh_hmac_ctx *ssh_hmac_start(int alg);
26 27
@@ -29,7 +30,7 @@ int ssh_hmac_init(struct ssh_hmac_ctx *ctx, const void *key, size_t klen)
29 __attribute__((__bounded__(__buffer__, 2, 3))); 30 __attribute__((__bounded__(__buffer__, 2, 3)));
30int ssh_hmac_update(struct ssh_hmac_ctx *ctx, const void *m, size_t mlen) 31int ssh_hmac_update(struct ssh_hmac_ctx *ctx, const void *m, size_t mlen)
31 __attribute__((__bounded__(__buffer__, 2, 3))); 32 __attribute__((__bounded__(__buffer__, 2, 3)));
32int ssh_hmac_update_buffer(struct ssh_hmac_ctx *ctx, const Buffer *b); 33int ssh_hmac_update_buffer(struct ssh_hmac_ctx *ctx, const struct sshbuf *b);
33int ssh_hmac_final(struct ssh_hmac_ctx *ctx, u_char *d, size_t dlen) 34int ssh_hmac_final(struct ssh_hmac_ctx *ctx, u_char *d, size_t dlen)
34 __attribute__((__bounded__(__buffer__, 2, 3))); 35 __attribute__((__bounded__(__buffer__, 2, 3)));
35void ssh_hmac_free(struct ssh_hmac_ctx *ctx); 36void ssh_hmac_free(struct ssh_hmac_ctx *ctx);
diff --git a/hostfile.c b/hostfile.c
index 91741cab8..ee2daf45f 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: hostfile.c,v 1.56 2014/04/29 18:01:49 markus Exp $ */ 1/* $OpenBSD: hostfile.c,v 1.57 2014/06/24 01:13:21 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
@@ -47,6 +47,7 @@
47#include <stdio.h> 47#include <stdio.h>
48#include <stdlib.h> 48#include <stdlib.h>
49#include <string.h> 49#include <string.h>
50#include <stdarg.h>
50 51
51#include "xmalloc.h" 52#include "xmalloc.h"
52#include "match.h" 53#include "match.h"
diff --git a/key.c b/key.c
index e8fc5b1b8..75327d491 100644
--- a/key.c
+++ b/key.c
@@ -1,2694 +1,469 @@
1/* $OpenBSD: key.c,v 1.117 2014/04/29 18:01:49 markus Exp $ */ 1/* $OpenBSD: key.c,v 1.119 2014/06/30 12:54:39 djm Exp $ */
2/* 2/*
3 * read_bignum(): 3 * placed in the public domain
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 *
6 * As far as I am concerned, the code I have written for this software
7 * can be used freely for any purpose. Any derived versions of this
8 * software must be clearly marked as such, and if the derived work is
9 * incompatible with the protocol description in the RFC file, it must be
10 * called by a name other than "ssh" or "Secure Shell".
11 *
12 *
13 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
14 * Copyright (c) 2008 Alexander von Gernler. All rights reserved.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */ 4 */
36 5
37#include "includes.h" 6#include "includes.h"
38 7
39#include <sys/param.h> 8#include <sys/param.h>
40#include <sys/types.h> 9#include <sys/types.h>
41 10#include <errno.h>
42#include "crypto_api.h"
43
44#include <openssl/evp.h>
45#include <openbsd-compat/openssl-compat.h>
46
47#include <stdarg.h> 11#include <stdarg.h>
48#include <stdio.h> 12#include <stdio.h>
49#include <string.h>
50 13
51#include "xmalloc.h" 14#define SSH_KEY_NO_DEFINE
52#include "key.h" 15#include "key.h"
53#include "rsa.h"
54#include "uuencode.h"
55#include "buffer.h"
56#include "log.h"
57#include "misc.h"
58#include "ssh2.h"
59#include "digest.h"
60
61static int to_blob(const Key *, u_char **, u_int *, int);
62static Key *key_from_blob2(const u_char *, u_int, int);
63
64static struct KeyCert *
65cert_new(void)
66{
67 struct KeyCert *cert;
68
69 cert = xcalloc(1, sizeof(*cert));
70 buffer_init(&cert->certblob);
71 buffer_init(&cert->critical);
72 buffer_init(&cert->extensions);
73 cert->key_id = NULL;
74 cert->principals = NULL;
75 cert->signature_key = NULL;
76 return cert;
77}
78
79Key *
80key_new(int type)
81{
82 Key *k;
83#ifdef WITH_OPENSSL
84 RSA *rsa;
85 DSA *dsa;
86#endif
87
88 k = xcalloc(1, sizeof(*k));
89 k->type = type;
90 k->ecdsa = NULL;
91 k->ecdsa_nid = -1;
92 k->dsa = NULL;
93 k->rsa = NULL;
94 k->cert = NULL;
95 k->ed25519_sk = NULL;
96 k->ed25519_pk = NULL;
97 switch (k->type) {
98#ifdef WITH_OPENSSL
99 case KEY_RSA1:
100 case KEY_RSA:
101 case KEY_RSA_CERT_V00:
102 case KEY_RSA_CERT:
103 if ((rsa = RSA_new()) == NULL)
104 fatal("key_new: RSA_new failed");
105 if ((rsa->n = BN_new()) == NULL)
106 fatal("key_new: BN_new failed");
107 if ((rsa->e = BN_new()) == NULL)
108 fatal("key_new: BN_new failed");
109 k->rsa = rsa;
110 break;
111 case KEY_DSA:
112 case KEY_DSA_CERT_V00:
113 case KEY_DSA_CERT:
114 if ((dsa = DSA_new()) == NULL)
115 fatal("key_new: DSA_new failed");
116 if ((dsa->p = BN_new()) == NULL)
117 fatal("key_new: BN_new failed");
118 if ((dsa->q = BN_new()) == NULL)
119 fatal("key_new: BN_new failed");
120 if ((dsa->g = BN_new()) == NULL)
121 fatal("key_new: BN_new failed");
122 if ((dsa->pub_key = BN_new()) == NULL)
123 fatal("key_new: BN_new failed");
124 k->dsa = dsa;
125 break;
126#ifdef OPENSSL_HAS_ECC
127 case KEY_ECDSA:
128 case KEY_ECDSA_CERT:
129 /* Cannot do anything until we know the group */
130 break;
131#endif
132#endif
133 case KEY_ED25519:
134 case KEY_ED25519_CERT:
135 /* no need to prealloc */
136 break;
137 case KEY_UNSPEC:
138 break;
139 default:
140 fatal("key_new: bad key type %d", k->type);
141 break;
142 }
143
144 if (key_is_cert(k))
145 k->cert = cert_new();
146 16
147 return k; 17#include "compat.h"
148} 18#include "sshkey.h"
19#include "ssherr.h"
20#include "log.h"
21#include "authfile.h"
149 22
150void 23void
151key_add_private(Key *k) 24key_add_private(Key *k)
152{ 25{
153 switch (k->type) { 26 int r;
154#ifdef WITH_OPENSSL 27
155 case KEY_RSA1: 28 if ((r = sshkey_add_private(k)) != 0)
156 case KEY_RSA: 29 fatal("%s: %s", __func__, ssh_err(r));
157 case KEY_RSA_CERT_V00:
158 case KEY_RSA_CERT:
159 if ((k->rsa->d = BN_new()) == NULL)
160 fatal("key_new_private: BN_new failed");
161 if ((k->rsa->iqmp = BN_new()) == NULL)
162 fatal("key_new_private: BN_new failed");
163 if ((k->rsa->q = BN_new()) == NULL)
164 fatal("key_new_private: BN_new failed");
165 if ((k->rsa->p = BN_new()) == NULL)
166 fatal("key_new_private: BN_new failed");
167 if ((k->rsa->dmq1 = BN_new()) == NULL)
168 fatal("key_new_private: BN_new failed");
169 if ((k->rsa->dmp1 = BN_new()) == NULL)
170 fatal("key_new_private: BN_new failed");
171 break;
172 case KEY_DSA:
173 case KEY_DSA_CERT_V00:
174 case KEY_DSA_CERT:
175 if ((k->dsa->priv_key = BN_new()) == NULL)
176 fatal("key_new_private: BN_new failed");
177 break;
178 case KEY_ECDSA:
179 case KEY_ECDSA_CERT:
180 /* Cannot do anything until we know the group */
181 break;
182#endif
183 case KEY_ED25519:
184 case KEY_ED25519_CERT:
185 /* no need to prealloc */
186 break;
187 case KEY_UNSPEC:
188 break;
189 default:
190 break;
191 }
192} 30}
193 31
194Key * 32Key *
195key_new_private(int type) 33key_new_private(int type)
196{ 34{
197 Key *k = key_new(type); 35 Key *ret = NULL;
198
199 key_add_private(k);
200 return k;
201}
202
203static void
204cert_free(struct KeyCert *cert)
205{
206 u_int i;
207
208 buffer_free(&cert->certblob);
209 buffer_free(&cert->critical);
210 buffer_free(&cert->extensions);
211 free(cert->key_id);
212 for (i = 0; i < cert->nprincipals; i++)
213 free(cert->principals[i]);
214 free(cert->principals);
215 if (cert->signature_key != NULL)
216 key_free(cert->signature_key);
217 free(cert);
218}
219
220void
221key_free(Key *k)
222{
223 if (k == NULL)
224 fatal("key_free: key is NULL");
225 switch (k->type) {
226#ifdef WITH_OPENSSL
227 case KEY_RSA1:
228 case KEY_RSA:
229 case KEY_RSA_CERT_V00:
230 case KEY_RSA_CERT:
231 if (k->rsa != NULL)
232 RSA_free(k->rsa);
233 k->rsa = NULL;
234 break;
235 case KEY_DSA:
236 case KEY_DSA_CERT_V00:
237 case KEY_DSA_CERT:
238 if (k->dsa != NULL)
239 DSA_free(k->dsa);
240 k->dsa = NULL;
241 break;
242#ifdef OPENSSL_HAS_ECC
243 case KEY_ECDSA:
244 case KEY_ECDSA_CERT:
245 if (k->ecdsa != NULL)
246 EC_KEY_free(k->ecdsa);
247 k->ecdsa = NULL;
248 break;
249#endif
250 case KEY_ED25519:
251 case KEY_ED25519_CERT:
252 if (k->ed25519_pk) {
253 explicit_bzero(k->ed25519_pk, ED25519_PK_SZ);
254 free(k->ed25519_pk);
255 k->ed25519_pk = NULL;
256 }
257 if (k->ed25519_sk) {
258 explicit_bzero(k->ed25519_sk, ED25519_SK_SZ);
259 free(k->ed25519_sk);
260 k->ed25519_sk = NULL;
261 }
262 break;
263 case KEY_UNSPEC:
264 break;
265 default:
266 fatal("key_free: bad key type %d", k->type);
267 break;
268 }
269 if (key_is_cert(k)) {
270 if (k->cert != NULL)
271 cert_free(k->cert);
272 k->cert = NULL;
273 }
274
275 free(k);
276}
277
278static int
279cert_compare(struct KeyCert *a, struct KeyCert *b)
280{
281 if (a == NULL && b == NULL)
282 return 1;
283 if (a == NULL || b == NULL)
284 return 0;
285 if (buffer_len(&a->certblob) != buffer_len(&b->certblob))
286 return 0;
287 if (timingsafe_bcmp(buffer_ptr(&a->certblob), buffer_ptr(&b->certblob),
288 buffer_len(&a->certblob)) != 0)
289 return 0;
290 return 1;
291}
292
293/*
294 * Compare public portions of key only, allowing comparisons between
295 * certificates and plain keys too.
296 */
297int
298key_equal_public(const Key *a, const Key *b)
299{
300#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
301 BN_CTX *bnctx;
302#endif
303
304 if (a == NULL || b == NULL ||
305 key_type_plain(a->type) != key_type_plain(b->type))
306 return 0;
307
308 switch (a->type) {
309#ifdef WITH_OPENSSL
310 case KEY_RSA1:
311 case KEY_RSA_CERT_V00:
312 case KEY_RSA_CERT:
313 case KEY_RSA:
314 return a->rsa != NULL && b->rsa != NULL &&
315 BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
316 BN_cmp(a->rsa->n, b->rsa->n) == 0;
317 case KEY_DSA_CERT_V00:
318 case KEY_DSA_CERT:
319 case KEY_DSA:
320 return a->dsa != NULL && b->dsa != NULL &&
321 BN_cmp(a->dsa->p, b->dsa->p) == 0 &&
322 BN_cmp(a->dsa->q, b->dsa->q) == 0 &&
323 BN_cmp(a->dsa->g, b->dsa->g) == 0 &&
324 BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0;
325#ifdef OPENSSL_HAS_ECC
326 case KEY_ECDSA_CERT:
327 case KEY_ECDSA:
328 if (a->ecdsa == NULL || b->ecdsa == NULL ||
329 EC_KEY_get0_public_key(a->ecdsa) == NULL ||
330 EC_KEY_get0_public_key(b->ecdsa) == NULL)
331 return 0;
332 if ((bnctx = BN_CTX_new()) == NULL)
333 fatal("%s: BN_CTX_new failed", __func__);
334 if (EC_GROUP_cmp(EC_KEY_get0_group(a->ecdsa),
335 EC_KEY_get0_group(b->ecdsa), bnctx) != 0 ||
336 EC_POINT_cmp(EC_KEY_get0_group(a->ecdsa),
337 EC_KEY_get0_public_key(a->ecdsa),
338 EC_KEY_get0_public_key(b->ecdsa), bnctx) != 0) {
339 BN_CTX_free(bnctx);
340 return 0;
341 }
342 BN_CTX_free(bnctx);
343 return 1;
344#endif /* OPENSSL_HAS_ECC */
345#endif /* WITH_OPENSSL */
346 case KEY_ED25519:
347 case KEY_ED25519_CERT:
348 return a->ed25519_pk != NULL && b->ed25519_pk != NULL &&
349 memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) == 0;
350 default:
351 fatal("key_equal: bad key type %d", a->type);
352 }
353 /* NOTREACHED */
354}
355 36
356int 37 if ((ret = sshkey_new_private(type)) == NULL)
357key_equal(const Key *a, const Key *b) 38 fatal("%s: failed", __func__);
358{ 39 return ret;
359 if (a == NULL || b == NULL || a->type != b->type)
360 return 0;
361 if (key_is_cert(a)) {
362 if (!cert_compare(a->cert, b->cert))
363 return 0;
364 }
365 return key_equal_public(a, b);
366} 40}
367 41
368u_char* 42u_char*
369key_fingerprint_raw(const Key *k, enum fp_type dgst_type, 43key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
370 u_int *dgst_raw_length) 44 u_int *dgst_raw_length)
371{ 45{
372 u_char *blob = NULL; 46 u_char *ret = NULL;
373 u_char *retval = NULL; 47 size_t dlen;
374 u_int len = 0; 48 int r;
375 int hash_alg = -1; 49
376#ifdef WITH_OPENSSL 50 if (dgst_raw_length != NULL)
377 int nlen, elen; 51 *dgst_raw_length = 0;
378#endif 52 if ((r = sshkey_fingerprint_raw(k, dgst_type, &ret, &dlen)) != 0)
379 53 fatal("%s: %s", __func__, ssh_err(r));
380 *dgst_raw_length = 0; 54 if (dlen > INT_MAX)
381 55 fatal("%s: giant len %zu", __func__, dlen);
382 /* XXX switch to DIGEST_* directly? */ 56 *dgst_raw_length = dlen;
383 switch (dgst_type) { 57 return ret;
384 case SSH_FP_MD5:
385 hash_alg = SSH_DIGEST_MD5;
386 break;
387 case SSH_FP_SHA1:
388 hash_alg = SSH_DIGEST_SHA1;
389 break;
390 case SSH_FP_SHA256:
391 hash_alg = SSH_DIGEST_SHA256;
392 break;
393 default:
394 fatal("%s: bad digest type %d", __func__, dgst_type);
395 }
396 switch (k->type) {
397#ifdef WITH_OPENSSL
398 case KEY_RSA1:
399 nlen = BN_num_bytes(k->rsa->n);
400 elen = BN_num_bytes(k->rsa->e);
401 len = nlen + elen;
402 blob = xmalloc(len);
403 BN_bn2bin(k->rsa->n, blob);
404 BN_bn2bin(k->rsa->e, blob + nlen);
405 break;
406 case KEY_DSA:
407 case KEY_ECDSA:
408 case KEY_RSA:
409#endif
410 case KEY_ED25519:
411 key_to_blob(k, &blob, &len);
412 break;
413#ifdef WITH_OPENSSL
414 case KEY_DSA_CERT_V00:
415 case KEY_RSA_CERT_V00:
416 case KEY_DSA_CERT:
417 case KEY_ECDSA_CERT:
418 case KEY_RSA_CERT:
419#endif
420 case KEY_ED25519_CERT:
421 /* We want a fingerprint of the _key_ not of the cert */
422 to_blob(k, &blob, &len, 1);
423 break;
424 case KEY_UNSPEC:
425 return retval;
426 default:
427 fatal("%s: bad key type %d", __func__, k->type);
428 break;
429 }
430 if (blob != NULL) {
431 retval = xmalloc(SSH_DIGEST_MAX_LENGTH);
432 if ((ssh_digest_memory(hash_alg, blob, len,
433 retval, SSH_DIGEST_MAX_LENGTH)) != 0)
434 fatal("%s: digest_memory failed", __func__);
435 explicit_bzero(blob, len);
436 free(blob);
437 *dgst_raw_length = ssh_digest_bytes(hash_alg);
438 } else {
439 fatal("%s: blob is null", __func__);
440 }
441 return retval;
442}
443
444static char *
445key_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len)
446{
447 char *retval;
448 u_int i;
449
450 retval = xcalloc(1, dgst_raw_len * 3 + 1);
451 for (i = 0; i < dgst_raw_len; i++) {
452 char hex[4];
453 snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]);
454 strlcat(retval, hex, dgst_raw_len * 3 + 1);
455 }
456
457 /* Remove the trailing ':' character */
458 retval[(dgst_raw_len * 3) - 1] = '\0';
459 return retval;
460}
461
462static char *
463key_fingerprint_bubblebabble(u_char *dgst_raw, u_int dgst_raw_len)
464{
465 char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' };
466 char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
467 'n', 'p', 'r', 's', 't', 'v', 'z', 'x' };
468 u_int i, j = 0, rounds, seed = 1;
469 char *retval;
470
471 rounds = (dgst_raw_len / 2) + 1;
472 retval = xcalloc((rounds * 6), sizeof(char));
473 retval[j++] = 'x';
474 for (i = 0; i < rounds; i++) {
475 u_int idx0, idx1, idx2, idx3, idx4;
476 if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) {
477 idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) +
478 seed) % 6;
479 idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15;
480 idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) +
481 (seed / 6)) % 6;
482 retval[j++] = vowels[idx0];
483 retval[j++] = consonants[idx1];
484 retval[j++] = vowels[idx2];
485 if ((i + 1) < rounds) {
486 idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15;
487 idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15;
488 retval[j++] = consonants[idx3];
489 retval[j++] = '-';
490 retval[j++] = consonants[idx4];
491 seed = ((seed * 5) +
492 ((((u_int)(dgst_raw[2 * i])) * 7) +
493 ((u_int)(dgst_raw[(2 * i) + 1])))) % 36;
494 }
495 } else {
496 idx0 = seed % 6;
497 idx1 = 16;
498 idx2 = seed / 6;
499 retval[j++] = vowels[idx0];
500 retval[j++] = consonants[idx1];
501 retval[j++] = vowels[idx2];
502 }
503 }
504 retval[j++] = 'x';
505 retval[j++] = '\0';
506 return retval;
507}
508
509/*
510 * Draw an ASCII-Art representing the fingerprint so human brain can
511 * profit from its built-in pattern recognition ability.
512 * This technique is called "random art" and can be found in some
513 * scientific publications like this original paper:
514 *
515 * "Hash Visualization: a New Technique to improve Real-World Security",
516 * Perrig A. and Song D., 1999, International Workshop on Cryptographic
517 * Techniques and E-Commerce (CrypTEC '99)
518 * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf
519 *
520 * The subject came up in a talk by Dan Kaminsky, too.
521 *
522 * If you see the picture is different, the key is different.
523 * If the picture looks the same, you still know nothing.
524 *
525 * The algorithm used here is a worm crawling over a discrete plane,
526 * leaving a trace (augmenting the field) everywhere it goes.
527 * Movement is taken from dgst_raw 2bit-wise. Bumping into walls
528 * makes the respective movement vector be ignored for this turn.
529 * Graphs are not unambiguous, because circles in graphs can be
530 * walked in either direction.
531 */
532
533/*
534 * Field sizes for the random art. Have to be odd, so the starting point
535 * can be in the exact middle of the picture, and FLDBASE should be >=8 .
536 * Else pictures would be too dense, and drawing the frame would
537 * fail, too, because the key type would not fit in anymore.
538 */
539#define FLDBASE 8
540#define FLDSIZE_Y (FLDBASE + 1)
541#define FLDSIZE_X (FLDBASE * 2 + 1)
542static char *
543key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k)
544{
545 /*
546 * Chars to be used after each other every time the worm
547 * intersects with itself. Matter of taste.
548 */
549 char *augmentation_string = " .o+=*BOX@%&#/^SE";
550 char *retval, *p;
551 u_char field[FLDSIZE_X][FLDSIZE_Y];
552 u_int i, b;
553 int x, y;
554 size_t len = strlen(augmentation_string) - 1;
555
556 retval = xcalloc(1, (FLDSIZE_X + 3) * (FLDSIZE_Y + 2));
557
558 /* initialize field */
559 memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char));
560 x = FLDSIZE_X / 2;
561 y = FLDSIZE_Y / 2;
562
563 /* process raw key */
564 for (i = 0; i < dgst_raw_len; i++) {
565 int input;
566 /* each byte conveys four 2-bit move commands */
567 input = dgst_raw[i];
568 for (b = 0; b < 4; b++) {
569 /* evaluate 2 bit, rest is shifted later */
570 x += (input & 0x1) ? 1 : -1;
571 y += (input & 0x2) ? 1 : -1;
572
573 /* assure we are still in bounds */
574 x = MAX(x, 0);
575 y = MAX(y, 0);
576 x = MIN(x, FLDSIZE_X - 1);
577 y = MIN(y, FLDSIZE_Y - 1);
578
579 /* augment the field */
580 if (field[x][y] < len - 2)
581 field[x][y]++;
582 input = input >> 2;
583 }
584 }
585
586 /* mark starting point and end point*/
587 field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;
588 field[x][y] = len;
589
590 /* fill in retval */
591 snprintf(retval, FLDSIZE_X, "+--[%4s %4u]", key_type(k), key_size(k));
592 p = strchr(retval, '\0');
593
594 /* output upper border */
595 for (i = p - retval - 1; i < FLDSIZE_X; i++)
596 *p++ = '-';
597 *p++ = '+';
598 *p++ = '\n';
599
600 /* output content */
601 for (y = 0; y < FLDSIZE_Y; y++) {
602 *p++ = '|';
603 for (x = 0; x < FLDSIZE_X; x++)
604 *p++ = augmentation_string[MIN(field[x][y], len)];
605 *p++ = '|';
606 *p++ = '\n';
607 }
608
609 /* output lower border */
610 *p++ = '+';
611 for (i = 0; i < FLDSIZE_X; i++)
612 *p++ = '-';
613 *p++ = '+';
614
615 return retval;
616}
617
618char *
619key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
620{
621 char *retval = NULL;
622 u_char *dgst_raw;
623 u_int dgst_raw_len;
624
625 dgst_raw = key_fingerprint_raw(k, dgst_type, &dgst_raw_len);
626 if (!dgst_raw)
627 fatal("key_fingerprint: null from key_fingerprint_raw()");
628 switch (dgst_rep) {
629 case SSH_FP_HEX:
630 retval = key_fingerprint_hex(dgst_raw, dgst_raw_len);
631 break;
632 case SSH_FP_BUBBLEBABBLE:
633 retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len);
634 break;
635 case SSH_FP_RANDOMART:
636 retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, k);
637 break;
638 default:
639 fatal("key_fingerprint: bad digest representation %d",
640 dgst_rep);
641 break;
642 }
643 explicit_bzero(dgst_raw, dgst_raw_len);
644 free(dgst_raw);
645 return retval;
646}
647
648#ifdef WITH_SSH1
649/*
650 * Reads a multiple-precision integer in decimal from the buffer, and advances
651 * the pointer. The integer must already be initialized. This function is
652 * permitted to modify the buffer. This leaves *cpp to point just beyond the
653 * last processed (and maybe modified) character. Note that this may modify
654 * the buffer containing the number.
655 */
656static int
657read_bignum(char **cpp, BIGNUM * value)
658{
659 char *cp = *cpp;
660 int old;
661
662 /* Skip any leading whitespace. */
663 for (; *cp == ' ' || *cp == '\t'; cp++)
664 ;
665
666 /* Check that it begins with a decimal digit. */
667 if (*cp < '0' || *cp > '9')
668 return 0;
669
670 /* Save starting position. */
671 *cpp = cp;
672
673 /* Move forward until all decimal digits skipped. */
674 for (; *cp >= '0' && *cp <= '9'; cp++)
675 ;
676
677 /* Save the old terminating character, and replace it by \0. */
678 old = *cp;
679 *cp = 0;
680
681 /* Parse the number. */
682 if (BN_dec2bn(&value, *cpp) == 0)
683 return 0;
684
685 /* Restore old terminating character. */
686 *cp = old;
687
688 /* Move beyond the number and return success. */
689 *cpp = cp;
690 return 1;
691}
692
693static int
694write_bignum(FILE *f, BIGNUM *num)
695{
696 char *buf = BN_bn2dec(num);
697 if (buf == NULL) {
698 error("write_bignum: BN_bn2dec() failed");
699 return 0;
700 }
701 fprintf(f, " %s", buf);
702 OPENSSL_free(buf);
703 return 1;
704} 58}
705#endif
706 59
707/* returns 1 ok, -1 error */
708int 60int
709key_read(Key *ret, char **cpp) 61key_read(Key *ret, char **cpp)
710{ 62{
711 Key *k; 63 return sshkey_read(ret, cpp) == 0 ? 1 : -1;
712 int success = -1;
713 char *cp, *space;
714 int len, n, type;
715 u_char *blob;
716#ifdef WITH_SSH1
717 u_int bits;
718#endif
719#ifdef OPENSSL_HAS_ECC
720 int curve_nid = -1;
721#endif
722
723 cp = *cpp;
724
725 switch (ret->type) {
726 case KEY_RSA1:
727#ifdef WITH_SSH1
728 /* Get number of bits. */
729 if (*cp < '0' || *cp > '9')
730 return -1; /* Bad bit count... */
731 for (bits = 0; *cp >= '0' && *cp <= '9'; cp++)
732 bits = 10 * bits + *cp - '0';
733 if (bits == 0)
734 return -1;
735 *cpp = cp;
736 /* Get public exponent, public modulus. */
737 if (!read_bignum(cpp, ret->rsa->e))
738 return -1;
739 if (!read_bignum(cpp, ret->rsa->n))
740 return -1;
741 /* validate the claimed number of bits */
742 if ((u_int)BN_num_bits(ret->rsa->n) != bits) {
743 verbose("key_read: claimed key size %d does not match "
744 "actual %d", bits, BN_num_bits(ret->rsa->n));
745 return -1;
746 }
747 success = 1;
748#endif
749 break;
750 case KEY_UNSPEC:
751 case KEY_RSA:
752 case KEY_DSA:
753 case KEY_ECDSA:
754 case KEY_ED25519:
755 case KEY_DSA_CERT_V00:
756 case KEY_RSA_CERT_V00:
757 case KEY_DSA_CERT:
758 case KEY_ECDSA_CERT:
759 case KEY_RSA_CERT:
760 case KEY_ED25519_CERT:
761 space = strchr(cp, ' ');
762 if (space == NULL) {
763 debug3("key_read: missing whitespace");
764 return -1;
765 }
766 *space = '\0';
767 type = key_type_from_name(cp);
768#ifdef OPENSSL_HAS_ECC
769 if (key_type_plain(type) == KEY_ECDSA &&
770 (curve_nid = key_ecdsa_nid_from_name(cp)) == -1) {
771 debug("key_read: invalid curve");
772 return -1;
773 }
774#endif
775 *space = ' ';
776 if (type == KEY_UNSPEC) {
777 debug3("key_read: missing keytype");
778 return -1;
779 }
780 cp = space+1;
781 if (*cp == '\0') {
782 debug3("key_read: short string");
783 return -1;
784 }
785 if (ret->type == KEY_UNSPEC) {
786 ret->type = type;
787 } else if (ret->type != type) {
788 /* is a key, but different type */
789 debug3("key_read: type mismatch");
790 return -1;
791 }
792 len = 2*strlen(cp);
793 blob = xmalloc(len);
794 n = uudecode(cp, blob, len);
795 if (n < 0) {
796 error("key_read: uudecode %s failed", cp);
797 free(blob);
798 return -1;
799 }
800 k = key_from_blob(blob, (u_int)n);
801 free(blob);
802 if (k == NULL) {
803 error("key_read: key_from_blob %s failed", cp);
804 return -1;
805 }
806 if (k->type != type) {
807 error("key_read: type mismatch: encoding error");
808 key_free(k);
809 return -1;
810 }
811#ifdef OPENSSL_HAS_ECC
812 if (key_type_plain(type) == KEY_ECDSA &&
813 curve_nid != k->ecdsa_nid) {
814 error("key_read: type mismatch: EC curve mismatch");
815 key_free(k);
816 return -1;
817 }
818#endif
819/*XXXX*/
820 if (key_is_cert(ret)) {
821 if (!key_is_cert(k)) {
822 error("key_read: loaded key is not a cert");
823 key_free(k);
824 return -1;
825 }
826 if (ret->cert != NULL)
827 cert_free(ret->cert);
828 ret->cert = k->cert;
829 k->cert = NULL;
830 }
831#ifdef WITH_OPENSSL
832 if (key_type_plain(ret->type) == KEY_RSA) {
833 if (ret->rsa != NULL)
834 RSA_free(ret->rsa);
835 ret->rsa = k->rsa;
836 k->rsa = NULL;
837#ifdef DEBUG_PK
838 RSA_print_fp(stderr, ret->rsa, 8);
839#endif
840 }
841 if (key_type_plain(ret->type) == KEY_DSA) {
842 if (ret->dsa != NULL)
843 DSA_free(ret->dsa);
844 ret->dsa = k->dsa;
845 k->dsa = NULL;
846#ifdef DEBUG_PK
847 DSA_print_fp(stderr, ret->dsa, 8);
848#endif
849 }
850#ifdef OPENSSL_HAS_ECC
851 if (key_type_plain(ret->type) == KEY_ECDSA) {
852 if (ret->ecdsa != NULL)
853 EC_KEY_free(ret->ecdsa);
854 ret->ecdsa = k->ecdsa;
855 ret->ecdsa_nid = k->ecdsa_nid;
856 k->ecdsa = NULL;
857 k->ecdsa_nid = -1;
858#ifdef DEBUG_PK
859 key_dump_ec_key(ret->ecdsa);
860#endif
861 }
862#endif
863#endif
864 if (key_type_plain(ret->type) == KEY_ED25519) {
865 free(ret->ed25519_pk);
866 ret->ed25519_pk = k->ed25519_pk;
867 k->ed25519_pk = NULL;
868#ifdef DEBUG_PK
869 /* XXX */
870#endif
871 }
872 success = 1;
873/*XXXX*/
874 key_free(k);
875 if (success != 1)
876 break;
877 /* advance cp: skip whitespace and data */
878 while (*cp == ' ' || *cp == '\t')
879 cp++;
880 while (*cp != '\0' && *cp != ' ' && *cp != '\t')
881 cp++;
882 *cpp = cp;
883 break;
884 default:
885 fatal("key_read: bad key type: %d", ret->type);
886 break;
887 }
888 return success;
889} 64}
890 65
891int 66int
892key_write(const Key *key, FILE *f) 67key_write(const Key *key, FILE *f)
893{ 68{
894 int n, success = 0; 69 return sshkey_write(key, f) == 0 ? 1 : 0;
895#ifdef WITH_SSH1
896 u_int bits = 0;
897#endif
898 u_int len;
899 u_char *blob;
900 char *uu;
901
902 if (key_is_cert(key)) {
903 if (key->cert == NULL) {
904 error("%s: no cert data", __func__);
905 return 0;
906 }
907 if (buffer_len(&key->cert->certblob) == 0) {
908 error("%s: no signed certificate blob", __func__);
909 return 0;
910 }
911 }
912
913 switch (key->type) {
914#ifdef WITH_SSH1
915 case KEY_RSA1:
916 if (key->rsa == NULL)
917 return 0;
918 /* size of modulus 'n' */
919 bits = BN_num_bits(key->rsa->n);
920 fprintf(f, "%u", bits);
921 if (write_bignum(f, key->rsa->e) &&
922 write_bignum(f, key->rsa->n))
923 return 1;
924 error("key_write: failed for RSA key");
925 return 0;
926#endif
927#ifdef WITH_OPENSSL
928 case KEY_DSA:
929 case KEY_DSA_CERT_V00:
930 case KEY_DSA_CERT:
931 if (key->dsa == NULL)
932 return 0;
933 break;
934#ifdef OPENSSL_HAS_ECC
935 case KEY_ECDSA:
936 case KEY_ECDSA_CERT:
937 if (key->ecdsa == NULL)
938 return 0;
939 break;
940#endif
941 case KEY_RSA:
942 case KEY_RSA_CERT_V00:
943 case KEY_RSA_CERT:
944 if (key->rsa == NULL)
945 return 0;
946 break;
947#endif
948 case KEY_ED25519:
949 case KEY_ED25519_CERT:
950 if (key->ed25519_pk == NULL)
951 return 0;
952 break;
953 default:
954 return 0;
955 }
956
957 key_to_blob(key, &blob, &len);
958 uu = xmalloc(2*len);
959 n = uuencode(blob, len, uu, 2*len);
960 if (n > 0) {
961 fprintf(f, "%s %s", key_ssh_name(key), uu);
962 success = 1;
963 }
964 free(blob);
965 free(uu);
966
967 return success;
968}
969
970const char *
971key_cert_type(const Key *k)
972{
973 switch (k->cert->type) {
974 case SSH2_CERT_TYPE_USER:
975 return "user";
976 case SSH2_CERT_TYPE_HOST:
977 return "host";
978 default:
979 return "unknown";
980 }
981}
982
983struct keytype {
984 char *name;
985 char *shortname;
986 int type;
987 int nid;
988 int cert;
989};
990static const struct keytype keytypes[] = {
991#ifdef WITH_OPENSSL
992#ifdef WITH_SSH1
993 { NULL, "RSA1", KEY_RSA1, 0, 0 },
994#endif
995 { "ssh-rsa", "RSA", KEY_RSA, 0, 0 },
996 { "ssh-dss", "DSA", KEY_DSA, 0, 0 },
997#ifdef OPENSSL_HAS_ECC
998 { "ecdsa-sha2-nistp256", "ECDSA", KEY_ECDSA, NID_X9_62_prime256v1, 0 },
999 { "ecdsa-sha2-nistp384", "ECDSA", KEY_ECDSA, NID_secp384r1, 0 },
1000# ifdef OPENSSL_HAS_NISTP521
1001 { "ecdsa-sha2-nistp521", "ECDSA", KEY_ECDSA, NID_secp521r1, 0 },
1002# endif
1003#endif /* OPENSSL_HAS_ECC */
1004 { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", KEY_RSA_CERT, 0, 1 },
1005 { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", KEY_DSA_CERT, 0, 1 },
1006#ifdef OPENSSL_HAS_ECC
1007 { "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-CERT",
1008 KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1 },
1009 { "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA-CERT",
1010 KEY_ECDSA_CERT, NID_secp384r1, 1 },
1011# ifdef OPENSSL_HAS_NISTP521
1012 { "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT",
1013 KEY_ECDSA_CERT, NID_secp521r1, 1 },
1014# endif
1015#endif /* OPENSSL_HAS_ECC */
1016 { "ssh-rsa-cert-v00@openssh.com", "RSA-CERT-V00",
1017 KEY_RSA_CERT_V00, 0, 1 },
1018 { "ssh-dss-cert-v00@openssh.com", "DSA-CERT-V00",
1019 KEY_DSA_CERT_V00, 0, 1 },
1020#endif
1021 { "ssh-ed25519", "ED25519", KEY_ED25519, 0, 0 },
1022 { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT",
1023 KEY_ED25519_CERT, 0, 1 },
1024 { NULL, NULL, -1, -1, 0 }
1025};
1026
1027const char *
1028key_type(const Key *k)
1029{
1030 const struct keytype *kt;
1031
1032 for (kt = keytypes; kt->type != -1; kt++) {
1033 if (kt->type == k->type)
1034 return kt->shortname;
1035 }
1036 return "unknown";
1037}
1038
1039static const char *
1040key_ssh_name_from_type_nid(int type, int nid)
1041{
1042 const struct keytype *kt;
1043
1044 for (kt = keytypes; kt->type != -1; kt++) {
1045 if (kt->type == type && (kt->nid == 0 || kt->nid == nid))
1046 return kt->name;
1047 }
1048 return "ssh-unknown";
1049}
1050
1051const char *
1052key_ssh_name(const Key *k)
1053{
1054 return key_ssh_name_from_type_nid(k->type, k->ecdsa_nid);
1055}
1056
1057const char *
1058key_ssh_name_plain(const Key *k)
1059{
1060 return key_ssh_name_from_type_nid(key_type_plain(k->type),
1061 k->ecdsa_nid);
1062}
1063
1064int
1065key_type_from_name(char *name)
1066{
1067 const struct keytype *kt;
1068
1069 for (kt = keytypes; kt->type != -1; kt++) {
1070 /* Only allow shortname matches for plain key types */
1071 if ((kt->name != NULL && strcmp(name, kt->name) == 0) ||
1072 (!kt->cert && strcasecmp(kt->shortname, name) == 0))
1073 return kt->type;
1074 }
1075 debug2("key_type_from_name: unknown key type '%s'", name);
1076 return KEY_UNSPEC;
1077}
1078
1079int
1080key_ecdsa_nid_from_name(const char *name)
1081{
1082 const struct keytype *kt;
1083
1084 for (kt = keytypes; kt->type != -1; kt++) {
1085 if (kt->type != KEY_ECDSA && kt->type != KEY_ECDSA_CERT)
1086 continue;
1087 if (kt->name != NULL && strcmp(name, kt->name) == 0)
1088 return kt->nid;
1089 }
1090 debug2("%s: unknown/non-ECDSA key type '%s'", __func__, name);
1091 return -1;
1092}
1093
1094char *
1095key_alg_list(int certs_only, int plain_only)
1096{
1097 char *ret = NULL;
1098 size_t nlen, rlen = 0;
1099 const struct keytype *kt;
1100
1101 for (kt = keytypes; kt->type != -1; kt++) {
1102 if (kt->name == NULL)
1103 continue;
1104 if ((certs_only && !kt->cert) || (plain_only && kt->cert))
1105 continue;
1106 if (ret != NULL)
1107 ret[rlen++] = '\n';
1108 nlen = strlen(kt->name);
1109 ret = xrealloc(ret, 1, rlen + nlen + 2);
1110 memcpy(ret + rlen, kt->name, nlen + 1);
1111 rlen += nlen;
1112 }
1113 return ret;
1114}
1115
1116int
1117key_type_is_cert(int type)
1118{
1119 const struct keytype *kt;
1120
1121 for (kt = keytypes; kt->type != -1; kt++) {
1122 if (kt->type == type)
1123 return kt->cert;
1124 }
1125 return 0;
1126}
1127
1128static int
1129key_type_is_valid_ca(int type)
1130{
1131 switch (type) {
1132 case KEY_RSA:
1133 case KEY_DSA:
1134 case KEY_ECDSA:
1135 case KEY_ED25519:
1136 return 1;
1137 default:
1138 return 0;
1139 }
1140}
1141
1142u_int
1143key_size(const Key *k)
1144{
1145 switch (k->type) {
1146#ifdef WITH_OPENSSL
1147 case KEY_RSA1:
1148 case KEY_RSA:
1149 case KEY_RSA_CERT_V00:
1150 case KEY_RSA_CERT:
1151 return BN_num_bits(k->rsa->n);
1152 case KEY_DSA:
1153 case KEY_DSA_CERT_V00:
1154 case KEY_DSA_CERT:
1155 return BN_num_bits(k->dsa->p);
1156#ifdef OPENSSL_HAS_ECC
1157 case KEY_ECDSA:
1158 case KEY_ECDSA_CERT:
1159 return key_curve_nid_to_bits(k->ecdsa_nid);
1160#endif
1161#endif
1162 case KEY_ED25519:
1163 return 256; /* XXX */
1164 }
1165 return 0;
1166}
1167
1168#ifdef WITH_OPENSSL
1169static RSA *
1170rsa_generate_private_key(u_int bits)
1171{
1172 RSA *private = RSA_new();
1173 BIGNUM *f4 = BN_new();
1174
1175 if (private == NULL)
1176 fatal("%s: RSA_new failed", __func__);
1177 if (f4 == NULL)
1178 fatal("%s: BN_new failed", __func__);
1179 if (!BN_set_word(f4, RSA_F4))
1180 fatal("%s: BN_new failed", __func__);
1181 if (!RSA_generate_key_ex(private, bits, f4, NULL))
1182 fatal("%s: key generation failed.", __func__);
1183 BN_free(f4);
1184 return private;
1185}
1186
1187static DSA*
1188dsa_generate_private_key(u_int bits)
1189{
1190 DSA *private = DSA_new();
1191
1192 if (private == NULL)
1193 fatal("%s: DSA_new failed", __func__);
1194 if (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL,
1195 NULL, NULL))
1196 fatal("%s: DSA_generate_parameters failed", __func__);
1197 if (!DSA_generate_key(private))
1198 fatal("%s: DSA_generate_key failed.", __func__);
1199 return private;
1200}
1201
1202int
1203key_ecdsa_bits_to_nid(int bits)
1204{
1205 switch (bits) {
1206#ifdef OPENSSL_HAS_ECC
1207 case 256:
1208 return NID_X9_62_prime256v1;
1209 case 384:
1210 return NID_secp384r1;
1211# ifdef OPENSSL_HAS_NISTP521
1212 case 521:
1213 return NID_secp521r1;
1214# endif
1215#endif
1216 default:
1217 return -1;
1218 }
1219}
1220
1221#ifdef OPENSSL_HAS_ECC
1222int
1223key_ecdsa_key_to_nid(EC_KEY *k)
1224{
1225 EC_GROUP *eg;
1226 int nids[] = {
1227 NID_X9_62_prime256v1,
1228 NID_secp384r1,
1229# ifdef OPENSSL_HAS_NISTP521
1230 NID_secp521r1,
1231# endif
1232 -1
1233 };
1234 int nid;
1235 u_int i;
1236 BN_CTX *bnctx;
1237 const EC_GROUP *g = EC_KEY_get0_group(k);
1238
1239 /*
1240 * The group may be stored in a ASN.1 encoded private key in one of two
1241 * ways: as a "named group", which is reconstituted by ASN.1 object ID
1242 * or explicit group parameters encoded into the key blob. Only the
1243 * "named group" case sets the group NID for us, but we can figure
1244 * it out for the other case by comparing against all the groups that
1245 * are supported.
1246 */
1247 if ((nid = EC_GROUP_get_curve_name(g)) > 0)
1248 return nid;
1249 if ((bnctx = BN_CTX_new()) == NULL)
1250 fatal("%s: BN_CTX_new() failed", __func__);
1251 for (i = 0; nids[i] != -1; i++) {
1252 if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL)
1253 fatal("%s: EC_GROUP_new_by_curve_name failed",
1254 __func__);
1255 if (EC_GROUP_cmp(g, eg, bnctx) == 0)
1256 break;
1257 EC_GROUP_free(eg);
1258 }
1259 BN_CTX_free(bnctx);
1260 debug3("%s: nid = %d", __func__, nids[i]);
1261 if (nids[i] != -1) {
1262 /* Use the group with the NID attached */
1263 EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE);
1264 if (EC_KEY_set_group(k, eg) != 1)
1265 fatal("%s: EC_KEY_set_group", __func__);
1266 }
1267 return nids[i];
1268} 70}
1269 71
1270static EC_KEY*
1271ecdsa_generate_private_key(u_int bits, int *nid)
1272{
1273 EC_KEY *private;
1274
1275 if ((*nid = key_ecdsa_bits_to_nid(bits)) == -1)
1276 fatal("%s: invalid key length", __func__);
1277 if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL)
1278 fatal("%s: EC_KEY_new_by_curve_name failed", __func__);
1279 if (EC_KEY_generate_key(private) != 1)
1280 fatal("%s: EC_KEY_generate_key failed", __func__);
1281 EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE);
1282 return private;
1283}
1284#endif /* OPENSSL_HAS_ECC */
1285#endif /* WITH_OPENSSL */
1286
1287Key * 72Key *
1288key_generate(int type, u_int bits) 73key_generate(int type, u_int bits)
1289{ 74{
1290 Key *k = key_new(KEY_UNSPEC); 75 int r;
1291 switch (type) { 76 Key *ret = NULL;
1292#ifdef WITH_OPENSSL 77
1293 case KEY_DSA: 78 if ((r = sshkey_generate(type, bits, &ret)) != 0)
1294 k->dsa = dsa_generate_private_key(bits); 79 fatal("%s: %s", __func__, ssh_err(r));
1295 break; 80 return ret;
1296#ifdef OPENSSL_HAS_ECC
1297 case KEY_ECDSA:
1298 k->ecdsa = ecdsa_generate_private_key(bits, &k->ecdsa_nid);
1299 break;
1300#endif
1301 case KEY_RSA:
1302 case KEY_RSA1:
1303 k->rsa = rsa_generate_private_key(bits);
1304 break;
1305#endif
1306 case KEY_RSA_CERT_V00:
1307 case KEY_DSA_CERT_V00:
1308 case KEY_RSA_CERT:
1309 case KEY_DSA_CERT:
1310 fatal("key_generate: cert keys cannot be generated directly");
1311#endif
1312 case KEY_ED25519:
1313 k->ed25519_pk = xmalloc(ED25519_PK_SZ);
1314 k->ed25519_sk = xmalloc(ED25519_SK_SZ);
1315 crypto_sign_ed25519_keypair(k->ed25519_pk, k->ed25519_sk);
1316 break;
1317 default:
1318 fatal("key_generate: unknown type %d", type);
1319 }
1320 k->type = type;
1321 return k;
1322} 81}
1323 82
1324void 83void
1325key_cert_copy(const Key *from_key, struct Key *to_key) 84key_cert_copy(const Key *from_key, Key *to_key)
1326{ 85{
1327 u_int i; 86 int r;
1328 const struct KeyCert *from;
1329 struct KeyCert *to;
1330
1331 if (to_key->cert != NULL) {
1332 cert_free(to_key->cert);
1333 to_key->cert = NULL;
1334 }
1335 87
1336 if ((from = from_key->cert) == NULL) 88 if ((r = sshkey_cert_copy(from_key, to_key)) != 0)
1337 return; 89 fatal("%s: %s", __func__, ssh_err(r));
1338
1339 to = to_key->cert = cert_new();
1340
1341 buffer_append(&to->certblob, buffer_ptr(&from->certblob),
1342 buffer_len(&from->certblob));
1343
1344 buffer_append(&to->critical,
1345 buffer_ptr(&from->critical), buffer_len(&from->critical));
1346 buffer_append(&to->extensions,
1347 buffer_ptr(&from->extensions), buffer_len(&from->extensions));
1348
1349 to->serial = from->serial;
1350 to->type = from->type;
1351 to->key_id = from->key_id == NULL ? NULL : xstrdup(from->key_id);
1352 to->valid_after = from->valid_after;
1353 to->valid_before = from->valid_before;
1354 to->signature_key = from->signature_key == NULL ?
1355 NULL : key_from_private(from->signature_key);
1356
1357 to->nprincipals = from->nprincipals;
1358 if (to->nprincipals > CERT_MAX_PRINCIPALS)
1359 fatal("%s: nprincipals (%u) > CERT_MAX_PRINCIPALS (%u)",
1360 __func__, to->nprincipals, CERT_MAX_PRINCIPALS);
1361 if (to->nprincipals > 0) {
1362 to->principals = xcalloc(from->nprincipals,
1363 sizeof(*to->principals));
1364 for (i = 0; i < to->nprincipals; i++)
1365 to->principals[i] = xstrdup(from->principals[i]);
1366 }
1367} 90}
1368 91
1369Key * 92Key *
1370key_from_private(const Key *k) 93key_from_private(const Key *k)
1371{ 94{
1372 Key *n = NULL; 95 int r;
1373 switch (k->type) { 96 Key *ret = NULL;
1374#ifdef WITH_OPENSSL
1375 case KEY_DSA:
1376 case KEY_DSA_CERT_V00:
1377 case KEY_DSA_CERT:
1378 n = key_new(k->type);
1379 if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) ||
1380 (BN_copy(n->dsa->q, k->dsa->q) == NULL) ||
1381 (BN_copy(n->dsa->g, k->dsa->g) == NULL) ||
1382 (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL))
1383 fatal("key_from_private: BN_copy failed");
1384 break;
1385#ifdef OPENSSL_HAS_ECC
1386 case KEY_ECDSA:
1387 case KEY_ECDSA_CERT:
1388 n = key_new(k->type);
1389 n->ecdsa_nid = k->ecdsa_nid;
1390 if ((n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid)) == NULL)
1391 fatal("%s: EC_KEY_new_by_curve_name failed", __func__);
1392 if (EC_KEY_set_public_key(n->ecdsa,
1393 EC_KEY_get0_public_key(k->ecdsa)) != 1)
1394 fatal("%s: EC_KEY_set_public_key failed", __func__);
1395 break;
1396#endif
1397 case KEY_RSA:
1398 case KEY_RSA1:
1399 case KEY_RSA_CERT_V00:
1400 case KEY_RSA_CERT:
1401 n = key_new(k->type);
1402 if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||
1403 (BN_copy(n->rsa->e, k->rsa->e) == NULL))
1404 fatal("key_from_private: BN_copy failed");
1405 break;
1406#endif
1407 case KEY_ED25519:
1408 case KEY_ED25519_CERT:
1409 n = key_new(k->type);
1410 if (k->ed25519_pk != NULL) {
1411 n->ed25519_pk = xmalloc(ED25519_PK_SZ);
1412 memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
1413 }
1414 break;
1415 default:
1416 fatal("key_from_private: unknown type %d", k->type);
1417 break;
1418 }
1419 if (key_is_cert(k))
1420 key_cert_copy(k, n);
1421 return n;
1422}
1423
1424int
1425key_names_valid2(const char *names)
1426{
1427 char *s, *cp, *p;
1428
1429 if (names == NULL || strcmp(names, "") == 0)
1430 return 0;
1431 s = cp = xstrdup(names);
1432 for ((p = strsep(&cp, ",")); p && *p != '\0';
1433 (p = strsep(&cp, ","))) {
1434 switch (key_type_from_name(p)) {
1435 case KEY_RSA1:
1436 case KEY_UNSPEC:
1437 free(s);
1438 return 0;
1439 }
1440 }
1441 debug3("key names ok: [%s]", names);
1442 free(s);
1443 return 1;
1444}
1445
1446static int
1447cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen)
1448{
1449 u_char *principals, *critical, *exts, *sig_key, *sig;
1450 u_int signed_len, plen, clen, sklen, slen, kidlen, elen;
1451 Buffer tmp;
1452 char *principal;
1453 int ret = -1;
1454 int v00 = key->type == KEY_DSA_CERT_V00 ||
1455 key->type == KEY_RSA_CERT_V00;
1456
1457 buffer_init(&tmp);
1458
1459 /* Copy the entire key blob for verification and later serialisation */
1460 buffer_append(&key->cert->certblob, blob, blen);
1461
1462 elen = 0; /* Not touched for v00 certs */
1463 principals = exts = critical = sig_key = sig = NULL;
1464 if ((!v00 && buffer_get_int64_ret(&key->cert->serial, b) != 0) ||
1465 buffer_get_int_ret(&key->cert->type, b) != 0 ||
1466 (key->cert->key_id = buffer_get_cstring_ret(b, &kidlen)) == NULL ||
1467 (principals = buffer_get_string_ret(b, &plen)) == NULL ||
1468 buffer_get_int64_ret(&key->cert->valid_after, b) != 0 ||
1469 buffer_get_int64_ret(&key->cert->valid_before, b) != 0 ||
1470 (critical = buffer_get_string_ret(b, &clen)) == NULL ||
1471 (!v00 && (exts = buffer_get_string_ret(b, &elen)) == NULL) ||
1472 (v00 && buffer_get_string_ptr_ret(b, NULL) == NULL) || /* nonce */
1473 buffer_get_string_ptr_ret(b, NULL) == NULL || /* reserved */
1474 (sig_key = buffer_get_string_ret(b, &sklen)) == NULL) {
1475 error("%s: parse error", __func__);
1476 goto out;
1477 }
1478
1479 /* Signature is left in the buffer so we can calculate this length */
1480 signed_len = buffer_len(&key->cert->certblob) - buffer_len(b);
1481
1482 if ((sig = buffer_get_string_ret(b, &slen)) == NULL) {
1483 error("%s: parse error", __func__);
1484 goto out;
1485 }
1486
1487 if (key->cert->type != SSH2_CERT_TYPE_USER &&
1488 key->cert->type != SSH2_CERT_TYPE_HOST) {
1489 error("Unknown certificate type %u", key->cert->type);
1490 goto out;
1491 }
1492
1493 buffer_append(&tmp, principals, plen);
1494 while (buffer_len(&tmp) > 0) {
1495 if (key->cert->nprincipals >= CERT_MAX_PRINCIPALS) {
1496 error("%s: Too many principals", __func__);
1497 goto out;
1498 }
1499 if ((principal = buffer_get_cstring_ret(&tmp, &plen)) == NULL) {
1500 error("%s: Principals data invalid", __func__);
1501 goto out;
1502 }
1503 key->cert->principals = xrealloc(key->cert->principals,
1504 key->cert->nprincipals + 1, sizeof(*key->cert->principals));
1505 key->cert->principals[key->cert->nprincipals++] = principal;
1506 }
1507
1508 buffer_clear(&tmp);
1509
1510 buffer_append(&key->cert->critical, critical, clen);
1511 buffer_append(&tmp, critical, clen);
1512 /* validate structure */
1513 while (buffer_len(&tmp) != 0) {
1514 if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL ||
1515 buffer_get_string_ptr_ret(&tmp, NULL) == NULL) {
1516 error("%s: critical option data invalid", __func__);
1517 goto out;
1518 }
1519 }
1520 buffer_clear(&tmp);
1521
1522 buffer_append(&key->cert->extensions, exts, elen);
1523 buffer_append(&tmp, exts, elen);
1524 /* validate structure */
1525 while (buffer_len(&tmp) != 0) {
1526 if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL ||
1527 buffer_get_string_ptr_ret(&tmp, NULL) == NULL) {
1528 error("%s: extension data invalid", __func__);
1529 goto out;
1530 }
1531 }
1532 buffer_clear(&tmp);
1533
1534 if ((key->cert->signature_key = key_from_blob2(sig_key, sklen, 0))
1535 == NULL) {
1536 error("%s: Signature key invalid", __func__);
1537 goto out;
1538 }
1539 if (!key_type_is_valid_ca(key->cert->signature_key->type)) {
1540 error("%s: Invalid signature key type %s (%d)", __func__,
1541 key_type(key->cert->signature_key),
1542 key->cert->signature_key->type);
1543 goto out;
1544 }
1545 97
1546 switch (key_verify(key->cert->signature_key, sig, slen, 98 if ((r = sshkey_from_private(k, &ret)) != 0)
1547 buffer_ptr(&key->cert->certblob), signed_len)) { 99 fatal("%s: %s", __func__, ssh_err(r));
1548 case 1:
1549 ret = 0;
1550 break; /* Good signature */
1551 case 0:
1552 error("%s: Invalid signature on certificate", __func__);
1553 goto out;
1554 case -1:
1555 error("%s: Certificate signature verification failed",
1556 __func__);
1557 goto out;
1558 }
1559
1560 out:
1561 buffer_free(&tmp);
1562 free(principals);
1563 free(critical);
1564 free(exts);
1565 free(sig_key);
1566 free(sig);
1567 return ret; 100 return ret;
1568} 101}
1569 102
1570static Key * 103static void
1571key_from_blob2(const u_char *blob, u_int blen, int allow_cert) 104fatal_on_fatal_errors(int r, const char *func, int extra_fatal)
1572{ 105{
1573 Buffer b; 106 if (r == SSH_ERR_INTERNAL_ERROR ||
1574 int rlen, type; 107 r == SSH_ERR_ALLOC_FAIL ||
1575 u_int len; 108 (extra_fatal != 0 && r == extra_fatal))
1576 char *ktype = NULL, *curve = NULL; 109 fatal("%s: %s", func, ssh_err(r));
1577 u_char *pk = NULL;
1578 Key *key = NULL;
1579#ifdef OPENSSL_HAS_ECC
1580 EC_POINT *q = NULL;
1581 int nid = -1;
1582#endif
1583
1584#ifdef DEBUG_PK
1585 dump_base64(stderr, blob, blen);
1586#endif
1587 buffer_init(&b);
1588 buffer_append(&b, blob, blen);
1589 if ((ktype = buffer_get_cstring_ret(&b, NULL)) == NULL) {
1590 error("key_from_blob: can't read key type");
1591 goto out;
1592 }
1593
1594 type = key_type_from_name(ktype);
1595#ifdef OPENSSL_HAS_ECC
1596 if (key_type_plain(type) == KEY_ECDSA)
1597 nid = key_ecdsa_nid_from_name(ktype);
1598#endif
1599 if (!allow_cert && key_type_is_cert(type)) {
1600 error("key_from_blob: certificate not allowed in this context");
1601 goto out;
1602 }
1603 switch (type) {
1604#ifdef WITH_OPENSSL
1605 case KEY_RSA_CERT:
1606 (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */
1607 /* FALLTHROUGH */
1608 case KEY_RSA:
1609 case KEY_RSA_CERT_V00:
1610 key = key_new(type);
1611 if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 ||
1612 buffer_get_bignum2_ret(&b, key->rsa->n) == -1) {
1613 error("key_from_blob: can't read rsa key");
1614 goto badkey;
1615 }
1616#ifdef DEBUG_PK
1617 RSA_print_fp(stderr, key->rsa, 8);
1618#endif
1619 break;
1620 case KEY_DSA_CERT:
1621 (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */
1622 /* FALLTHROUGH */
1623 case KEY_DSA:
1624 case KEY_DSA_CERT_V00:
1625 key = key_new(type);
1626 if (buffer_get_bignum2_ret(&b, key->dsa->p) == -1 ||
1627 buffer_get_bignum2_ret(&b, key->dsa->q) == -1 ||
1628 buffer_get_bignum2_ret(&b, key->dsa->g) == -1 ||
1629 buffer_get_bignum2_ret(&b, key->dsa->pub_key) == -1) {
1630 error("key_from_blob: can't read dsa key");
1631 goto badkey;
1632 }
1633#ifdef DEBUG_PK
1634 DSA_print_fp(stderr, key->dsa, 8);
1635#endif
1636 break;
1637#ifdef OPENSSL_HAS_ECC
1638 case KEY_ECDSA_CERT:
1639 (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */
1640 /* FALLTHROUGH */
1641 case KEY_ECDSA:
1642 key = key_new(type);
1643 key->ecdsa_nid = nid;
1644 if ((curve = buffer_get_string_ret(&b, NULL)) == NULL) {
1645 error("key_from_blob: can't read ecdsa curve");
1646 goto badkey;
1647 }
1648 if (key->ecdsa_nid != key_curve_name_to_nid(curve)) {
1649 error("key_from_blob: ecdsa curve doesn't match type");
1650 goto badkey;
1651 }
1652 if (key->ecdsa != NULL)
1653 EC_KEY_free(key->ecdsa);
1654 if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid))
1655 == NULL)
1656 fatal("key_from_blob: EC_KEY_new_by_curve_name failed");
1657 if ((q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL)
1658 fatal("key_from_blob: EC_POINT_new failed");
1659 if (buffer_get_ecpoint_ret(&b, EC_KEY_get0_group(key->ecdsa),
1660 q) == -1) {
1661 error("key_from_blob: can't read ecdsa key point");
1662 goto badkey;
1663 }
1664 if (key_ec_validate_public(EC_KEY_get0_group(key->ecdsa),
1665 q) != 0)
1666 goto badkey;
1667 if (EC_KEY_set_public_key(key->ecdsa, q) != 1)
1668 fatal("key_from_blob: EC_KEY_set_public_key failed");
1669#ifdef DEBUG_PK
1670 key_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q);
1671#endif
1672 break;
1673#endif /* OPENSSL_HAS_ECC */
1674 case KEY_ED25519_CERT:
1675 (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */
1676 /* FALLTHROUGH */
1677 case KEY_ED25519:
1678 if ((pk = buffer_get_string_ret(&b, &len)) == NULL) {
1679 error("key_from_blob: can't read ed25519 key");
1680 goto badkey;
1681 }
1682 if (len != ED25519_PK_SZ) {
1683 error("key_from_blob: ed25519 len %d != %d",
1684 len, ED25519_PK_SZ);
1685 goto badkey;
1686 }
1687 key = key_new(type);
1688 key->ed25519_pk = pk;
1689 pk = NULL;
1690 break;
1691 case KEY_UNSPEC:
1692 key = key_new(type);
1693 break;
1694 default:
1695 error("key_from_blob: cannot handle type %s", ktype);
1696 goto out;
1697 }
1698 if (key_is_cert(key) && cert_parse(&b, key, blob, blen) == -1) {
1699 error("key_from_blob: can't parse cert data");
1700 goto badkey;
1701 }
1702 rlen = buffer_len(&b);
1703 if (key != NULL && rlen != 0)
1704 error("key_from_blob: remaining bytes in key blob %d", rlen);
1705 out:
1706 free(ktype);
1707 free(curve);
1708 free(pk);
1709#ifdef OPENSSL_HAS_ECC
1710 if (q != NULL)
1711 EC_POINT_free(q);
1712#endif
1713 buffer_free(&b);
1714 return key;
1715
1716 badkey:
1717 key_free(key);
1718 key = NULL;
1719 goto out;
1720} 110}
1721 111
1722Key * 112Key *
1723key_from_blob(const u_char *blob, u_int blen) 113key_from_blob(const u_char *blob, u_int blen)
1724{ 114{
1725 return key_from_blob2(blob, blen, 1); 115 int r;
116 Key *ret = NULL;
117
118 if ((r = sshkey_from_blob(blob, blen, &ret)) != 0) {
119 fatal_on_fatal_errors(r, __func__, 0);
120 error("%s: %s", __func__, ssh_err(r));
121 return NULL;
122 }
123 return ret;
1726} 124}
1727 125
1728static int 126int
1729to_blob(const Key *key, u_char **blobp, u_int *lenp, int force_plain) 127key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
1730{ 128{
1731 Buffer b; 129 u_char *blob;
1732 int len, type; 130 size_t blen;
131 int r;
1733 132
1734 if (blobp != NULL) 133 if (blobp != NULL)
1735 *blobp = NULL; 134 *blobp = NULL;
1736 if (lenp != NULL) 135 if (lenp != NULL)
1737 *lenp = 0; 136 *lenp = 0;
1738 if (key == NULL) { 137 if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) {
1739 error("key_to_blob: key == NULL"); 138 fatal_on_fatal_errors(r, __func__, 0);
139 error("%s: %s", __func__, ssh_err(r));
1740 return 0; 140 return 0;
1741 } 141 }
1742 buffer_init(&b); 142 if (blen > INT_MAX)
1743 type = force_plain ? key_type_plain(key->type) : key->type; 143 fatal("%s: giant len %zu", __func__, blen);
1744 switch (type) { 144 if (blobp != NULL)
1745#ifdef WITH_OPENSSL 145 *blobp = blob;
1746 case KEY_DSA_CERT_V00:
1747 case KEY_RSA_CERT_V00:
1748 case KEY_DSA_CERT:
1749 case KEY_ECDSA_CERT:
1750 case KEY_RSA_CERT:
1751#endif
1752 case KEY_ED25519_CERT:
1753 /* Use the existing blob */
1754 buffer_append(&b, buffer_ptr(&key->cert->certblob),
1755 buffer_len(&key->cert->certblob));
1756 break;
1757#ifdef WITH_OPENSSL
1758 case KEY_DSA:
1759 buffer_put_cstring(&b,
1760 key_ssh_name_from_type_nid(type, key->ecdsa_nid));
1761 buffer_put_bignum2(&b, key->dsa->p);
1762 buffer_put_bignum2(&b, key->dsa->q);
1763 buffer_put_bignum2(&b, key->dsa->g);
1764 buffer_put_bignum2(&b, key->dsa->pub_key);
1765 break;
1766#ifdef OPENSSL_HAS_ECC
1767 case KEY_ECDSA:
1768 buffer_put_cstring(&b,
1769 key_ssh_name_from_type_nid(type, key->ecdsa_nid));
1770 buffer_put_cstring(&b, key_curve_nid_to_name(key->ecdsa_nid));
1771 buffer_put_ecpoint(&b, EC_KEY_get0_group(key->ecdsa),
1772 EC_KEY_get0_public_key(key->ecdsa));
1773 break;
1774#endif
1775 case KEY_RSA:
1776 buffer_put_cstring(&b,
1777 key_ssh_name_from_type_nid(type, key->ecdsa_nid));
1778 buffer_put_bignum2(&b, key->rsa->e);
1779 buffer_put_bignum2(&b, key->rsa->n);
1780 break;
1781#endif
1782 case KEY_ED25519:
1783 buffer_put_cstring(&b,
1784 key_ssh_name_from_type_nid(type, key->ecdsa_nid));
1785 buffer_put_string(&b, key->ed25519_pk, ED25519_PK_SZ);
1786 break;
1787 default:
1788 error("key_to_blob: unsupported key type %d", key->type);
1789 buffer_free(&b);
1790 return 0;
1791 }
1792 len = buffer_len(&b);
1793 if (lenp != NULL) 146 if (lenp != NULL)
1794 *lenp = len; 147 *lenp = blen;
1795 if (blobp != NULL) { 148 return blen;
1796 *blobp = xmalloc(len);
1797 memcpy(*blobp, buffer_ptr(&b), len);
1798 }
1799 explicit_bzero(buffer_ptr(&b), len);
1800 buffer_free(&b);
1801 return len;
1802} 149}
1803 150
1804int 151int
1805key_to_blob(const Key *key, u_char **blobp, u_int *lenp) 152key_sign(const Key *key, u_char **sigp, u_int *lenp,
1806{
1807 return to_blob(key, blobp, lenp, 0);
1808}
1809
1810int
1811key_sign(
1812 const Key *key,
1813 u_char **sigp, u_int *lenp,
1814 const u_char *data, u_int datalen) 153 const u_char *data, u_int datalen)
1815{ 154{
1816 switch (key->type) { 155 int r;
1817#ifdef WITH_OPENSSL 156 u_char *sig;
1818 case KEY_DSA_CERT_V00: 157 size_t siglen;
1819 case KEY_DSA_CERT: 158
1820 case KEY_DSA: 159 if (sigp != NULL)
1821 return ssh_dss_sign(key, sigp, lenp, data, datalen); 160 *sigp = NULL;
1822#ifdef OPENSSL_HAS_ECC 161 if (lenp != NULL)
1823 case KEY_ECDSA_CERT: 162 *lenp = 0;
1824 case KEY_ECDSA: 163 if ((r = sshkey_sign(key, &sig, &siglen,
1825 return ssh_ecdsa_sign(key, sigp, lenp, data, datalen); 164 data, datalen, datafellows)) != 0) {
1826#endif 165 fatal_on_fatal_errors(r, __func__, 0);
1827 case KEY_RSA_CERT_V00: 166 error("%s: %s", __func__, ssh_err(r));
1828 case KEY_RSA_CERT:
1829 case KEY_RSA:
1830 return ssh_rsa_sign(key, sigp, lenp, data, datalen);
1831#endif
1832 case KEY_ED25519:
1833 case KEY_ED25519_CERT:
1834 return ssh_ed25519_sign(key, sigp, lenp, data, datalen);
1835 default:
1836 error("key_sign: invalid key type %d", key->type);
1837 return -1; 167 return -1;
1838 } 168 }
169 if (siglen > INT_MAX)
170 fatal("%s: giant len %zu", __func__, siglen);
171 if (sigp != NULL)
172 *sigp = sig;
173 if (lenp != NULL)
174 *lenp = siglen;
175 return 0;
1839} 176}
1840 177
1841/*
1842 * key_verify returns 1 for a correct signature, 0 for an incorrect signature
1843 * and -1 on error.
1844 */
1845int 178int
1846key_verify( 179key_verify(const Key *key, const u_char *signature, u_int signaturelen,
1847 const Key *key,
1848 const u_char *signature, u_int signaturelen,
1849 const u_char *data, u_int datalen) 180 const u_char *data, u_int datalen)
1850{ 181{
1851 if (signaturelen == 0) 182 int r;
1852 return -1;
1853 183
1854 switch (key->type) { 184 if ((r = sshkey_verify(key, signature, signaturelen,
1855#ifdef WITH_OPENSSL 185 data, datalen, datafellows)) != 0) {
1856 case KEY_DSA_CERT_V00: 186 fatal_on_fatal_errors(r, __func__, 0);
1857 case KEY_DSA_CERT: 187 error("%s: %s", __func__, ssh_err(r));
1858 case KEY_DSA: 188 return r == SSH_ERR_SIGNATURE_INVALID ? 0 : -1;
1859 return ssh_dss_verify(key, signature, signaturelen, data, datalen);
1860#ifdef OPENSSL_HAS_ECC
1861 case KEY_ECDSA_CERT:
1862 case KEY_ECDSA:
1863 return ssh_ecdsa_verify(key, signature, signaturelen, data, datalen);
1864#endif
1865 case KEY_RSA_CERT_V00:
1866 case KEY_RSA_CERT:
1867 case KEY_RSA:
1868 return ssh_rsa_verify(key, signature, signaturelen, data, datalen);
1869#endif
1870 case KEY_ED25519:
1871 case KEY_ED25519_CERT:
1872 return ssh_ed25519_verify(key, signature, signaturelen, data, datalen);
1873 default:
1874 error("key_verify: invalid key type %d", key->type);
1875 return -1;
1876 } 189 }
190 return 1;
1877} 191}
1878 192
1879/* Converts a private to a public key */
1880Key * 193Key *
1881key_demote(const Key *k) 194key_demote(const Key *k)
1882{ 195{
1883 Key *pk; 196 int r;
1884 197 Key *ret = NULL;
1885 pk = xcalloc(1, sizeof(*pk));
1886 pk->type = k->type;
1887 pk->flags = k->flags;
1888 pk->ecdsa_nid = k->ecdsa_nid;
1889 pk->dsa = NULL;
1890 pk->ecdsa = NULL;
1891 pk->rsa = NULL;
1892 pk->ed25519_pk = NULL;
1893 pk->ed25519_sk = NULL;
1894
1895 switch (k->type) {
1896#ifdef WITH_OPENSSL
1897 case KEY_RSA_CERT_V00:
1898 case KEY_RSA_CERT:
1899 key_cert_copy(k, pk);
1900 /* FALLTHROUGH */
1901 case KEY_RSA1:
1902 case KEY_RSA:
1903 if ((pk->rsa = RSA_new()) == NULL)
1904 fatal("key_demote: RSA_new failed");
1905 if ((pk->rsa->e = BN_dup(k->rsa->e)) == NULL)
1906 fatal("key_demote: BN_dup failed");
1907 if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL)
1908 fatal("key_demote: BN_dup failed");
1909 break;
1910 case KEY_DSA_CERT_V00:
1911 case KEY_DSA_CERT:
1912 key_cert_copy(k, pk);
1913 /* FALLTHROUGH */
1914 case KEY_DSA:
1915 if ((pk->dsa = DSA_new()) == NULL)
1916 fatal("key_demote: DSA_new failed");
1917 if ((pk->dsa->p = BN_dup(k->dsa->p)) == NULL)
1918 fatal("key_demote: BN_dup failed");
1919 if ((pk->dsa->q = BN_dup(k->dsa->q)) == NULL)
1920 fatal("key_demote: BN_dup failed");
1921 if ((pk->dsa->g = BN_dup(k->dsa->g)) == NULL)
1922 fatal("key_demote: BN_dup failed");
1923 if ((pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL)
1924 fatal("key_demote: BN_dup failed");
1925 break;
1926#ifdef OPENSSL_HAS_ECC
1927 case KEY_ECDSA_CERT:
1928 key_cert_copy(k, pk);
1929 /* FALLTHROUGH */
1930 case KEY_ECDSA:
1931 if ((pk->ecdsa = EC_KEY_new_by_curve_name(pk->ecdsa_nid)) == NULL)
1932 fatal("key_demote: EC_KEY_new_by_curve_name failed");
1933 if (EC_KEY_set_public_key(pk->ecdsa,
1934 EC_KEY_get0_public_key(k->ecdsa)) != 1)
1935 fatal("key_demote: EC_KEY_set_public_key failed");
1936 break;
1937#endif
1938 case KEY_ED25519_CERT:
1939 key_cert_copy(k, pk);
1940 /* FALLTHROUGH */
1941 case KEY_ED25519:
1942 if (k->ed25519_pk != NULL) {
1943 pk->ed25519_pk = xmalloc(ED25519_PK_SZ);
1944 memcpy(pk->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
1945 }
1946 break;
1947 default:
1948 fatal("key_demote: bad key type %d", k->type);
1949 break;
1950 }
1951
1952 return (pk);
1953}
1954
1955int
1956key_is_cert(const Key *k)
1957{
1958 if (k == NULL)
1959 return 0;
1960 return key_type_is_cert(k->type);
1961}
1962 198
1963/* Return the cert-less equivalent to a certified key type */ 199 if ((r = sshkey_demote(k, &ret)) != 0)
1964int 200 fatal("%s: %s", __func__, ssh_err(r));
1965key_type_plain(int type) 201 return ret;
1966{
1967 switch (type) {
1968 case KEY_RSA_CERT_V00:
1969 case KEY_RSA_CERT:
1970 return KEY_RSA;
1971 case KEY_DSA_CERT_V00:
1972 case KEY_DSA_CERT:
1973 return KEY_DSA;
1974 case KEY_ECDSA_CERT:
1975 return KEY_ECDSA;
1976 case KEY_ED25519_CERT:
1977 return KEY_ED25519;
1978 default:
1979 return type;
1980 }
1981} 202}
1982 203
1983/* Convert a plain key to their _CERT equivalent */
1984int 204int
1985key_to_certified(Key *k, int legacy) 205key_to_certified(Key *k, int legacy)
1986{ 206{
1987 switch (k->type) { 207 int r;
1988 case KEY_RSA: 208
1989 k->cert = cert_new(); 209 if ((r = sshkey_to_certified(k, legacy)) != 0) {
1990 k->type = legacy ? KEY_RSA_CERT_V00 : KEY_RSA_CERT; 210 fatal_on_fatal_errors(r, __func__, 0);
1991 return 0; 211 error("%s: %s", __func__, ssh_err(r));
1992 case KEY_DSA:
1993 k->cert = cert_new();
1994 k->type = legacy ? KEY_DSA_CERT_V00 : KEY_DSA_CERT;
1995 return 0;
1996 case KEY_ECDSA:
1997 if (legacy)
1998 fatal("%s: legacy ECDSA certificates are not supported",
1999 __func__);
2000 k->cert = cert_new();
2001 k->type = KEY_ECDSA_CERT;
2002 return 0;
2003 case KEY_ED25519:
2004 if (legacy)
2005 fatal("%s: legacy ED25519 certificates are not "
2006 "supported", __func__);
2007 k->cert = cert_new();
2008 k->type = KEY_ED25519_CERT;
2009 return 0;
2010 default:
2011 error("%s: key has incorrect type %s", __func__, key_type(k));
2012 return -1; 212 return -1;
2013 } 213 }
214 return 0;
2014} 215}
2015 216
2016/* Convert a certificate to its raw key equivalent */
2017int 217int
2018key_drop_cert(Key *k) 218key_drop_cert(Key *k)
2019{ 219{
2020 if (!key_type_is_cert(k->type)) { 220 int r;
2021 error("%s: key has incorrect type %s", __func__, key_type(k)); 221
222 if ((r = sshkey_drop_cert(k)) != 0) {
223 fatal_on_fatal_errors(r, __func__, 0);
224 error("%s: %s", __func__, ssh_err(r));
2022 return -1; 225 return -1;
2023 } 226 }
2024 cert_free(k->cert);
2025 k->cert = NULL;
2026 k->type = key_type_plain(k->type);
2027 return 0; 227 return 0;
2028} 228}
2029 229
2030/* Sign a certified key, (re-)generating the signed certblob. */
2031int 230int
2032key_certify(Key *k, Key *ca) 231key_certify(Key *k, Key *ca)
2033{ 232{
2034 Buffer principals; 233 int r;
2035 u_char *ca_blob, *sig_blob, nonce[32];
2036 u_int i, ca_len, sig_len;
2037 234
2038 if (k->cert == NULL) { 235 if ((r = sshkey_certify(k, ca)) != 0) {
2039 error("%s: key lacks cert info", __func__); 236 fatal_on_fatal_errors(r, __func__, 0);
237 error("%s: %s", __func__, ssh_err(r));
2040 return -1; 238 return -1;
2041 } 239 }
240 return 0;
241}
2042 242
2043 if (!key_is_cert(k)) { 243int
2044 error("%s: certificate has unknown type %d", __func__, 244key_cert_check_authority(const Key *k, int want_host, int require_principal,
2045 k->cert->type); 245 const char *name, const char **reason)
2046 return -1; 246{
2047 } 247 int r;
2048 248
2049 if (!key_type_is_valid_ca(ca->type)) { 249 if ((r = sshkey_cert_check_authority(k, want_host, require_principal,
2050 error("%s: CA key has unsupported type %s", __func__, 250 name, reason)) != 0) {
2051 key_type(ca)); 251 fatal_on_fatal_errors(r, __func__, 0);
252 error("%s: %s", __func__, ssh_err(r));
2052 return -1; 253 return -1;
2053 } 254 }
255 return 0;
256}
2054 257
2055 key_to_blob(ca, &ca_blob, &ca_len);
2056
2057 buffer_clear(&k->cert->certblob);
2058 buffer_put_cstring(&k->cert->certblob, key_ssh_name(k));
2059
2060 /* -v01 certs put nonce first */
2061 arc4random_buf(&nonce, sizeof(nonce));
2062 if (!key_cert_is_legacy(k))
2063 buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce));
2064
2065 /* XXX this substantially duplicates to_blob(); refactor */
2066 switch (k->type) {
2067#ifdef WITH_OPENSSL 258#ifdef WITH_OPENSSL
2068 case KEY_DSA_CERT_V00: 259int
2069 case KEY_DSA_CERT: 260key_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
2070 buffer_put_bignum2(&k->cert->certblob, k->dsa->p); 261{
2071 buffer_put_bignum2(&k->cert->certblob, k->dsa->q); 262 int r;
2072 buffer_put_bignum2(&k->cert->certblob, k->dsa->g);
2073 buffer_put_bignum2(&k->cert->certblob, k->dsa->pub_key);
2074 break;
2075#ifdef OPENSSL_HAS_ECC
2076 case KEY_ECDSA_CERT:
2077 buffer_put_cstring(&k->cert->certblob,
2078 key_curve_nid_to_name(k->ecdsa_nid));
2079 buffer_put_ecpoint(&k->cert->certblob,
2080 EC_KEY_get0_group(k->ecdsa),
2081 EC_KEY_get0_public_key(k->ecdsa));
2082 break;
2083#endif
2084 case KEY_RSA_CERT_V00:
2085 case KEY_RSA_CERT:
2086 buffer_put_bignum2(&k->cert->certblob, k->rsa->e);
2087 buffer_put_bignum2(&k->cert->certblob, k->rsa->n);
2088 break;
2089#endif
2090 case KEY_ED25519_CERT:
2091 buffer_put_string(&k->cert->certblob,
2092 k->ed25519_pk, ED25519_PK_SZ);
2093 break;
2094 default:
2095 error("%s: key has incorrect type %s", __func__, key_type(k));
2096 buffer_clear(&k->cert->certblob);
2097 free(ca_blob);
2098 return -1;
2099 }
2100
2101 /* -v01 certs have a serial number next */
2102 if (!key_cert_is_legacy(k))
2103 buffer_put_int64(&k->cert->certblob, k->cert->serial);
2104
2105 buffer_put_int(&k->cert->certblob, k->cert->type);
2106 buffer_put_cstring(&k->cert->certblob, k->cert->key_id);
2107
2108 buffer_init(&principals);
2109 for (i = 0; i < k->cert->nprincipals; i++)
2110 buffer_put_cstring(&principals, k->cert->principals[i]);
2111 buffer_put_string(&k->cert->certblob, buffer_ptr(&principals),
2112 buffer_len(&principals));
2113 buffer_free(&principals);
2114
2115 buffer_put_int64(&k->cert->certblob, k->cert->valid_after);
2116 buffer_put_int64(&k->cert->certblob, k->cert->valid_before);
2117 buffer_put_string(&k->cert->certblob,
2118 buffer_ptr(&k->cert->critical), buffer_len(&k->cert->critical));
2119
2120 /* -v01 certs have non-critical options here */
2121 if (!key_cert_is_legacy(k)) {
2122 buffer_put_string(&k->cert->certblob,
2123 buffer_ptr(&k->cert->extensions),
2124 buffer_len(&k->cert->extensions));
2125 }
2126
2127 /* -v00 certs put the nonce at the end */
2128 if (key_cert_is_legacy(k))
2129 buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce));
2130
2131 buffer_put_string(&k->cert->certblob, NULL, 0); /* reserved */
2132 buffer_put_string(&k->cert->certblob, ca_blob, ca_len);
2133 free(ca_blob);
2134 263
2135 /* Sign the whole mess */ 264 if ((r = sshkey_ec_validate_public(group, public)) != 0) {
2136 if (key_sign(ca, &sig_blob, &sig_len, buffer_ptr(&k->cert->certblob), 265 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
2137 buffer_len(&k->cert->certblob)) != 0) { 266 error("%s: %s", __func__, ssh_err(r));
2138 error("%s: signature operation failed", __func__);
2139 buffer_clear(&k->cert->certblob);
2140 return -1; 267 return -1;
2141 } 268 }
2142 /* Append signature and we are done */
2143 buffer_put_string(&k->cert->certblob, sig_blob, sig_len);
2144 free(sig_blob);
2145
2146 return 0; 269 return 0;
2147} 270}
2148 271
2149int 272int
2150key_cert_check_authority(const Key *k, int want_host, int require_principal, 273key_ec_validate_private(const EC_KEY *key)
2151 const char *name, const char **reason)
2152{ 274{
2153 u_int i, principal_matches; 275 int r;
2154 time_t now = time(NULL); 276
2155 277 if ((r = sshkey_ec_validate_private(key)) != 0) {
2156 if (want_host) { 278 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
2157 if (k->cert->type != SSH2_CERT_TYPE_HOST) { 279 error("%s: %s", __func__, ssh_err(r));
2158 *reason = "Certificate invalid: not a host certificate";
2159 return -1;
2160 }
2161 } else {
2162 if (k->cert->type != SSH2_CERT_TYPE_USER) {
2163 *reason = "Certificate invalid: not a user certificate";
2164 return -1;
2165 }
2166 }
2167 if (now < 0) {
2168 error("%s: system clock lies before epoch", __func__);
2169 *reason = "Certificate invalid: not yet valid";
2170 return -1;
2171 }
2172 if ((u_int64_t)now < k->cert->valid_after) {
2173 *reason = "Certificate invalid: not yet valid";
2174 return -1;
2175 }
2176 if ((u_int64_t)now >= k->cert->valid_before) {
2177 *reason = "Certificate invalid: expired";
2178 return -1; 280 return -1;
2179 } 281 }
2180 if (k->cert->nprincipals == 0) {
2181 if (require_principal) {
2182 *reason = "Certificate lacks principal list";
2183 return -1;
2184 }
2185 } else if (name != NULL) {
2186 principal_matches = 0;
2187 for (i = 0; i < k->cert->nprincipals; i++) {
2188 if (strcmp(name, k->cert->principals[i]) == 0) {
2189 principal_matches = 1;
2190 break;
2191 }
2192 }
2193 if (!principal_matches) {
2194 *reason = "Certificate invalid: name is not a listed "
2195 "principal";
2196 return -1;
2197 }
2198 }
2199 return 0; 282 return 0;
2200} 283}
284#endif /* WITH_OPENSSL */
2201 285
2202int 286void
2203key_cert_is_legacy(const Key *k) 287key_private_serialize(const Key *key, struct sshbuf *b)
2204{ 288{
2205 switch (k->type) { 289 int r;
2206 case KEY_DSA_CERT_V00:
2207 case KEY_RSA_CERT_V00:
2208 return 1;
2209 default:
2210 return 0;
2211 }
2212}
2213 290
2214#ifdef WITH_OPENSSL 291 if ((r = sshkey_private_serialize(key, b)) != 0)
2215/* XXX: these are really begging for a table-driven approach */ 292 fatal("%s: %s", __func__, ssh_err(r));
2216int
2217key_curve_name_to_nid(const char *name)
2218{
2219#ifdef OPENSSL_HAS_ECC
2220 if (strcmp(name, "nistp256") == 0)
2221 return NID_X9_62_prime256v1;
2222 else if (strcmp(name, "nistp384") == 0)
2223 return NID_secp384r1;
2224# ifdef OPENSSL_HAS_NISTP521
2225 else if (strcmp(name, "nistp521") == 0)
2226 return NID_secp521r1;
2227# endif
2228#endif
2229
2230 debug("%s: unsupported EC curve name \"%.100s\"", __func__, name);
2231 return -1;
2232} 293}
2233 294
2234u_int 295Key *
2235key_curve_nid_to_bits(int nid) 296key_private_deserialize(struct sshbuf *blob)
2236{ 297{
2237 switch (nid) { 298 int r;
2238#ifdef OPENSSL_HAS_ECC 299 Key *ret = NULL;
2239 case NID_X9_62_prime256v1: 300
2240 return 256; 301 if ((r = sshkey_private_deserialize(blob, &ret)) != 0) {
2241 case NID_secp384r1: 302 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
2242 return 384; 303 error("%s: %s", __func__, ssh_err(r));
2243# ifdef OPENSSL_HAS_NISTP521 304 return NULL;
2244 case NID_secp521r1:
2245 return 521;
2246# endif
2247#endif
2248 default:
2249 error("%s: unsupported EC curve nid %d", __func__, nid);
2250 return 0;
2251 } 305 }
306 return ret;
2252} 307}
2253 308
2254const char * 309/* authfile.c */
2255key_curve_nid_to_name(int nid)
2256{
2257#ifdef OPENSSL_HAS_ECC
2258 if (nid == NID_X9_62_prime256v1)
2259 return "nistp256";
2260 else if (nid == NID_secp384r1)
2261 return "nistp384";
2262# ifdef OPENSSL_HAS_NISTP521
2263 else if (nid == NID_secp521r1)
2264 return "nistp521";
2265# endif
2266#endif
2267 error("%s: unsupported EC curve nid %d", __func__, nid);
2268 return NULL;
2269}
2270 310
2271#ifdef OPENSSL_HAS_ECC
2272int 311int
2273key_ec_nid_to_hash_alg(int nid) 312key_save_private(Key *key, const char *filename, const char *passphrase,
313 const char *comment, int force_new_format, const char *new_format_cipher,
314 int new_format_rounds)
2274{ 315{
2275 int kbits = key_curve_nid_to_bits(nid); 316 int r;
2276 317
2277 if (kbits == 0) 318 if ((r = sshkey_save_private(key, filename, passphrase, comment,
2278 fatal("%s: invalid nid %d", __func__, nid); 319 force_new_format, new_format_cipher, new_format_rounds)) != 0) {
2279 /* RFC5656 section 6.2.1 */ 320 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
2280 if (kbits <= 256) 321 error("%s: %s", __func__, ssh_err(r));
2281 return SSH_DIGEST_SHA256; 322 return 0;
2282 else if (kbits <= 384) 323 }
2283 return SSH_DIGEST_SHA384; 324 return 1;
2284 else
2285 return SSH_DIGEST_SHA512;
2286} 325}
2287 326
2288int 327int
2289key_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) 328key_load_file(int fd, const char *filename, struct sshbuf *blob)
2290{ 329{
2291 BN_CTX *bnctx; 330 int r;
2292 EC_POINT *nq = NULL;
2293 BIGNUM *order, *x, *y, *tmp;
2294 int ret = -1;
2295
2296 if ((bnctx = BN_CTX_new()) == NULL)
2297 fatal("%s: BN_CTX_new failed", __func__);
2298 BN_CTX_start(bnctx);
2299
2300 /*
2301 * We shouldn't ever hit this case because bignum_get_ecpoint()
2302 * refuses to load GF2m points.
2303 */
2304 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
2305 NID_X9_62_prime_field) {
2306 error("%s: group is not a prime field", __func__);
2307 goto out;
2308 }
2309
2310 /* Q != infinity */
2311 if (EC_POINT_is_at_infinity(group, public)) {
2312 error("%s: received degenerate public key (infinity)",
2313 __func__);
2314 goto out;
2315 }
2316 331
2317 if ((x = BN_CTX_get(bnctx)) == NULL || 332 if ((r = sshkey_load_file(fd, filename, blob)) != 0) {
2318 (y = BN_CTX_get(bnctx)) == NULL || 333 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
2319 (order = BN_CTX_get(bnctx)) == NULL || 334 error("%s: %s", __func__, ssh_err(r));
2320 (tmp = BN_CTX_get(bnctx)) == NULL) 335 return 0;
2321 fatal("%s: BN_CTX_get failed", __func__);
2322
2323 /* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */
2324 if (EC_GROUP_get_order(group, order, bnctx) != 1)
2325 fatal("%s: EC_GROUP_get_order failed", __func__);
2326 if (EC_POINT_get_affine_coordinates_GFp(group, public,
2327 x, y, bnctx) != 1)
2328 fatal("%s: EC_POINT_get_affine_coordinates_GFp", __func__);
2329 if (BN_num_bits(x) <= BN_num_bits(order) / 2) {
2330 error("%s: public key x coordinate too small: "
2331 "bits(x) = %d, bits(order)/2 = %d", __func__,
2332 BN_num_bits(x), BN_num_bits(order) / 2);
2333 goto out;
2334 }
2335 if (BN_num_bits(y) <= BN_num_bits(order) / 2) {
2336 error("%s: public key y coordinate too small: "
2337 "bits(y) = %d, bits(order)/2 = %d", __func__,
2338 BN_num_bits(x), BN_num_bits(order) / 2);
2339 goto out;
2340 } 336 }
337 return 1;
338}
2341 339
2342 /* nQ == infinity (n == order of subgroup) */ 340Key *
2343 if ((nq = EC_POINT_new(group)) == NULL) 341key_load_cert(const char *filename)
2344 fatal("%s: BN_CTX_tmp failed", __func__); 342{
2345 if (EC_POINT_mul(group, nq, NULL, public, order, bnctx) != 1) 343 int r;
2346 fatal("%s: EC_GROUP_mul failed", __func__); 344 Key *ret = NULL;
2347 if (EC_POINT_is_at_infinity(group, nq) != 1) {
2348 error("%s: received degenerate public key (nQ != infinity)",
2349 __func__);
2350 goto out;
2351 }
2352 345
2353 /* x < order - 1, y < order - 1 */ 346 if ((r = sshkey_load_cert(filename, &ret)) != 0) {
2354 if (!BN_sub(tmp, order, BN_value_one())) 347 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
2355 fatal("%s: BN_sub failed", __func__); 348 if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT)
2356 if (BN_cmp(x, tmp) >= 0) { 349 debug("%s: %s", __func__, ssh_err(r));
2357 error("%s: public key x coordinate >= group order - 1", 350 else
2358 __func__); 351 error("%s: %s", __func__, ssh_err(r));
2359 goto out; 352 return NULL;
2360 }
2361 if (BN_cmp(y, tmp) >= 0) {
2362 error("%s: public key y coordinate >= group order - 1",
2363 __func__);
2364 goto out;
2365 } 353 }
2366 ret = 0;
2367 out:
2368 BN_CTX_free(bnctx);
2369 EC_POINT_free(nq);
2370 return ret; 354 return ret;
355
2371} 356}
2372 357
2373int 358Key *
2374key_ec_validate_private(const EC_KEY *key) 359key_load_public(const char *filename, char **commentp)
2375{ 360{
2376 BN_CTX *bnctx; 361 int r;
2377 BIGNUM *order, *tmp; 362 Key *ret = NULL;
2378 int ret = -1;
2379
2380 if ((bnctx = BN_CTX_new()) == NULL)
2381 fatal("%s: BN_CTX_new failed", __func__);
2382 BN_CTX_start(bnctx);
2383
2384 if ((order = BN_CTX_get(bnctx)) == NULL ||
2385 (tmp = BN_CTX_get(bnctx)) == NULL)
2386 fatal("%s: BN_CTX_get failed", __func__);
2387
2388 /* log2(private) > log2(order)/2 */
2389 if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1)
2390 fatal("%s: EC_GROUP_get_order failed", __func__);
2391 if (BN_num_bits(EC_KEY_get0_private_key(key)) <=
2392 BN_num_bits(order) / 2) {
2393 error("%s: private key too small: "
2394 "bits(y) = %d, bits(order)/2 = %d", __func__,
2395 BN_num_bits(EC_KEY_get0_private_key(key)),
2396 BN_num_bits(order) / 2);
2397 goto out;
2398 }
2399 363
2400 /* private < order - 1 */ 364 if ((r = sshkey_load_public(filename, &ret, commentp)) != 0) {
2401 if (!BN_sub(tmp, order, BN_value_one())) 365 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
2402 fatal("%s: BN_sub failed", __func__); 366 if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT)
2403 if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0) { 367 debug("%s: %s", __func__, ssh_err(r));
2404 error("%s: private key >= group order - 1", __func__); 368 else
2405 goto out; 369 error("%s: %s", __func__, ssh_err(r));
370 return NULL;
2406 } 371 }
2407 ret = 0;
2408 out:
2409 BN_CTX_free(bnctx);
2410 return ret; 372 return ret;
2411} 373}
2412#endif
2413 374
2414#if defined(DEBUG_KEXECDH) || defined(DEBUG_PK) 375Key *
2415void 376key_load_private(const char *path, const char *passphrase,
2416key_dump_ec_point(const EC_GROUP *group, const EC_POINT *point) 377 char **commentp)
2417{ 378{
2418 BIGNUM *x, *y; 379 int r;
2419 BN_CTX *bnctx; 380 Key *ret = NULL;
2420 381
2421 if (point == NULL) { 382 if ((r = sshkey_load_private(path, passphrase, &ret, commentp)) != 0) {
2422 fputs("point=(NULL)\n", stderr); 383 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
2423 return; 384 if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT)
385 debug("%s: %s", __func__, ssh_err(r));
386 else
387 error("%s: %s", __func__, ssh_err(r));
388 return NULL;
2424 } 389 }
2425 if ((bnctx = BN_CTX_new()) == NULL) 390 return ret;
2426 fatal("%s: BN_CTX_new failed", __func__);
2427 BN_CTX_start(bnctx);
2428 if ((x = BN_CTX_get(bnctx)) == NULL || (y = BN_CTX_get(bnctx)) == NULL)
2429 fatal("%s: BN_CTX_get failed", __func__);
2430 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
2431 NID_X9_62_prime_field)
2432 fatal("%s: group is not a prime field", __func__);
2433 if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y, bnctx) != 1)
2434 fatal("%s: EC_POINT_get_affine_coordinates_GFp", __func__);
2435 fputs("x=", stderr);
2436 BN_print_fp(stderr, x);
2437 fputs("\ny=", stderr);
2438 BN_print_fp(stderr, y);
2439 fputs("\n", stderr);
2440 BN_CTX_free(bnctx);
2441} 391}
2442 392
2443void 393Key *
2444key_dump_ec_key(const EC_KEY *key) 394key_load_private_cert(int type, const char *filename, const char *passphrase,
2445{ 395 int *perm_ok)
2446 const BIGNUM *exponent; 396{
2447 397 int r;
2448 key_dump_ec_point(EC_KEY_get0_group(key), EC_KEY_get0_public_key(key)); 398 Key *ret = NULL;
2449 fputs("exponent=", stderr); 399
2450 if ((exponent = EC_KEY_get0_private_key(key)) == NULL) 400 if ((r = sshkey_load_private_cert(type, filename, passphrase,
2451 fputs("(NULL)", stderr); 401 &ret, perm_ok)) != 0) {
2452 else 402 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
2453 BN_print_fp(stderr, EC_KEY_get0_private_key(key)); 403 if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT)
2454 fputs("\n", stderr); 404 debug("%s: %s", __func__, ssh_err(r));
405 else
406 error("%s: %s", __func__, ssh_err(r));
407 return NULL;
408 }
409 return ret;
2455} 410}
2456#endif /* defined(DEBUG_KEXECDH) || defined(DEBUG_PK) */
2457#endif /* OPENSSL_HAS_ECC */
2458 411
2459void 412Key *
2460key_private_serialize(const Key *key, Buffer *b) 413key_load_private_type(int type, const char *filename, const char *passphrase,
2461{ 414 char **commentp, int *perm_ok)
2462 buffer_put_cstring(b, key_ssh_name(key)); 415{
2463 switch (key->type) { 416 int r;
2464#ifdef WITH_OPENSSL 417 Key *ret = NULL;
2465 case KEY_RSA: 418
2466 buffer_put_bignum2(b, key->rsa->n); 419 if ((r = sshkey_load_private_type(type, filename, passphrase,
2467 buffer_put_bignum2(b, key->rsa->e); 420 &ret, commentp, perm_ok)) != 0) {
2468 buffer_put_bignum2(b, key->rsa->d); 421 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
2469 buffer_put_bignum2(b, key->rsa->iqmp); 422 if ((r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT) ||
2470 buffer_put_bignum2(b, key->rsa->p); 423 (r == SSH_ERR_KEY_WRONG_PASSPHRASE))
2471 buffer_put_bignum2(b, key->rsa->q); 424 debug("%s: %s", __func__, ssh_err(r));
2472 break; 425 else
2473 case KEY_RSA_CERT_V00: 426 error("%s: %s", __func__, ssh_err(r));
2474 case KEY_RSA_CERT: 427 return NULL;
2475 if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
2476 fatal("%s: no cert/certblob", __func__);
2477 buffer_put_string(b, buffer_ptr(&key->cert->certblob),
2478 buffer_len(&key->cert->certblob));
2479 buffer_put_bignum2(b, key->rsa->d);
2480 buffer_put_bignum2(b, key->rsa->iqmp);
2481 buffer_put_bignum2(b, key->rsa->p);
2482 buffer_put_bignum2(b, key->rsa->q);
2483 break;
2484 case KEY_DSA:
2485 buffer_put_bignum2(b, key->dsa->p);
2486 buffer_put_bignum2(b, key->dsa->q);
2487 buffer_put_bignum2(b, key->dsa->g);
2488 buffer_put_bignum2(b, key->dsa->pub_key);
2489 buffer_put_bignum2(b, key->dsa->priv_key);
2490 break;
2491 case KEY_DSA_CERT_V00:
2492 case KEY_DSA_CERT:
2493 if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
2494 fatal("%s: no cert/certblob", __func__);
2495 buffer_put_string(b, buffer_ptr(&key->cert->certblob),
2496 buffer_len(&key->cert->certblob));
2497 buffer_put_bignum2(b, key->dsa->priv_key);
2498 break;
2499#ifdef OPENSSL_HAS_ECC
2500 case KEY_ECDSA:
2501 buffer_put_cstring(b, key_curve_nid_to_name(key->ecdsa_nid));
2502 buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
2503 EC_KEY_get0_public_key(key->ecdsa));
2504 buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa));
2505 break;
2506 case KEY_ECDSA_CERT:
2507 if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
2508 fatal("%s: no cert/certblob", __func__);
2509 buffer_put_string(b, buffer_ptr(&key->cert->certblob),
2510 buffer_len(&key->cert->certblob));
2511 buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa));
2512 break;
2513#endif /* OPENSSL_HAS_ECC */
2514 case KEY_ED25519:
2515 buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ);
2516 buffer_put_string(b, key->ed25519_sk, ED25519_SK_SZ);
2517 break;
2518#endif
2519#endif
2520 case KEY_ED25519_CERT:
2521 if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
2522 fatal("%s: no cert/certblob", __func__);
2523 buffer_put_string(b, buffer_ptr(&key->cert->certblob),
2524 buffer_len(&key->cert->certblob));
2525 buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ);
2526 buffer_put_string(b, key->ed25519_sk, ED25519_SK_SZ);
2527 break;
2528 } 428 }
429 return ret;
2529} 430}
2530 431
432#ifdef WITH_OPENSSL
2531Key * 433Key *
2532key_private_deserialize(Buffer *blob) 434key_load_private_pem(int fd, int type, const char *passphrase,
435 char **commentp)
2533{ 436{
2534 char *type_name; 437 int r;
2535 Key *k = NULL; 438 Key *ret = NULL;
2536 u_char *cert; 439
2537 u_int len, pklen, sklen; 440 if ((r = sshkey_load_private_pem(fd, type, passphrase,
2538 int type; 441 &ret, commentp)) != 0) {
2539#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) 442 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
2540 char *curve; 443 error("%s: %s", __func__, ssh_err(r));
2541 BIGNUM *exponent;
2542 EC_POINT *q;
2543#endif
2544
2545 type_name = buffer_get_string(blob, NULL);
2546 type = key_type_from_name(type_name);
2547 switch (type) {
2548#ifdef WITH_OPENSSL
2549 case KEY_DSA:
2550 k = key_new_private(type);
2551 buffer_get_bignum2(blob, k->dsa->p);
2552 buffer_get_bignum2(blob, k->dsa->q);
2553 buffer_get_bignum2(blob, k->dsa->g);
2554 buffer_get_bignum2(blob, k->dsa->pub_key);
2555 buffer_get_bignum2(blob, k->dsa->priv_key);
2556 break;
2557 case KEY_DSA_CERT_V00:
2558 case KEY_DSA_CERT:
2559 cert = buffer_get_string(blob, &len);
2560 if ((k = key_from_blob(cert, len)) == NULL)
2561 fatal("Certificate parse failed");
2562 free(cert);
2563 key_add_private(k);
2564 buffer_get_bignum2(blob, k->dsa->priv_key);
2565 break;
2566#ifdef OPENSSL_HAS_ECC
2567 case KEY_ECDSA:
2568 k = key_new_private(type);
2569 k->ecdsa_nid = key_ecdsa_nid_from_name(type_name);
2570 curve = buffer_get_string(blob, NULL);
2571 if (k->ecdsa_nid != key_curve_name_to_nid(curve))
2572 fatal("%s: curve names mismatch", __func__);
2573 free(curve);
2574 k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
2575 if (k->ecdsa == NULL)
2576 fatal("%s: EC_KEY_new_by_curve_name failed",
2577 __func__);
2578 q = EC_POINT_new(EC_KEY_get0_group(k->ecdsa));
2579 if (q == NULL)
2580 fatal("%s: BN_new failed", __func__);
2581 if ((exponent = BN_new()) == NULL)
2582 fatal("%s: BN_new failed", __func__);
2583 buffer_get_ecpoint(blob,
2584 EC_KEY_get0_group(k->ecdsa), q);
2585 buffer_get_bignum2(blob, exponent);
2586 if (EC_KEY_set_public_key(k->ecdsa, q) != 1)
2587 fatal("%s: EC_KEY_set_public_key failed",
2588 __func__);
2589 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1)
2590 fatal("%s: EC_KEY_set_private_key failed",
2591 __func__);
2592 if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
2593 EC_KEY_get0_public_key(k->ecdsa)) != 0)
2594 fatal("%s: bad ECDSA public key", __func__);
2595 if (key_ec_validate_private(k->ecdsa) != 0)
2596 fatal("%s: bad ECDSA private key", __func__);
2597 BN_clear_free(exponent);
2598 EC_POINT_free(q);
2599 break;
2600 case KEY_ECDSA_CERT:
2601 cert = buffer_get_string(blob, &len);
2602 if ((k = key_from_blob(cert, len)) == NULL)
2603 fatal("Certificate parse failed");
2604 free(cert);
2605 key_add_private(k);
2606 if ((exponent = BN_new()) == NULL)
2607 fatal("%s: BN_new failed", __func__);
2608 buffer_get_bignum2(blob, exponent);
2609 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1)
2610 fatal("%s: EC_KEY_set_private_key failed",
2611 __func__);
2612 if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
2613 EC_KEY_get0_public_key(k->ecdsa)) != 0 ||
2614 key_ec_validate_private(k->ecdsa) != 0)
2615 fatal("%s: bad ECDSA key", __func__);
2616 BN_clear_free(exponent);
2617 break;
2618#endif
2619 case KEY_RSA:
2620 k = key_new_private(type);
2621 buffer_get_bignum2(blob, k->rsa->n);
2622 buffer_get_bignum2(blob, k->rsa->e);
2623 buffer_get_bignum2(blob, k->rsa->d);
2624 buffer_get_bignum2(blob, k->rsa->iqmp);
2625 buffer_get_bignum2(blob, k->rsa->p);
2626 buffer_get_bignum2(blob, k->rsa->q);
2627
2628 /* Generate additional parameters */
2629 rsa_generate_additional_parameters(k->rsa);
2630 break;
2631 case KEY_RSA_CERT_V00:
2632 case KEY_RSA_CERT:
2633 cert = buffer_get_string(blob, &len);
2634 if ((k = key_from_blob(cert, len)) == NULL)
2635 fatal("Certificate parse failed");
2636 free(cert);
2637 key_add_private(k);
2638 buffer_get_bignum2(blob, k->rsa->d);
2639 buffer_get_bignum2(blob, k->rsa->iqmp);
2640 buffer_get_bignum2(blob, k->rsa->p);
2641 buffer_get_bignum2(blob, k->rsa->q);
2642 break;
2643#endif
2644#endif
2645 case KEY_ED25519:
2646 k = key_new_private(type);
2647 k->ed25519_pk = buffer_get_string(blob, &pklen);
2648 k->ed25519_sk = buffer_get_string(blob, &sklen);
2649 if (pklen != ED25519_PK_SZ)
2650 fatal("%s: ed25519 pklen %d != %d",
2651 __func__, pklen, ED25519_PK_SZ);
2652 if (sklen != ED25519_SK_SZ)
2653 fatal("%s: ed25519 sklen %d != %d",
2654 __func__, sklen, ED25519_SK_SZ);
2655 break;
2656 case KEY_ED25519_CERT:
2657 cert = buffer_get_string(blob, &len);
2658 if ((k = key_from_blob(cert, len)) == NULL)
2659 fatal("Certificate parse failed");
2660 free(cert);
2661 key_add_private(k);
2662 k->ed25519_pk = buffer_get_string(blob, &pklen);
2663 k->ed25519_sk = buffer_get_string(blob, &sklen);
2664 if (pklen != ED25519_PK_SZ)
2665 fatal("%s: ed25519 pklen %d != %d",
2666 __func__, pklen, ED25519_PK_SZ);
2667 if (sklen != ED25519_SK_SZ)
2668 fatal("%s: ed25519 sklen %d != %d",
2669 __func__, sklen, ED25519_SK_SZ);
2670 break;
2671 default:
2672 free(type_name);
2673 buffer_clear(blob);
2674 return NULL; 444 return NULL;
2675 } 445 }
2676 free(type_name); 446 return ret;
447}
448#endif /* WITH_OPENSSL */
2677 449
2678 /* enable blinding */ 450int
2679 switch (k->type) { 451key_perm_ok(int fd, const char *filename)
2680#ifdef WITH_OPENSSL 452{
2681 case KEY_RSA: 453 return sshkey_perm_ok(fd, filename) == 0 ? 1 : 0;
2682 case KEY_RSA_CERT_V00: 454}
2683 case KEY_RSA_CERT: 455
2684 case KEY_RSA1: 456int
2685 if (RSA_blinding_on(k->rsa, NULL) != 1) { 457key_in_file(Key *key, const char *filename, int strict_type)
2686 error("%s: RSA_blinding_on failed", __func__); 458{
2687 key_free(k); 459 int r;
2688 return NULL; 460
2689 } 461 if ((r = sshkey_in_file(key, filename, strict_type)) != 0) {
2690 break; 462 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
2691#endif 463 if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT)
464 return 0;
465 error("%s: %s", __func__, ssh_err(r));
466 return r == SSH_ERR_KEY_NOT_FOUND ? 0 : -1;
2692 } 467 }
2693 return k; 468 return 1;
2694} 469}
diff --git a/key.h b/key.h
index d8ad13d08..4be4fedd6 100644
--- a/key.h
+++ b/key.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: key.h,v 1.41 2014/01/09 23:20:00 djm Exp $ */ 1/* $OpenBSD: key.h,v 1.42 2014/06/24 01:13:21 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.
@@ -26,141 +26,86 @@
26#ifndef KEY_H 26#ifndef KEY_H
27#define KEY_H 27#define KEY_H
28 28
29#include "buffer.h" 29#include "sshkey.h"
30#include <openssl/rsa.h> 30
31#include <openssl/dsa.h> 31typedef struct sshkey Key;
32#ifdef OPENSSL_HAS_ECC 32
33#include <openssl/ec.h> 33#define types sshkey_types
34#define fp_type sshkey_fp_type
35#define fp_rep sshkey_fp_rep
36
37#ifndef SSH_KEY_NO_DEFINE
38#define key_new sshkey_new
39#define key_free sshkey_free
40#define key_equal_public sshkey_equal_public
41#define key_equal sshkey_equal
42#define key_fingerprint sshkey_fingerprint
43#define key_type sshkey_type
44#define key_cert_type sshkey_cert_type
45#define key_ssh_name sshkey_ssh_name
46#define key_ssh_name_plain sshkey_ssh_name_plain
47#define key_type_from_name sshkey_type_from_name
48#define key_ecdsa_nid_from_name sshkey_ecdsa_nid_from_name
49#define key_type_is_cert sshkey_type_is_cert
50#define key_size sshkey_size
51#define key_ecdsa_bits_to_nid sshkey_ecdsa_bits_to_nid
52#define key_ecdsa_key_to_nid sshkey_ecdsa_key_to_nid
53#define key_names_valid2 sshkey_names_valid2
54#define key_is_cert sshkey_is_cert
55#define key_type_plain sshkey_type_plain
56#define key_cert_is_legacy sshkey_cert_is_legacy
57#define key_curve_name_to_nid sshkey_curve_name_to_nid
58#define key_curve_nid_to_bits sshkey_curve_nid_to_bits
59#define key_curve_nid_to_name sshkey_curve_nid_to_name
60#define key_ec_nid_to_hash_alg sshkey_ec_nid_to_hash_alg
61#define key_dump_ec_point sshkey_dump_ec_point
62#define key_dump_ec_key sshkey_dump_ec_key
63#define key_fingerprint sshkey_fingerprint
34#endif 64#endif
35 65
36typedef struct Key Key; 66void key_add_private(Key *);
37enum types { 67Key *key_new_private(int);
38 KEY_RSA1, 68void key_free(Key *);
39 KEY_RSA, 69Key *key_demote(const Key *);
40 KEY_DSA, 70u_char *key_fingerprint_raw(const Key *, enum fp_type, u_int *);
41 KEY_ECDSA, 71int key_write(const Key *, FILE *);
42 KEY_ED25519, 72int key_read(Key *, char **);
43 KEY_RSA_CERT,
44 KEY_DSA_CERT,
45 KEY_ECDSA_CERT,
46 KEY_ED25519_CERT,
47 KEY_RSA_CERT_V00,
48 KEY_DSA_CERT_V00,
49 KEY_UNSPEC
50};
51enum fp_type {
52 SSH_FP_SHA1,
53 SSH_FP_MD5,
54 SSH_FP_SHA256
55};
56enum fp_rep {
57 SSH_FP_HEX,
58 SSH_FP_BUBBLEBABBLE,
59 SSH_FP_RANDOMART
60};
61
62/* key is stored in external hardware */
63#define KEY_FLAG_EXT 0x0001
64
65#define CERT_MAX_PRINCIPALS 256
66struct KeyCert {
67 Buffer certblob; /* Kept around for use on wire */
68 u_int type; /* SSH2_CERT_TYPE_USER or SSH2_CERT_TYPE_HOST */
69 u_int64_t serial;
70 char *key_id;
71 u_int nprincipals;
72 char **principals;
73 u_int64_t valid_after, valid_before;
74 Buffer critical;
75 Buffer extensions;
76 Key *signature_key;
77};
78
79struct Key {
80 int type;
81 int flags;
82 RSA *rsa;
83 DSA *dsa;
84 int ecdsa_nid; /* NID of curve */
85#ifdef OPENSSL_HAS_ECC
86 EC_KEY *ecdsa;
87#else
88 void *ecdsa;
89#endif
90 struct KeyCert *cert;
91 u_char *ed25519_sk;
92 u_char *ed25519_pk;
93};
94
95#define ED25519_SK_SZ crypto_sign_ed25519_SECRETKEYBYTES
96#define ED25519_PK_SZ crypto_sign_ed25519_PUBLICKEYBYTES
97
98Key *key_new(int);
99void key_add_private(Key *);
100Key *key_new_private(int);
101void key_free(Key *);
102Key *key_demote(const Key *);
103int key_equal_public(const Key *, const Key *);
104int key_equal(const Key *, const Key *);
105char *key_fingerprint(const Key *, enum fp_type, enum fp_rep);
106u_char *key_fingerprint_raw(const Key *, enum fp_type, u_int *);
107const char *key_type(const Key *);
108const char *key_cert_type(const Key *);
109int key_write(const Key *, FILE *);
110int key_read(Key *, char **);
111u_int key_size(const Key *);
112 73
113Key *key_generate(int, u_int); 74Key *key_generate(int, u_int);
114Key *key_from_private(const Key *); 75Key *key_from_private(const Key *);
115int key_type_from_name(char *);
116int key_is_cert(const Key *);
117int key_type_is_cert(int);
118int key_type_plain(int);
119int key_to_certified(Key *, int); 76int key_to_certified(Key *, int);
120int key_drop_cert(Key *); 77int key_drop_cert(Key *);
121int key_certify(Key *, Key *); 78int key_certify(Key *, Key *);
122void key_cert_copy(const Key *, struct Key *); 79void key_cert_copy(const Key *, Key *);
123int key_cert_check_authority(const Key *, int, int, const char *, 80int key_cert_check_authority(const Key *, int, int, const char *,
124 const char **); 81 const char **);
125int key_cert_is_legacy(const Key *); 82char *key_alg_list(int, int);
126 83
127int key_ecdsa_nid_from_name(const char *); 84#ifdef WITH_OPENSSL
128int key_curve_name_to_nid(const char *); 85int key_ec_validate_public(const EC_GROUP *, const EC_POINT *);
129const char *key_curve_nid_to_name(int); 86int key_ec_validate_private(const EC_KEY *);
130u_int key_curve_nid_to_bits(int); 87#endif /* WITH_OPENSSL */
131int key_ecdsa_bits_to_nid(int);
132#ifdef OPENSSL_HAS_ECC
133int key_ecdsa_key_to_nid(EC_KEY *);
134int key_ec_nid_to_hash_alg(int nid);
135int key_ec_validate_public(const EC_GROUP *, const EC_POINT *);
136int key_ec_validate_private(const EC_KEY *);
137#endif
138char *key_alg_list(int, int);
139 88
140Key *key_from_blob(const u_char *, u_int); 89Key *key_from_blob(const u_char *, u_int);
141int key_to_blob(const Key *, u_char **, u_int *); 90int key_to_blob(const Key *, u_char **, u_int *);
142const char *key_ssh_name(const Key *);
143const char *key_ssh_name_plain(const Key *);
144int key_names_valid2(const char *);
145 91
146int key_sign(const Key *, u_char **, u_int *, const u_char *, u_int); 92int key_sign(const Key *, u_char **, u_int *, const u_char *, u_int);
147int key_verify(const Key *, const u_char *, u_int, const u_char *, u_int); 93int key_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
148 94
149int ssh_dss_sign(const Key *, u_char **, u_int *, const u_char *, u_int); 95void key_private_serialize(const Key *, struct sshbuf *);
150int ssh_dss_verify(const Key *, const u_char *, u_int, const u_char *, u_int); 96Key *key_private_deserialize(struct sshbuf *);
151int ssh_ecdsa_sign(const Key *, u_char **, u_int *, const u_char *, u_int); 97
152int ssh_ecdsa_verify(const Key *, const u_char *, u_int, const u_char *, u_int); 98/* authfile.c */
153int ssh_rsa_sign(const Key *, u_char **, u_int *, const u_char *, u_int); 99int key_save_private(Key *, const char *, const char *, const char *,
154int ssh_rsa_verify(const Key *, const u_char *, u_int, const u_char *, u_int); 100 int, const char *, int);
155int ssh_ed25519_sign(const Key *, u_char **, u_int *, const u_char *, u_int); 101int key_load_file(int, const char *, struct sshbuf *);
156int ssh_ed25519_verify(const Key *, const u_char *, u_int, const u_char *, u_int); 102Key *key_load_cert(const char *);
157 103Key *key_load_public(const char *, char **);
158#if defined(OPENSSL_HAS_ECC) && (defined(DEBUG_KEXECDH) || defined(DEBUG_PK)) 104Key *key_load_private(const char *, const char *, char **);
159void key_dump_ec_point(const EC_GROUP *, const EC_POINT *); 105Key *key_load_private_cert(int, const char *, const char *, int *);
160void key_dump_ec_key(const EC_KEY *); 106Key *key_load_private_type(int, const char *, const char *, char **, int *);
161#endif 107Key *key_load_private_pem(int, int, const char *, char **);
162 108int key_perm_ok(int, const char *);
163void key_private_serialize(const Key *, Buffer *); 109int key_in_file(Key *, const char *, int);
164Key *key_private_deserialize(Buffer *);
165 110
166#endif 111#endif
diff --git a/krl.c b/krl.c
index 557a48ebb..eb31df90f 100644
--- a/krl.c
+++ b/krl.c
@@ -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.16 2014/06/24 00:52:02 djm Exp $ */ 17/* $OpenBSD: krl.c,v 1.17 2014/06/24 01:13:21 djm Exp $ */
18 18
19#include "includes.h" 19#include "includes.h"
20 20
@@ -366,7 +366,7 @@ plain_key_blob(const Key *key, u_char **blob, u_int *blen)
366 } 366 }
367 r = key_to_blob(kcopy, blob, blen); 367 r = key_to_blob(kcopy, blob, blen);
368 free(kcopy); 368 free(kcopy);
369 return r == 0 ? -1 : 0; 369 return r;
370} 370}
371 371
372/* Revoke a key blob. Ownership of blob is transferred to the tree */ 372/* Revoke a key blob. Ownership of blob is transferred to the tree */
@@ -394,7 +394,7 @@ ssh_krl_revoke_key_explicit(struct ssh_krl *krl, const Key *key)
394 u_int len; 394 u_int len;
395 395
396 debug3("%s: revoke type %s", __func__, key_type(key)); 396 debug3("%s: revoke type %s", __func__, key_type(key));
397 if (plain_key_blob(key, &blob, &len) != 0) 397 if (plain_key_blob(key, &blob, &len) < 0)
398 return -1; 398 return -1;
399 return revoke_blob(&krl->revoked_keys, blob, len); 399 return revoke_blob(&krl->revoked_keys, blob, len);
400} 400}
@@ -1130,7 +1130,7 @@ is_key_revoked(struct ssh_krl *krl, const Key *key)
1130 1130
1131 /* Next, explicit keys */ 1131 /* Next, explicit keys */
1132 memset(&rb, 0, sizeof(rb)); 1132 memset(&rb, 0, sizeof(rb));
1133 if (plain_key_blob(key, &rb.blob, &rb.len) != 0) 1133 if (plain_key_blob(key, &rb.blob, &rb.len) < 0)
1134 return -1; 1134 return -1;
1135 erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb); 1135 erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb);
1136 free(rb.blob); 1136 free(rb.blob);
diff --git a/monitor.c b/monitor.c
index 9391ae8d1..68f4dbc71 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor.c,v 1.133 2014/05/03 17:20:34 markus Exp $ */ 1/* $OpenBSD: monitor.c,v 1.134 2014/06/24 01:13:21 djm Exp $ */
2/* 2/*
3 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 3 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4 * Copyright 2002 Markus Friedl <markus@openbsd.org> 4 * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -40,9 +40,10 @@
40#endif 40#endif
41#include <pwd.h> 41#include <pwd.h>
42#include <signal.h> 42#include <signal.h>
43#include <stdarg.h>
44#include <stdlib.h> 43#include <stdlib.h>
45#include <string.h> 44#include <string.h>
45#include <stdarg.h>
46#include <stdio.h>
46#include <unistd.h> 47#include <unistd.h>
47#ifdef HAVE_POLL_H 48#ifdef HAVE_POLL_H
48#include <poll.h> 49#include <poll.h>
diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c
index 0e5f2cea5..36570e4ad 100644
--- a/openbsd-compat/openssl-compat.c
+++ b/openbsd-compat/openssl-compat.c
@@ -1,4 +1,4 @@
1/* $Id: openssl-compat.c,v 1.18 2014/06/17 13:06:08 dtucker Exp $ */ 1/* $Id: openssl-compat.c,v 1.19 2014/07/02 05:28:07 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au> 4 * Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au>
@@ -16,6 +16,7 @@
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */ 17 */
18 18
19#define SSH_DONT_OVERLOAD_OPENSSL_FUNCS
19#include "includes.h" 20#include "includes.h"
20 21
21#include <stdarg.h> 22#include <stdarg.h>
@@ -26,13 +27,8 @@
26# include <openssl/conf.h> 27# include <openssl/conf.h>
27#endif 28#endif
28 29
29#ifndef HAVE_RSA_GET_DEFAULT_METHOD
30# include <openssl/rsa.h>
31#endif
32
33#include "log.h" 30#include "log.h"
34 31
35#define SSH_DONT_OVERLOAD_OPENSSL_FUNCS
36#include "openssl-compat.h" 32#include "openssl-compat.h"
37 33
38/* 34/*
@@ -70,139 +66,6 @@ ssh_compatible_openssl(long headerver, long libver)
70 return 0; 66 return 0;
71} 67}
72 68
73#ifdef SSH_OLD_EVP
74int
75ssh_EVP_CipherInit(EVP_CIPHER_CTX *evp, const EVP_CIPHER *type,
76 unsigned char *key, unsigned char *iv, int enc)
77{
78 EVP_CipherInit(evp, type, key, iv, enc);
79 return 1;
80}
81
82int
83ssh_EVP_Cipher(EVP_CIPHER_CTX *evp, char *dst, char *src, int len)
84{
85 EVP_Cipher(evp, dst, src, len);
86 return 1;
87}
88
89int
90ssh_EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *evp)
91{
92 EVP_CIPHER_CTX_cleanup(evp);
93 return 1;
94}
95#endif
96
97#ifndef HAVE_EVP_DIGESTINIT_EX
98int
99EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *md, void *engine)
100{
101 if (engine != NULL)
102 fatal("%s: ENGINE is not supported", __func__);
103# ifdef OPENSSL_EVP_DIGESTUPDATE_VOID
104 EVP_DigestInit(ctx, md);
105 return 1;
106# else
107 return EVP_DigestInit(ctx, md);
108# endif
109}
110#endif
111
112#ifndef HAVE_EVP_DIGESTFINAL_EX
113int
114EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s)
115{
116# ifdef OPENSSL_EVP_DIGESTUPDATE_VOID
117 EVP_DigestFinal(ctx, md, s);
118 return 1;
119# else
120 return EVP_DigestFinal(ctx, md, s);
121# endif
122}
123#endif
124
125#ifdef OPENSSL_EVP_DIGESTUPDATE_VOID
126int
127ssh_EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt)
128{
129 EVP_DigestUpdate(ctx, d, cnt);
130 return 1;
131}
132#endif
133
134#ifndef HAVE_EVP_MD_CTX_COPY_EX
135int
136EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
137{
138 return EVP_MD_CTX_copy(out, in);
139}
140#endif
141
142#ifndef HAVE_BN_IS_PRIME_EX
143int
144BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, void *cb)
145{
146 if (cb != NULL)
147 fatal("%s: callback args not supported", __func__);
148 return BN_is_prime(p, nchecks, NULL, ctx, NULL);
149}
150#endif
151
152#ifndef HAVE_RSA_GENERATE_KEY_EX
153int
154RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *bn_e, void *cb)
155{
156 RSA *new_rsa, tmp_rsa;
157 unsigned long e;
158
159 if (cb != NULL)
160 fatal("%s: callback args not supported", __func__);
161 e = BN_get_word(bn_e);
162 if (e == 0xffffffffL)
163 fatal("%s: value of e too large", __func__);
164 new_rsa = RSA_generate_key(bits, e, NULL, NULL);
165 if (new_rsa == NULL)
166 return 0;
167 /* swap rsa/new_rsa then free new_rsa */
168 tmp_rsa = *rsa;
169 *rsa = *new_rsa;
170 *new_rsa = tmp_rsa;
171 RSA_free(new_rsa);
172 return 1;
173}
174#endif
175
176#ifndef HAVE_DSA_GENERATE_PARAMETERS_EX
177int
178DSA_generate_parameters_ex(DSA *dsa, int bits, const unsigned char *seed,
179 int seed_len, int *counter_ret, unsigned long *h_ret, void *cb)
180{
181 DSA *new_dsa, tmp_dsa;
182
183 if (cb != NULL)
184 fatal("%s: callback args not supported", __func__);
185 new_dsa = DSA_generate_parameters(bits, (unsigned char *)seed, seed_len,
186 counter_ret, h_ret, NULL, NULL);
187 if (new_dsa == NULL)
188 return 0;
189 /* swap dsa/new_dsa then free new_dsa */
190 tmp_dsa = *dsa;
191 *dsa = *new_dsa;
192 *new_dsa = tmp_dsa;
193 DSA_free(new_dsa);
194 return 1;
195}
196#endif
197
198#ifndef HAVE_RSA_GET_DEFAULT_METHOD
199RSA_METHOD *
200RSA_get_default_method(void)
201{
202 return RSA_PKCS1_SSLeay();
203}
204#endif
205
206#ifdef USE_OPENSSL_ENGINE 69#ifdef USE_OPENSSL_ENGINE
207void 70void
208ssh_OpenSSL_add_all_algorithms(void) 71ssh_OpenSSL_add_all_algorithms(void)
diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h
index 199dcc882..d088d2962 100644
--- a/openbsd-compat/openssl-compat.h
+++ b/openbsd-compat/openssl-compat.h
@@ -1,4 +1,4 @@
1/* $Id: openssl-compat.h,v 1.27 2014/06/17 13:06:08 dtucker Exp $ */ 1/* $Id: openssl-compat.h,v 1.28 2014/07/02 05:28:07 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au> 4 * Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au>
@@ -24,22 +24,8 @@
24 24
25int ssh_compatible_openssl(long, long); 25int ssh_compatible_openssl(long, long);
26 26
27/* Only in 0.9.8 */ 27#if (OPENSSL_VERSION_NUMBER <= 0x0090805fL)
28#ifndef OPENSSL_DSA_MAX_MODULUS_BITS 28#error OpenSSL 0.9.8f or greater is required
29# define OPENSSL_DSA_MAX_MODULUS_BITS 10000
30#endif
31#ifndef OPENSSL_RSA_MAX_MODULUS_BITS
32# define OPENSSL_RSA_MAX_MODULUS_BITS 16384
33#endif
34
35/* OPENSSL_free() is Free() in versions before OpenSSL 0.9.6 */
36#if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x0090600f)
37# define OPENSSL_free(x) Free(x)
38#endif
39
40#if OPENSSL_VERSION_NUMBER < 0x00906000L
41# define SSH_OLD_EVP
42# define EVP_CIPHER_CTX_get_app_data(e) ((e)->app_data)
43#endif 29#endif
44 30
45#if OPENSSL_VERSION_NUMBER < 0x10000001L 31#if OPENSSL_VERSION_NUMBER < 0x10000001L
@@ -48,31 +34,6 @@ int ssh_compatible_openssl(long, long);
48# define LIBCRYPTO_EVP_INL_TYPE size_t 34# define LIBCRYPTO_EVP_INL_TYPE size_t
49#endif 35#endif
50 36
51#if (OPENSSL_VERSION_NUMBER < 0x00907000L) || defined(OPENSSL_LOBOTOMISED_AES)
52# define USE_BUILTIN_RIJNDAEL
53#endif
54
55#ifdef USE_BUILTIN_RIJNDAEL
56# include "rijndael.h"
57# define AES_KEY rijndael_ctx
58# define AES_BLOCK_SIZE 16
59# define AES_encrypt(a, b, c) rijndael_encrypt(c, a, b)
60# define AES_set_encrypt_key(a, b, c) rijndael_set_key(c, (char *)a, b, 1)
61# define EVP_aes_128_cbc evp_rijndael
62# define EVP_aes_192_cbc evp_rijndael
63# define EVP_aes_256_cbc evp_rijndael
64const EVP_CIPHER *evp_rijndael(void);
65void ssh_rijndael_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
66#endif
67
68#ifndef OPENSSL_HAVE_EVPCTR
69#define EVP_aes_128_ctr evp_aes_128_ctr
70#define EVP_aes_192_ctr evp_aes_128_ctr
71#define EVP_aes_256_ctr evp_aes_128_ctr
72const EVP_CIPHER *evp_aes_128_ctr(void);
73void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, size_t);
74#endif
75
76/* Avoid some #ifdef. Code that uses these is unreachable without GCM */ 37/* Avoid some #ifdef. Code that uses these is unreachable without GCM */
77#if !defined(OPENSSL_HAVE_EVPGCM) && !defined(EVP_CTRL_GCM_SET_IV_FIXED) 38#if !defined(OPENSSL_HAVE_EVPGCM) && !defined(EVP_CTRL_GCM_SET_IV_FIXED)
78# define EVP_CTRL_GCM_SET_IV_FIXED -1 39# define EVP_CTRL_GCM_SET_IV_FIXED -1
@@ -90,26 +51,9 @@ void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, size_t);
90# endif 51# endif
91#endif 52#endif
92 53
93#if OPENSSL_VERSION_NUMBER < 0x00907000L
94#define EVP_X_STATE(evp) &(evp).c
95#define EVP_X_STATE_LEN(evp) sizeof((evp).c)
96#else
97#define EVP_X_STATE(evp) (evp).cipher_data
98#define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size
99#endif
100
101/* OpenSSL 0.9.8e returns cipher key len not context key len */
102#if (OPENSSL_VERSION_NUMBER == 0x0090805fL)
103# define EVP_CIPHER_CTX_key_length(c) ((c)->key_len)
104#endif
105
106#ifndef HAVE_RSA_GET_DEFAULT_METHOD
107RSA_METHOD *RSA_get_default_method(void);
108#endif
109
110/* 54/*
111 * We overload some of the OpenSSL crypto functions with ssh_* equivalents 55 * We overload some of the OpenSSL crypto functions with ssh_* equivalents
112 * which cater for older and/or less featureful OpenSSL version. 56 * to automatically handle OpenSSL engine initialisation.
113 * 57 *
114 * In order for the compat library to call the real functions, it must 58 * In order for the compat library to call the real functions, it must
115 * define SSH_DONT_OVERLOAD_OPENSSL_FUNCS before including this file and 59 * define SSH_DONT_OVERLOAD_OPENSSL_FUNCS before including this file and
@@ -117,19 +61,6 @@ RSA_METHOD *RSA_get_default_method(void);
117 */ 61 */
118#ifndef SSH_DONT_OVERLOAD_OPENSSL_FUNCS 62#ifndef SSH_DONT_OVERLOAD_OPENSSL_FUNCS
119 63
120# ifdef SSH_OLD_EVP
121# ifdef EVP_Cipher
122# undef EVP_Cipher
123# endif
124# define EVP_CipherInit(a,b,c,d,e) ssh_EVP_CipherInit((a),(b),(c),(d),(e))
125# define EVP_Cipher(a,b,c,d) ssh_EVP_Cipher((a),(b),(c),(d))
126# define EVP_CIPHER_CTX_cleanup(a) ssh_EVP_CIPHER_CTX_cleanup((a))
127# endif /* SSH_OLD_EVP */
128
129# ifdef OPENSSL_EVP_DIGESTUPDATE_VOID
130# define EVP_DigestUpdate(a,b,c) ssh_EVP_DigestUpdate((a),(b),(c))
131# endif
132
133# ifdef USE_OPENSSL_ENGINE 64# ifdef USE_OPENSSL_ENGINE
134# ifdef OpenSSL_add_all_algorithms 65# ifdef OpenSSL_add_all_algorithms
135# undef OpenSSL_add_all_algorithms 66# undef OpenSSL_add_all_algorithms
@@ -137,48 +68,7 @@ RSA_METHOD *RSA_get_default_method(void);
137# define OpenSSL_add_all_algorithms() ssh_OpenSSL_add_all_algorithms() 68# define OpenSSL_add_all_algorithms() ssh_OpenSSL_add_all_algorithms()
138# endif 69# endif
139 70
140# ifndef HAVE_BN_IS_PRIME_EX
141int BN_is_prime_ex(const BIGNUM *, int, BN_CTX *, void *);
142# endif
143
144# ifndef HAVE_DSA_GENERATE_PARAMETERS_EX
145int DSA_generate_parameters_ex(DSA *, int, const unsigned char *, int, int *,
146 unsigned long *, void *);
147# endif
148
149# ifndef HAVE_RSA_GENERATE_KEY_EX
150int RSA_generate_key_ex(RSA *, int, BIGNUM *, void *);
151# endif
152
153# ifndef HAVE_EVP_DIGESTINIT_EX
154int EVP_DigestInit_ex(EVP_MD_CTX *, const EVP_MD *, void *);
155# endif
156
157# ifndef HAVE_EVP_DISESTFINAL_EX
158int EVP_DigestFinal_ex(EVP_MD_CTX *, unsigned char *, unsigned int *);
159# endif
160
161# ifndef EVP_MD_CTX_COPY_EX
162int EVP_MD_CTX_copy_ex(EVP_MD_CTX *, const EVP_MD_CTX *);
163# endif
164
165int ssh_EVP_CipherInit(EVP_CIPHER_CTX *, const EVP_CIPHER *, unsigned char *,
166 unsigned char *, int);
167int ssh_EVP_Cipher(EVP_CIPHER_CTX *, char *, char *, int);
168int ssh_EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *);
169void ssh_OpenSSL_add_all_algorithms(void); 71void ssh_OpenSSL_add_all_algorithms(void);
170 72
171# ifndef HAVE_HMAC_CTX_INIT
172# define HMAC_CTX_init(a)
173# endif
174
175# ifndef HAVE_EVP_MD_CTX_INIT
176# define EVP_MD_CTX_init(a)
177# endif
178
179# ifndef HAVE_EVP_MD_CTX_CLEANUP
180# define EVP_MD_CTX_cleanup(a)
181# endif
182
183#endif /* SSH_DONT_OVERLOAD_OPENSSL_FUNCS */ 73#endif /* SSH_DONT_OVERLOAD_OPENSSL_FUNCS */
184 74
diff --git a/packet.c b/packet.c
index 3dd66d7d9..b97257986 100644
--- a/packet.c
+++ b/packet.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: packet.c,v 1.196 2014/05/03 17:20:34 markus Exp $ */ 1/* $OpenBSD: packet.c,v 1.197 2014/06/24 01:13:21 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
@@ -78,6 +78,7 @@
78#include "canohost.h" 78#include "canohost.h"
79#include "misc.h" 79#include "misc.h"
80#include "ssh.h" 80#include "ssh.h"
81#include "ssherr.h"
81#include "roaming.h" 82#include "roaming.h"
82 83
83#ifdef PACKET_DEBUG 84#ifdef PACKET_DEBUG
@@ -222,6 +223,7 @@ void
222packet_set_connection(int fd_in, int fd_out) 223packet_set_connection(int fd_in, int fd_out)
223{ 224{
224 const Cipher *none = cipher_by_name("none"); 225 const Cipher *none = cipher_by_name("none");
226 int r;
225 227
226 if (none == NULL) 228 if (none == NULL)
227 fatal("packet_set_connection: cannot load cipher 'none'"); 229 fatal("packet_set_connection: cannot load cipher 'none'");
@@ -229,10 +231,11 @@ packet_set_connection(int fd_in, int fd_out)
229 active_state = alloc_session_state(); 231 active_state = alloc_session_state();
230 active_state->connection_in = fd_in; 232 active_state->connection_in = fd_in;
231 active_state->connection_out = fd_out; 233 active_state->connection_out = fd_out;
232 cipher_init(&active_state->send_context, none, (const u_char *)"", 234 if ((r = cipher_init(&active_state->send_context, none,
233 0, NULL, 0, CIPHER_ENCRYPT); 235 (const u_char *)"", 0, NULL, 0, CIPHER_ENCRYPT)) != 0 ||
234 cipher_init(&active_state->receive_context, none, (const u_char *)"", 236 (r = cipher_init(&active_state->receive_context, none,
235 0, NULL, 0, CIPHER_DECRYPT); 237 (const u_char *)"", 0, NULL, 0, CIPHER_DECRYPT)) != 0)
238 fatal("%s: cipher_init: %s", __func__, ssh_err(r));
236 active_state->newkeys[MODE_IN] = active_state->newkeys[MODE_OUT] = NULL; 239 active_state->newkeys[MODE_IN] = active_state->newkeys[MODE_OUT] = NULL;
237 if (!active_state->initialized) { 240 if (!active_state->initialized) {
238 active_state->initialized = 1; 241 active_state->initialized = 1;
@@ -329,13 +332,15 @@ void
329packet_get_keyiv(int mode, u_char *iv, u_int len) 332packet_get_keyiv(int mode, u_char *iv, u_int len)
330{ 333{
331 CipherContext *cc; 334 CipherContext *cc;
335 int r;
332 336
333 if (mode == MODE_OUT) 337 if (mode == MODE_OUT)
334 cc = &active_state->send_context; 338 cc = &active_state->send_context;
335 else 339 else
336 cc = &active_state->receive_context; 340 cc = &active_state->receive_context;
337 341
338 cipher_get_keyiv(cc, iv, len); 342 if ((r = cipher_get_keyiv(cc, iv, len)) != 0)
343 fatal("%s: cipher_get_keyiv: %s", __func__, ssh_err(r));
339} 344}
340 345
341int 346int
@@ -381,13 +386,15 @@ void
381packet_set_iv(int mode, u_char *dat) 386packet_set_iv(int mode, u_char *dat)
382{ 387{
383 CipherContext *cc; 388 CipherContext *cc;
389 int r;
384 390
385 if (mode == MODE_OUT) 391 if (mode == MODE_OUT)
386 cc = &active_state->send_context; 392 cc = &active_state->send_context;
387 else 393 else
388 cc = &active_state->receive_context; 394 cc = &active_state->receive_context;
389 395
390 cipher_set_keyiv(cc, dat); 396 if ((r = cipher_set_keyiv(cc, dat)) != 0)
397 fatal("%s: cipher_set_keyiv: %s", __func__, ssh_err(r));
391} 398}
392 399
393int 400int
@@ -552,6 +559,7 @@ void
552packet_set_encryption_key(const u_char *key, u_int keylen, int number) 559packet_set_encryption_key(const u_char *key, u_int keylen, int number)
553{ 560{
554 const Cipher *cipher = cipher_by_number(number); 561 const Cipher *cipher = cipher_by_number(number);
562 int r;
555 563
556 if (cipher == NULL) 564 if (cipher == NULL)
557 fatal("packet_set_encryption_key: unknown cipher number %d", number); 565 fatal("packet_set_encryption_key: unknown cipher number %d", number);
@@ -561,10 +569,11 @@ packet_set_encryption_key(const u_char *key, u_int keylen, int number)
561 fatal("packet_set_encryption_key: keylen too big: %d", keylen); 569 fatal("packet_set_encryption_key: keylen too big: %d", keylen);
562 memcpy(active_state->ssh1_key, key, keylen); 570 memcpy(active_state->ssh1_key, key, keylen);
563 active_state->ssh1_keylen = keylen; 571 active_state->ssh1_keylen = keylen;
564 cipher_init(&active_state->send_context, cipher, key, keylen, NULL, 572 if ((r = cipher_init(&active_state->send_context, cipher,
565 0, CIPHER_ENCRYPT); 573 key, keylen, NULL, 0, CIPHER_ENCRYPT)) != 0 ||
566 cipher_init(&active_state->receive_context, cipher, key, keylen, NULL, 574 (r = cipher_init(&active_state->receive_context, cipher,
567 0, CIPHER_DECRYPT); 575 key, keylen, NULL, 0, CIPHER_DECRYPT)) != 0)
576 fatal("%s: cipher_init: %s", __func__, ssh_err(r));
568} 577}
569 578
570u_int 579u_int
@@ -744,7 +753,7 @@ set_newkeys(int mode)
744 Comp *comp; 753 Comp *comp;
745 CipherContext *cc; 754 CipherContext *cc;
746 u_int64_t *max_blocks; 755 u_int64_t *max_blocks;
747 int crypt_type; 756 int r, crypt_type;
748 757
749 debug2("set_newkeys: mode %d", mode); 758 debug2("set_newkeys: mode %d", mode);
750 759
@@ -786,8 +795,9 @@ set_newkeys(int mode)
786 if (cipher_authlen(enc->cipher) == 0 && mac_init(mac) == 0) 795 if (cipher_authlen(enc->cipher) == 0 && mac_init(mac) == 0)
787 mac->enabled = 1; 796 mac->enabled = 1;
788 DBG(debug("cipher_init_context: %d", mode)); 797 DBG(debug("cipher_init_context: %d", mode));
789 cipher_init(cc, enc->cipher, enc->key, enc->key_len, 798 if ((r = cipher_init(cc, enc->cipher, enc->key, enc->key_len,
790 enc->iv, enc->iv_len, crypt_type); 799 enc->iv, enc->iv_len, crypt_type)) != 0)
800 fatal("%s: cipher_init: %s", __func__, ssh_err(r));
791 /* Deleting the keys does not gain extra security */ 801 /* Deleting the keys does not gain extra security */
792 /* explicit_bzero(enc->iv, enc->block_size); 802 /* explicit_bzero(enc->iv, enc->block_size);
793 explicit_bzero(enc->key, enc->key_len); 803 explicit_bzero(enc->key, enc->key_len);
diff --git a/rsa.c b/rsa.c
index d0b5bbf5e..5ecacef90 100644
--- a/rsa.c
+++ b/rsa.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: rsa.c,v 1.31 2014/02/02 03:44:31 djm Exp $ */ 1/* $OpenBSD: rsa.c,v 1.32 2014/06/24 01:13:21 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
@@ -67,85 +67,122 @@
67#include <stdarg.h> 67#include <stdarg.h>
68#include <string.h> 68#include <string.h>
69 69
70#include "xmalloc.h"
71#include "rsa.h" 70#include "rsa.h"
72#include "log.h" 71#include "log.h"
72#include "ssherr.h"
73 73
74void 74int
75rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key) 75rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key)
76{ 76{
77 u_char *inbuf, *outbuf; 77 u_char *inbuf = NULL, *outbuf = NULL;
78 int len, ilen, olen; 78 int len, ilen, olen, r = SSH_ERR_INTERNAL_ERROR;
79 79
80 if (BN_num_bits(key->e) < 2 || !BN_is_odd(key->e)) 80 if (BN_num_bits(key->e) < 2 || !BN_is_odd(key->e))
81 fatal("rsa_public_encrypt() exponent too small or not odd"); 81 return SSH_ERR_INVALID_ARGUMENT;
82 82
83 olen = BN_num_bytes(key->n); 83 olen = BN_num_bytes(key->n);
84 outbuf = xmalloc(olen); 84 if ((outbuf = malloc(olen)) == NULL) {
85 r = SSH_ERR_ALLOC_FAIL;
86 goto out;
87 }
85 88
86 ilen = BN_num_bytes(in); 89 ilen = BN_num_bytes(in);
87 inbuf = xmalloc(ilen); 90 if ((inbuf = malloc(ilen)) == NULL) {
91 r = SSH_ERR_ALLOC_FAIL;
92 goto out;
93 }
88 BN_bn2bin(in, inbuf); 94 BN_bn2bin(in, inbuf);
89 95
90 if ((len = RSA_public_encrypt(ilen, inbuf, outbuf, key, 96 if ((len = RSA_public_encrypt(ilen, inbuf, outbuf, key,
91 RSA_PKCS1_PADDING)) <= 0) 97 RSA_PKCS1_PADDING)) <= 0) {
92 fatal("rsa_public_encrypt() failed"); 98 r = SSH_ERR_LIBCRYPTO_ERROR;
99 goto out;
100 }
93 101
94 if (BN_bin2bn(outbuf, len, out) == NULL) 102 if (BN_bin2bn(outbuf, len, out) == NULL) {
95 fatal("rsa_public_encrypt: BN_bin2bn failed"); 103 r = SSH_ERR_LIBCRYPTO_ERROR;
104 goto out;
105 }
106 r = 0;
96 107
97 explicit_bzero(outbuf, olen); 108 out:
98 explicit_bzero(inbuf, ilen); 109 if (outbuf != NULL) {
99 free(outbuf); 110 explicit_bzero(outbuf, olen);
100 free(inbuf); 111 free(outbuf);
112 }
113 if (inbuf != NULL) {
114 explicit_bzero(inbuf, ilen);
115 free(inbuf);
116 }
117 return r;
101} 118}
102 119
103int 120int
104rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key) 121rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key)
105{ 122{
106 u_char *inbuf, *outbuf; 123 u_char *inbuf = NULL, *outbuf = NULL;
107 int len, ilen, olen; 124 int len, ilen, olen, r = SSH_ERR_INTERNAL_ERROR;
108 125
109 olen = BN_num_bytes(key->n); 126 olen = BN_num_bytes(key->n);
110 outbuf = xmalloc(olen); 127 if ((outbuf = malloc(olen)) == NULL) {
128 r = SSH_ERR_ALLOC_FAIL;
129 goto out;
130 }
111 131
112 ilen = BN_num_bytes(in); 132 ilen = BN_num_bytes(in);
113 inbuf = xmalloc(ilen); 133 if ((inbuf = malloc(ilen)) == NULL) {
134 r = SSH_ERR_ALLOC_FAIL;
135 goto out;
136 }
114 BN_bn2bin(in, inbuf); 137 BN_bn2bin(in, inbuf);
115 138
116 if ((len = RSA_private_decrypt(ilen, inbuf, outbuf, key, 139 if ((len = RSA_private_decrypt(ilen, inbuf, outbuf, key,
117 RSA_PKCS1_PADDING)) <= 0) { 140 RSA_PKCS1_PADDING)) <= 0) {
118 error("rsa_private_decrypt() failed"); 141 r = SSH_ERR_LIBCRYPTO_ERROR;
119 } else { 142 goto out;
120 if (BN_bin2bn(outbuf, len, out) == NULL) 143 } else if (BN_bin2bn(outbuf, len, out) == NULL) {
121 fatal("rsa_private_decrypt: BN_bin2bn failed"); 144 r = SSH_ERR_LIBCRYPTO_ERROR;
145 goto out;
146 }
147 r = 0;
148 out:
149 if (outbuf != NULL) {
150 explicit_bzero(outbuf, olen);
151 free(outbuf);
152 }
153 if (inbuf != NULL) {
154 explicit_bzero(inbuf, ilen);
155 free(inbuf);
122 } 156 }
123 explicit_bzero(outbuf, olen); 157 return r;
124 explicit_bzero(inbuf, ilen);
125 free(outbuf);
126 free(inbuf);
127 return len;
128} 158}
129 159
130/* calculate p-1 and q-1 */ 160/* calculate p-1 and q-1 */
131void 161int
132rsa_generate_additional_parameters(RSA *rsa) 162rsa_generate_additional_parameters(RSA *rsa)
133{ 163{
134 BIGNUM *aux; 164 BIGNUM *aux = NULL;
135 BN_CTX *ctx; 165 BN_CTX *ctx = NULL;
166 int r;
136 167
137 if ((aux = BN_new()) == NULL)
138 fatal("rsa_generate_additional_parameters: BN_new failed");
139 if ((ctx = BN_CTX_new()) == NULL) 168 if ((ctx = BN_CTX_new()) == NULL)
140 fatal("rsa_generate_additional_parameters: BN_CTX_new failed"); 169 return SSH_ERR_ALLOC_FAIL;
170 if ((aux = BN_new()) == NULL) {
171 r = SSH_ERR_ALLOC_FAIL;
172 goto out;
173 }
141 174
142 if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) || 175 if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) ||
143 (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) || 176 (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) ||
144 (BN_sub(aux, rsa->p, BN_value_one()) == 0) || 177 (BN_sub(aux, rsa->p, BN_value_one()) == 0) ||
145 (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) 178 (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) {
146 fatal("rsa_generate_additional_parameters: BN_sub/mod failed"); 179 r = SSH_ERR_LIBCRYPTO_ERROR;
147 180 goto out;
181 }
182 r = 0;
183 out:
148 BN_clear_free(aux); 184 BN_clear_free(aux);
149 BN_CTX_free(ctx); 185 BN_CTX_free(ctx);
186 return r;
150} 187}
151 188
diff --git a/rsa.h b/rsa.h
index b841ea4e1..c476707d5 100644
--- a/rsa.h
+++ b/rsa.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: rsa.h,v 1.16 2006/03/25 22:22:43 djm Exp $ */ 1/* $OpenBSD: rsa.h,v 1.17 2014/06/24 01:13:21 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -19,8 +19,8 @@
19#include <openssl/bn.h> 19#include <openssl/bn.h>
20#include <openssl/rsa.h> 20#include <openssl/rsa.h>
21 21
22void rsa_public_encrypt(BIGNUM *, BIGNUM *, RSA *); 22int rsa_public_encrypt(BIGNUM *, BIGNUM *, RSA *);
23int rsa_private_decrypt(BIGNUM *, BIGNUM *, RSA *); 23int rsa_private_decrypt(BIGNUM *, BIGNUM *, RSA *);
24void rsa_generate_additional_parameters(RSA *); 24int rsa_generate_additional_parameters(RSA *);
25 25
26#endif /* RSA_H */ 26#endif /* RSA_H */
diff --git a/ssh-add.c b/ssh-add.c
index 3421452af..46b91cbde 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-add.c,v 1.109 2014/02/02 03:44:31 djm Exp $ */ 1/* $OpenBSD: ssh-add.c,v 1.110 2014/06/24 01:13:21 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
@@ -62,6 +62,7 @@
62#include "authfile.h" 62#include "authfile.h"
63#include "pathnames.h" 63#include "pathnames.h"
64#include "misc.h" 64#include "misc.h"
65#include "ssherr.h"
65 66
66/* argv0 */ 67/* argv0 */
67extern char *__progname; 68extern char *__progname;
@@ -170,7 +171,7 @@ add_file(AuthenticationConnection *ac, const char *filename, int key_only)
170 Key *private, *cert; 171 Key *private, *cert;
171 char *comment = NULL; 172 char *comment = NULL;
172 char msg[1024], *certpath = NULL; 173 char msg[1024], *certpath = NULL;
173 int fd, perms_ok, ret = -1; 174 int r, fd, perms_ok, ret = -1;
174 Buffer keyblob; 175 Buffer keyblob;
175 176
176 if (strcmp(filename, "-") == 0) { 177 if (strcmp(filename, "-") == 0) {
@@ -201,12 +202,18 @@ add_file(AuthenticationConnection *ac, const char *filename, int key_only)
201 close(fd); 202 close(fd);
202 203
203 /* At first, try empty passphrase */ 204 /* At first, try empty passphrase */
204 private = key_parse_private(&keyblob, filename, "", &comment); 205 if ((r = sshkey_parse_private_fileblob(&keyblob, filename, "",
206 &private, &comment)) != 0 && r != SSH_ERR_KEY_WRONG_PASSPHRASE)
207 fatal("Cannot parse %s: %s", filename, ssh_err(r));
205 if (comment == NULL) 208 if (comment == NULL)
206 comment = xstrdup(filename); 209 comment = xstrdup(filename);
207 /* try last */ 210 /* try last */
208 if (private == NULL && pass != NULL) 211 if (private == NULL && pass != NULL) {
209 private = key_parse_private(&keyblob, filename, pass, NULL); 212 if ((r = sshkey_parse_private_fileblob(&keyblob, filename, pass,
213 &private, &comment)) != 0 &&
214 r != SSH_ERR_KEY_WRONG_PASSPHRASE)
215 fatal("Cannot parse %s: %s", filename, ssh_err(r));
216 }
210 if (private == NULL) { 217 if (private == NULL) {
211 /* clear passphrase since it did not work */ 218 /* clear passphrase since it did not work */
212 clear_pass(); 219 clear_pass();
@@ -220,8 +227,11 @@ add_file(AuthenticationConnection *ac, const char *filename, int key_only)
220 buffer_free(&keyblob); 227 buffer_free(&keyblob);
221 return -1; 228 return -1;
222 } 229 }
223 private = key_parse_private(&keyblob, filename, pass, 230 if ((r = sshkey_parse_private_fileblob(&keyblob,
224 &comment); 231 filename, pass, &private, &comment)) != 0 &&
232 r != SSH_ERR_KEY_WRONG_PASSPHRASE)
233 fatal("Cannot parse %s: %s",
234 filename, ssh_err(r));
225 if (private != NULL) 235 if (private != NULL)
226 break; 236 break;
227 clear_pass(); 237 clear_pass();
diff --git a/ssh-agent.c b/ssh-agent.c
index bc96ad705..693d763e2 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.185 2014/04/29 18:01:49 markus Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.186 2014/06/24 01:13:21 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
@@ -278,7 +278,7 @@ process_authentication_challenge1(SocketEntry *e)
278 if (id != NULL && (!id->confirm || confirm_key(id) == 0)) { 278 if (id != NULL && (!id->confirm || confirm_key(id) == 0)) {
279 Key *private = id->key; 279 Key *private = id->key;
280 /* Decrypt the challenge using the private key. */ 280 /* Decrypt the challenge using the private key. */
281 if (rsa_private_decrypt(challenge, challenge, private->rsa) <= 0) 281 if (rsa_private_decrypt(challenge, challenge, private->rsa) != 0)
282 goto failure; 282 goto failure;
283 283
284 /* The response is MD5 of decrypted challenge plus session id. */ 284 /* The response is MD5 of decrypted challenge plus session id. */
@@ -365,12 +365,16 @@ process_sign_request2(SocketEntry *e)
365static void 365static void
366process_remove_identity(SocketEntry *e, int version) 366process_remove_identity(SocketEntry *e, int version)
367{ 367{
368 u_int blen, bits; 368 u_int blen;
369 int success = 0; 369 int success = 0;
370 Key *key = NULL; 370 Key *key = NULL;
371 u_char *blob; 371 u_char *blob;
372#ifdef WITH_SSH1
373 u_int bits;
374#endif /* WITH_SSH1 */
372 375
373 switch (version) { 376 switch (version) {
377#ifdef WITH_SSH1
374 case 1: 378 case 1:
375 key = key_new(KEY_RSA1); 379 key = key_new(KEY_RSA1);
376 bits = buffer_get_int(&e->request); 380 bits = buffer_get_int(&e->request);
@@ -381,6 +385,7 @@ process_remove_identity(SocketEntry *e, int version)
381 logit("Warning: identity keysize mismatch: actual %u, announced %u", 385 logit("Warning: identity keysize mismatch: actual %u, announced %u",
382 key_size(key), bits); 386 key_size(key), bits);
383 break; 387 break;
388#endif /* WITH_SSH1 */
384 case 2: 389 case 2:
385 blob = buffer_get_string(&e->request, &blen); 390 blob = buffer_get_string(&e->request, &blen);
386 key = key_from_blob(blob, blen); 391 key = key_from_blob(blob, blen);
@@ -477,6 +482,7 @@ process_add_identity(SocketEntry *e, int version)
477 Key *k = NULL; 482 Key *k = NULL;
478 483
479 switch (version) { 484 switch (version) {
485#ifdef WITH_SSH1
480 case 1: 486 case 1:
481 k = key_new_private(KEY_RSA1); 487 k = key_new_private(KEY_RSA1);
482 (void) buffer_get_int(&e->request); /* ignored */ 488 (void) buffer_get_int(&e->request); /* ignored */
@@ -490,7 +496,9 @@ process_add_identity(SocketEntry *e, int version)
490 buffer_get_bignum(&e->request, k->rsa->p); /* q */ 496 buffer_get_bignum(&e->request, k->rsa->p); /* q */
491 497
492 /* Generate additional parameters */ 498 /* Generate additional parameters */
493 rsa_generate_additional_parameters(k->rsa); 499 if (rsa_generate_additional_parameters(k->rsa) != 0)
500 fatal("%s: rsa_generate_additional_parameters "
501 "error", __func__);
494 502
495 /* enable blinding */ 503 /* enable blinding */
496 if (RSA_blinding_on(k->rsa, NULL) != 1) { 504 if (RSA_blinding_on(k->rsa, NULL) != 1) {
@@ -499,6 +507,7 @@ process_add_identity(SocketEntry *e, int version)
499 goto send; 507 goto send;
500 } 508 }
501 break; 509 break;
510#endif /* WITH_SSH1 */
502 case 2: 511 case 2:
503 k = key_private_deserialize(&e->request); 512 k = key_private_deserialize(&e->request);
504 if (k == NULL) { 513 if (k == NULL) {
@@ -507,11 +516,10 @@ process_add_identity(SocketEntry *e, int version)
507 } 516 }
508 break; 517 break;
509 } 518 }
510 comment = buffer_get_string(&e->request, NULL); 519 if (k == NULL)
511 if (k == NULL) {
512 free(comment);
513 goto send; 520 goto send;
514 } 521 comment = buffer_get_string(&e->request, NULL);
522
515 while (buffer_len(&e->request)) { 523 while (buffer_len(&e->request)) {
516 switch ((type = buffer_get_char(&e->request))) { 524 switch ((type = buffer_get_char(&e->request))) {
517 case SSH_AGENT_CONSTRAIN_LIFETIME: 525 case SSH_AGENT_CONSTRAIN_LIFETIME:
diff --git a/ssh-dss.c b/ssh-dss.c
index 6b4abcb7d..02d1ec2d6 100644
--- a/ssh-dss.c
+++ b/ssh-dss.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-dss.c,v 1.31 2014/02/02 03:44:31 djm Exp $ */ 1/* $OpenBSD: ssh-dss.c,v 1.32 2014/06/24 01:13:21 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -33,157 +33,186 @@
33#include <stdarg.h> 33#include <stdarg.h>
34#include <string.h> 34#include <string.h>
35 35
36#include "xmalloc.h" 36#include "sshbuf.h"
37#include "buffer.h"
38#include "compat.h" 37#include "compat.h"
39#include "log.h" 38#include "ssherr.h"
40#include "key.h"
41#include "digest.h" 39#include "digest.h"
40#define SSHKEY_INTERNAL
41#include "sshkey.h"
42 42
43#define INTBLOB_LEN 20 43#define INTBLOB_LEN 20
44#define SIGBLOB_LEN (2*INTBLOB_LEN) 44#define SIGBLOB_LEN (2*INTBLOB_LEN)
45 45
46int 46int
47ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp, 47ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
48 const u_char *data, u_int datalen) 48 const u_char *data, size_t datalen, u_int compat)
49{ 49{
50 DSA_SIG *sig; 50 DSA_SIG *sig = NULL;
51 u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN]; 51 u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN];
52 u_int rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); 52 size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
53 Buffer b; 53 struct sshbuf *b = NULL;
54 54 int ret = SSH_ERR_INVALID_ARGUMENT;
55 if (key == NULL || key_type_plain(key->type) != KEY_DSA || 55
56 key->dsa == NULL) { 56 if (lenp != NULL)
57 error("%s: no DSA key", __func__); 57 *lenp = 0;
58 return -1; 58 if (sigp != NULL)
59 } 59 *sigp = NULL;
60 60
61 if (ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen, 61 if (key == NULL || key->dsa == NULL ||
62 digest, sizeof(digest)) != 0) { 62 sshkey_type_plain(key->type) != KEY_DSA)
63 error("%s: ssh_digest_memory failed", __func__); 63 return SSH_ERR_INVALID_ARGUMENT;
64 return -1; 64 if (dlen == 0)
65 } 65 return SSH_ERR_INTERNAL_ERROR;
66 66
67 sig = DSA_do_sign(digest, dlen, key->dsa); 67 if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
68 explicit_bzero(digest, sizeof(digest)); 68 digest, sizeof(digest))) != 0)
69 69 goto out;
70 if (sig == NULL) { 70
71 error("ssh_dss_sign: sign failed"); 71 if ((sig = DSA_do_sign(digest, dlen, key->dsa)) == NULL) {
72 return -1; 72 ret = SSH_ERR_LIBCRYPTO_ERROR;
73 goto out;
73 } 74 }
74 75
75 rlen = BN_num_bytes(sig->r); 76 rlen = BN_num_bytes(sig->r);
76 slen = BN_num_bytes(sig->s); 77 slen = BN_num_bytes(sig->s);
77 if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) { 78 if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
78 error("bad sig size %u %u", rlen, slen); 79 ret = SSH_ERR_INTERNAL_ERROR;
79 DSA_SIG_free(sig); 80 goto out;
80 return -1;
81 } 81 }
82 explicit_bzero(sigblob, SIGBLOB_LEN); 82 explicit_bzero(sigblob, SIGBLOB_LEN);
83 BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen); 83 BN_bn2bin(sig->r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen);
84 BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen); 84 BN_bn2bin(sig->s, sigblob + SIGBLOB_LEN - slen);
85 DSA_SIG_free(sig);
86 85
87 if (datafellows & SSH_BUG_SIGBLOB) { 86 if (compat & SSH_BUG_SIGBLOB) {
88 if (lenp != NULL)
89 *lenp = SIGBLOB_LEN;
90 if (sigp != NULL) { 87 if (sigp != NULL) {
91 *sigp = xmalloc(SIGBLOB_LEN); 88 if ((*sigp = malloc(SIGBLOB_LEN)) == NULL) {
89 ret = SSH_ERR_ALLOC_FAIL;
90 goto out;
91 }
92 memcpy(*sigp, sigblob, SIGBLOB_LEN); 92 memcpy(*sigp, sigblob, SIGBLOB_LEN);
93 } 93 }
94 if (lenp != NULL)
95 *lenp = SIGBLOB_LEN;
96 ret = 0;
94 } else { 97 } else {
95 /* ietf-drafts */ 98 /* ietf-drafts */
96 buffer_init(&b); 99 if ((b = sshbuf_new()) == NULL) {
97 buffer_put_cstring(&b, "ssh-dss"); 100 ret = SSH_ERR_ALLOC_FAIL;
98 buffer_put_string(&b, sigblob, SIGBLOB_LEN); 101 goto out;
99 len = buffer_len(&b); 102 }
100 if (lenp != NULL) 103 if ((ret = sshbuf_put_cstring(b, "ssh-dss")) != 0 ||
101 *lenp = len; 104 (ret = sshbuf_put_string(b, sigblob, SIGBLOB_LEN)) != 0)
105 goto out;
106 len = sshbuf_len(b);
102 if (sigp != NULL) { 107 if (sigp != NULL) {
103 *sigp = xmalloc(len); 108 if ((*sigp = malloc(len)) == NULL) {
104 memcpy(*sigp, buffer_ptr(&b), len); 109 ret = SSH_ERR_ALLOC_FAIL;
110 goto out;
111 }
112 memcpy(*sigp, sshbuf_ptr(b), len);
105 } 113 }
106 buffer_free(&b); 114 if (lenp != NULL)
115 *lenp = len;
116 ret = 0;
107 } 117 }
108 return 0; 118 out:
119 explicit_bzero(digest, sizeof(digest));
120 if (sig != NULL)
121 DSA_SIG_free(sig);
122 if (b != NULL)
123 sshbuf_free(b);
124 return ret;
109} 125}
126
110int 127int
111ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen, 128ssh_dss_verify(const struct sshkey *key,
112 const u_char *data, u_int datalen) 129 const u_char *signature, size_t signaturelen,
130 const u_char *data, size_t datalen, u_int compat)
113{ 131{
114 DSA_SIG *sig; 132 DSA_SIG *sig = NULL;
115 u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob; 133 u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL;
116 u_int len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); 134 size_t len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
117 int rlen, ret; 135 int ret = SSH_ERR_INTERNAL_ERROR;
118 Buffer b; 136 struct sshbuf *b = NULL;
119 137 char *ktype = NULL;
120 if (key == NULL || key_type_plain(key->type) != KEY_DSA || 138
121 key->dsa == NULL) { 139 if (key == NULL || key->dsa == NULL ||
122 error("%s: no DSA key", __func__); 140 sshkey_type_plain(key->type) != KEY_DSA)
123 return -1; 141 return SSH_ERR_INVALID_ARGUMENT;
124 } 142 if (dlen == 0)
143 return SSH_ERR_INTERNAL_ERROR;
125 144
126 /* fetch signature */ 145 /* fetch signature */
127 if (datafellows & SSH_BUG_SIGBLOB) { 146 if (compat & SSH_BUG_SIGBLOB) {
128 sigblob = xmalloc(signaturelen); 147 if ((sigblob = malloc(signaturelen)) == NULL)
148 return SSH_ERR_ALLOC_FAIL;
129 memcpy(sigblob, signature, signaturelen); 149 memcpy(sigblob, signature, signaturelen);
130 len = signaturelen; 150 len = signaturelen;
131 } else { 151 } else {
132 /* ietf-drafts */ 152 /* ietf-drafts */
133 char *ktype; 153 if ((b = sshbuf_from(signature, signaturelen)) == NULL)
134 buffer_init(&b); 154 return SSH_ERR_ALLOC_FAIL;
135 buffer_append(&b, signature, signaturelen); 155 if (sshbuf_get_cstring(b, &ktype, NULL) != 0 ||
136 ktype = buffer_get_cstring(&b, NULL); 156 sshbuf_get_string(b, &sigblob, &len) != 0) {
157 ret = SSH_ERR_INVALID_FORMAT;
158 goto out;
159 }
137 if (strcmp("ssh-dss", ktype) != 0) { 160 if (strcmp("ssh-dss", ktype) != 0) {
138 error("%s: cannot handle type %s", __func__, ktype); 161 ret = SSH_ERR_KEY_TYPE_MISMATCH;
139 buffer_free(&b); 162 goto out;
140 free(ktype);
141 return -1;
142 } 163 }
143 free(ktype); 164 if (sshbuf_len(b) != 0) {
144 sigblob = buffer_get_string(&b, &len); 165 ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
145 rlen = buffer_len(&b); 166 goto out;
146 buffer_free(&b);
147 if (rlen != 0) {
148 error("%s: remaining bytes in signature %d",
149 __func__, rlen);
150 free(sigblob);
151 return -1;
152 } 167 }
153 } 168 }
154 169
155 if (len != SIGBLOB_LEN) { 170 if (len != SIGBLOB_LEN) {
156 fatal("bad sigbloblen %u != SIGBLOB_LEN", len); 171 ret = SSH_ERR_INVALID_FORMAT;
172 goto out;
157 } 173 }
158 174
159 /* parse signature */ 175 /* parse signature */
160 if ((sig = DSA_SIG_new()) == NULL) 176 if ((sig = DSA_SIG_new()) == NULL ||
161 fatal("%s: DSA_SIG_new failed", __func__); 177 (sig->r = BN_new()) == NULL ||
162 if ((sig->r = BN_new()) == NULL) 178 (sig->s = BN_new()) == NULL) {
163 fatal("%s: BN_new failed", __func__); 179 ret = SSH_ERR_ALLOC_FAIL;
164 if ((sig->s = BN_new()) == NULL) 180 goto out;
165 fatal("ssh_dss_verify: BN_new failed"); 181 }
166 if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) || 182 if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) ||
167 (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL)) 183 (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL)) {
168 fatal("%s: BN_bin2bn failed", __func__); 184 ret = SSH_ERR_LIBCRYPTO_ERROR;
169 185 goto out;
170 /* clean up */ 186 }
171 explicit_bzero(sigblob, len);
172 free(sigblob);
173 187
174 /* sha1 the data */ 188 /* sha1 the data */
175 if (ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen, 189 if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
176 digest, sizeof(digest)) != 0) { 190 digest, sizeof(digest))) != 0)
177 error("%s: digest_memory failed", __func__); 191 goto out;
178 return -1; 192
193 switch (DSA_do_verify(digest, dlen, sig, key->dsa)) {
194 case 1:
195 ret = 0;
196 break;
197 case 0:
198 ret = SSH_ERR_SIGNATURE_INVALID;
199 goto out;
200 default:
201 ret = SSH_ERR_LIBCRYPTO_ERROR;
202 goto out;
179 } 203 }
180 204
181 ret = DSA_do_verify(digest, dlen, sig, key->dsa); 205 out:
182 explicit_bzero(digest, sizeof(digest)); 206 explicit_bzero(digest, sizeof(digest));
183 207 if (sig != NULL)
184 DSA_SIG_free(sig); 208 DSA_SIG_free(sig);
185 209 if (b != NULL)
186 debug("%s: signature %s", __func__, 210 sshbuf_free(b);
187 ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error"); 211 if (ktype != NULL)
212 free(ktype);
213 if (sigblob != NULL) {
214 explicit_bzero(sigblob, len);
215 free(sigblob);
216 }
188 return ret; 217 return ret;
189} 218}
diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c
index 551c9c460..1119db045 100644
--- a/ssh-ecdsa.c
+++ b/ssh-ecdsa.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-ecdsa.c,v 1.10 2014/02/03 23:28:00 djm Exp $ */ 1/* $OpenBSD: ssh-ecdsa.c,v 1.11 2014/06/24 01:13:21 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2010 Damien Miller. All rights reserved. 4 * Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -37,141 +37,155 @@
37 37
38#include <string.h> 38#include <string.h>
39 39
40#include "xmalloc.h" 40#include "sshbuf.h"
41#include "buffer.h" 41#include "ssherr.h"
42#include "compat.h"
43#include "log.h"
44#include "key.h"
45#include "digest.h" 42#include "digest.h"
43#define SSHKEY_INTERNAL
44#include "sshkey.h"
46 45
46/* ARGSUSED */
47int 47int
48ssh_ecdsa_sign(const Key *key, u_char **sigp, u_int *lenp, 48ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
49 const u_char *data, u_int datalen) 49 const u_char *data, size_t datalen, u_int compat)
50{ 50{
51 ECDSA_SIG *sig; 51 ECDSA_SIG *sig = NULL;
52 int hash_alg; 52 int hash_alg;
53 u_char digest[SSH_DIGEST_MAX_LENGTH]; 53 u_char digest[SSH_DIGEST_MAX_LENGTH];
54 u_int len, dlen; 54 size_t len, dlen;
55 Buffer b, bb; 55 struct sshbuf *b = NULL, *bb = NULL;
56 int ret = SSH_ERR_INTERNAL_ERROR;
56 57
57 if (key == NULL || key_type_plain(key->type) != KEY_ECDSA || 58 if (lenp != NULL)
58 key->ecdsa == NULL) { 59 *lenp = 0;
59 error("%s: no ECDSA key", __func__); 60 if (sigp != NULL)
60 return -1; 61 *sigp = NULL;
62
63 if (key == NULL || key->ecdsa == NULL ||
64 sshkey_type_plain(key->type) != KEY_ECDSA)
65 return SSH_ERR_INVALID_ARGUMENT;
66
67 if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 ||
68 (dlen = ssh_digest_bytes(hash_alg)) == 0)
69 return SSH_ERR_INTERNAL_ERROR;
70 if ((ret = ssh_digest_memory(hash_alg, data, datalen,
71 digest, sizeof(digest))) != 0)
72 goto out;
73
74 if ((sig = ECDSA_do_sign(digest, dlen, key->ecdsa)) == NULL) {
75 ret = SSH_ERR_LIBCRYPTO_ERROR;
76 goto out;
61 } 77 }
62 78
63 hash_alg = key_ec_nid_to_hash_alg(key->ecdsa_nid); 79 if ((bb = sshbuf_new()) == NULL || (b = sshbuf_new()) == NULL) {
64 if ((dlen = ssh_digest_bytes(hash_alg)) == 0) { 80 ret = SSH_ERR_ALLOC_FAIL;
65 error("%s: bad hash algorithm %d", __func__, hash_alg); 81 goto out;
66 return -1;
67 }
68 if (ssh_digest_memory(hash_alg, data, datalen,
69 digest, sizeof(digest)) != 0) {
70 error("%s: digest_memory failed", __func__);
71 return -1;
72 } 82 }
73 83 if ((ret = sshbuf_put_bignum2(bb, sig->r)) != 0 ||
74 sig = ECDSA_do_sign(digest, dlen, key->ecdsa); 84 (ret = sshbuf_put_bignum2(bb, sig->s)) != 0)
75 explicit_bzero(digest, sizeof(digest)); 85 goto out;
76 86 if ((ret = sshbuf_put_cstring(b, sshkey_ssh_name_plain(key))) != 0 ||
77 if (sig == NULL) { 87 (ret = sshbuf_put_stringb(b, bb)) != 0)
78 error("%s: sign failed", __func__); 88 goto out;
79 return -1; 89 len = sshbuf_len(b);
90 if (sigp != NULL) {
91 if ((*sigp = malloc(len)) == NULL) {
92 ret = SSH_ERR_ALLOC_FAIL;
93 goto out;
94 }
95 memcpy(*sigp, sshbuf_ptr(b), len);
80 } 96 }
81
82 buffer_init(&bb);
83 buffer_put_bignum2(&bb, sig->r);
84 buffer_put_bignum2(&bb, sig->s);
85 ECDSA_SIG_free(sig);
86
87 buffer_init(&b);
88 buffer_put_cstring(&b, key_ssh_name_plain(key));
89 buffer_put_string(&b, buffer_ptr(&bb), buffer_len(&bb));
90 buffer_free(&bb);
91 len = buffer_len(&b);
92 if (lenp != NULL) 97 if (lenp != NULL)
93 *lenp = len; 98 *lenp = len;
94 if (sigp != NULL) { 99 ret = 0;
95 *sigp = xmalloc(len); 100 out:
96 memcpy(*sigp, buffer_ptr(&b), len); 101 explicit_bzero(digest, sizeof(digest));
97 } 102 if (b != NULL)
98 buffer_free(&b); 103 sshbuf_free(b);
99 104 if (bb != NULL)
100 return 0; 105 sshbuf_free(bb);
106 if (sig != NULL)
107 ECDSA_SIG_free(sig);
108 return ret;
101} 109}
110
111/* ARGSUSED */
102int 112int
103ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen, 113ssh_ecdsa_verify(const struct sshkey *key,
104 const u_char *data, u_int datalen) 114 const u_char *signature, size_t signaturelen,
115 const u_char *data, size_t datalen, u_int compat)
105{ 116{
106 ECDSA_SIG *sig; 117 ECDSA_SIG *sig = NULL;
107 int hash_alg; 118 int hash_alg;
108 u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob; 119 u_char digest[SSH_DIGEST_MAX_LENGTH];
109 u_int len, dlen; 120 size_t dlen;
110 int rlen, ret; 121 int ret = SSH_ERR_INTERNAL_ERROR;
111 Buffer b, bb; 122 struct sshbuf *b = NULL, *sigbuf = NULL;
112 char *ktype; 123 char *ktype = NULL;
113 124
114 if (key == NULL || key_type_plain(key->type) != KEY_ECDSA || 125 if (key == NULL || key->ecdsa == NULL ||
115 key->ecdsa == NULL) { 126 sshkey_type_plain(key->type) != KEY_ECDSA)
116 error("%s: no ECDSA key", __func__); 127 return SSH_ERR_INVALID_ARGUMENT;
117 return -1; 128
118 } 129 if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 ||
130 (dlen = ssh_digest_bytes(hash_alg)) == 0)
131 return SSH_ERR_INTERNAL_ERROR;
119 132
120 /* fetch signature */ 133 /* fetch signature */
121 buffer_init(&b); 134 if ((b = sshbuf_from(signature, signaturelen)) == NULL)
122 buffer_append(&b, signature, signaturelen); 135 return SSH_ERR_ALLOC_FAIL;
123 ktype = buffer_get_string(&b, NULL); 136 if (sshbuf_get_cstring(b, &ktype, NULL) != 0 ||
124 if (strcmp(key_ssh_name_plain(key), ktype) != 0) { 137 sshbuf_froms(b, &sigbuf) != 0) {
125 error("%s: cannot handle type %s", __func__, ktype); 138 ret = SSH_ERR_INVALID_FORMAT;
126 buffer_free(&b); 139 goto out;
127 free(ktype);
128 return -1;
129 } 140 }
130 free(ktype); 141 if (strcmp(sshkey_ssh_name_plain(key), ktype) != 0) {
131 sigblob = buffer_get_string(&b, &len); 142 ret = SSH_ERR_KEY_TYPE_MISMATCH;
132 rlen = buffer_len(&b); 143 goto out;
133 buffer_free(&b); 144 }
134 if (rlen != 0) { 145 if (sshbuf_len(b) != 0) {
135 error("%s: remaining bytes in signature %d", __func__, rlen); 146 ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
136 free(sigblob); 147 goto out;
137 return -1;
138 } 148 }
139 149
140 /* parse signature */ 150 /* parse signature */
141 if ((sig = ECDSA_SIG_new()) == NULL) 151 if ((sig = ECDSA_SIG_new()) == NULL) {
142 fatal("%s: ECDSA_SIG_new failed", __func__); 152 ret = SSH_ERR_ALLOC_FAIL;
143 153 goto out;
144 buffer_init(&bb); 154 }
145 buffer_append(&bb, sigblob, len); 155 if (sshbuf_get_bignum2(sigbuf, sig->r) != 0 ||
146 buffer_get_bignum2(&bb, sig->r); 156 sshbuf_get_bignum2(sigbuf, sig->s) != 0) {
147 buffer_get_bignum2(&bb, sig->s); 157 ret = SSH_ERR_INVALID_FORMAT;
148 if (buffer_len(&bb) != 0) 158 goto out;
149 fatal("%s: remaining bytes in inner sigblob", __func__); 159 }
150 buffer_free(&bb); 160 if (sshbuf_len(sigbuf) != 0) {
151 161 ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
152 /* clean up */ 162 goto out;
153 explicit_bzero(sigblob, len);
154 free(sigblob);
155
156 /* hash the data */
157 hash_alg = key_ec_nid_to_hash_alg(key->ecdsa_nid);
158 if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
159 error("%s: bad hash algorithm %d", __func__, hash_alg);
160 return -1;
161 } 163 }
162 if (ssh_digest_memory(hash_alg, data, datalen, 164 if ((ret = ssh_digest_memory(hash_alg, data, datalen,
163 digest, sizeof(digest)) != 0) { 165 digest, sizeof(digest))) != 0)
164 error("%s: digest_memory failed", __func__); 166 goto out;
165 return -1; 167
168 switch (ECDSA_do_verify(digest, dlen, sig, key->ecdsa)) {
169 case 1:
170 ret = 0;
171 break;
172 case 0:
173 ret = SSH_ERR_SIGNATURE_INVALID;
174 goto out;
175 default:
176 ret = SSH_ERR_LIBCRYPTO_ERROR;
177 goto out;
166 } 178 }
167 179
168 ret = ECDSA_do_verify(digest, dlen, sig, key->ecdsa); 180 out:
169 explicit_bzero(digest, sizeof(digest)); 181 explicit_bzero(digest, sizeof(digest));
170 182 if (sigbuf != NULL)
171 ECDSA_SIG_free(sig); 183 sshbuf_free(sigbuf);
172 184 if (b != NULL)
173 debug("%s: signature %s", __func__, 185 sshbuf_free(b);
174 ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error"); 186 if (sig != NULL)
187 ECDSA_SIG_free(sig);
188 free(ktype);
175 return ret; 189 return ret;
176} 190}
177 191
diff --git a/ssh-ed25519.c b/ssh-ed25519.c
index 160d1f23b..cb87d4790 100644
--- a/ssh-ed25519.c
+++ b/ssh-ed25519.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-ed25519.c,v 1.3 2014/02/23 20:03:42 djm Exp $ */ 1/* $OpenBSD: ssh-ed25519.c,v 1.4 2014/06/24 01:13:21 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2013 Markus Friedl <markus@openbsd.org> 3 * Copyright (c) 2013 Markus Friedl <markus@openbsd.org>
4 * 4 *
@@ -18,132 +18,149 @@
18#include "includes.h" 18#include "includes.h"
19 19
20#include <sys/types.h> 20#include <sys/types.h>
21#include <limits.h>
21 22
22#include "crypto_api.h" 23#include "crypto_api.h"
23 24
24#include <limits.h>
25#include <string.h> 25#include <string.h>
26#include <stdarg.h> 26#include <stdarg.h>
27 27
28#include "xmalloc.h" 28#include "xmalloc.h"
29#include "log.h" 29#include "log.h"
30#include "buffer.h" 30#include "buffer.h"
31#include "key.h" 31#define SSHKEY_INTERNAL
32#include "sshkey.h"
33#include "ssherr.h"
32#include "ssh.h" 34#include "ssh.h"
33 35
34int 36int
35ssh_ed25519_sign(const Key *key, u_char **sigp, u_int *lenp, 37ssh_ed25519_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
36 const u_char *data, u_int datalen) 38 const u_char *data, size_t datalen, u_int compat)
37{ 39{
38 u_char *sig; 40 u_char *sig = NULL;
39 u_int slen, len; 41 size_t slen = 0, len;
40 unsigned long long smlen; 42 unsigned long long smlen;
41 int ret; 43 int r, ret;
42 Buffer b; 44 struct sshbuf *b = NULL;
43 45
44 if (key == NULL || key_type_plain(key->type) != KEY_ED25519 || 46 if (lenp != NULL)
45 key->ed25519_sk == NULL) { 47 *lenp = 0;
46 error("%s: no ED25519 key", __func__); 48 if (sigp != NULL)
47 return -1; 49 *sigp = NULL;
48 }
49 50
50 if (datalen >= UINT_MAX - crypto_sign_ed25519_BYTES) { 51 if (key == NULL ||
51 error("%s: datalen %u too long", __func__, datalen); 52 sshkey_type_plain(key->type) != KEY_ED25519 ||
52 return -1; 53 key->ed25519_sk == NULL ||
53 } 54 datalen >= INT_MAX - crypto_sign_ed25519_BYTES)
55 return SSH_ERR_INVALID_ARGUMENT;
54 smlen = slen = datalen + crypto_sign_ed25519_BYTES; 56 smlen = slen = datalen + crypto_sign_ed25519_BYTES;
55 sig = xmalloc(slen); 57 if ((sig = malloc(slen)) == NULL)
58 return SSH_ERR_ALLOC_FAIL;
56 59
57 if ((ret = crypto_sign_ed25519(sig, &smlen, data, datalen, 60 if ((ret = crypto_sign_ed25519(sig, &smlen, data, datalen,
58 key->ed25519_sk)) != 0 || smlen <= datalen) { 61 key->ed25519_sk)) != 0 || smlen <= datalen) {
59 error("%s: crypto_sign_ed25519 failed: %d", __func__, ret); 62 r = SSH_ERR_INVALID_ARGUMENT; /* XXX better error? */
60 free(sig); 63 goto out;
61 return -1;
62 } 64 }
63 /* encode signature */ 65 /* encode signature */
64 buffer_init(&b); 66 if ((b = sshbuf_new()) == NULL) {
65 buffer_put_cstring(&b, "ssh-ed25519"); 67 r = SSH_ERR_ALLOC_FAIL;
66 buffer_put_string(&b, sig, smlen - datalen); 68 goto out;
67 len = buffer_len(&b); 69 }
70 if ((r = sshbuf_put_cstring(b, "ssh-ed25519")) != 0 ||
71 (r = sshbuf_put_string(b, sig, smlen - datalen)) != 0)
72 goto out;
73 len = sshbuf_len(b);
74 if (sigp != NULL) {
75 if ((*sigp = malloc(len)) == NULL) {
76 r = SSH_ERR_ALLOC_FAIL;
77 goto out;
78 }
79 memcpy(*sigp, sshbuf_ptr(b), len);
80 }
68 if (lenp != NULL) 81 if (lenp != NULL)
69 *lenp = len; 82 *lenp = len;
70 if (sigp != NULL) { 83 /* success */
71 *sigp = xmalloc(len); 84 r = 0;
72 memcpy(*sigp, buffer_ptr(&b), len); 85 out:
86 sshbuf_free(b);
87 if (sig != NULL) {
88 explicit_bzero(sig, slen);
89 free(sig);
73 } 90 }
74 buffer_free(&b);
75 explicit_bzero(sig, slen);
76 free(sig);
77 91
78 return 0; 92 return r;
79} 93}
80 94
81int 95int
82ssh_ed25519_verify(const Key *key, const u_char *signature, u_int signaturelen, 96ssh_ed25519_verify(const struct sshkey *key,
83 const u_char *data, u_int datalen) 97 const u_char *signature, size_t signaturelen,
98 const u_char *data, size_t datalen, u_int compat)
84{ 99{
85 Buffer b; 100 struct sshbuf *b = NULL;
86 char *ktype; 101 char *ktype = NULL;
87 u_char *sigblob, *sm, *m; 102 const u_char *sigblob;
88 u_int len; 103 u_char *sm = NULL, *m = NULL;
89 unsigned long long smlen, mlen; 104 size_t len;
90 int rlen, ret; 105 unsigned long long smlen = 0, mlen = 0;
106 int r, ret;
91 107
92 if (key == NULL || key_type_plain(key->type) != KEY_ED25519 || 108 if (key == NULL ||
93 key->ed25519_pk == NULL) { 109 sshkey_type_plain(key->type) != KEY_ED25519 ||
94 error("%s: no ED25519 key", __func__); 110 key->ed25519_pk == NULL ||
95 return -1; 111 datalen >= INT_MAX - crypto_sign_ed25519_BYTES)
96 } 112 return SSH_ERR_INVALID_ARGUMENT;
97 buffer_init(&b); 113
98 buffer_append(&b, signature, signaturelen); 114 if ((b = sshbuf_from(signature, signaturelen)) == NULL)
99 ktype = buffer_get_cstring(&b, NULL); 115 return SSH_ERR_ALLOC_FAIL;
116 if ((r = sshbuf_get_cstring(b, &ktype, NULL)) != 0 ||
117 (r = sshbuf_get_string_direct(b, &sigblob, &len)) != 0)
118 goto out;
100 if (strcmp("ssh-ed25519", ktype) != 0) { 119 if (strcmp("ssh-ed25519", ktype) != 0) {
101 error("%s: cannot handle type %s", __func__, ktype); 120 r = SSH_ERR_KEY_TYPE_MISMATCH;
102 buffer_free(&b); 121 goto out;
103 free(ktype);
104 return -1;
105 } 122 }
106 free(ktype); 123 if (sshbuf_len(b) != 0) {
107 sigblob = buffer_get_string(&b, &len); 124 r = SSH_ERR_UNEXPECTED_TRAILING_DATA;
108 rlen = buffer_len(&b); 125 goto out;
109 buffer_free(&b);
110 if (rlen != 0) {
111 error("%s: remaining bytes in signature %d", __func__, rlen);
112 free(sigblob);
113 return -1;
114 } 126 }
115 if (len > crypto_sign_ed25519_BYTES) { 127 if (len > crypto_sign_ed25519_BYTES) {
116 error("%s: len %u > crypto_sign_ed25519_BYTES %u", __func__, 128 r = SSH_ERR_INVALID_FORMAT;
117 len, crypto_sign_ed25519_BYTES); 129 goto out;
118 free(sigblob);
119 return -1;
120 } 130 }
131 if (datalen >= SIZE_MAX - len)
132 return SSH_ERR_INVALID_ARGUMENT;
121 smlen = len + datalen; 133 smlen = len + datalen;
122 sm = xmalloc(smlen); 134 mlen = smlen;
135 if ((sm = malloc(smlen)) == NULL || (m = xmalloc(mlen)) == NULL) {
136 r = SSH_ERR_ALLOC_FAIL;
137 goto out;
138 }
123 memcpy(sm, sigblob, len); 139 memcpy(sm, sigblob, len);
124 memcpy(sm+len, data, datalen); 140 memcpy(sm+len, data, datalen);
125 mlen = smlen;
126 m = xmalloc(mlen);
127 if ((ret = crypto_sign_ed25519_open(m, &mlen, sm, smlen, 141 if ((ret = crypto_sign_ed25519_open(m, &mlen, sm, smlen,
128 key->ed25519_pk)) != 0) { 142 key->ed25519_pk)) != 0) {
129 debug2("%s: crypto_sign_ed25519_open failed: %d", 143 debug2("%s: crypto_sign_ed25519_open failed: %d",
130 __func__, ret); 144 __func__, ret);
131 } 145 }
132 if (ret == 0 && mlen != datalen) { 146 if (ret != 0 || mlen != datalen) {
133 debug2("%s: crypto_sign_ed25519_open " 147 r = SSH_ERR_SIGNATURE_INVALID;
134 "mlen != datalen (%llu != %u)", __func__, mlen, datalen); 148 goto out;
135 ret = -1;
136 } 149 }
137 /* XXX compare 'm' and 'data' ? */ 150 /* XXX compare 'm' and 'data' ? */
138 151 /* success */
139 explicit_bzero(sigblob, len); 152 r = 0;
140 explicit_bzero(sm, smlen); 153 out:
141 explicit_bzero(m, smlen); /* NB. mlen may be invalid if ret != 0 */ 154 if (sm != NULL) {
142 free(sigblob); 155 explicit_bzero(sm, smlen);
143 free(sm); 156 free(sm);
144 free(m); 157 }
145 debug("%s: signature %scorrect", __func__, (ret != 0) ? "in" : ""); 158 if (m != NULL) {
146 159 explicit_bzero(m, smlen); /* NB mlen may be invalid if r != 0 */
147 /* translate return code carefully */ 160 free(m);
148 return (ret == 0) ? 1 : -1; 161 }
162 sshbuf_free(b);
163 free(ktype);
164 return r;
149} 165}
166
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 085f1ec55..e2aa215b2 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.246 2014/04/29 18:01:49 markus Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.247 2014/06/24 01:13:21 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
@@ -482,7 +482,9 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
482 buffer_get_bignum_bits(&b, key->rsa->iqmp); 482 buffer_get_bignum_bits(&b, key->rsa->iqmp);
483 buffer_get_bignum_bits(&b, key->rsa->q); 483 buffer_get_bignum_bits(&b, key->rsa->q);
484 buffer_get_bignum_bits(&b, key->rsa->p); 484 buffer_get_bignum_bits(&b, key->rsa->p);
485 rsa_generate_additional_parameters(key->rsa); 485 if (rsa_generate_additional_parameters(key->rsa) != 0)
486 fatal("%s: rsa_generate_additional_parameters "
487 "error", __func__);
486 break; 488 break;
487 } 489 }
488 rlen = buffer_len(&b); 490 rlen = buffer_len(&b);
@@ -1637,12 +1639,12 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
1637 public->cert->valid_after = cert_valid_from; 1639 public->cert->valid_after = cert_valid_from;
1638 public->cert->valid_before = cert_valid_to; 1640 public->cert->valid_before = cert_valid_to;
1639 if (v00) { 1641 if (v00) {
1640 prepare_options_buf(&public->cert->critical, 1642 prepare_options_buf(public->cert->critical,
1641 OPTIONS_CRITICAL|OPTIONS_EXTENSIONS); 1643 OPTIONS_CRITICAL|OPTIONS_EXTENSIONS);
1642 } else { 1644 } else {
1643 prepare_options_buf(&public->cert->critical, 1645 prepare_options_buf(public->cert->critical,
1644 OPTIONS_CRITICAL); 1646 OPTIONS_CRITICAL);
1645 prepare_options_buf(&public->cert->extensions, 1647 prepare_options_buf(public->cert->extensions,
1646 OPTIONS_EXTENSIONS); 1648 OPTIONS_EXTENSIONS);
1647 } 1649 }
1648 public->cert->signature_key = key_from_private(ca); 1650 public->cert->signature_key = key_from_private(ca);
@@ -1913,19 +1915,19 @@ do_show_cert(struct passwd *pw)
1913 printf("\n"); 1915 printf("\n");
1914 } 1916 }
1915 printf(" Critical Options: "); 1917 printf(" Critical Options: ");
1916 if (buffer_len(&key->cert->critical) == 0) 1918 if (buffer_len(key->cert->critical) == 0)
1917 printf("(none)\n"); 1919 printf("(none)\n");
1918 else { 1920 else {
1919 printf("\n"); 1921 printf("\n");
1920 show_options(&key->cert->critical, v00, 1); 1922 show_options(key->cert->critical, v00, 1);
1921 } 1923 }
1922 if (!v00) { 1924 if (!v00) {
1923 printf(" Extensions: "); 1925 printf(" Extensions: ");
1924 if (buffer_len(&key->cert->extensions) == 0) 1926 if (buffer_len(key->cert->extensions) == 0)
1925 printf("(none)\n"); 1927 printf("(none)\n");
1926 else { 1928 else {
1927 printf("\n"); 1929 printf("\n");
1928 show_options(&key->cert->extensions, v00, 0); 1930 show_options(key->cert->extensions, v00, 0);
1929 } 1931 }
1930 } 1932 }
1931 exit(0); 1933 exit(0);
diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c
index 6c9f9d2c1..8c74864aa 100644
--- a/ssh-pkcs11-client.c
+++ b/ssh-pkcs11-client.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-pkcs11-client.c,v 1.4 2013/05/17 00:13:14 djm Exp $ */ 1/* $OpenBSD: ssh-pkcs11-client.c,v 1.5 2014/06/24 01:13:21 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2010 Markus Friedl. All rights reserved. 3 * Copyright (c) 2010 Markus Friedl. All rights reserved.
4 * 4 *
@@ -30,6 +30,8 @@
30#include <unistd.h> 30#include <unistd.h>
31#include <errno.h> 31#include <errno.h>
32 32
33#include <openssl/rsa.h>
34
33#include "pathnames.h" 35#include "pathnames.h"
34#include "xmalloc.h" 36#include "xmalloc.h"
35#include "buffer.h" 37#include "buffer.h"
diff --git a/ssh-pkcs11-helper.c b/ssh-pkcs11-helper.c
index b7c52beb8..0b1d8e4cc 100644
--- a/ssh-pkcs11-helper.c
+++ b/ssh-pkcs11-helper.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-pkcs11-helper.c,v 1.7 2013/12/02 02:56:17 djm Exp $ */ 1/* $OpenBSD: ssh-pkcs11-helper.c,v 1.8 2014/06/24 01:13:21 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2010 Markus Friedl. All rights reserved. 3 * Copyright (c) 2010 Markus Friedl. All rights reserved.
4 * 4 *
@@ -169,7 +169,7 @@ process_sign(void)
169{ 169{
170 u_char *blob, *data, *signature = NULL; 170 u_char *blob, *data, *signature = NULL;
171 u_int blen, dlen, slen = 0; 171 u_int blen, dlen, slen = 0;
172 int ok = -1, ret; 172 int ok = -1;
173 Key *key, *found; 173 Key *key, *found;
174 Buffer msg; 174 Buffer msg;
175 175
@@ -179,6 +179,9 @@ process_sign(void)
179 179
180 if ((key = key_from_blob(blob, blen)) != NULL) { 180 if ((key = key_from_blob(blob, blen)) != NULL) {
181 if ((found = lookup_key(key)) != NULL) { 181 if ((found = lookup_key(key)) != NULL) {
182#ifdef WITH_OPENSSL
183 int ret;
184
182 slen = RSA_size(key->rsa); 185 slen = RSA_size(key->rsa);
183 signature = xmalloc(slen); 186 signature = xmalloc(slen);
184 if ((ret = RSA_private_encrypt(dlen, data, signature, 187 if ((ret = RSA_private_encrypt(dlen, data, signature,
@@ -186,6 +189,7 @@ process_sign(void)
186 slen = ret; 189 slen = ret;
187 ok = 0; 190 ok = 0;
188 } 191 }
192#endif /* WITH_OPENSSL */
189 } 193 }
190 key_free(key); 194 key_free(key);
191 } 195 }
diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c
index d3e877291..c96be3bd2 100644
--- a/ssh-pkcs11.c
+++ b/ssh-pkcs11.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-pkcs11.c,v 1.13 2014/05/02 03:27:54 djm Exp $ */ 1/* $OpenBSD: ssh-pkcs11.c,v 1.14 2014/06/24 01:13:21 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2010 Markus Friedl. All rights reserved. 3 * Copyright (c) 2010 Markus Friedl. All rights reserved.
4 * 4 *
@@ -520,7 +520,7 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
520 key = key_new(KEY_UNSPEC); 520 key = key_new(KEY_UNSPEC);
521 key->rsa = rsa; 521 key->rsa = rsa;
522 key->type = KEY_RSA; 522 key->type = KEY_RSA;
523 key->flags |= KEY_FLAG_EXT; 523 key->flags |= SSHKEY_FLAG_EXT;
524 if (pkcs11_key_included(keysp, nkeys, key)) { 524 if (pkcs11_key_included(keysp, nkeys, key)) {
525 key_free(key); 525 key_free(key);
526 } else { 526 } else {
diff --git a/ssh-rsa.c b/ssh-rsa.c
index c6f25b3ee..fec1953b4 100644
--- a/ssh-rsa.c
+++ b/ssh-rsa.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-rsa.c,v 1.51 2014/02/02 03:44:31 djm Exp $ */ 1/* $OpenBSD: ssh-rsa.c,v 1.52 2014/06/24 01:13:21 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org> 3 * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org>
4 * 4 *
@@ -25,163 +25,167 @@
25#include <stdarg.h> 25#include <stdarg.h>
26#include <string.h> 26#include <string.h>
27 27
28#include "xmalloc.h" 28#include "sshbuf.h"
29#include "log.h"
30#include "buffer.h"
31#include "key.h"
32#include "compat.h" 29#include "compat.h"
33#include "misc.h" 30#include "ssherr.h"
34#include "ssh.h" 31#define SSHKEY_INTERNAL
32#include "sshkey.h"
35#include "digest.h" 33#include "digest.h"
36 34
37static int openssh_RSA_verify(int, u_char *, u_int, u_char *, u_int, RSA *); 35static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *);
38 36
39/* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */ 37/* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */
40int 38int
41ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp, 39ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
42 const u_char *data, u_int datalen) 40 const u_char *data, size_t datalen, u_int compat)
43{ 41{
44 int hash_alg; 42 int hash_alg;
45 u_char digest[SSH_DIGEST_MAX_LENGTH], *sig; 43 u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL;
46 u_int slen, dlen, len; 44 size_t slen;
47 int ok, nid; 45 u_int dlen, len;
48 Buffer b; 46 int nid, ret = SSH_ERR_INTERNAL_ERROR;
47 struct sshbuf *b = NULL;
49 48
50 if (key == NULL || key_type_plain(key->type) != KEY_RSA || 49 if (lenp != NULL)
51 key->rsa == NULL) { 50 *lenp = 0;
52 error("%s: no RSA key", __func__); 51 if (sigp != NULL)
53 return -1; 52 *sigp = NULL;
54 } 53
54 if (key == NULL || key->rsa == NULL ||
55 sshkey_type_plain(key->type) != KEY_RSA)
56 return SSH_ERR_INVALID_ARGUMENT;
57 slen = RSA_size(key->rsa);
58 if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
59 return SSH_ERR_INVALID_ARGUMENT;
55 60
56 /* hash the data */ 61 /* hash the data */
57 hash_alg = SSH_DIGEST_SHA1; 62 hash_alg = SSH_DIGEST_SHA1;
58 nid = NID_sha1; 63 nid = NID_sha1;
59 if ((dlen = ssh_digest_bytes(hash_alg)) == 0) { 64 if ((dlen = ssh_digest_bytes(hash_alg)) == 0)
60 error("%s: bad hash algorithm %d", __func__, hash_alg); 65 return SSH_ERR_INTERNAL_ERROR;
61 return -1; 66 if ((ret = ssh_digest_memory(hash_alg, data, datalen,
62 } 67 digest, sizeof(digest))) != 0)
63 if (ssh_digest_memory(hash_alg, data, datalen, 68 goto out;
64 digest, sizeof(digest)) != 0) {
65 error("%s: ssh_digest_memory failed", __func__);
66 return -1;
67 }
68
69 slen = RSA_size(key->rsa);
70 sig = xmalloc(slen);
71
72 ok = RSA_sign(nid, digest, dlen, sig, &len, key->rsa);
73 explicit_bzero(digest, sizeof(digest));
74 69
75 if (ok != 1) { 70 if ((sig = malloc(slen)) == NULL) {
76 int ecode = ERR_get_error(); 71 ret = SSH_ERR_ALLOC_FAIL;
72 goto out;
73 }
77 74
78 error("%s: RSA_sign failed: %s", __func__, 75 if (RSA_sign(nid, digest, dlen, sig, &len, key->rsa) != 1) {
79 ERR_error_string(ecode, NULL)); 76 ret = SSH_ERR_LIBCRYPTO_ERROR;
80 free(sig); 77 goto out;
81 return -1;
82 } 78 }
83 if (len < slen) { 79 if (len < slen) {
84 u_int diff = slen - len; 80 size_t diff = slen - len;
85 debug("slen %u > len %u", slen, len);
86 memmove(sig + diff, sig, len); 81 memmove(sig + diff, sig, len);
87 explicit_bzero(sig, diff); 82 explicit_bzero(sig, diff);
88 } else if (len > slen) { 83 } else if (len > slen) {
89 error("%s: slen %u slen2 %u", __func__, slen, len); 84 ret = SSH_ERR_INTERNAL_ERROR;
90 free(sig); 85 goto out;
91 return -1;
92 } 86 }
93 /* encode signature */ 87 /* encode signature */
94 buffer_init(&b); 88 if ((b = sshbuf_new()) == NULL) {
95 buffer_put_cstring(&b, "ssh-rsa"); 89 ret = SSH_ERR_ALLOC_FAIL;
96 buffer_put_string(&b, sig, slen); 90 goto out;
97 len = buffer_len(&b); 91 }
92 if ((ret = sshbuf_put_cstring(b, "ssh-rsa")) != 0 ||
93 (ret = sshbuf_put_string(b, sig, slen)) != 0)
94 goto out;
95 len = sshbuf_len(b);
96 if (sigp != NULL) {
97 if ((*sigp = malloc(len)) == NULL) {
98 ret = SSH_ERR_ALLOC_FAIL;
99 goto out;
100 }
101 memcpy(*sigp, sshbuf_ptr(b), len);
102 }
98 if (lenp != NULL) 103 if (lenp != NULL)
99 *lenp = len; 104 *lenp = len;
100 if (sigp != NULL) { 105 ret = 0;
101 *sigp = xmalloc(len); 106 out:
102 memcpy(*sigp, buffer_ptr(&b), len); 107 explicit_bzero(digest, sizeof(digest));
108 if (sig != NULL) {
109 explicit_bzero(sig, slen);
110 free(sig);
103 } 111 }
104 buffer_free(&b); 112 if (b != NULL)
105 explicit_bzero(sig, slen); 113 sshbuf_free(b);
106 free(sig);
107
108 return 0; 114 return 0;
109} 115}
110 116
111int 117int
112ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen, 118ssh_rsa_verify(const struct sshkey *key,
113 const u_char *data, u_int datalen) 119 const u_char *signature, size_t signaturelen,
120 const u_char *data, size_t datalen, u_int compat)
114{ 121{
115 Buffer b; 122 char *ktype = NULL;
116 int hash_alg; 123 int hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
117 char *ktype; 124 size_t len, diff, modlen, dlen;
118 u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob; 125 struct sshbuf *b = NULL;
119 u_int len, dlen, modlen; 126 u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL;
120 int rlen, ret;
121 127
122 if (key == NULL || key_type_plain(key->type) != KEY_RSA || 128 if (key == NULL || key->rsa == NULL ||
123 key->rsa == NULL) { 129 sshkey_type_plain(key->type) != KEY_RSA ||
124 error("%s: no RSA key", __func__); 130 BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
125 return -1; 131 return SSH_ERR_INVALID_ARGUMENT;
126 }
127 132
128 if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { 133 if ((b = sshbuf_from(signature, signaturelen)) == NULL)
129 error("%s: RSA modulus too small: %d < minimum %d bits", 134 return SSH_ERR_ALLOC_FAIL;
130 __func__, BN_num_bits(key->rsa->n), 135 if (sshbuf_get_cstring(b, &ktype, NULL) != 0) {
131 SSH_RSA_MINIMUM_MODULUS_SIZE); 136 ret = SSH_ERR_INVALID_FORMAT;
132 return -1; 137 goto out;
133 } 138 }
134 buffer_init(&b);
135 buffer_append(&b, signature, signaturelen);
136 ktype = buffer_get_cstring(&b, NULL);
137 if (strcmp("ssh-rsa", ktype) != 0) { 139 if (strcmp("ssh-rsa", ktype) != 0) {
138 error("%s: cannot handle type %s", __func__, ktype); 140 ret = SSH_ERR_KEY_TYPE_MISMATCH;
139 buffer_free(&b); 141 goto out;
140 free(ktype);
141 return -1;
142 } 142 }
143 free(ktype); 143 if (sshbuf_get_string(b, &sigblob, &len) != 0) {
144 sigblob = buffer_get_string(&b, &len); 144 ret = SSH_ERR_INVALID_FORMAT;
145 rlen = buffer_len(&b); 145 goto out;
146 buffer_free(&b); 146 }
147 if (rlen != 0) { 147 if (sshbuf_len(b) != 0) {
148 error("%s: remaining bytes in signature %d", __func__, rlen); 148 ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
149 free(sigblob); 149 goto out;
150 return -1;
151 } 150 }
152 /* RSA_verify expects a signature of RSA_size */ 151 /* RSA_verify expects a signature of RSA_size */
153 modlen = RSA_size(key->rsa); 152 modlen = RSA_size(key->rsa);
154 if (len > modlen) { 153 if (len > modlen) {
155 error("%s: len %u > modlen %u", __func__, len, modlen); 154 ret = SSH_ERR_KEY_BITS_MISMATCH;
156 free(sigblob); 155 goto out;
157 return -1;
158 } else if (len < modlen) { 156 } else if (len < modlen) {
159 u_int diff = modlen - len; 157 diff = modlen - len;
160 debug("%s: add padding: modlen %u > len %u", __func__, 158 osigblob = sigblob;
161 modlen, len); 159 if ((sigblob = realloc(sigblob, modlen)) == NULL) {
162 sigblob = xrealloc(sigblob, 1, modlen); 160 sigblob = osigblob; /* put it back for clear/free */
161 ret = SSH_ERR_ALLOC_FAIL;
162 goto out;
163 }
163 memmove(sigblob + diff, sigblob, len); 164 memmove(sigblob + diff, sigblob, len);
164 explicit_bzero(sigblob, diff); 165 explicit_bzero(sigblob, diff);
165 len = modlen; 166 len = modlen;
166 } 167 }
167 /* hash the data */
168 hash_alg = SSH_DIGEST_SHA1; 168 hash_alg = SSH_DIGEST_SHA1;
169 if ((dlen = ssh_digest_bytes(hash_alg)) == 0) { 169 if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
170 error("%s: bad hash algorithm %d", __func__, hash_alg); 170 ret = SSH_ERR_INTERNAL_ERROR;
171 return -1; 171 goto out;
172 }
173 if (ssh_digest_memory(hash_alg, data, datalen,
174 digest, sizeof(digest)) != 0) {
175 error("%s: ssh_digest_memory failed", __func__);
176 return -1;
177 } 172 }
173 if ((ret = ssh_digest_memory(hash_alg, data, datalen,
174 digest, sizeof(digest))) != 0)
175 goto out;
178 176
179 ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len, 177 ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len,
180 key->rsa); 178 key->rsa);
179 out:
180 if (sigblob != NULL) {
181 explicit_bzero(sigblob, len);
182 free(sigblob);
183 }
184 if (ktype != NULL)
185 free(ktype);
186 if (b != NULL)
187 sshbuf_free(b);
181 explicit_bzero(digest, sizeof(digest)); 188 explicit_bzero(digest, sizeof(digest));
182 explicit_bzero(sigblob, len);
183 free(sigblob);
184 debug("%s: signature %scorrect", __func__, (ret == 0) ? "in" : "");
185 return ret; 189 return ret;
186} 190}
187 191
@@ -204,15 +208,15 @@ static const u_char id_sha1[] = {
204}; 208};
205 209
206static int 210static int
207openssh_RSA_verify(int hash_alg, u_char *hash, u_int hashlen, 211openssh_RSA_verify(int hash_alg, u_char *hash, size_t hashlen,
208 u_char *sigbuf, u_int siglen, RSA *rsa) 212 u_char *sigbuf, size_t siglen, RSA *rsa)
209{ 213{
210 u_int ret, rsasize, oidlen = 0, hlen = 0; 214 size_t ret, rsasize = 0, oidlen = 0, hlen = 0;
211 int len, oidmatch, hashmatch; 215 int len, oidmatch, hashmatch;
212 const u_char *oid = NULL; 216 const u_char *oid = NULL;
213 u_char *decrypted = NULL; 217 u_char *decrypted = NULL;
214 218
215 ret = 0; 219 ret = SSH_ERR_INTERNAL_ERROR;
216 switch (hash_alg) { 220 switch (hash_alg) {
217 case SSH_DIGEST_SHA1: 221 case SSH_DIGEST_SHA1:
218 oid = id_sha1; 222 oid = id_sha1;
@@ -223,37 +227,39 @@ openssh_RSA_verify(int hash_alg, u_char *hash, u_int hashlen,
223 goto done; 227 goto done;
224 } 228 }
225 if (hashlen != hlen) { 229 if (hashlen != hlen) {
226 error("bad hashlen"); 230 ret = SSH_ERR_INVALID_ARGUMENT;
227 goto done; 231 goto done;
228 } 232 }
229 rsasize = RSA_size(rsa); 233 rsasize = RSA_size(rsa);
230 if (siglen == 0 || siglen > rsasize) { 234 if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM ||
231 error("bad siglen"); 235 siglen == 0 || siglen > rsasize) {
236 ret = SSH_ERR_INVALID_ARGUMENT;
237 goto done;
238 }
239 if ((decrypted = malloc(rsasize)) == NULL) {
240 ret = SSH_ERR_ALLOC_FAIL;
232 goto done; 241 goto done;
233 } 242 }
234 decrypted = xmalloc(rsasize);
235 if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa, 243 if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa,
236 RSA_PKCS1_PADDING)) < 0) { 244 RSA_PKCS1_PADDING)) < 0) {
237 error("RSA_public_decrypt failed: %s", 245 ret = SSH_ERR_LIBCRYPTO_ERROR;
238 ERR_error_string(ERR_get_error(), NULL));
239 goto done; 246 goto done;
240 } 247 }
241 if (len < 0 || (u_int)len != hlen + oidlen) { 248 if (len < 0 || (size_t)len != hlen + oidlen) {
242 error("bad decrypted len: %d != %d + %d", len, hlen, oidlen); 249 ret = SSH_ERR_INVALID_FORMAT;
243 goto done; 250 goto done;
244 } 251 }
245 oidmatch = timingsafe_bcmp(decrypted, oid, oidlen) == 0; 252 oidmatch = timingsafe_bcmp(decrypted, oid, oidlen) == 0;
246 hashmatch = timingsafe_bcmp(decrypted + oidlen, hash, hlen) == 0; 253 hashmatch = timingsafe_bcmp(decrypted + oidlen, hash, hlen) == 0;
247 if (!oidmatch) { 254 if (!oidmatch || !hashmatch) {
248 error("oid mismatch"); 255 ret = SSH_ERR_SIGNATURE_INVALID;
249 goto done;
250 }
251 if (!hashmatch) {
252 error("hash mismatch");
253 goto done; 256 goto done;
254 } 257 }
255 ret = 1; 258 ret = 0;
256done: 259done:
257 free(decrypted); 260 if (decrypted) {
261 explicit_bzero(decrypted, rsasize);
262 free(decrypted);
263 }
258 return ret; 264 return ret;
259} 265}
diff --git a/sshbuf-misc.c b/sshbuf-misc.c
index 22dbfd5a4..bfeffe674 100644
--- a/sshbuf-misc.c
+++ b/sshbuf-misc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshbuf-misc.c,v 1.1 2014/04/30 05:29:56 djm Exp $ */ 1/* $OpenBSD: sshbuf-misc.c,v 1.2 2014/06/24 01:13:21 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller 3 * Copyright (c) 2011 Damien Miller
4 * 4 *
@@ -33,12 +33,11 @@
33#include "sshbuf.h" 33#include "sshbuf.h"
34 34
35void 35void
36sshbuf_dump(struct sshbuf *buf, FILE *f) 36sshbuf_dump_data(const void *s, size_t len, FILE *f)
37{ 37{
38 const u_char *p = sshbuf_ptr(buf); 38 size_t i, j;
39 size_t i, j, len = sshbuf_len(buf); 39 const u_char *p = (const u_char *)s;
40 40
41 fprintf(f, "buffer %p len = %zu\n", buf, len);
42 for (i = 0; i < len; i += 16) { 41 for (i = 0; i < len; i += 16) {
43 fprintf(f, "%.4zd: ", i); 42 fprintf(f, "%.4zd: ", i);
44 for (j = i; j < i + 16; j++) { 43 for (j = i; j < i + 16; j++) {
@@ -60,6 +59,13 @@ sshbuf_dump(struct sshbuf *buf, FILE *f)
60 } 59 }
61} 60}
62 61
62void
63sshbuf_dump(struct sshbuf *buf, FILE *f)
64{
65 fprintf(f, "buffer %p len = %zu\n", buf, sshbuf_len(buf));
66 sshbuf_dump_data(sshbuf_ptr(buf), sshbuf_len(buf), f);
67}
68
63char * 69char *
64sshbuf_dtob16(struct sshbuf *buf) 70sshbuf_dtob16(struct sshbuf *buf)
65{ 71{
diff --git a/sshbuf.h b/sshbuf.h
index 1dd9be45c..4561c0637 100644
--- a/sshbuf.h
+++ b/sshbuf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshbuf.h,v 1.2 2014/06/10 21:46:11 dtucker Exp $ */ 1/* $OpenBSD: sshbuf.h,v 1.3 2014/06/24 01:13:21 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller 3 * Copyright (c) 2011 Damien Miller
4 * 4 *
@@ -216,9 +216,12 @@ int sshbuf_put_ec(struct sshbuf *buf, const EC_POINT *v, const EC_GROUP *g);
216int sshbuf_put_eckey(struct sshbuf *buf, const EC_KEY *v); 216int sshbuf_put_eckey(struct sshbuf *buf, const EC_KEY *v);
217#endif 217#endif
218 218
219/* Dump the contents of the buffer to stderr in a human-readable format */ 219/* Dump the contents of the buffer in a human-readable format */
220void sshbuf_dump(struct sshbuf *buf, FILE *f); 220void sshbuf_dump(struct sshbuf *buf, FILE *f);
221 221
222/* Dump specified memory in a human-readable format */
223void sshbuf_dump_data(const void *s, size_t len, FILE *f);
224
222/* Return the hexadecimal representation of the contents of the buffer */ 225/* Return the hexadecimal representation of the contents of the buffer */
223char *sshbuf_dtob16(struct sshbuf *buf); 226char *sshbuf_dtob16(struct sshbuf *buf);
224 227
diff --git a/sshconnect.c b/sshconnect.c
index 5d14ca6cc..590dfe0f7 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect.c,v 1.248 2014/04/29 18:01:49 markus Exp $ */ 1/* $OpenBSD: sshconnect.c,v 1.249 2014/06/24 01:13:21 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
@@ -709,7 +709,7 @@ check_host_cert(const char *host, const Key *host_key)
709 error("%s", reason); 709 error("%s", reason);
710 return 0; 710 return 0;
711 } 711 }
712 if (buffer_len(&host_key->cert->critical) != 0) { 712 if (buffer_len(host_key->cert->critical) != 0) {
713 error("Certificate for %s contains unsupported " 713 error("Certificate for %s contains unsupported "
714 "critical options(s)", host); 714 "critical options(s)", host);
715 return 0; 715 return 0;
diff --git a/sshconnect1.c b/sshconnect1.c
index 921408ec1..62a7bd17f 100644
--- a/sshconnect1.c
+++ b/sshconnect1.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect1.c,v 1.74 2014/02/02 03:44:32 djm Exp $ */ 1/* $OpenBSD: sshconnect1.c,v 1.75 2014/06/24 01:13:21 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
@@ -166,7 +166,7 @@ respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
166 166
167 /* Decrypt the challenge using the private key. */ 167 /* Decrypt the challenge using the private key. */
168 /* XXX think about Bleichenbacher, too */ 168 /* XXX think about Bleichenbacher, too */
169 if (rsa_private_decrypt(challenge, challenge, prv) <= 0) 169 if (rsa_private_decrypt(challenge, challenge, prv) != 0)
170 packet_disconnect( 170 packet_disconnect(
171 "respond_to_rsa_challenge: rsa_private_decrypt failed"); 171 "respond_to_rsa_challenge: rsa_private_decrypt failed");
172 172
@@ -253,7 +253,7 @@ try_rsa_authentication(int idx)
253 * load the private key. Try first with empty passphrase; if it 253 * load the private key. Try first with empty passphrase; if it
254 * fails, ask for a passphrase. 254 * fails, ask for a passphrase.
255 */ 255 */
256 if (public->flags & KEY_FLAG_EXT) 256 if (public->flags & SSHKEY_FLAG_EXT)
257 private = public; 257 private = public;
258 else 258 else
259 private = key_load_private_type(KEY_RSA1, authfile, "", NULL, 259 private = key_load_private_type(KEY_RSA1, authfile, "", NULL,
@@ -302,7 +302,7 @@ try_rsa_authentication(int idx)
302 respond_to_rsa_challenge(challenge, private->rsa); 302 respond_to_rsa_challenge(challenge, private->rsa);
303 303
304 /* Destroy the private key unless it in external hardware. */ 304 /* Destroy the private key unless it in external hardware. */
305 if (!(private->flags & KEY_FLAG_EXT)) 305 if (!(private->flags & SSHKEY_FLAG_EXT))
306 key_free(private); 306 key_free(private);
307 307
308 /* We no longer need the challenge. */ 308 /* We no longer need the challenge. */
@@ -592,8 +592,9 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
592 BN_num_bits(server_key->rsa->n), 592 BN_num_bits(server_key->rsa->n),
593 SSH_KEY_BITS_RESERVED); 593 SSH_KEY_BITS_RESERVED);
594 } 594 }
595 rsa_public_encrypt(key, key, server_key->rsa); 595 if (rsa_public_encrypt(key, key, server_key->rsa) != 0 ||
596 rsa_public_encrypt(key, key, host_key->rsa); 596 rsa_public_encrypt(key, key, host_key->rsa) != 0)
597 fatal("%s: rsa_public_encrypt failed", __func__);
597 } else { 598 } else {
598 /* Host key has smaller modulus (or they are equal). */ 599 /* Host key has smaller modulus (or they are equal). */
599 if (BN_num_bits(server_key->rsa->n) < 600 if (BN_num_bits(server_key->rsa->n) <
@@ -604,8 +605,9 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
604 BN_num_bits(host_key->rsa->n), 605 BN_num_bits(host_key->rsa->n),
605 SSH_KEY_BITS_RESERVED); 606 SSH_KEY_BITS_RESERVED);
606 } 607 }
607 rsa_public_encrypt(key, key, host_key->rsa); 608 if (rsa_public_encrypt(key, key, host_key->rsa) != 0 ||
608 rsa_public_encrypt(key, key, server_key->rsa); 609 rsa_public_encrypt(key, key, server_key->rsa) != 0)
610 fatal("%s: rsa_public_encrypt failed", __func__);
609 } 611 }
610 612
611 /* Destroy the public keys since we no longer need them. */ 613 /* Destroy the public keys since we no longer need them. */
diff --git a/sshconnect2.c b/sshconnect2.c
index 658398436..eb1b0ae3c 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect2.c,v 1.208 2014/06/05 22:17:50 djm Exp $ */ 1/* $OpenBSD: sshconnect2.c,v 1.209 2014/06/24 01:13:21 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Damien Miller. All rights reserved. 4 * Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -970,7 +970,7 @@ identity_sign(Identity *id, u_char **sigp, u_int *lenp,
970 * we have already loaded the private key or 970 * we have already loaded the private key or
971 * the private key is stored in external hardware 971 * the private key is stored in external hardware
972 */ 972 */
973 if (id->isprivate || (id->key->flags & KEY_FLAG_EXT)) 973 if (id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT))
974 return (key_sign(id->key, sigp, lenp, data, datalen)); 974 return (key_sign(id->key, sigp, lenp, data, datalen));
975 /* load the private key from the file */ 975 /* load the private key from the file */
976 if ((prv = load_identity_file(id->filename, id->userprovided)) == NULL) 976 if ((prv = load_identity_file(id->filename, id->userprovided)) == NULL)
@@ -1178,12 +1178,12 @@ pubkey_prepare(Authctxt *authctxt)
1178 } 1178 }
1179 /* Prefer PKCS11 keys that are explicitly listed */ 1179 /* Prefer PKCS11 keys that are explicitly listed */
1180 TAILQ_FOREACH_SAFE(id, &files, next, tmp) { 1180 TAILQ_FOREACH_SAFE(id, &files, next, tmp) {
1181 if (id->key == NULL || (id->key->flags & KEY_FLAG_EXT) == 0) 1181 if (id->key == NULL || (id->key->flags & SSHKEY_FLAG_EXT) == 0)
1182 continue; 1182 continue;
1183 found = 0; 1183 found = 0;
1184 TAILQ_FOREACH(id2, &files, next) { 1184 TAILQ_FOREACH(id2, &files, next) {
1185 if (id2->key == NULL || 1185 if (id2->key == NULL ||
1186 (id2->key->flags & KEY_FLAG_EXT) == 0) 1186 (id2->key->flags & SSHKEY_FLAG_EXT) == 0)
1187 continue; 1187 continue;
1188 if (key_equal(id->key, id2->key)) { 1188 if (key_equal(id->key, id2->key)) {
1189 TAILQ_REMOVE(&files, id, next); 1189 TAILQ_REMOVE(&files, id, next);
diff --git a/sshd.c b/sshd.c
index 6e7192cf5..67eb66a11 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshd.c,v 1.426 2014/04/29 18:01:49 markus Exp $ */ 1/* $OpenBSD: sshd.c,v 1.427 2014/06/24 01:13:21 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
@@ -1031,8 +1031,10 @@ recv_rexec_state(int fd, Buffer *conf)
1031 buffer_get_bignum(&m, sensitive_data.server_key->rsa->iqmp); 1031 buffer_get_bignum(&m, sensitive_data.server_key->rsa->iqmp);
1032 buffer_get_bignum(&m, sensitive_data.server_key->rsa->p); 1032 buffer_get_bignum(&m, sensitive_data.server_key->rsa->p);
1033 buffer_get_bignum(&m, sensitive_data.server_key->rsa->q); 1033 buffer_get_bignum(&m, sensitive_data.server_key->rsa->q);
1034 rsa_generate_additional_parameters( 1034 if (rsa_generate_additional_parameters(
1035 sensitive_data.server_key->rsa); 1035 sensitive_data.server_key->rsa) != 0)
1036 fatal("%s: rsa_generate_additional_parameters "
1037 "error", __func__);
1036#else 1038#else
1037 fatal("ssh1 not supported"); 1039 fatal("ssh1 not supported");
1038#endif 1040#endif
@@ -2215,10 +2217,10 @@ ssh1_session_key(BIGNUM *session_key_int)
2215 SSH_KEY_BITS_RESERVED); 2217 SSH_KEY_BITS_RESERVED);
2216 } 2218 }
2217 if (rsa_private_decrypt(session_key_int, session_key_int, 2219 if (rsa_private_decrypt(session_key_int, session_key_int,
2218 sensitive_data.server_key->rsa) <= 0) 2220 sensitive_data.server_key->rsa) != 0)
2219 rsafail++; 2221 rsafail++;
2220 if (rsa_private_decrypt(session_key_int, session_key_int, 2222 if (rsa_private_decrypt(session_key_int, session_key_int,
2221 sensitive_data.ssh1_host_key->rsa) <= 0) 2223 sensitive_data.ssh1_host_key->rsa) != 0)
2222 rsafail++; 2224 rsafail++;
2223 } else { 2225 } else {
2224 /* Host key has bigger modulus (or they are equal). */ 2226 /* Host key has bigger modulus (or they are equal). */
@@ -2233,10 +2235,10 @@ ssh1_session_key(BIGNUM *session_key_int)
2233 SSH_KEY_BITS_RESERVED); 2235 SSH_KEY_BITS_RESERVED);
2234 } 2236 }
2235 if (rsa_private_decrypt(session_key_int, session_key_int, 2237 if (rsa_private_decrypt(session_key_int, session_key_int,
2236 sensitive_data.ssh1_host_key->rsa) < 0) 2238 sensitive_data.ssh1_host_key->rsa) != 0)
2237 rsafail++; 2239 rsafail++;
2238 if (rsa_private_decrypt(session_key_int, session_key_int, 2240 if (rsa_private_decrypt(session_key_int, session_key_int,
2239 sensitive_data.server_key->rsa) < 0) 2241 sensitive_data.server_key->rsa) != 0)
2240 rsafail++; 2242 rsafail++;
2241 } 2243 }
2242 return (rsafail); 2244 return (rsafail);
diff --git a/sshkey.c b/sshkey.c
new file mode 100644
index 000000000..24023d036
--- /dev/null
+++ b/sshkey.c
@@ -0,0 +1,3843 @@
1/* $OpenBSD: sshkey.c,v 1.2 2014/06/27 18:50:39 markus 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>
31#include <sys/types.h>
32
33#include <openssl/evp.h>
34#include <openssl/err.h>
35#include <openssl/pem.h>
36
37#include "crypto_api.h"
38
39#include <errno.h>
40#include <stdio.h>
41#include <string.h>
42#include <util.h>
43
44#include "ssh2.h"
45#include "ssherr.h"
46#include "misc.h"
47#include "sshbuf.h"
48#include "rsa.h"
49#include "cipher.h"
50#include "digest.h"
51#define SSHKEY_INTERNAL
52#include "sshkey.h"
53
54/* openssh private key file format */
55#define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n"
56#define MARK_END "-----END OPENSSH PRIVATE KEY-----\n"
57#define MARK_BEGIN_LEN (sizeof(MARK_BEGIN) - 1)
58#define MARK_END_LEN (sizeof(MARK_END) - 1)
59#define KDFNAME "bcrypt"
60#define AUTH_MAGIC "openssh-key-v1"
61#define SALT_LEN 16
62#define DEFAULT_CIPHERNAME "aes256-cbc"
63#define DEFAULT_ROUNDS 16
64
65/* Version identification string for SSH v1 identity files. */
66#define LEGACY_BEGIN "SSH PRIVATE KEY FILE FORMAT 1.1\n"
67
68static int sshkey_from_blob_internal(const u_char *blob, size_t blen,
69 struct sshkey **keyp, int allow_cert);
70
71/* Supported key types */
72struct keytype {
73 const char *name;
74 const char *shortname;
75 int type;
76 int nid;
77 int cert;
78};
79static const struct keytype keytypes[] = {
80 { "ssh-ed25519", "ED25519", KEY_ED25519, 0, 0 },
81 { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT",
82 KEY_ED25519_CERT, 0, 1 },
83#ifdef WITH_OPENSSL
84 { NULL, "RSA1", KEY_RSA1, 0, 0 },
85 { "ssh-rsa", "RSA", KEY_RSA, 0, 0 },
86 { "ssh-dss", "DSA", KEY_DSA, 0, 0 },
87# ifdef OPENSSL_HAS_ECC
88 { "ecdsa-sha2-nistp256", "ECDSA", KEY_ECDSA, NID_X9_62_prime256v1, 0 },
89 { "ecdsa-sha2-nistp384", "ECDSA", KEY_ECDSA, NID_secp384r1, 0 },
90# ifdef OPENSSL_HAS_NISTP521
91 { "ecdsa-sha2-nistp521", "ECDSA", KEY_ECDSA, NID_secp521r1, 0 },
92# endif /* OPENSSL_HAS_NISTP521 */
93# endif /* OPENSSL_HAS_ECC */
94 { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", KEY_RSA_CERT, 0, 1 },
95 { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", KEY_DSA_CERT, 0, 1 },
96# ifdef OPENSSL_HAS_ECC
97 { "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-CERT",
98 KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1 },
99 { "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA-CERT",
100 KEY_ECDSA_CERT, NID_secp384r1, 1 },
101# ifdef OPENSSL_HAS_NISTP521
102 { "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT",
103 KEY_ECDSA_CERT, NID_secp521r1, 1 },
104# endif /* OPENSSL_HAS_NISTP521 */
105# endif /* OPENSSL_HAS_ECC */
106 { "ssh-rsa-cert-v00@openssh.com", "RSA-CERT-V00",
107 KEY_RSA_CERT_V00, 0, 1 },
108 { "ssh-dss-cert-v00@openssh.com", "DSA-CERT-V00",
109 KEY_DSA_CERT_V00, 0, 1 },
110#endif /* WITH_OPENSSL */
111 { NULL, NULL, -1, -1, 0 }
112};
113
114const char *
115sshkey_type(const struct sshkey *k)
116{
117 const struct keytype *kt;
118
119 for (kt = keytypes; kt->type != -1; kt++) {
120 if (kt->type == k->type)
121 return kt->shortname;
122 }
123 return "unknown";
124}
125
126static const char *
127sshkey_ssh_name_from_type_nid(int type, int nid)
128{
129 const struct keytype *kt;
130
131 for (kt = keytypes; kt->type != -1; kt++) {
132 if (kt->type == type && (kt->nid == 0 || kt->nid == nid))
133 return kt->name;
134 }
135 return "ssh-unknown";
136}
137
138int
139sshkey_type_is_cert(int type)
140{
141 const struct keytype *kt;
142
143 for (kt = keytypes; kt->type != -1; kt++) {
144 if (kt->type == type)
145 return kt->cert;
146 }
147 return 0;
148}
149
150const char *
151sshkey_ssh_name(const struct sshkey *k)
152{
153 return sshkey_ssh_name_from_type_nid(k->type, k->ecdsa_nid);
154}
155
156const char *
157sshkey_ssh_name_plain(const struct sshkey *k)
158{
159 return sshkey_ssh_name_from_type_nid(sshkey_type_plain(k->type),
160 k->ecdsa_nid);
161}
162
163int
164sshkey_type_from_name(const char *name)
165{
166 const struct keytype *kt;
167
168 for (kt = keytypes; kt->type != -1; kt++) {
169 /* Only allow shortname matches for plain key types */
170 if ((kt->name != NULL && strcmp(name, kt->name) == 0) ||
171 (!kt->cert && strcasecmp(kt->shortname, name) == 0))
172 return kt->type;
173 }
174 return KEY_UNSPEC;
175}
176
177int
178sshkey_ecdsa_nid_from_name(const char *name)
179{
180 const struct keytype *kt;
181
182 for (kt = keytypes; kt->type != -1; kt++) {
183 if (kt->type != KEY_ECDSA && kt->type != KEY_ECDSA_CERT)
184 continue;
185 if (kt->name != NULL && strcmp(name, kt->name) == 0)
186 return kt->nid;
187 }
188 return -1;
189}
190
191char *
192key_alg_list(int certs_only, int plain_only)
193{
194 char *tmp, *ret = NULL;
195 size_t nlen, rlen = 0;
196 const struct keytype *kt;
197
198 for (kt = keytypes; kt->type != -1; kt++) {
199 if (kt->name == NULL)
200 continue;
201 if ((certs_only && !kt->cert) || (plain_only && kt->cert))
202 continue;
203 if (ret != NULL)
204 ret[rlen++] = '\n';
205 nlen = strlen(kt->name);
206 if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {
207 free(ret);
208 return NULL;
209 }
210 ret = tmp;
211 memcpy(ret + rlen, kt->name, nlen + 1);
212 rlen += nlen;
213 }
214 return ret;
215}
216
217int
218sshkey_names_valid2(const char *names)
219{
220 char *s, *cp, *p;
221
222 if (names == NULL || strcmp(names, "") == 0)
223 return 0;
224 if ((s = cp = strdup(names)) == NULL)
225 return 0;
226 for ((p = strsep(&cp, ",")); p && *p != '\0';
227 (p = strsep(&cp, ","))) {
228 switch (sshkey_type_from_name(p)) {
229 case KEY_RSA1:
230 case KEY_UNSPEC:
231 free(s);
232 return 0;
233 }
234 }
235 free(s);
236 return 1;
237}
238
239u_int
240sshkey_size(const struct sshkey *k)
241{
242 switch (k->type) {
243#ifdef WITH_OPENSSL
244 case KEY_RSA1:
245 case KEY_RSA:
246 case KEY_RSA_CERT_V00:
247 case KEY_RSA_CERT:
248 return BN_num_bits(k->rsa->n);
249 case KEY_DSA:
250 case KEY_DSA_CERT_V00:
251 case KEY_DSA_CERT:
252 return BN_num_bits(k->dsa->p);
253 case KEY_ECDSA:
254 case KEY_ECDSA_CERT:
255 return sshkey_curve_nid_to_bits(k->ecdsa_nid);
256#endif /* WITH_OPENSSL */
257 case KEY_ED25519:
258 case KEY_ED25519_CERT:
259 return 256; /* XXX */
260 }
261 return 0;
262}
263
264int
265sshkey_cert_is_legacy(const struct sshkey *k)
266{
267 switch (k->type) {
268 case KEY_DSA_CERT_V00:
269 case KEY_RSA_CERT_V00:
270 return 1;
271 default:
272 return 0;
273 }
274}
275
276static int
277sshkey_type_is_valid_ca(int type)
278{
279 switch (type) {
280 case KEY_RSA:
281 case KEY_DSA:
282 case KEY_ECDSA:
283 case KEY_ED25519:
284 return 1;
285 default:
286 return 0;
287 }
288}
289
290int
291sshkey_is_cert(const struct sshkey *k)
292{
293 if (k == NULL)
294 return 0;
295 return sshkey_type_is_cert(k->type);
296}
297
298/* Return the cert-less equivalent to a certified key type */
299int
300sshkey_type_plain(int type)
301{
302 switch (type) {
303 case KEY_RSA_CERT_V00:
304 case KEY_RSA_CERT:
305 return KEY_RSA;
306 case KEY_DSA_CERT_V00:
307 case KEY_DSA_CERT:
308 return KEY_DSA;
309 case KEY_ECDSA_CERT:
310 return KEY_ECDSA;
311 case KEY_ED25519_CERT:
312 return KEY_ED25519;
313 default:
314 return type;
315 }
316}
317
318#ifdef WITH_OPENSSL
319/* XXX: these are really begging for a table-driven approach */
320int
321sshkey_curve_name_to_nid(const char *name)
322{
323 if (strcmp(name, "nistp256") == 0)
324 return NID_X9_62_prime256v1;
325 else if (strcmp(name, "nistp384") == 0)
326 return NID_secp384r1;
327# ifdef OPENSSL_HAS_NISTP521
328 else if (strcmp(name, "nistp521") == 0)
329 return NID_secp521r1;
330# endif /* OPENSSL_HAS_NISTP521 */
331 else
332 return -1;
333}
334
335u_int
336sshkey_curve_nid_to_bits(int nid)
337{
338 switch (nid) {
339 case NID_X9_62_prime256v1:
340 return 256;
341 case NID_secp384r1:
342 return 384;
343# ifdef OPENSSL_HAS_NISTP521
344 case NID_secp521r1:
345 return 521;
346# endif /* OPENSSL_HAS_NISTP521 */
347 default:
348 return 0;
349 }
350}
351
352int
353sshkey_ecdsa_bits_to_nid(int bits)
354{
355 switch (bits) {
356 case 256:
357 return NID_X9_62_prime256v1;
358 case 384:
359 return NID_secp384r1;
360# ifdef OPENSSL_HAS_NISTP521
361 case 521:
362 return NID_secp521r1;
363# endif /* OPENSSL_HAS_NISTP521 */
364 default:
365 return -1;
366 }
367}
368
369const char *
370sshkey_curve_nid_to_name(int nid)
371{
372 switch (nid) {
373 case NID_X9_62_prime256v1:
374 return "nistp256";
375 case NID_secp384r1:
376 return "nistp384";
377# ifdef OPENSSL_HAS_NISTP521
378 case NID_secp521r1:
379 return "nistp521";
380# endif /* OPENSSL_HAS_NISTP521 */
381 default:
382 return NULL;
383 }
384}
385
386int
387sshkey_ec_nid_to_hash_alg(int nid)
388{
389 int kbits = sshkey_curve_nid_to_bits(nid);
390
391 if (kbits <= 0)
392 return -1;
393
394 /* RFC5656 section 6.2.1 */
395 if (kbits <= 256)
396 return SSH_DIGEST_SHA256;
397 else if (kbits <= 384)
398 return SSH_DIGEST_SHA384;
399 else
400 return SSH_DIGEST_SHA512;
401}
402#endif /* WITH_OPENSSL */
403
404static void
405cert_free(struct sshkey_cert *cert)
406{
407 u_int i;
408
409 if (cert == NULL)
410 return;
411 if (cert->certblob != NULL)
412 sshbuf_free(cert->certblob);
413 if (cert->critical != NULL)
414 sshbuf_free(cert->critical);
415 if (cert->extensions != NULL)
416 sshbuf_free(cert->extensions);
417 if (cert->key_id != NULL)
418 free(cert->key_id);
419 for (i = 0; i < cert->nprincipals; i++)
420 free(cert->principals[i]);
421 if (cert->principals != NULL)
422 free(cert->principals);
423 if (cert->signature_key != NULL)
424 sshkey_free(cert->signature_key);
425 explicit_bzero(cert, sizeof(*cert));
426 free(cert);
427}
428
429static struct sshkey_cert *
430cert_new(void)
431{
432 struct sshkey_cert *cert;
433
434 if ((cert = calloc(1, sizeof(*cert))) == NULL)
435 return NULL;
436 if ((cert->certblob = sshbuf_new()) == NULL ||
437 (cert->critical = sshbuf_new()) == NULL ||
438 (cert->extensions = sshbuf_new()) == NULL) {
439 cert_free(cert);
440 return NULL;
441 }
442 cert->key_id = NULL;
443 cert->principals = NULL;
444 cert->signature_key = NULL;
445 return cert;
446}
447
448struct sshkey *
449sshkey_new(int type)
450{
451 struct sshkey *k;
452#ifdef WITH_OPENSSL
453 RSA *rsa;
454 DSA *dsa;
455#endif /* WITH_OPENSSL */
456
457 if ((k = calloc(1, sizeof(*k))) == NULL)
458 return NULL;
459 k->type = type;
460 k->ecdsa = NULL;
461 k->ecdsa_nid = -1;
462 k->dsa = NULL;
463 k->rsa = NULL;
464 k->cert = NULL;
465 k->ed25519_sk = NULL;
466 k->ed25519_pk = NULL;
467 switch (k->type) {
468#ifdef WITH_OPENSSL
469 case KEY_RSA1:
470 case KEY_RSA:
471 case KEY_RSA_CERT_V00:
472 case KEY_RSA_CERT:
473 if ((rsa = RSA_new()) == NULL ||
474 (rsa->n = BN_new()) == NULL ||
475 (rsa->e = BN_new()) == NULL) {
476 if (rsa != NULL)
477 RSA_free(rsa);
478 free(k);
479 return NULL;
480 }
481 k->rsa = rsa;
482 break;
483 case KEY_DSA:
484 case KEY_DSA_CERT_V00:
485 case KEY_DSA_CERT:
486 if ((dsa = DSA_new()) == NULL ||
487 (dsa->p = BN_new()) == NULL ||
488 (dsa->q = BN_new()) == NULL ||
489 (dsa->g = BN_new()) == NULL ||
490 (dsa->pub_key = BN_new()) == NULL) {
491 if (dsa != NULL)
492 DSA_free(dsa);
493 free(k);
494 return NULL;
495 }
496 k->dsa = dsa;
497 break;
498 case KEY_ECDSA:
499 case KEY_ECDSA_CERT:
500 /* Cannot do anything until we know the group */
501 break;
502#endif /* WITH_OPENSSL */
503 case KEY_ED25519:
504 case KEY_ED25519_CERT:
505 /* no need to prealloc */
506 break;
507 case KEY_UNSPEC:
508 break;
509 default:
510 free(k);
511 return NULL;
512 break;
513 }
514
515 if (sshkey_is_cert(k)) {
516 if ((k->cert = cert_new()) == NULL) {
517 sshkey_free(k);
518 return NULL;
519 }
520 }
521
522 return k;
523}
524
525int
526sshkey_add_private(struct sshkey *k)
527{
528 switch (k->type) {
529#ifdef WITH_OPENSSL
530 case KEY_RSA1:
531 case KEY_RSA:
532 case KEY_RSA_CERT_V00:
533 case KEY_RSA_CERT:
534#define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL)
535 if (bn_maybe_alloc_failed(k->rsa->d) ||
536 bn_maybe_alloc_failed(k->rsa->iqmp) ||
537 bn_maybe_alloc_failed(k->rsa->q) ||
538 bn_maybe_alloc_failed(k->rsa->p) ||
539 bn_maybe_alloc_failed(k->rsa->dmq1) ||
540 bn_maybe_alloc_failed(k->rsa->dmp1))
541 return SSH_ERR_ALLOC_FAIL;
542 break;
543 case KEY_DSA:
544 case KEY_DSA_CERT_V00:
545 case KEY_DSA_CERT:
546 if (bn_maybe_alloc_failed(k->dsa->priv_key))
547 return SSH_ERR_ALLOC_FAIL;
548 break;
549#undef bn_maybe_alloc_failed
550 case KEY_ECDSA:
551 case KEY_ECDSA_CERT:
552 /* Cannot do anything until we know the group */
553 break;
554#endif /* WITH_OPENSSL */
555 case KEY_ED25519:
556 case KEY_ED25519_CERT:
557 /* no need to prealloc */
558 break;
559 case KEY_UNSPEC:
560 break;
561 default:
562 return SSH_ERR_INVALID_ARGUMENT;
563 }
564 return 0;
565}
566
567struct sshkey *
568sshkey_new_private(int type)
569{
570 struct sshkey *k = sshkey_new(type);
571
572 if (k == NULL)
573 return NULL;
574 if (sshkey_add_private(k) != 0) {
575 sshkey_free(k);
576 return NULL;
577 }
578 return k;
579}
580
581void
582sshkey_free(struct sshkey *k)
583{
584 if (k == NULL)
585 return;
586 switch (k->type) {
587#ifdef WITH_OPENSSL
588 case KEY_RSA1:
589 case KEY_RSA:
590 case KEY_RSA_CERT_V00:
591 case KEY_RSA_CERT:
592 if (k->rsa != NULL)
593 RSA_free(k->rsa);
594 k->rsa = NULL;
595 break;
596 case KEY_DSA:
597 case KEY_DSA_CERT_V00:
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#ifdef WITH_OPENSSL
659 BN_CTX *bnctx;
660#endif /* WITH_OPENSSL */
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_V00:
670 case KEY_RSA_CERT:
671 case KEY_RSA:
672 return a->rsa != NULL && b->rsa != NULL &&
673 BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
674 BN_cmp(a->rsa->n, b->rsa->n) == 0;
675 case KEY_DSA_CERT_V00:
676 case KEY_DSA_CERT:
677 case KEY_DSA:
678 return a->dsa != NULL && b->dsa != NULL &&
679 BN_cmp(a->dsa->p, b->dsa->p) == 0 &&
680 BN_cmp(a->dsa->q, b->dsa->q) == 0 &&
681 BN_cmp(a->dsa->g, b->dsa->g) == 0 &&
682 BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0;
683# ifdef OPENSSL_HAS_ECC
684 case KEY_ECDSA_CERT:
685 case KEY_ECDSA:
686 if (a->ecdsa == NULL || b->ecdsa == NULL ||
687 EC_KEY_get0_public_key(a->ecdsa) == NULL ||
688 EC_KEY_get0_public_key(b->ecdsa) == NULL)
689 return 0;
690 if ((bnctx = BN_CTX_new()) == NULL)
691 return 0;
692 if (EC_GROUP_cmp(EC_KEY_get0_group(a->ecdsa),
693 EC_KEY_get0_group(b->ecdsa), bnctx) != 0 ||
694 EC_POINT_cmp(EC_KEY_get0_group(a->ecdsa),
695 EC_KEY_get0_public_key(a->ecdsa),
696 EC_KEY_get0_public_key(b->ecdsa), bnctx) != 0) {
697 BN_CTX_free(bnctx);
698 return 0;
699 }
700 BN_CTX_free(bnctx);
701 return 1;
702# endif /* OPENSSL_HAS_ECC */
703#endif /* WITH_OPENSSL */
704 case KEY_ED25519:
705 case KEY_ED25519_CERT:
706 return a->ed25519_pk != NULL && b->ed25519_pk != NULL &&
707 memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) == 0;
708 default:
709 return 0;
710 }
711 /* NOTREACHED */
712}
713
714int
715sshkey_equal(const struct sshkey *a, const struct sshkey *b)
716{
717 if (a == NULL || b == NULL || a->type != b->type)
718 return 0;
719 if (sshkey_is_cert(a)) {
720 if (!cert_compare(a->cert, b->cert))
721 return 0;
722 }
723 return sshkey_equal_public(a, b);
724}
725
726static int
727to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain)
728{
729 int type, ret = SSH_ERR_INTERNAL_ERROR;
730 const char *typename;
731
732 if (key == NULL)
733 return SSH_ERR_INVALID_ARGUMENT;
734
735 type = force_plain ? sshkey_type_plain(key->type) : key->type;
736 typename = sshkey_ssh_name_from_type_nid(type, key->ecdsa_nid);
737
738 switch (type) {
739#ifdef WITH_OPENSSL
740 case KEY_DSA_CERT_V00:
741 case KEY_RSA_CERT_V00:
742 case KEY_DSA_CERT:
743 case KEY_ECDSA_CERT:
744 case KEY_RSA_CERT:
745#endif /* WITH_OPENSSL */
746 case KEY_ED25519_CERT:
747 /* Use the existing blob */
748 /* XXX modified flag? */
749 if ((ret = sshbuf_putb(b, key->cert->certblob)) != 0)
750 return ret;
751 break;
752#ifdef WITH_OPENSSL
753 case KEY_DSA:
754 if (key->dsa == NULL)
755 return SSH_ERR_INVALID_ARGUMENT;
756 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
757 (ret = sshbuf_put_bignum2(b, key->dsa->p)) != 0 ||
758 (ret = sshbuf_put_bignum2(b, key->dsa->q)) != 0 ||
759 (ret = sshbuf_put_bignum2(b, key->dsa->g)) != 0 ||
760 (ret = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0)
761 return ret;
762 break;
763 case KEY_ECDSA:
764 if (key->ecdsa == NULL)
765 return SSH_ERR_INVALID_ARGUMENT;
766 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
767 (ret = sshbuf_put_cstring(b,
768 sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 ||
769 (ret = sshbuf_put_eckey(b, key->ecdsa)) != 0)
770 return ret;
771 break;
772 case KEY_RSA:
773 if (key->rsa == NULL)
774 return SSH_ERR_INVALID_ARGUMENT;
775 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
776 (ret = sshbuf_put_bignum2(b, key->rsa->e)) != 0 ||
777 (ret = sshbuf_put_bignum2(b, key->rsa->n)) != 0)
778 return ret;
779 break;
780#endif /* WITH_OPENSSL */
781 case KEY_ED25519:
782 if (key->ed25519_pk == NULL)
783 return SSH_ERR_INVALID_ARGUMENT;
784 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
785 (ret = sshbuf_put_string(b,
786 key->ed25519_pk, ED25519_PK_SZ)) != 0)
787 return ret;
788 break;
789 default:
790 return SSH_ERR_KEY_TYPE_UNKNOWN;
791 }
792 return 0;
793}
794
795int
796sshkey_to_blob_buf(const struct sshkey *key, struct sshbuf *b)
797{
798 return to_blob_buf(key, b, 0);
799}
800
801int
802sshkey_plain_to_blob_buf(const struct sshkey *key, struct sshbuf *b)
803{
804 return to_blob_buf(key, b, 1);
805}
806
807static int
808to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp, int force_plain)
809{
810 int ret = SSH_ERR_INTERNAL_ERROR;
811 size_t len;
812 struct sshbuf *b = NULL;
813
814 if (lenp != NULL)
815 *lenp = 0;
816 if (blobp != NULL)
817 *blobp = NULL;
818 if ((b = sshbuf_new()) == NULL)
819 return SSH_ERR_ALLOC_FAIL;
820 if ((ret = to_blob_buf(key, b, force_plain)) != 0)
821 goto out;
822 len = sshbuf_len(b);
823 if (lenp != NULL)
824 *lenp = len;
825 if (blobp != NULL) {
826 if ((*blobp = malloc(len)) == NULL) {
827 ret = SSH_ERR_ALLOC_FAIL;
828 goto out;
829 }
830 memcpy(*blobp, sshbuf_ptr(b), len);
831 }
832 ret = 0;
833 out:
834 sshbuf_free(b);
835 return ret;
836}
837
838int
839sshkey_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp)
840{
841 return to_blob(key, blobp, lenp, 0);
842}
843
844int
845sshkey_plain_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp)
846{
847 return to_blob(key, blobp, lenp, 1);
848}
849
850int
851sshkey_fingerprint_raw(const struct sshkey *k, enum sshkey_fp_type dgst_type,
852 u_char **retp, size_t *lenp)
853{
854 u_char *blob = NULL, *ret = NULL;
855 size_t blob_len = 0;
856 int hash_alg = -1, r = SSH_ERR_INTERNAL_ERROR;
857
858 if (retp != NULL)
859 *retp = NULL;
860 if (lenp != NULL)
861 *lenp = 0;
862
863 switch (dgst_type) {
864 case SSH_FP_MD5:
865 hash_alg = SSH_DIGEST_MD5;
866 break;
867 case SSH_FP_SHA1:
868 hash_alg = SSH_DIGEST_SHA1;
869 break;
870 case SSH_FP_SHA256:
871 hash_alg = SSH_DIGEST_SHA256;
872 break;
873 default:
874 r = SSH_ERR_INVALID_ARGUMENT;
875 goto out;
876 }
877
878 if (k->type == KEY_RSA1) {
879#ifdef WITH_OPENSSL
880 int nlen = BN_num_bytes(k->rsa->n);
881 int elen = BN_num_bytes(k->rsa->e);
882
883 blob_len = nlen + elen;
884 if (nlen >= INT_MAX - elen ||
885 (blob = malloc(blob_len)) == NULL) {
886 r = SSH_ERR_ALLOC_FAIL;
887 goto out;
888 }
889 BN_bn2bin(k->rsa->n, blob);
890 BN_bn2bin(k->rsa->e, blob + nlen);
891#endif /* WITH_OPENSSL */
892 } else if ((r = to_blob(k, &blob, &blob_len, 1)) != 0)
893 goto out;
894 if ((ret = calloc(1, SSH_DIGEST_MAX_LENGTH)) == NULL) {
895 r = SSH_ERR_ALLOC_FAIL;
896 goto out;
897 }
898 if ((r = ssh_digest_memory(hash_alg, blob, blob_len,
899 ret, SSH_DIGEST_MAX_LENGTH)) != 0)
900 goto out;
901 /* success */
902 if (retp != NULL) {
903 *retp = ret;
904 ret = NULL;
905 }
906 if (lenp != NULL)
907 *lenp = ssh_digest_bytes(hash_alg);
908 r = 0;
909 out:
910 free(ret);
911 if (blob != NULL) {
912 explicit_bzero(blob, blob_len);
913 free(blob);
914 }
915 return r;
916}
917
918static char *
919fingerprint_hex(u_char *dgst_raw, size_t dgst_raw_len)
920{
921 char *retval;
922 size_t i;
923
924 if ((retval = calloc(1, dgst_raw_len * 3 + 1)) == NULL)
925 return NULL;
926 for (i = 0; i < dgst_raw_len; i++) {
927 char hex[4];
928 snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]);
929 strlcat(retval, hex, dgst_raw_len * 3 + 1);
930 }
931
932 /* Remove the trailing ':' character */
933 retval[(dgst_raw_len * 3) - 1] = '\0';
934 return retval;
935}
936
937static char *
938fingerprint_bubblebabble(u_char *dgst_raw, size_t dgst_raw_len)
939{
940 char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' };
941 char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
942 'n', 'p', 'r', 's', 't', 'v', 'z', 'x' };
943 u_int i, j = 0, rounds, seed = 1;
944 char *retval;
945
946 rounds = (dgst_raw_len / 2) + 1;
947 if ((retval = calloc(rounds, 6)) == NULL)
948 return NULL;
949 retval[j++] = 'x';
950 for (i = 0; i < rounds; i++) {
951 u_int idx0, idx1, idx2, idx3, idx4;
952 if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) {
953 idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) +
954 seed) % 6;
955 idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15;
956 idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) +
957 (seed / 6)) % 6;
958 retval[j++] = vowels[idx0];
959 retval[j++] = consonants[idx1];
960 retval[j++] = vowels[idx2];
961 if ((i + 1) < rounds) {
962 idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15;
963 idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15;
964 retval[j++] = consonants[idx3];
965 retval[j++] = '-';
966 retval[j++] = consonants[idx4];
967 seed = ((seed * 5) +
968 ((((u_int)(dgst_raw[2 * i])) * 7) +
969 ((u_int)(dgst_raw[(2 * i) + 1])))) % 36;
970 }
971 } else {
972 idx0 = seed % 6;
973 idx1 = 16;
974 idx2 = seed / 6;
975 retval[j++] = vowels[idx0];
976 retval[j++] = consonants[idx1];
977 retval[j++] = vowels[idx2];
978 }
979 }
980 retval[j++] = 'x';
981 retval[j++] = '\0';
982 return retval;
983}
984
985/*
986 * Draw an ASCII-Art representing the fingerprint so human brain can
987 * profit from its built-in pattern recognition ability.
988 * This technique is called "random art" and can be found in some
989 * scientific publications like this original paper:
990 *
991 * "Hash Visualization: a New Technique to improve Real-World Security",
992 * Perrig A. and Song D., 1999, International Workshop on Cryptographic
993 * Techniques and E-Commerce (CrypTEC '99)
994 * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf
995 *
996 * The subject came up in a talk by Dan Kaminsky, too.
997 *
998 * If you see the picture is different, the key is different.
999 * If the picture looks the same, you still know nothing.
1000 *
1001 * The algorithm used here is a worm crawling over a discrete plane,
1002 * leaving a trace (augmenting the field) everywhere it goes.
1003 * Movement is taken from dgst_raw 2bit-wise. Bumping into walls
1004 * makes the respective movement vector be ignored for this turn.
1005 * Graphs are not unambiguous, because circles in graphs can be
1006 * walked in either direction.
1007 */
1008
1009/*
1010 * Field sizes for the random art. Have to be odd, so the starting point
1011 * can be in the exact middle of the picture, and FLDBASE should be >=8 .
1012 * Else pictures would be too dense, and drawing the frame would
1013 * fail, too, because the key type would not fit in anymore.
1014 */
1015#define FLDBASE 8
1016#define FLDSIZE_Y (FLDBASE + 1)
1017#define FLDSIZE_X (FLDBASE * 2 + 1)
1018static char *
1019fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len,
1020 const struct sshkey *k)
1021{
1022 /*
1023 * Chars to be used after each other every time the worm
1024 * intersects with itself. Matter of taste.
1025 */
1026 char *augmentation_string = " .o+=*BOX@%&#/^SE";
1027 char *retval, *p;
1028 u_char field[FLDSIZE_X][FLDSIZE_Y];
1029 size_t i;
1030 u_int b;
1031 int x, y;
1032 size_t len = strlen(augmentation_string) - 1;
1033
1034 if ((retval = calloc((FLDSIZE_X + 3), (FLDSIZE_Y + 2))) == NULL)
1035 return NULL;
1036
1037 /* initialize field */
1038 memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char));
1039 x = FLDSIZE_X / 2;
1040 y = FLDSIZE_Y / 2;
1041
1042 /* process raw key */
1043 for (i = 0; i < dgst_raw_len; i++) {
1044 int input;
1045 /* each byte conveys four 2-bit move commands */
1046 input = dgst_raw[i];
1047 for (b = 0; b < 4; b++) {
1048 /* evaluate 2 bit, rest is shifted later */
1049 x += (input & 0x1) ? 1 : -1;
1050 y += (input & 0x2) ? 1 : -1;
1051
1052 /* assure we are still in bounds */
1053 x = MAX(x, 0);
1054 y = MAX(y, 0);
1055 x = MIN(x, FLDSIZE_X - 1);
1056 y = MIN(y, FLDSIZE_Y - 1);
1057
1058 /* augment the field */
1059 if (field[x][y] < len - 2)
1060 field[x][y]++;
1061 input = input >> 2;
1062 }
1063 }
1064
1065 /* mark starting point and end point*/
1066 field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;
1067 field[x][y] = len;
1068
1069 /* fill in retval */
1070 snprintf(retval, FLDSIZE_X, "+--[%4s %4u]",
1071 sshkey_type(k), sshkey_size(k));
1072 p = strchr(retval, '\0');
1073
1074 /* output upper border */
1075 for (i = p - retval - 1; i < FLDSIZE_X; i++)
1076 *p++ = '-';
1077 *p++ = '+';
1078 *p++ = '\n';
1079
1080 /* output content */
1081 for (y = 0; y < FLDSIZE_Y; y++) {
1082 *p++ = '|';
1083 for (x = 0; x < FLDSIZE_X; x++)
1084 *p++ = augmentation_string[MIN(field[x][y], len)];
1085 *p++ = '|';
1086 *p++ = '\n';
1087 }
1088
1089 /* output lower border */
1090 *p++ = '+';
1091 for (i = 0; i < FLDSIZE_X; i++)
1092 *p++ = '-';
1093 *p++ = '+';
1094
1095 return retval;
1096}
1097
1098char *
1099sshkey_fingerprint(const struct sshkey *k, enum sshkey_fp_type dgst_type,
1100 enum sshkey_fp_rep dgst_rep)
1101{
1102 char *retval = NULL;
1103 u_char *dgst_raw;
1104 size_t dgst_raw_len;
1105
1106 if (sshkey_fingerprint_raw(k, dgst_type, &dgst_raw, &dgst_raw_len) != 0)
1107 return NULL;
1108 switch (dgst_rep) {
1109 case SSH_FP_HEX:
1110 retval = fingerprint_hex(dgst_raw, dgst_raw_len);
1111 break;
1112 case SSH_FP_BUBBLEBABBLE:
1113 retval = fingerprint_bubblebabble(dgst_raw, dgst_raw_len);
1114 break;
1115 case SSH_FP_RANDOMART:
1116 retval = fingerprint_randomart(dgst_raw, dgst_raw_len, k);
1117 break;
1118 default:
1119 explicit_bzero(dgst_raw, dgst_raw_len);
1120 free(dgst_raw);
1121 return NULL;
1122 }
1123 explicit_bzero(dgst_raw, dgst_raw_len);
1124 free(dgst_raw);
1125 return retval;
1126}
1127
1128#ifdef WITH_SSH1
1129/*
1130 * Reads a multiple-precision integer in decimal from the buffer, and advances
1131 * the pointer. The integer must already be initialized. This function is
1132 * permitted to modify the buffer. This leaves *cpp to point just beyond the
1133 * last processed character.
1134 */
1135static int
1136read_decimal_bignum(char **cpp, BIGNUM *v)
1137{
1138 char *cp;
1139 size_t e;
1140 int skip = 1; /* skip white space */
1141
1142 cp = *cpp;
1143 while (*cp == ' ' || *cp == '\t')
1144 cp++;
1145 e = strspn(cp, "0123456789");
1146 if (e == 0)
1147 return SSH_ERR_INVALID_FORMAT;
1148 if (e > SSHBUF_MAX_BIGNUM * 3)
1149 return SSH_ERR_BIGNUM_TOO_LARGE;
1150 if (cp[e] == '\0')
1151 skip = 0;
1152 else if (index(" \t\r\n", cp[e]) == NULL)
1153 return SSH_ERR_INVALID_FORMAT;
1154 cp[e] = '\0';
1155 if (BN_dec2bn(&v, cp) <= 0)
1156 return SSH_ERR_INVALID_FORMAT;
1157 *cpp = cp + e + skip;
1158 return 0;
1159}
1160#endif /* WITH_SSH1 */
1161
1162/* returns 0 ok, and < 0 error */
1163int
1164sshkey_read(struct sshkey *ret, char **cpp)
1165{
1166 struct sshkey *k;
1167 int retval = SSH_ERR_INVALID_FORMAT;
1168 char *cp, *space;
1169 int r, type, curve_nid = -1;
1170 struct sshbuf *blob;
1171#ifdef WITH_SSH1
1172 char *ep;
1173 u_long bits;
1174#endif /* WITH_SSH1 */
1175
1176 cp = *cpp;
1177
1178 switch (ret->type) {
1179 case KEY_RSA1:
1180#ifdef WITH_SSH1
1181 /* Get number of bits. */
1182 bits = strtoul(cp, &ep, 10);
1183 if (*cp == '\0' || index(" \t\r\n", *ep) == NULL ||
1184 bits == 0 || bits > SSHBUF_MAX_BIGNUM * 8)
1185 return SSH_ERR_INVALID_FORMAT; /* Bad bit count... */
1186 /* Get public exponent, public modulus. */
1187 if ((r = read_decimal_bignum(&ep, ret->rsa->e)) < 0)
1188 return r;
1189 if ((r = read_decimal_bignum(&ep, ret->rsa->n)) < 0)
1190 return r;
1191 *cpp = ep;
1192 /* validate the claimed number of bits */
1193 if (BN_num_bits(ret->rsa->n) != (int)bits)
1194 return SSH_ERR_KEY_BITS_MISMATCH;
1195 retval = 0;
1196#endif /* WITH_SSH1 */
1197 break;
1198 case KEY_UNSPEC:
1199 case KEY_RSA:
1200 case KEY_DSA:
1201 case KEY_ECDSA:
1202 case KEY_ED25519:
1203 case KEY_DSA_CERT_V00:
1204 case KEY_RSA_CERT_V00:
1205 case KEY_DSA_CERT:
1206 case KEY_ECDSA_CERT:
1207 case KEY_RSA_CERT:
1208 case KEY_ED25519_CERT:
1209 space = strchr(cp, ' ');
1210 if (space == NULL)
1211 return SSH_ERR_INVALID_FORMAT;
1212 *space = '\0';
1213 type = sshkey_type_from_name(cp);
1214 if (sshkey_type_plain(type) == KEY_ECDSA &&
1215 (curve_nid = sshkey_ecdsa_nid_from_name(cp)) == -1)
1216 return SSH_ERR_EC_CURVE_INVALID;
1217 *space = ' ';
1218 if (type == KEY_UNSPEC)
1219 return SSH_ERR_INVALID_FORMAT;
1220 cp = space+1;
1221 if (*cp == '\0')
1222 return SSH_ERR_INVALID_FORMAT;
1223 if (ret->type == KEY_UNSPEC) {
1224 ret->type = type;
1225 } else if (ret->type != type)
1226 return SSH_ERR_KEY_TYPE_MISMATCH;
1227 if ((blob = sshbuf_new()) == NULL)
1228 return SSH_ERR_ALLOC_FAIL;
1229 /* trim comment */
1230 space = strchr(cp, ' ');
1231 if (space)
1232 *space = '\0';
1233 if ((r = sshbuf_b64tod(blob, cp)) != 0) {
1234 sshbuf_free(blob);
1235 return r;
1236 }
1237 if ((r = sshkey_from_blob(sshbuf_ptr(blob),
1238 sshbuf_len(blob), &k)) != 0) {
1239 sshbuf_free(blob);
1240 return r;
1241 }
1242 sshbuf_free(blob);
1243 if (k->type != type) {
1244 sshkey_free(k);
1245 return SSH_ERR_KEY_TYPE_MISMATCH;
1246 }
1247 if (sshkey_type_plain(type) == KEY_ECDSA &&
1248 curve_nid != k->ecdsa_nid) {
1249 sshkey_free(k);
1250 return SSH_ERR_EC_CURVE_MISMATCH;
1251 }
1252/*XXXX*/
1253 if (sshkey_is_cert(ret)) {
1254 if (!sshkey_is_cert(k)) {
1255 sshkey_free(k);
1256 return SSH_ERR_EXPECTED_CERT;
1257 }
1258 if (ret->cert != NULL)
1259 cert_free(ret->cert);
1260 ret->cert = k->cert;
1261 k->cert = NULL;
1262 }
1263#ifdef WITH_OPENSSL
1264 if (sshkey_type_plain(ret->type) == KEY_RSA) {
1265 if (ret->rsa != NULL)
1266 RSA_free(ret->rsa);
1267 ret->rsa = k->rsa;
1268 k->rsa = NULL;
1269#ifdef DEBUG_PK
1270 RSA_print_fp(stderr, ret->rsa, 8);
1271#endif
1272 }
1273 if (sshkey_type_plain(ret->type) == KEY_DSA) {
1274 if (ret->dsa != NULL)
1275 DSA_free(ret->dsa);
1276 ret->dsa = k->dsa;
1277 k->dsa = NULL;
1278#ifdef DEBUG_PK
1279 DSA_print_fp(stderr, ret->dsa, 8);
1280#endif
1281 }
1282# ifdef OPENSSL_HAS_ECC
1283 if (sshkey_type_plain(ret->type) == KEY_ECDSA) {
1284 if (ret->ecdsa != NULL)
1285 EC_KEY_free(ret->ecdsa);
1286 ret->ecdsa = k->ecdsa;
1287 ret->ecdsa_nid = k->ecdsa_nid;
1288 k->ecdsa = NULL;
1289 k->ecdsa_nid = -1;
1290#ifdef DEBUG_PK
1291 sshkey_dump_ec_key(ret->ecdsa);
1292#endif
1293 }
1294# endif /* OPENSSL_HAS_ECC */
1295#endif /* WITH_OPENSSL */
1296 if (sshkey_type_plain(ret->type) == KEY_ED25519) {
1297 free(ret->ed25519_pk);
1298 ret->ed25519_pk = k->ed25519_pk;
1299 k->ed25519_pk = NULL;
1300#ifdef DEBUG_PK
1301 /* XXX */
1302#endif
1303 }
1304 retval = 0;
1305/*XXXX*/
1306 sshkey_free(k);
1307 if (retval != 0)
1308 break;
1309 /* advance cp: skip whitespace and data */
1310 while (*cp == ' ' || *cp == '\t')
1311 cp++;
1312 while (*cp != '\0' && *cp != ' ' && *cp != '\t')
1313 cp++;
1314 *cpp = cp;
1315 break;
1316 default:
1317 return SSH_ERR_INVALID_ARGUMENT;
1318 }
1319 return retval;
1320}
1321
1322int
1323sshkey_write(const struct sshkey *key, FILE *f)
1324{
1325 int ret = SSH_ERR_INTERNAL_ERROR;
1326 struct sshbuf *b = NULL, *bb = NULL;
1327 char *uu = NULL;
1328#ifdef WITH_SSH1
1329 u_int bits = 0;
1330 char *dec_e = NULL, *dec_n = NULL;
1331#endif /* WITH_SSH1 */
1332
1333 if (sshkey_is_cert(key)) {
1334 if (key->cert == NULL)
1335 return SSH_ERR_EXPECTED_CERT;
1336 if (sshbuf_len(key->cert->certblob) == 0)
1337 return SSH_ERR_KEY_LACKS_CERTBLOB;
1338 }
1339 if ((b = sshbuf_new()) == NULL)
1340 return SSH_ERR_ALLOC_FAIL;
1341 switch (key->type) {
1342#ifdef WITH_SSH1
1343 case KEY_RSA1:
1344 if (key->rsa == NULL || key->rsa->e == NULL ||
1345 key->rsa->n == NULL) {
1346 ret = SSH_ERR_INVALID_ARGUMENT;
1347 goto out;
1348 }
1349 if ((dec_e = BN_bn2dec(key->rsa->e)) == NULL ||
1350 (dec_n = BN_bn2dec(key->rsa->n)) == NULL) {
1351 ret = SSH_ERR_ALLOC_FAIL;
1352 goto out;
1353 }
1354 /* size of modulus 'n' */
1355 if ((bits = BN_num_bits(key->rsa->n)) <= 0) {
1356 ret = SSH_ERR_INVALID_ARGUMENT;
1357 goto out;
1358 }
1359 if ((ret = sshbuf_putf(b, "%u %s %s", bits, dec_e, dec_n)) != 0)
1360 goto out;
1361#endif /* WITH_SSH1 */
1362 break;
1363#ifdef WITH_OPENSSL
1364 case KEY_DSA:
1365 case KEY_DSA_CERT_V00:
1366 case KEY_DSA_CERT:
1367 case KEY_ECDSA:
1368 case KEY_ECDSA_CERT:
1369 case KEY_RSA:
1370 case KEY_RSA_CERT_V00:
1371 case KEY_RSA_CERT:
1372#endif /* WITH_OPENSSL */
1373 case KEY_ED25519:
1374 case KEY_ED25519_CERT:
1375 if ((bb = sshbuf_new()) == NULL) {
1376 ret = SSH_ERR_ALLOC_FAIL;
1377 goto out;
1378 }
1379 if ((ret = sshkey_to_blob_buf(key, bb)) != 0)
1380 goto out;
1381 if ((uu = sshbuf_dtob64(bb)) == NULL) {
1382 ret = SSH_ERR_ALLOC_FAIL;
1383 goto out;
1384 }
1385 if ((ret = sshbuf_putf(b, "%s ", sshkey_ssh_name(key))) != 0)
1386 goto out;
1387 if ((ret = sshbuf_put(b, uu, strlen(uu))) != 0)
1388 goto out;
1389 break;
1390 default:
1391 ret = SSH_ERR_KEY_TYPE_UNKNOWN;
1392 goto out;
1393 }
1394 if (fwrite(sshbuf_ptr(b), sshbuf_len(b), 1, f) != 1) {
1395 if (feof(f))
1396 errno = EPIPE;
1397 ret = SSH_ERR_SYSTEM_ERROR;
1398 goto out;
1399 }
1400 ret = 0;
1401 out:
1402 if (b != NULL)
1403 sshbuf_free(b);
1404 if (bb != NULL)
1405 sshbuf_free(bb);
1406 if (uu != NULL)
1407 free(uu);
1408#ifdef WITH_SSH1
1409 if (dec_e != NULL)
1410 OPENSSL_free(dec_e);
1411 if (dec_n != NULL)
1412 OPENSSL_free(dec_n);
1413#endif /* WITH_SSH1 */
1414 return ret;
1415}
1416
1417const char *
1418sshkey_cert_type(const struct sshkey *k)
1419{
1420 switch (k->cert->type) {
1421 case SSH2_CERT_TYPE_USER:
1422 return "user";
1423 case SSH2_CERT_TYPE_HOST:
1424 return "host";
1425 default:
1426 return "unknown";
1427 }
1428}
1429
1430#ifdef WITH_OPENSSL
1431static int
1432rsa_generate_private_key(u_int bits, RSA **rsap)
1433{
1434 RSA *private = NULL;
1435 BIGNUM *f4 = NULL;
1436 int ret = SSH_ERR_INTERNAL_ERROR;
1437
1438 if (rsap == NULL ||
1439 bits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
1440 bits > SSHBUF_MAX_BIGNUM * 8)
1441 return SSH_ERR_INVALID_ARGUMENT;
1442 *rsap = NULL;
1443 if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) {
1444 ret = SSH_ERR_ALLOC_FAIL;
1445 goto out;
1446 }
1447 if (!BN_set_word(f4, RSA_F4) ||
1448 !RSA_generate_key_ex(private, bits, f4, NULL)) {
1449 ret = SSH_ERR_LIBCRYPTO_ERROR;
1450 goto out;
1451 }
1452 *rsap = private;
1453 private = NULL;
1454 ret = 0;
1455 out:
1456 if (private != NULL)
1457 RSA_free(private);
1458 if (f4 != NULL)
1459 BN_free(f4);
1460 return ret;
1461}
1462
1463static int
1464dsa_generate_private_key(u_int bits, DSA **dsap)
1465{
1466 DSA *private;
1467 int ret = SSH_ERR_INTERNAL_ERROR;
1468
1469 if (dsap == NULL || bits != 1024)
1470 return SSH_ERR_INVALID_ARGUMENT;
1471 if ((private = DSA_new()) == NULL) {
1472 ret = SSH_ERR_ALLOC_FAIL;
1473 goto out;
1474 }
1475 *dsap = NULL;
1476 if (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL,
1477 NULL, NULL) || !DSA_generate_key(private)) {
1478 DSA_free(private);
1479 ret = SSH_ERR_LIBCRYPTO_ERROR;
1480 goto out;
1481 }
1482 *dsap = private;
1483 private = NULL;
1484 ret = 0;
1485 out:
1486 if (private != NULL)
1487 DSA_free(private);
1488 return ret;
1489}
1490
1491# ifdef OPENSSL_HAS_ECC
1492int
1493sshkey_ecdsa_key_to_nid(EC_KEY *k)
1494{
1495 EC_GROUP *eg;
1496 int nids[] = {
1497 NID_X9_62_prime256v1,
1498 NID_secp384r1,
1499# ifdef OPENSSL_HAS_NISTP521
1500 NID_secp521r1,
1501# endif /* OPENSSL_HAS_NISTP521 */
1502 -1
1503 };
1504 int nid;
1505 u_int i;
1506 BN_CTX *bnctx;
1507 const EC_GROUP *g = EC_KEY_get0_group(k);
1508
1509 /*
1510 * The group may be stored in a ASN.1 encoded private key in one of two
1511 * ways: as a "named group", which is reconstituted by ASN.1 object ID
1512 * or explicit group parameters encoded into the key blob. Only the
1513 * "named group" case sets the group NID for us, but we can figure
1514 * it out for the other case by comparing against all the groups that
1515 * are supported.
1516 */
1517 if ((nid = EC_GROUP_get_curve_name(g)) > 0)
1518 return nid;
1519 if ((bnctx = BN_CTX_new()) == NULL)
1520 return -1;
1521 for (i = 0; nids[i] != -1; i++) {
1522 if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) {
1523 BN_CTX_free(bnctx);
1524 return -1;
1525 }
1526 if (EC_GROUP_cmp(g, eg, bnctx) == 0)
1527 break;
1528 EC_GROUP_free(eg);
1529 }
1530 BN_CTX_free(bnctx);
1531 if (nids[i] != -1) {
1532 /* Use the group with the NID attached */
1533 EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE);
1534 if (EC_KEY_set_group(k, eg) != 1) {
1535 EC_GROUP_free(eg);
1536 return -1;
1537 }
1538 }
1539 return nids[i];
1540}
1541
1542static int
1543ecdsa_generate_private_key(u_int bits, int *nid, EC_KEY **ecdsap)
1544{
1545 EC_KEY *private;
1546 int ret = SSH_ERR_INTERNAL_ERROR;
1547
1548 if (nid == NULL || ecdsap == NULL ||
1549 (*nid = sshkey_ecdsa_bits_to_nid(bits)) == -1)
1550 return SSH_ERR_INVALID_ARGUMENT;
1551 *ecdsap = NULL;
1552 if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) {
1553 ret = SSH_ERR_ALLOC_FAIL;
1554 goto out;
1555 }
1556 if (EC_KEY_generate_key(private) != 1) {
1557 ret = SSH_ERR_LIBCRYPTO_ERROR;
1558 goto out;
1559 }
1560 EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE);
1561 *ecdsap = private;
1562 private = NULL;
1563 ret = 0;
1564 out:
1565 if (private != NULL)
1566 EC_KEY_free(private);
1567 return ret;
1568}
1569# endif /* OPENSSL_HAS_ECC */
1570#endif /* WITH_OPENSSL */
1571
1572int
1573sshkey_generate(int type, u_int bits, struct sshkey **keyp)
1574{
1575 struct sshkey *k;
1576 int ret = SSH_ERR_INTERNAL_ERROR;
1577
1578 if (keyp == NULL)
1579 return SSH_ERR_INVALID_ARGUMENT;
1580 *keyp = NULL;
1581 if ((k = sshkey_new(KEY_UNSPEC)) == NULL)
1582 return SSH_ERR_ALLOC_FAIL;
1583 switch (type) {
1584 case KEY_ED25519:
1585 if ((k->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL ||
1586 (k->ed25519_sk = malloc(ED25519_SK_SZ)) == NULL) {
1587 ret = SSH_ERR_ALLOC_FAIL;
1588 break;
1589 }
1590 crypto_sign_ed25519_keypair(k->ed25519_pk, k->ed25519_sk);
1591 ret = 0;
1592 break;
1593#ifdef WITH_OPENSSL
1594 case KEY_DSA:
1595 ret = dsa_generate_private_key(bits, &k->dsa);
1596 break;
1597# ifdef OPENSSL_HAS_ECC
1598 case KEY_ECDSA:
1599 ret = ecdsa_generate_private_key(bits, &k->ecdsa_nid,
1600 &k->ecdsa);
1601 break;
1602# endif /* OPENSSL_HAS_ECC */
1603 case KEY_RSA:
1604 case KEY_RSA1:
1605 ret = rsa_generate_private_key(bits, &k->rsa);
1606 break;
1607#endif /* WITH_OPENSSL */
1608 default:
1609 ret = SSH_ERR_INVALID_ARGUMENT;
1610 }
1611 if (ret == 0) {
1612 k->type = type;
1613 *keyp = k;
1614 } else
1615 sshkey_free(k);
1616 return ret;
1617}
1618
1619int
1620sshkey_cert_copy(const struct sshkey *from_key, struct sshkey *to_key)
1621{
1622 u_int i;
1623 const struct sshkey_cert *from;
1624 struct sshkey_cert *to;
1625 int ret = SSH_ERR_INTERNAL_ERROR;
1626
1627 if (to_key->cert != NULL) {
1628 cert_free(to_key->cert);
1629 to_key->cert = NULL;
1630 }
1631
1632 if ((from = from_key->cert) == NULL)
1633 return SSH_ERR_INVALID_ARGUMENT;
1634
1635 if ((to = to_key->cert = cert_new()) == NULL)
1636 return SSH_ERR_ALLOC_FAIL;
1637
1638 if ((ret = sshbuf_putb(to->certblob, from->certblob)) != 0 ||
1639 (ret = sshbuf_putb(to->critical, from->critical)) != 0 ||
1640 (ret = sshbuf_putb(to->extensions, from->extensions) != 0))
1641 return ret;
1642
1643 to->serial = from->serial;
1644 to->type = from->type;
1645 if (from->key_id == NULL)
1646 to->key_id = NULL;
1647 else if ((to->key_id = strdup(from->key_id)) == NULL)
1648 return SSH_ERR_ALLOC_FAIL;
1649 to->valid_after = from->valid_after;
1650 to->valid_before = from->valid_before;
1651 if (from->signature_key == NULL)
1652 to->signature_key = NULL;
1653 else if ((ret = sshkey_from_private(from->signature_key,
1654 &to->signature_key)) != 0)
1655 return ret;
1656
1657 if (from->nprincipals > SSHKEY_CERT_MAX_PRINCIPALS)
1658 return SSH_ERR_INVALID_ARGUMENT;
1659 if (from->nprincipals > 0) {
1660 if ((to->principals = calloc(from->nprincipals,
1661 sizeof(*to->principals))) == NULL)
1662 return SSH_ERR_ALLOC_FAIL;
1663 for (i = 0; i < from->nprincipals; i++) {
1664 to->principals[i] = strdup(from->principals[i]);
1665 if (to->principals[i] == NULL) {
1666 to->nprincipals = i;
1667 return SSH_ERR_ALLOC_FAIL;
1668 }
1669 }
1670 }
1671 to->nprincipals = from->nprincipals;
1672 return 0;
1673}
1674
1675int
1676sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
1677{
1678 struct sshkey *n = NULL;
1679 int ret = SSH_ERR_INTERNAL_ERROR;
1680
1681 if (pkp != NULL)
1682 *pkp = NULL;
1683
1684 switch (k->type) {
1685#ifdef WITH_OPENSSL
1686 case KEY_DSA:
1687 case KEY_DSA_CERT_V00:
1688 case KEY_DSA_CERT:
1689 if ((n = sshkey_new(k->type)) == NULL)
1690 return SSH_ERR_ALLOC_FAIL;
1691 if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) ||
1692 (BN_copy(n->dsa->q, k->dsa->q) == NULL) ||
1693 (BN_copy(n->dsa->g, k->dsa->g) == NULL) ||
1694 (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL)) {
1695 sshkey_free(n);
1696 return SSH_ERR_ALLOC_FAIL;
1697 }
1698 break;
1699# ifdef OPENSSL_HAS_ECC
1700 case KEY_ECDSA:
1701 case KEY_ECDSA_CERT:
1702 if ((n = sshkey_new(k->type)) == NULL)
1703 return SSH_ERR_ALLOC_FAIL;
1704 n->ecdsa_nid = k->ecdsa_nid;
1705 n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
1706 if (n->ecdsa == NULL) {
1707 sshkey_free(n);
1708 return SSH_ERR_ALLOC_FAIL;
1709 }
1710 if (EC_KEY_set_public_key(n->ecdsa,
1711 EC_KEY_get0_public_key(k->ecdsa)) != 1) {
1712 sshkey_free(n);
1713 return SSH_ERR_LIBCRYPTO_ERROR;
1714 }
1715 break;
1716# endif /* OPENSSL_HAS_ECC */
1717 case KEY_RSA:
1718 case KEY_RSA1:
1719 case KEY_RSA_CERT_V00:
1720 case KEY_RSA_CERT:
1721 if ((n = sshkey_new(k->type)) == NULL)
1722 return SSH_ERR_ALLOC_FAIL;
1723 if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||
1724 (BN_copy(n->rsa->e, k->rsa->e) == NULL)) {
1725 sshkey_free(n);
1726 return SSH_ERR_ALLOC_FAIL;
1727 }
1728 break;
1729#endif /* WITH_OPENSSL */
1730 case KEY_ED25519:
1731 case KEY_ED25519_CERT:
1732 if ((n = sshkey_new(k->type)) == NULL)
1733 return SSH_ERR_ALLOC_FAIL;
1734 if (k->ed25519_pk != NULL) {
1735 if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {
1736 sshkey_free(n);
1737 return SSH_ERR_ALLOC_FAIL;
1738 }
1739 memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
1740 }
1741 break;
1742 default:
1743 return SSH_ERR_KEY_TYPE_UNKNOWN;
1744 }
1745 if (sshkey_is_cert(k)) {
1746 if ((ret = sshkey_cert_copy(k, n)) != 0) {
1747 sshkey_free(n);
1748 return ret;
1749 }
1750 }
1751 *pkp = n;
1752 return 0;
1753}
1754
1755static int
1756cert_parse(struct sshbuf *b, struct sshkey *key, const u_char *blob,
1757 size_t blen)
1758{
1759 u_char *principals = NULL, *critical = NULL, *exts = NULL;
1760 u_char *sig_key = NULL, *sig = NULL;
1761 size_t signed_len, plen, clen, sklen, slen, kidlen, elen;
1762 struct sshbuf *tmp;
1763 char *principal;
1764 int ret = SSH_ERR_INTERNAL_ERROR;
1765 int v00 = sshkey_cert_is_legacy(key);
1766 char **oprincipals;
1767
1768 if ((tmp = sshbuf_new()) == NULL)
1769 return SSH_ERR_ALLOC_FAIL;
1770
1771 /* Copy the entire key blob for verification and later serialisation */
1772 if ((ret = sshbuf_put(key->cert->certblob, blob, blen)) != 0)
1773 return ret;
1774
1775 elen = 0; /* Not touched for v00 certs */
1776 principals = exts = critical = sig_key = sig = NULL;
1777 if ((!v00 && (ret = sshbuf_get_u64(b, &key->cert->serial)) != 0) ||
1778 (ret = sshbuf_get_u32(b, &key->cert->type)) != 0 ||
1779 (ret = sshbuf_get_cstring(b, &key->cert->key_id, &kidlen)) != 0 ||
1780 (ret = sshbuf_get_string(b, &principals, &plen)) != 0 ||
1781 (ret = sshbuf_get_u64(b, &key->cert->valid_after)) != 0 ||
1782 (ret = sshbuf_get_u64(b, &key->cert->valid_before)) != 0 ||
1783 (ret = sshbuf_get_string(b, &critical, &clen)) != 0 ||
1784 (!v00 && (ret = sshbuf_get_string(b, &exts, &elen)) != 0) ||
1785 (v00 && (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0) ||
1786 (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0 ||
1787 (ret = sshbuf_get_string(b, &sig_key, &sklen)) != 0) {
1788 /* XXX debug print error for ret */
1789 ret = SSH_ERR_INVALID_FORMAT;
1790 goto out;
1791 }
1792
1793 /* Signature is left in the buffer so we can calculate this length */
1794 signed_len = sshbuf_len(key->cert->certblob) - sshbuf_len(b);
1795
1796 if ((ret = sshbuf_get_string(b, &sig, &slen)) != 0) {
1797 ret = SSH_ERR_INVALID_FORMAT;
1798 goto out;
1799 }
1800
1801 if (key->cert->type != SSH2_CERT_TYPE_USER &&
1802 key->cert->type != SSH2_CERT_TYPE_HOST) {
1803 ret = SSH_ERR_KEY_CERT_UNKNOWN_TYPE;
1804 goto out;
1805 }
1806
1807 if ((ret = sshbuf_put(tmp, principals, plen)) != 0)
1808 goto out;
1809 while (sshbuf_len(tmp) > 0) {
1810 if (key->cert->nprincipals >= SSHKEY_CERT_MAX_PRINCIPALS) {
1811 ret = SSH_ERR_INVALID_FORMAT;
1812 goto out;
1813 }
1814 if ((ret = sshbuf_get_cstring(tmp, &principal, &plen)) != 0) {
1815 ret = SSH_ERR_INVALID_FORMAT;
1816 goto out;
1817 }
1818 oprincipals = key->cert->principals;
1819 key->cert->principals = realloc(key->cert->principals,
1820 (key->cert->nprincipals + 1) *
1821 sizeof(*key->cert->principals));
1822 if (key->cert->principals == NULL) {
1823 free(principal);
1824 key->cert->principals = oprincipals;
1825 ret = SSH_ERR_ALLOC_FAIL;
1826 goto out;
1827 }
1828 key->cert->principals[key->cert->nprincipals++] = principal;
1829 }
1830
1831 sshbuf_reset(tmp);
1832
1833 if ((ret = sshbuf_put(key->cert->critical, critical, clen)) != 0 ||
1834 (ret = sshbuf_put(tmp, critical, clen)) != 0)
1835 goto out;
1836
1837 /* validate structure */
1838 while (sshbuf_len(tmp) != 0) {
1839 if ((ret = sshbuf_get_string_direct(tmp, NULL, NULL)) != 0 ||
1840 (ret = sshbuf_get_string_direct(tmp, NULL, NULL)) != 0) {
1841 ret = SSH_ERR_INVALID_FORMAT;
1842 goto out;
1843 }
1844 }
1845 sshbuf_reset(tmp);
1846
1847 if ((ret = sshbuf_put(key->cert->extensions, exts, elen)) != 0 ||
1848 (ret = sshbuf_put(tmp, exts, elen)) != 0)
1849 goto out;
1850
1851 /* validate structure */
1852 while (sshbuf_len(tmp) != 0) {
1853 if ((ret = sshbuf_get_string_direct(tmp, NULL, NULL)) != 0 ||
1854 (ret = sshbuf_get_string_direct(tmp, NULL, NULL)) != 0) {
1855 ret = SSH_ERR_INVALID_FORMAT;
1856 goto out;
1857 }
1858 }
1859 sshbuf_reset(tmp);
1860
1861 if (sshkey_from_blob_internal(sig_key, sklen,
1862 &key->cert->signature_key, 0) != 0) {
1863 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
1864 goto out;
1865 }
1866 if (!sshkey_type_is_valid_ca(key->cert->signature_key->type)) {
1867 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
1868 goto out;
1869 }
1870
1871 if ((ret = sshkey_verify(key->cert->signature_key, sig, slen,
1872 sshbuf_ptr(key->cert->certblob), signed_len, 0)) != 0)
1873 goto out;
1874 ret = 0;
1875
1876 out:
1877 sshbuf_free(tmp);
1878 free(principals);
1879 free(critical);
1880 free(exts);
1881 free(sig_key);
1882 free(sig);
1883 return ret;
1884}
1885
1886static int
1887sshkey_from_blob_internal(const u_char *blob, size_t blen,
1888 struct sshkey **keyp, int allow_cert)
1889{
1890 struct sshbuf *b = NULL;
1891 int type, nid = -1, ret = SSH_ERR_INTERNAL_ERROR;
1892 char *ktype = NULL, *curve = NULL;
1893 struct sshkey *key = NULL;
1894 size_t len;
1895 u_char *pk = NULL;
1896#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
1897 EC_POINT *q = NULL;
1898#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */
1899
1900#ifdef DEBUG_PK /* XXX */
1901 dump_base64(stderr, blob, blen);
1902#endif
1903 *keyp = NULL;
1904 if ((b = sshbuf_from(blob, blen)) == NULL)
1905 return SSH_ERR_ALLOC_FAIL;
1906 if (sshbuf_get_cstring(b, &ktype, NULL) != 0) {
1907 ret = SSH_ERR_INVALID_FORMAT;
1908 goto out;
1909 }
1910
1911 type = sshkey_type_from_name(ktype);
1912 if (sshkey_type_plain(type) == KEY_ECDSA)
1913 nid = sshkey_ecdsa_nid_from_name(ktype);
1914 if (!allow_cert && sshkey_type_is_cert(type)) {
1915 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
1916 goto out;
1917 }
1918 switch (type) {
1919#ifdef WITH_OPENSSL
1920 case KEY_RSA_CERT:
1921 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
1922 ret = SSH_ERR_INVALID_FORMAT;
1923 goto out;
1924 }
1925 /* FALLTHROUGH */
1926 case KEY_RSA:
1927 case KEY_RSA_CERT_V00:
1928 if ((key = sshkey_new(type)) == NULL) {
1929 ret = SSH_ERR_ALLOC_FAIL;
1930 goto out;
1931 }
1932 if (sshbuf_get_bignum2(b, key->rsa->e) == -1 ||
1933 sshbuf_get_bignum2(b, key->rsa->n) == -1) {
1934 ret = SSH_ERR_INVALID_FORMAT;
1935 goto out;
1936 }
1937#ifdef DEBUG_PK
1938 RSA_print_fp(stderr, key->rsa, 8);
1939#endif
1940 break;
1941 case KEY_DSA_CERT:
1942 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
1943 ret = SSH_ERR_INVALID_FORMAT;
1944 goto out;
1945 }
1946 /* FALLTHROUGH */
1947 case KEY_DSA:
1948 case KEY_DSA_CERT_V00:
1949 if ((key = sshkey_new(type)) == NULL) {
1950 ret = SSH_ERR_ALLOC_FAIL;
1951 goto out;
1952 }
1953 if (sshbuf_get_bignum2(b, key->dsa->p) == -1 ||
1954 sshbuf_get_bignum2(b, key->dsa->q) == -1 ||
1955 sshbuf_get_bignum2(b, key->dsa->g) == -1 ||
1956 sshbuf_get_bignum2(b, key->dsa->pub_key) == -1) {
1957 ret = SSH_ERR_INVALID_FORMAT;
1958 goto out;
1959 }
1960#ifdef DEBUG_PK
1961 DSA_print_fp(stderr, key->dsa, 8);
1962#endif
1963 break;
1964 case KEY_ECDSA_CERT:
1965 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
1966 ret = SSH_ERR_INVALID_FORMAT;
1967 goto out;
1968 }
1969 /* FALLTHROUGH */
1970# ifdef OPENSSL_HAS_ECC
1971 case KEY_ECDSA:
1972 if ((key = sshkey_new(type)) == NULL) {
1973 ret = SSH_ERR_ALLOC_FAIL;
1974 goto out;
1975 }
1976 key->ecdsa_nid = nid;
1977 if (sshbuf_get_cstring(b, &curve, NULL) != 0) {
1978 ret = SSH_ERR_INVALID_FORMAT;
1979 goto out;
1980 }
1981 if (key->ecdsa_nid != sshkey_curve_name_to_nid(curve)) {
1982 ret = SSH_ERR_EC_CURVE_MISMATCH;
1983 goto out;
1984 }
1985 if (key->ecdsa != NULL)
1986 EC_KEY_free(key->ecdsa);
1987 if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid))
1988 == NULL) {
1989 ret = SSH_ERR_EC_CURVE_INVALID;
1990 goto out;
1991 }
1992 if ((q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL) {
1993 ret = SSH_ERR_ALLOC_FAIL;
1994 goto out;
1995 }
1996 if (sshbuf_get_ec(b, q, EC_KEY_get0_group(key->ecdsa)) != 0) {
1997 ret = SSH_ERR_INVALID_FORMAT;
1998 goto out;
1999 }
2000 if (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa),
2001 q) != 0) {
2002 ret = SSH_ERR_KEY_INVALID_EC_VALUE;
2003 goto out;
2004 }
2005 if (EC_KEY_set_public_key(key->ecdsa, q) != 1) {
2006 /* XXX assume it is a allocation error */
2007 ret = SSH_ERR_ALLOC_FAIL;
2008 goto out;
2009 }
2010#ifdef DEBUG_PK
2011 sshkey_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q);
2012#endif
2013 break;
2014# endif /* OPENSSL_HAS_ECC */
2015#endif /* WITH_OPENSSL */
2016 case KEY_ED25519_CERT:
2017 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
2018 ret = SSH_ERR_INVALID_FORMAT;
2019 goto out;
2020 }
2021 /* FALLTHROUGH */
2022 case KEY_ED25519:
2023 if ((ret = sshbuf_get_string(b, &pk, &len)) != 0)
2024 goto out;
2025 if (len != ED25519_PK_SZ) {
2026 ret = SSH_ERR_INVALID_FORMAT;
2027 goto out;
2028 }
2029 if ((key = sshkey_new(type)) == NULL) {
2030 ret = SSH_ERR_ALLOC_FAIL;
2031 goto out;
2032 }
2033 key->ed25519_pk = pk;
2034 pk = NULL;
2035 break;
2036 case KEY_UNSPEC:
2037 if ((key = sshkey_new(type)) == NULL) {
2038 ret = SSH_ERR_ALLOC_FAIL;
2039 goto out;
2040 }
2041 break;
2042 default:
2043 ret = SSH_ERR_KEY_TYPE_UNKNOWN;
2044 goto out;
2045 }
2046
2047 /* Parse certificate potion */
2048 if (sshkey_is_cert(key) &&
2049 (ret = cert_parse(b, key, blob, blen)) != 0)
2050 goto out;
2051
2052 if (key != NULL && sshbuf_len(b) != 0) {
2053 ret = SSH_ERR_INVALID_FORMAT;
2054 goto out;
2055 }
2056 ret = 0;
2057 *keyp = key;
2058 key = NULL;
2059 out:
2060 sshbuf_free(b);
2061 sshkey_free(key);
2062 free(ktype);
2063 free(curve);
2064 free(pk);
2065#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
2066 if (q != NULL)
2067 EC_POINT_free(q);
2068#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */
2069 return ret;
2070}
2071
2072int
2073sshkey_from_blob(const u_char *blob, size_t blen, struct sshkey **keyp)
2074{
2075 return sshkey_from_blob_internal(blob, blen, keyp, 1);
2076}
2077
2078int
2079sshkey_sign(const struct sshkey *key,
2080 u_char **sigp, size_t *lenp,
2081 const u_char *data, size_t datalen, u_int compat)
2082{
2083 if (sigp != NULL)
2084 *sigp = NULL;
2085 if (lenp != NULL)
2086 *lenp = 0;
2087 if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)
2088 return SSH_ERR_INVALID_ARGUMENT;
2089 switch (key->type) {
2090#ifdef WITH_OPENSSL
2091 case KEY_DSA_CERT_V00:
2092 case KEY_DSA_CERT:
2093 case KEY_DSA:
2094 return ssh_dss_sign(key, sigp, lenp, data, datalen, compat);
2095# ifdef OPENSSL_HAS_ECC
2096 case KEY_ECDSA_CERT:
2097 case KEY_ECDSA:
2098 return ssh_ecdsa_sign(key, sigp, lenp, data, datalen, compat);
2099# endif /* OPENSSL_HAS_ECC */
2100 case KEY_RSA_CERT_V00:
2101 case KEY_RSA_CERT:
2102 case KEY_RSA:
2103 return ssh_rsa_sign(key, sigp, lenp, data, datalen, compat);
2104#endif /* WITH_OPENSSL */
2105 case KEY_ED25519:
2106 case KEY_ED25519_CERT:
2107 return ssh_ed25519_sign(key, sigp, lenp, data, datalen, compat);
2108 default:
2109 return SSH_ERR_KEY_TYPE_UNKNOWN;
2110 }
2111}
2112
2113/*
2114 * ssh_key_verify returns 0 for a correct signature and < 0 on error.
2115 */
2116int
2117sshkey_verify(const struct sshkey *key,
2118 const u_char *sig, size_t siglen,
2119 const u_char *data, size_t dlen, u_int compat)
2120{
2121 if (siglen == 0)
2122 return -1;
2123
2124 if (dlen > SSH_KEY_MAX_SIGN_DATA_SIZE)
2125 return SSH_ERR_INVALID_ARGUMENT;
2126 switch (key->type) {
2127#ifdef WITH_OPENSSL
2128 case KEY_DSA_CERT_V00:
2129 case KEY_DSA_CERT:
2130 case KEY_DSA:
2131 return ssh_dss_verify(key, sig, siglen, data, dlen, compat);
2132# ifdef OPENSSL_HAS_ECC
2133 case KEY_ECDSA_CERT:
2134 case KEY_ECDSA:
2135 return ssh_ecdsa_verify(key, sig, siglen, data, dlen, compat);
2136# endif /* OPENSSL_HAS_ECC */
2137 case KEY_RSA_CERT_V00:
2138 case KEY_RSA_CERT:
2139 case KEY_RSA:
2140 return ssh_rsa_verify(key, sig, siglen, data, dlen, compat);
2141#endif /* WITH_OPENSSL */
2142 case KEY_ED25519:
2143 case KEY_ED25519_CERT:
2144 return ssh_ed25519_verify(key, sig, siglen, data, dlen, compat);
2145 default:
2146 return SSH_ERR_KEY_TYPE_UNKNOWN;
2147 }
2148}
2149
2150/* Converts a private to a public key */
2151int
2152sshkey_demote(const struct sshkey *k, struct sshkey **dkp)
2153{
2154 struct sshkey *pk;
2155 int ret = SSH_ERR_INTERNAL_ERROR;
2156
2157 if (dkp != NULL)
2158 *dkp = NULL;
2159
2160 if ((pk = calloc(1, sizeof(*pk))) == NULL)
2161 return SSH_ERR_ALLOC_FAIL;
2162 pk->type = k->type;
2163 pk->flags = k->flags;
2164 pk->ecdsa_nid = k->ecdsa_nid;
2165 pk->dsa = NULL;
2166 pk->ecdsa = NULL;
2167 pk->rsa = NULL;
2168 pk->ed25519_pk = NULL;
2169 pk->ed25519_sk = NULL;
2170
2171 switch (k->type) {
2172#ifdef WITH_OPENSSL
2173 case KEY_RSA_CERT_V00:
2174 case KEY_RSA_CERT:
2175 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2176 goto fail;
2177 /* FALLTHROUGH */
2178 case KEY_RSA1:
2179 case KEY_RSA:
2180 if ((pk->rsa = RSA_new()) == NULL ||
2181 (pk->rsa->e = BN_dup(k->rsa->e)) == NULL ||
2182 (pk->rsa->n = BN_dup(k->rsa->n)) == NULL) {
2183 ret = SSH_ERR_ALLOC_FAIL;
2184 goto fail;
2185 }
2186 break;
2187 case KEY_DSA_CERT_V00:
2188 case KEY_DSA_CERT:
2189 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2190 goto fail;
2191 /* FALLTHROUGH */
2192 case KEY_DSA:
2193 if ((pk->dsa = DSA_new()) == NULL ||
2194 (pk->dsa->p = BN_dup(k->dsa->p)) == NULL ||
2195 (pk->dsa->q = BN_dup(k->dsa->q)) == NULL ||
2196 (pk->dsa->g = BN_dup(k->dsa->g)) == NULL ||
2197 (pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) {
2198 ret = SSH_ERR_ALLOC_FAIL;
2199 goto fail;
2200 }
2201 break;
2202 case KEY_ECDSA_CERT:
2203 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2204 goto fail;
2205 /* FALLTHROUGH */
2206# ifdef OPENSSL_HAS_ECC
2207 case KEY_ECDSA:
2208 pk->ecdsa = EC_KEY_new_by_curve_name(pk->ecdsa_nid);
2209 if (pk->ecdsa == NULL) {
2210 ret = SSH_ERR_ALLOC_FAIL;
2211 goto fail;
2212 }
2213 if (EC_KEY_set_public_key(pk->ecdsa,
2214 EC_KEY_get0_public_key(k->ecdsa)) != 1) {
2215 ret = SSH_ERR_LIBCRYPTO_ERROR;
2216 goto fail;
2217 }
2218 break;
2219# endif /* OPENSSL_HAS_ECC */
2220#endif /* WITH_OPENSSL */
2221 case KEY_ED25519_CERT:
2222 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2223 goto fail;
2224 /* FALLTHROUGH */
2225 case KEY_ED25519:
2226 if (k->ed25519_pk != NULL) {
2227 if ((pk->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {
2228 ret = SSH_ERR_ALLOC_FAIL;
2229 goto fail;
2230 }
2231 memcpy(pk->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
2232 }
2233 break;
2234 default:
2235 ret = SSH_ERR_KEY_TYPE_UNKNOWN;
2236 fail:
2237 sshkey_free(pk);
2238 return ret;
2239 }
2240 *dkp = pk;
2241 return 0;
2242}
2243
2244/* Convert a plain key to their _CERT equivalent */
2245int
2246sshkey_to_certified(struct sshkey *k, int legacy)
2247{
2248 int newtype;
2249
2250 switch (k->type) {
2251#ifdef WITH_OPENSSL
2252 case KEY_RSA:
2253 newtype = legacy ? KEY_RSA_CERT_V00 : KEY_RSA_CERT;
2254 break;
2255 case KEY_DSA:
2256 newtype = legacy ? KEY_DSA_CERT_V00 : KEY_DSA_CERT;
2257 break;
2258 case KEY_ECDSA:
2259 if (legacy)
2260 return SSH_ERR_INVALID_ARGUMENT;
2261 newtype = KEY_ECDSA_CERT;
2262 break;
2263#endif /* WITH_OPENSSL */
2264 case KEY_ED25519:
2265 if (legacy)
2266 return SSH_ERR_INVALID_ARGUMENT;
2267 newtype = KEY_ED25519_CERT;
2268 break;
2269 default:
2270 return SSH_ERR_INVALID_ARGUMENT;
2271 }
2272 if ((k->cert = cert_new()) == NULL)
2273 return SSH_ERR_ALLOC_FAIL;
2274 k->type = newtype;
2275 return 0;
2276}
2277
2278/* Convert a certificate to its raw key equivalent */
2279int
2280sshkey_drop_cert(struct sshkey *k)
2281{
2282 if (!sshkey_type_is_cert(k->type))
2283 return SSH_ERR_KEY_TYPE_UNKNOWN;
2284 cert_free(k->cert);
2285 k->cert = NULL;
2286 k->type = sshkey_type_plain(k->type);
2287 return 0;
2288}
2289
2290/* Sign a certified key, (re-)generating the signed certblob. */
2291int
2292sshkey_certify(struct sshkey *k, struct sshkey *ca)
2293{
2294 struct sshbuf *principals = NULL;
2295 u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32];
2296 size_t i, ca_len, sig_len;
2297 int ret = SSH_ERR_INTERNAL_ERROR;
2298 struct sshbuf *cert;
2299
2300 if (k == NULL || k->cert == NULL ||
2301 k->cert->certblob == NULL || ca == NULL)
2302 return SSH_ERR_INVALID_ARGUMENT;
2303 if (!sshkey_is_cert(k))
2304 return SSH_ERR_KEY_TYPE_UNKNOWN;
2305 if (!sshkey_type_is_valid_ca(ca->type))
2306 return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
2307
2308 if ((ret = sshkey_to_blob(ca, &ca_blob, &ca_len)) != 0)
2309 return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
2310
2311 cert = k->cert->certblob; /* for readability */
2312 sshbuf_reset(cert);
2313 if ((ret = sshbuf_put_cstring(cert, sshkey_ssh_name(k))) != 0)
2314 goto out;
2315
2316 /* -v01 certs put nonce first */
2317 arc4random_buf(&nonce, sizeof(nonce));
2318 if (!sshkey_cert_is_legacy(k)) {
2319 if ((ret = sshbuf_put_string(cert, nonce, sizeof(nonce))) != 0)
2320 goto out;
2321 }
2322
2323 /* XXX this substantially duplicates to_blob(); refactor */
2324 switch (k->type) {
2325#ifdef WITH_OPENSSL
2326 case KEY_DSA_CERT_V00:
2327 case KEY_DSA_CERT:
2328 if ((ret = sshbuf_put_bignum2(cert, k->dsa->p)) != 0 ||
2329 (ret = sshbuf_put_bignum2(cert, k->dsa->q)) != 0 ||
2330 (ret = sshbuf_put_bignum2(cert, k->dsa->g)) != 0 ||
2331 (ret = sshbuf_put_bignum2(cert, k->dsa->pub_key)) != 0)
2332 goto out;
2333 break;
2334# ifdef OPENSSL_HAS_ECC
2335 case KEY_ECDSA_CERT:
2336 if ((ret = sshbuf_put_cstring(cert,
2337 sshkey_curve_nid_to_name(k->ecdsa_nid))) != 0 ||
2338 (ret = sshbuf_put_ec(cert,
2339 EC_KEY_get0_public_key(k->ecdsa),
2340 EC_KEY_get0_group(k->ecdsa))) != 0)
2341 goto out;
2342 break;
2343# endif /* OPENSSL_HAS_ECC */
2344 case KEY_RSA_CERT_V00:
2345 case KEY_RSA_CERT:
2346 if ((ret = sshbuf_put_bignum2(cert, k->rsa->e)) != 0 ||
2347 (ret = sshbuf_put_bignum2(cert, k->rsa->n)) != 0)
2348 goto out;
2349 break;
2350#endif /* WITH_OPENSSL */
2351 case KEY_ED25519_CERT:
2352 if ((ret = sshbuf_put_string(cert,
2353 k->ed25519_pk, ED25519_PK_SZ)) != 0)
2354 goto out;
2355 break;
2356 default:
2357 ret = SSH_ERR_INVALID_ARGUMENT;
2358 }
2359
2360 /* -v01 certs have a serial number next */
2361 if (!sshkey_cert_is_legacy(k)) {
2362 if ((ret = sshbuf_put_u64(cert, k->cert->serial)) != 0)
2363 goto out;
2364 }
2365
2366 if ((ret = sshbuf_put_u32(cert, k->cert->type)) != 0 ||
2367 (ret = sshbuf_put_cstring(cert, k->cert->key_id)) != 0)
2368 goto out;
2369
2370 if ((principals = sshbuf_new()) == NULL) {
2371 ret = SSH_ERR_ALLOC_FAIL;
2372 goto out;
2373 }
2374 for (i = 0; i < k->cert->nprincipals; i++) {
2375 if ((ret = sshbuf_put_cstring(principals,
2376 k->cert->principals[i])) != 0)
2377 goto out;
2378 }
2379 if ((ret = sshbuf_put_stringb(cert, principals)) != 0 ||
2380 (ret = sshbuf_put_u64(cert, k->cert->valid_after)) != 0 ||
2381 (ret = sshbuf_put_u64(cert, k->cert->valid_before)) != 0 ||
2382 (ret = sshbuf_put_stringb(cert, k->cert->critical)) != 0)
2383 goto out;
2384
2385 /* -v01 certs have non-critical options here */
2386 if (!sshkey_cert_is_legacy(k)) {
2387 if ((ret = sshbuf_put_stringb(cert, k->cert->extensions)) != 0)
2388 goto out;
2389 }
2390
2391 /* -v00 certs put the nonce at the end */
2392 if (sshkey_cert_is_legacy(k)) {
2393 if ((ret = sshbuf_put_string(cert, nonce, sizeof(nonce))) != 0)
2394 goto out;
2395 }
2396
2397 if ((ret = sshbuf_put_string(cert, NULL, 0)) != 0 || /* Reserved */
2398 (ret = sshbuf_put_string(cert, ca_blob, ca_len)) != 0)
2399 goto out;
2400
2401 /* Sign the whole mess */
2402 if ((ret = sshkey_sign(ca, &sig_blob, &sig_len, sshbuf_ptr(cert),
2403 sshbuf_len(cert), 0)) != 0)
2404 goto out;
2405
2406 /* Append signature and we are done */
2407 if ((ret = sshbuf_put_string(cert, sig_blob, sig_len)) != 0)
2408 goto out;
2409 ret = 0;
2410 out:
2411 if (ret != 0)
2412 sshbuf_reset(cert);
2413 if (sig_blob != NULL)
2414 free(sig_blob);
2415 if (ca_blob != NULL)
2416 free(ca_blob);
2417 if (principals != NULL)
2418 sshbuf_free(principals);
2419 return ret;
2420}
2421
2422int
2423sshkey_cert_check_authority(const struct sshkey *k,
2424 int want_host, int require_principal,
2425 const char *name, const char **reason)
2426{
2427 u_int i, principal_matches;
2428 time_t now = time(NULL);
2429
2430 if (reason != NULL)
2431 *reason = NULL;
2432
2433 if (want_host) {
2434 if (k->cert->type != SSH2_CERT_TYPE_HOST) {
2435 *reason = "Certificate invalid: not a host certificate";
2436 return SSH_ERR_KEY_CERT_INVALID;
2437 }
2438 } else {
2439 if (k->cert->type != SSH2_CERT_TYPE_USER) {
2440 *reason = "Certificate invalid: not a user certificate";
2441 return SSH_ERR_KEY_CERT_INVALID;
2442 }
2443 }
2444 if (now < 0) {
2445 /* yikes - system clock before epoch! */
2446 *reason = "Certificate invalid: not yet valid";
2447 return SSH_ERR_KEY_CERT_INVALID;
2448 }
2449 if ((u_int64_t)now < k->cert->valid_after) {
2450 *reason = "Certificate invalid: not yet valid";
2451 return SSH_ERR_KEY_CERT_INVALID;
2452 }
2453 if ((u_int64_t)now >= k->cert->valid_before) {
2454 *reason = "Certificate invalid: expired";
2455 return SSH_ERR_KEY_CERT_INVALID;
2456 }
2457 if (k->cert->nprincipals == 0) {
2458 if (require_principal) {
2459 *reason = "Certificate lacks principal list";
2460 return SSH_ERR_KEY_CERT_INVALID;
2461 }
2462 } else if (name != NULL) {
2463 principal_matches = 0;
2464 for (i = 0; i < k->cert->nprincipals; i++) {
2465 if (strcmp(name, k->cert->principals[i]) == 0) {
2466 principal_matches = 1;
2467 break;
2468 }
2469 }
2470 if (!principal_matches) {
2471 *reason = "Certificate invalid: name is not a listed "
2472 "principal";
2473 return SSH_ERR_KEY_CERT_INVALID;
2474 }
2475 }
2476 return 0;
2477}
2478
2479int
2480sshkey_private_serialize(const struct sshkey *key, struct sshbuf *b)
2481{
2482 int r = SSH_ERR_INTERNAL_ERROR;
2483
2484 if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0)
2485 goto out;
2486 switch (key->type) {
2487#ifdef WITH_OPENSSL
2488 case KEY_RSA:
2489 if ((r = sshbuf_put_bignum2(b, key->rsa->n)) != 0 ||
2490 (r = sshbuf_put_bignum2(b, key->rsa->e)) != 0 ||
2491 (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 ||
2492 (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 ||
2493 (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 ||
2494 (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0)
2495 goto out;
2496 break;
2497 case KEY_RSA_CERT_V00:
2498 case KEY_RSA_CERT:
2499 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
2500 r = SSH_ERR_INVALID_ARGUMENT;
2501 goto out;
2502 }
2503 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
2504 (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 ||
2505 (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 ||
2506 (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 ||
2507 (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0)
2508 goto out;
2509 break;
2510 case KEY_DSA:
2511 if ((r = sshbuf_put_bignum2(b, key->dsa->p)) != 0 ||
2512 (r = sshbuf_put_bignum2(b, key->dsa->q)) != 0 ||
2513 (r = sshbuf_put_bignum2(b, key->dsa->g)) != 0 ||
2514 (r = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0 ||
2515 (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0)
2516 goto out;
2517 break;
2518 case KEY_DSA_CERT_V00:
2519 case KEY_DSA_CERT:
2520 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
2521 r = SSH_ERR_INVALID_ARGUMENT;
2522 goto out;
2523 }
2524 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
2525 (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0)
2526 goto out;
2527 break;
2528# ifdef OPENSSL_HAS_ECC
2529 case KEY_ECDSA:
2530 if ((r = sshbuf_put_cstring(b,
2531 sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 ||
2532 (r = sshbuf_put_eckey(b, key->ecdsa)) != 0 ||
2533 (r = sshbuf_put_bignum2(b,
2534 EC_KEY_get0_private_key(key->ecdsa))) != 0)
2535 goto out;
2536 break;
2537 case KEY_ECDSA_CERT:
2538 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
2539 r = SSH_ERR_INVALID_ARGUMENT;
2540 goto out;
2541 }
2542 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
2543 (r = sshbuf_put_bignum2(b,
2544 EC_KEY_get0_private_key(key->ecdsa))) != 0)
2545 goto out;
2546 break;
2547# endif /* OPENSSL_HAS_ECC */
2548#endif /* WITH_OPENSSL */
2549 case KEY_ED25519:
2550 if ((r = sshbuf_put_string(b, key->ed25519_pk,
2551 ED25519_PK_SZ)) != 0 ||
2552 (r = sshbuf_put_string(b, key->ed25519_sk,
2553 ED25519_SK_SZ)) != 0)
2554 goto out;
2555 break;
2556 case KEY_ED25519_CERT:
2557 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
2558 r = SSH_ERR_INVALID_ARGUMENT;
2559 goto out;
2560 }
2561 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
2562 (r = sshbuf_put_string(b, key->ed25519_pk,
2563 ED25519_PK_SZ)) != 0 ||
2564 (r = sshbuf_put_string(b, key->ed25519_sk,
2565 ED25519_SK_SZ)) != 0)
2566 goto out;
2567 break;
2568 default:
2569 r = SSH_ERR_INVALID_ARGUMENT;
2570 goto out;
2571 }
2572 /* success */
2573 r = 0;
2574 out:
2575 return r;
2576}
2577
2578int
2579sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2580{
2581 char *tname = NULL, *curve = NULL;
2582 struct sshkey *k = NULL;
2583 const u_char *cert;
2584 size_t len, pklen = 0, sklen = 0;
2585 int type, r = SSH_ERR_INTERNAL_ERROR;
2586 u_char *ed25519_pk = NULL, *ed25519_sk = NULL;
2587#ifdef WITH_OPENSSL
2588 BIGNUM *exponent = NULL;
2589#endif /* WITH_OPENSSL */
2590
2591 if (kp != NULL)
2592 *kp = NULL;
2593 if ((r = sshbuf_get_cstring(buf, &tname, NULL)) != 0)
2594 goto out;
2595 type = sshkey_type_from_name(tname);
2596 switch (type) {
2597#ifdef WITH_OPENSSL
2598 case KEY_DSA:
2599 if ((k = sshkey_new_private(type)) == NULL) {
2600 r = SSH_ERR_ALLOC_FAIL;
2601 goto out;
2602 }
2603 if ((r = sshbuf_get_bignum2(buf, k->dsa->p)) != 0 ||
2604 (r = sshbuf_get_bignum2(buf, k->dsa->q)) != 0 ||
2605 (r = sshbuf_get_bignum2(buf, k->dsa->g)) != 0 ||
2606 (r = sshbuf_get_bignum2(buf, k->dsa->pub_key)) != 0 ||
2607 (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0)
2608 goto out;
2609 break;
2610 case KEY_DSA_CERT_V00:
2611 case KEY_DSA_CERT:
2612 if ((r = sshbuf_get_string_direct(buf, &cert, &len)) != 0 ||
2613 (r = sshkey_from_blob(cert, len, &k)) != 0 ||
2614 (r = sshkey_add_private(k)) != 0 ||
2615 (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0)
2616 goto out;
2617 break;
2618# ifdef OPENSSL_HAS_ECC
2619 case KEY_ECDSA:
2620 if ((k = sshkey_new_private(type)) == NULL) {
2621 r = SSH_ERR_ALLOC_FAIL;
2622 goto out;
2623 }
2624 if ((k->ecdsa_nid = sshkey_ecdsa_nid_from_name(tname)) == -1) {
2625 r = SSH_ERR_INVALID_ARGUMENT;
2626 goto out;
2627 }
2628 if ((r = sshbuf_get_cstring(buf, &curve, NULL)) != 0)
2629 goto out;
2630 if (k->ecdsa_nid != sshkey_curve_name_to_nid(curve)) {
2631 r = SSH_ERR_EC_CURVE_MISMATCH;
2632 goto out;
2633 }
2634 k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
2635 if (k->ecdsa == NULL || (exponent = BN_new()) == NULL) {
2636 r = SSH_ERR_LIBCRYPTO_ERROR;
2637 goto out;
2638 }
2639 if ((r = sshbuf_get_eckey(buf, k->ecdsa)) != 0 ||
2640 (r = sshbuf_get_bignum2(buf, exponent)))
2641 goto out;
2642 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) {
2643 r = SSH_ERR_LIBCRYPTO_ERROR;
2644 goto out;
2645 }
2646 if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
2647 EC_KEY_get0_public_key(k->ecdsa)) != 0) ||
2648 (r = sshkey_ec_validate_private(k->ecdsa)) != 0)
2649 goto out;
2650 break;
2651 case KEY_ECDSA_CERT:
2652 if ((exponent = BN_new()) == NULL) {
2653 r = SSH_ERR_LIBCRYPTO_ERROR;
2654 goto out;
2655 }
2656 if ((r = sshbuf_get_string_direct(buf, &cert, &len)) != 0 ||
2657 (r = sshkey_from_blob(cert, len, &k)) != 0 ||
2658 (r = sshkey_add_private(k)) != 0 ||
2659 (r = sshbuf_get_bignum2(buf, exponent)) != 0)
2660 goto out;
2661 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) {
2662 r = SSH_ERR_LIBCRYPTO_ERROR;
2663 goto out;
2664 }
2665 if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
2666 EC_KEY_get0_public_key(k->ecdsa)) != 0) ||
2667 (r = sshkey_ec_validate_private(k->ecdsa)) != 0)
2668 goto out;
2669 break;
2670# endif /* OPENSSL_HAS_ECC */
2671 case KEY_RSA:
2672 if ((k = sshkey_new_private(type)) == NULL) {
2673 r = SSH_ERR_ALLOC_FAIL;
2674 goto out;
2675 }
2676 if ((r = sshbuf_get_bignum2(buf, k->rsa->n)) != 0 ||
2677 (r = sshbuf_get_bignum2(buf, k->rsa->e)) != 0 ||
2678 (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 ||
2679 (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 ||
2680 (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 ||
2681 (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 ||
2682 (r = rsa_generate_additional_parameters(k->rsa)) != 0)
2683 goto out;
2684 break;
2685 case KEY_RSA_CERT_V00:
2686 case KEY_RSA_CERT:
2687 if ((r = sshbuf_get_string_direct(buf, &cert, &len)) != 0 ||
2688 (r = sshkey_from_blob(cert, len, &k)) != 0 ||
2689 (r = sshkey_add_private(k)) != 0 ||
2690 (r = sshbuf_get_bignum2(buf, k->rsa->d) != 0) ||
2691 (r = sshbuf_get_bignum2(buf, k->rsa->iqmp) != 0) ||
2692 (r = sshbuf_get_bignum2(buf, k->rsa->p) != 0) ||
2693 (r = sshbuf_get_bignum2(buf, k->rsa->q) != 0) ||
2694 (r = rsa_generate_additional_parameters(k->rsa)) != 0)
2695 goto out;
2696 break;
2697#endif /* WITH_OPENSSL */
2698 case KEY_ED25519:
2699 if ((k = sshkey_new_private(type)) == NULL) {
2700 r = SSH_ERR_ALLOC_FAIL;
2701 goto out;
2702 }
2703 if ((r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 ||
2704 (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0)
2705 goto out;
2706 if (pklen != ED25519_PK_SZ || sklen != ED25519_SK_SZ) {
2707 r = SSH_ERR_INVALID_FORMAT;
2708 goto out;
2709 }
2710 k->ed25519_pk = ed25519_pk;
2711 k->ed25519_sk = ed25519_sk;
2712 ed25519_pk = ed25519_sk = NULL;
2713 break;
2714 case KEY_ED25519_CERT:
2715 if ((r = sshbuf_get_string_direct(buf, &cert, &len)) != 0 ||
2716 (r = sshkey_from_blob(cert, len, &k)) != 0 ||
2717 (r = sshkey_add_private(k)) != 0 ||
2718 (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 ||
2719 (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0)
2720 goto out;
2721 if (pklen != ED25519_PK_SZ || sklen != ED25519_SK_SZ) {
2722 r = SSH_ERR_INVALID_FORMAT;
2723 goto out;
2724 }
2725 k->ed25519_pk = ed25519_pk;
2726 k->ed25519_sk = ed25519_sk;
2727 ed25519_pk = ed25519_sk = NULL;
2728 break;
2729 default:
2730 r = SSH_ERR_KEY_TYPE_UNKNOWN;
2731 goto out;
2732 }
2733#ifdef WITH_OPENSSL
2734 /* enable blinding */
2735 switch (k->type) {
2736 case KEY_RSA:
2737 case KEY_RSA_CERT_V00:
2738 case KEY_RSA_CERT:
2739 case KEY_RSA1:
2740 if (RSA_blinding_on(k->rsa, NULL) != 1) {
2741 r = SSH_ERR_LIBCRYPTO_ERROR;
2742 goto out;
2743 }
2744 break;
2745 }
2746#endif /* WITH_OPENSSL */
2747 /* success */
2748 r = 0;
2749 if (kp != NULL) {
2750 *kp = k;
2751 k = NULL;
2752 }
2753 out:
2754 free(tname);
2755 free(curve);
2756#ifdef WITH_OPENSSL
2757 if (exponent != NULL)
2758 BN_clear_free(exponent);
2759#endif /* WITH_OPENSSL */
2760 sshkey_free(k);
2761 if (ed25519_pk != NULL) {
2762 explicit_bzero(ed25519_pk, pklen);
2763 free(ed25519_pk);
2764 }
2765 if (ed25519_sk != NULL) {
2766 explicit_bzero(ed25519_sk, sklen);
2767 free(ed25519_sk);
2768 }
2769 return r;
2770}
2771
2772#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
2773int
2774sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
2775{
2776 BN_CTX *bnctx;
2777 EC_POINT *nq = NULL;
2778 BIGNUM *order, *x, *y, *tmp;
2779 int ret = SSH_ERR_KEY_INVALID_EC_VALUE;
2780
2781 if ((bnctx = BN_CTX_new()) == NULL)
2782 return SSH_ERR_ALLOC_FAIL;
2783 BN_CTX_start(bnctx);
2784
2785 /*
2786 * We shouldn't ever hit this case because bignum_get_ecpoint()
2787 * refuses to load GF2m points.
2788 */
2789 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
2790 NID_X9_62_prime_field)
2791 goto out;
2792
2793 /* Q != infinity */
2794 if (EC_POINT_is_at_infinity(group, public))
2795 goto out;
2796
2797 if ((x = BN_CTX_get(bnctx)) == NULL ||
2798 (y = BN_CTX_get(bnctx)) == NULL ||
2799 (order = BN_CTX_get(bnctx)) == NULL ||
2800 (tmp = BN_CTX_get(bnctx)) == NULL) {
2801 ret = SSH_ERR_ALLOC_FAIL;
2802 goto out;
2803 }
2804
2805 /* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */
2806 if (EC_GROUP_get_order(group, order, bnctx) != 1 ||
2807 EC_POINT_get_affine_coordinates_GFp(group, public,
2808 x, y, bnctx) != 1) {
2809 ret = SSH_ERR_LIBCRYPTO_ERROR;
2810 goto out;
2811 }
2812 if (BN_num_bits(x) <= BN_num_bits(order) / 2 ||
2813 BN_num_bits(y) <= BN_num_bits(order) / 2)
2814 goto out;
2815
2816 /* nQ == infinity (n == order of subgroup) */
2817 if ((nq = EC_POINT_new(group)) == NULL) {
2818 ret = SSH_ERR_ALLOC_FAIL;
2819 goto out;
2820 }
2821 if (EC_POINT_mul(group, nq, NULL, public, order, bnctx) != 1) {
2822 ret = SSH_ERR_LIBCRYPTO_ERROR;
2823 goto out;
2824 }
2825 if (EC_POINT_is_at_infinity(group, nq) != 1)
2826 goto out;
2827
2828 /* x < order - 1, y < order - 1 */
2829 if (!BN_sub(tmp, order, BN_value_one())) {
2830 ret = SSH_ERR_LIBCRYPTO_ERROR;
2831 goto out;
2832 }
2833 if (BN_cmp(x, tmp) >= 0 || BN_cmp(y, tmp) >= 0)
2834 goto out;
2835 ret = 0;
2836 out:
2837 BN_CTX_free(bnctx);
2838 if (nq != NULL)
2839 EC_POINT_free(nq);
2840 return ret;
2841}
2842
2843int
2844sshkey_ec_validate_private(const EC_KEY *key)
2845{
2846 BN_CTX *bnctx;
2847 BIGNUM *order, *tmp;
2848 int ret = SSH_ERR_KEY_INVALID_EC_VALUE;
2849
2850 if ((bnctx = BN_CTX_new()) == NULL)
2851 return SSH_ERR_ALLOC_FAIL;
2852 BN_CTX_start(bnctx);
2853
2854 if ((order = BN_CTX_get(bnctx)) == NULL ||
2855 (tmp = BN_CTX_get(bnctx)) == NULL) {
2856 ret = SSH_ERR_ALLOC_FAIL;
2857 goto out;
2858 }
2859
2860 /* log2(private) > log2(order)/2 */
2861 if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1) {
2862 ret = SSH_ERR_LIBCRYPTO_ERROR;
2863 goto out;
2864 }
2865 if (BN_num_bits(EC_KEY_get0_private_key(key)) <=
2866 BN_num_bits(order) / 2)
2867 goto out;
2868
2869 /* private < order - 1 */
2870 if (!BN_sub(tmp, order, BN_value_one())) {
2871 ret = SSH_ERR_LIBCRYPTO_ERROR;
2872 goto out;
2873 }
2874 if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0)
2875 goto out;
2876 ret = 0;
2877 out:
2878 BN_CTX_free(bnctx);
2879 return ret;
2880}
2881
2882void
2883sshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point)
2884{
2885 BIGNUM *x, *y;
2886 BN_CTX *bnctx;
2887
2888 if (point == NULL) {
2889 fputs("point=(NULL)\n", stderr);
2890 return;
2891 }
2892 if ((bnctx = BN_CTX_new()) == NULL) {
2893 fprintf(stderr, "%s: BN_CTX_new failed\n", __func__);
2894 return;
2895 }
2896 BN_CTX_start(bnctx);
2897 if ((x = BN_CTX_get(bnctx)) == NULL ||
2898 (y = BN_CTX_get(bnctx)) == NULL) {
2899 fprintf(stderr, "%s: BN_CTX_get failed\n", __func__);
2900 return;
2901 }
2902 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
2903 NID_X9_62_prime_field) {
2904 fprintf(stderr, "%s: group is not a prime field\n", __func__);
2905 return;
2906 }
2907 if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y,
2908 bnctx) != 1) {
2909 fprintf(stderr, "%s: EC_POINT_get_affine_coordinates_GFp\n",
2910 __func__);
2911 return;
2912 }
2913 fputs("x=", stderr);
2914 BN_print_fp(stderr, x);
2915 fputs("\ny=", stderr);
2916 BN_print_fp(stderr, y);
2917 fputs("\n", stderr);
2918 BN_CTX_free(bnctx);
2919}
2920
2921void
2922sshkey_dump_ec_key(const EC_KEY *key)
2923{
2924 const BIGNUM *exponent;
2925
2926 sshkey_dump_ec_point(EC_KEY_get0_group(key),
2927 EC_KEY_get0_public_key(key));
2928 fputs("exponent=", stderr);
2929 if ((exponent = EC_KEY_get0_private_key(key)) == NULL)
2930 fputs("(NULL)", stderr);
2931 else
2932 BN_print_fp(stderr, EC_KEY_get0_private_key(key));
2933 fputs("\n", stderr);
2934}
2935#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */
2936
2937static int
2938sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob,
2939 const char *passphrase, const char *comment, const char *ciphername,
2940 int rounds)
2941{
2942 u_char *cp, *b64 = NULL, *key = NULL, *pubkeyblob = NULL;
2943 u_char salt[SALT_LEN];
2944 size_t i, pubkeylen, keylen, ivlen, blocksize, authlen;
2945 u_int check;
2946 int r = SSH_ERR_INTERNAL_ERROR;
2947 struct sshcipher_ctx ciphercontext;
2948 const struct sshcipher *cipher;
2949 const char *kdfname = KDFNAME;
2950 struct sshbuf *encoded = NULL, *encrypted = NULL, *kdf = NULL;
2951
2952 memset(&ciphercontext, 0, sizeof(ciphercontext));
2953
2954 if (rounds <= 0)
2955 rounds = DEFAULT_ROUNDS;
2956 if (passphrase == NULL || !strlen(passphrase)) {
2957 ciphername = "none";
2958 kdfname = "none";
2959 } else if (ciphername == NULL)
2960 ciphername = DEFAULT_CIPHERNAME;
2961 else if (cipher_number(ciphername) != SSH_CIPHER_SSH2) {
2962 r = SSH_ERR_INVALID_ARGUMENT;
2963 goto out;
2964 }
2965 if ((cipher = cipher_by_name(ciphername)) == NULL) {
2966 r = SSH_ERR_INTERNAL_ERROR;
2967 goto out;
2968 }
2969
2970 if ((kdf = sshbuf_new()) == NULL ||
2971 (encoded = sshbuf_new()) == NULL ||
2972 (encrypted = sshbuf_new()) == NULL) {
2973 r = SSH_ERR_ALLOC_FAIL;
2974 goto out;
2975 }
2976 blocksize = cipher_blocksize(cipher);
2977 keylen = cipher_keylen(cipher);
2978 ivlen = cipher_ivlen(cipher);
2979 authlen = cipher_authlen(cipher);
2980 if ((key = calloc(1, keylen + ivlen)) == NULL) {
2981 r = SSH_ERR_ALLOC_FAIL;
2982 goto out;
2983 }
2984 if (strcmp(kdfname, "bcrypt") == 0) {
2985 arc4random_buf(salt, SALT_LEN);
2986 if (bcrypt_pbkdf(passphrase, strlen(passphrase),
2987 salt, SALT_LEN, key, keylen + ivlen, rounds) < 0) {
2988 r = SSH_ERR_INVALID_ARGUMENT;
2989 goto out;
2990 }
2991 if ((r = sshbuf_put_string(kdf, salt, SALT_LEN)) != 0 ||
2992 (r = sshbuf_put_u32(kdf, rounds)) != 0)
2993 goto out;
2994 } else if (strcmp(kdfname, "none") != 0) {
2995 /* Unsupported KDF type */
2996 r = SSH_ERR_KEY_UNKNOWN_CIPHER;
2997 goto out;
2998 }
2999 if ((r = cipher_init(&ciphercontext, cipher, key, keylen,
3000 key + keylen, ivlen, 1)) != 0)
3001 goto out;
3002
3003 if ((r = sshbuf_put(encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC))) != 0 ||
3004 (r = sshbuf_put_cstring(encoded, ciphername)) != 0 ||
3005 (r = sshbuf_put_cstring(encoded, kdfname)) != 0 ||
3006 (r = sshbuf_put_stringb(encoded, kdf)) != 0 ||
3007 (r = sshbuf_put_u32(encoded, 1)) != 0 || /* number of keys */
3008 (r = sshkey_to_blob(prv, &pubkeyblob, &pubkeylen)) != 0 ||
3009 (r = sshbuf_put_string(encoded, pubkeyblob, pubkeylen)) != 0)
3010 goto out;
3011
3012 /* set up the buffer that will be encrypted */
3013
3014 /* Random check bytes */
3015 check = arc4random();
3016 if ((r = sshbuf_put_u32(encrypted, check)) != 0 ||
3017 (r = sshbuf_put_u32(encrypted, check)) != 0)
3018 goto out;
3019
3020 /* append private key and comment*/
3021 if ((r = sshkey_private_serialize(prv, encrypted)) != 0 ||
3022 (r = sshbuf_put_cstring(encrypted, comment)) != 0)
3023 goto out;
3024
3025 /* padding */
3026 i = 0;
3027 while (sshbuf_len(encrypted) % blocksize) {
3028 if ((r = sshbuf_put_u8(encrypted, ++i & 0xff)) != 0)
3029 goto out;
3030 }
3031
3032 /* length in destination buffer */
3033 if ((r = sshbuf_put_u32(encoded, sshbuf_len(encrypted))) != 0)
3034 goto out;
3035
3036 /* encrypt */
3037 if ((r = sshbuf_reserve(encoded,
3038 sshbuf_len(encrypted) + authlen, &cp)) != 0)
3039 goto out;
3040 if ((r = cipher_crypt(&ciphercontext, 0, cp,
3041 sshbuf_ptr(encrypted), sshbuf_len(encrypted), 0, authlen)) != 0)
3042 goto out;
3043
3044 /* uuencode */
3045 if ((b64 = sshbuf_dtob64(encoded)) == NULL) {
3046 r = SSH_ERR_ALLOC_FAIL;
3047 goto out;
3048 }
3049
3050 sshbuf_reset(blob);
3051 if ((r = sshbuf_put(blob, MARK_BEGIN, MARK_BEGIN_LEN)) != 0)
3052 goto out;
3053 for (i = 0; i < strlen(b64); i++) {
3054 if ((r = sshbuf_put_u8(blob, b64[i])) != 0)
3055 goto out;
3056 /* insert line breaks */
3057 if (i % 70 == 69 && (r = sshbuf_put_u8(blob, '\n')) != 0)
3058 goto out;
3059 }
3060 if (i % 70 != 69 && (r = sshbuf_put_u8(blob, '\n')) != 0)
3061 goto out;
3062 if ((r = sshbuf_put(blob, MARK_END, MARK_END_LEN)) != 0)
3063 goto out;
3064
3065 /* success */
3066 r = 0;
3067
3068 out:
3069 sshbuf_free(kdf);
3070 sshbuf_free(encoded);
3071 sshbuf_free(encrypted);
3072 cipher_cleanup(&ciphercontext);
3073 explicit_bzero(salt, sizeof(salt));
3074 if (key != NULL) {
3075 explicit_bzero(key, keylen + ivlen);
3076 free(key);
3077 }
3078 if (pubkeyblob != NULL) {
3079 explicit_bzero(pubkeyblob, pubkeylen);
3080 free(pubkeyblob);
3081 }
3082 if (b64 != NULL) {
3083 explicit_bzero(b64, strlen(b64));
3084 free(b64);
3085 }
3086 return r;
3087}
3088
3089static int
3090sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
3091 struct sshkey **keyp, char **commentp)
3092{
3093 char *comment = NULL, *ciphername = NULL, *kdfname = NULL;
3094 const struct sshcipher *cipher = NULL;
3095 const u_char *cp;
3096 int r = SSH_ERR_INTERNAL_ERROR;
3097 size_t encoded_len;
3098 size_t i, keylen = 0, ivlen = 0, slen = 0;
3099 struct sshbuf *encoded = NULL, *decoded = NULL;
3100 struct sshbuf *kdf = NULL, *decrypted = NULL;
3101 struct sshcipher_ctx ciphercontext;
3102 struct sshkey *k = NULL;
3103 u_char *key = NULL, *salt = NULL, *dp, pad, last;
3104 u_int blocksize, rounds, nkeys, encrypted_len, check1, check2;
3105
3106 memset(&ciphercontext, 0, sizeof(ciphercontext));
3107 if (keyp != NULL)
3108 *keyp = NULL;
3109 if (commentp != NULL)
3110 *commentp = NULL;
3111
3112 if ((encoded = sshbuf_new()) == NULL ||
3113 (decoded = sshbuf_new()) == NULL ||
3114 (decrypted = sshbuf_new()) == NULL) {
3115 r = SSH_ERR_ALLOC_FAIL;
3116 goto out;
3117 }
3118
3119 /* check preamble */
3120 cp = sshbuf_ptr(blob);
3121 encoded_len = sshbuf_len(blob);
3122 if (encoded_len < (MARK_BEGIN_LEN + MARK_END_LEN) ||
3123 memcmp(cp, MARK_BEGIN, MARK_BEGIN_LEN) != 0) {
3124 r = SSH_ERR_INVALID_FORMAT;
3125 goto out;
3126 }
3127 cp += MARK_BEGIN_LEN;
3128 encoded_len -= MARK_BEGIN_LEN;
3129
3130 /* Look for end marker, removing whitespace as we go */
3131 while (encoded_len > 0) {
3132 if (*cp != '\n' && *cp != '\r') {
3133 if ((r = sshbuf_put_u8(encoded, *cp)) != 0)
3134 goto out;
3135 }
3136 last = *cp;
3137 encoded_len--;
3138 cp++;
3139 if (last == '\n') {
3140 if (encoded_len >= MARK_END_LEN &&
3141 memcmp(cp, MARK_END, MARK_END_LEN) == 0) {
3142 /* \0 terminate */
3143 if ((r = sshbuf_put_u8(encoded, 0)) != 0)
3144 goto out;
3145 break;
3146 }
3147 }
3148 }
3149 if (encoded_len == 0) {
3150 r = SSH_ERR_INVALID_FORMAT;
3151 goto out;
3152 }
3153
3154 /* decode base64 */
3155 if ((r = sshbuf_b64tod(decoded, sshbuf_ptr(encoded))) != 0)
3156 goto out;
3157
3158 /* check magic */
3159 if (sshbuf_len(decoded) < sizeof(AUTH_MAGIC) ||
3160 memcmp(sshbuf_ptr(decoded), AUTH_MAGIC, sizeof(AUTH_MAGIC))) {
3161 r = SSH_ERR_INVALID_FORMAT;
3162 goto out;
3163 }
3164 /* parse public portion of key */
3165 if ((r = sshbuf_consume(decoded, sizeof(AUTH_MAGIC))) != 0 ||
3166 (r = sshbuf_get_cstring(decoded, &ciphername, NULL)) != 0 ||
3167 (r = sshbuf_get_cstring(decoded, &kdfname, NULL)) != 0 ||
3168 (r = sshbuf_froms(decoded, &kdf)) != 0 ||
3169 (r = sshbuf_get_u32(decoded, &nkeys)) != 0 ||
3170 (r = sshbuf_skip_string(decoded)) != 0 || /* pubkey */
3171 (r = sshbuf_get_u32(decoded, &encrypted_len)) != 0)
3172 goto out;
3173
3174 if ((cipher = cipher_by_name(ciphername)) == NULL) {
3175 r = SSH_ERR_KEY_UNKNOWN_CIPHER;
3176 goto out;
3177 }
3178 if ((passphrase == NULL || strlen(passphrase) == 0) &&
3179 strcmp(ciphername, "none") != 0) {
3180 /* passphrase required */
3181 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3182 goto out;
3183 }
3184 if (strcmp(kdfname, "none") != 0 && strcmp(kdfname, "bcrypt") != 0) {
3185 r = SSH_ERR_KEY_UNKNOWN_CIPHER;
3186 goto out;
3187 }
3188 if (!strcmp(kdfname, "none") && strcmp(ciphername, "none") != 0) {
3189 r = SSH_ERR_INVALID_FORMAT;
3190 goto out;
3191 }
3192 if (nkeys != 1) {
3193 /* XXX only one key supported */
3194 r = SSH_ERR_INVALID_FORMAT;
3195 goto out;
3196 }
3197
3198 /* check size of encrypted key blob */
3199 blocksize = cipher_blocksize(cipher);
3200 if (encrypted_len < blocksize || (encrypted_len % blocksize) != 0) {
3201 r = SSH_ERR_INVALID_FORMAT;
3202 goto out;
3203 }
3204
3205 /* setup key */
3206 keylen = cipher_keylen(cipher);
3207 ivlen = cipher_ivlen(cipher);
3208 if ((key = calloc(1, keylen + ivlen)) == NULL) {
3209 r = SSH_ERR_ALLOC_FAIL;
3210 goto out;
3211 }
3212 if (strcmp(kdfname, "bcrypt") == 0) {
3213 if ((r = sshbuf_get_string(kdf, &salt, &slen)) != 0 ||
3214 (r = sshbuf_get_u32(kdf, &rounds)) != 0)
3215 goto out;
3216 if (bcrypt_pbkdf(passphrase, strlen(passphrase), salt, slen,
3217 key, keylen + ivlen, rounds) < 0) {
3218 r = SSH_ERR_INVALID_FORMAT;
3219 goto out;
3220 }
3221 }
3222
3223 /* decrypt private portion of key */
3224 if ((r = sshbuf_reserve(decrypted, encrypted_len, &dp)) != 0 ||
3225 (r = cipher_init(&ciphercontext, cipher, key, keylen,
3226 key + keylen, ivlen, 0)) != 0)
3227 goto out;
3228 if ((r = cipher_crypt(&ciphercontext, 0, dp, sshbuf_ptr(decoded),
3229 sshbuf_len(decoded), 0, cipher_authlen(cipher))) != 0) {
3230 /* an integrity error here indicates an incorrect passphrase */
3231 if (r == SSH_ERR_MAC_INVALID)
3232 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3233 goto out;
3234 }
3235 if ((r = sshbuf_consume(decoded, encrypted_len)) != 0)
3236 goto out;
3237 /* there should be no trailing data */
3238 if (sshbuf_len(decoded) != 0) {
3239 r = SSH_ERR_INVALID_FORMAT;
3240 goto out;
3241 }
3242
3243 /* check check bytes */
3244 if ((r = sshbuf_get_u32(decrypted, &check1)) != 0 ||
3245 (r = sshbuf_get_u32(decrypted, &check2)) != 0)
3246 goto out;
3247 if (check1 != check2) {
3248 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3249 goto out;
3250 }
3251
3252 /* Load the private key and comment */
3253 if ((r = sshkey_private_deserialize(decrypted, &k)) != 0 ||
3254 (r = sshbuf_get_cstring(decrypted, &comment, NULL)) != 0)
3255 goto out;
3256
3257 /* Check deterministic padding */
3258 i = 0;
3259 while (sshbuf_len(decrypted)) {
3260 if ((r = sshbuf_get_u8(decrypted, &pad)) != 0)
3261 goto out;
3262 if (pad != (++i & 0xff)) {
3263 r = SSH_ERR_INVALID_FORMAT;
3264 goto out;
3265 }
3266 }
3267
3268 /* XXX decode pubkey and check against private */
3269
3270 /* success */
3271 r = 0;
3272 if (keyp != NULL) {
3273 *keyp = k;
3274 k = NULL;
3275 }
3276 if (commentp != NULL) {
3277 *commentp = comment;
3278 comment = NULL;
3279 }
3280 out:
3281 pad = 0;
3282 cipher_cleanup(&ciphercontext);
3283 free(ciphername);
3284 free(kdfname);
3285 free(comment);
3286 if (salt != NULL) {
3287 explicit_bzero(salt, slen);
3288 free(salt);
3289 }
3290 if (key != NULL) {
3291 explicit_bzero(key, keylen + ivlen);
3292 free(key);
3293 }
3294 sshbuf_free(encoded);
3295 sshbuf_free(decoded);
3296 sshbuf_free(kdf);
3297 sshbuf_free(decrypted);
3298 sshkey_free(k);
3299 return r;
3300}
3301
3302#if WITH_SSH1
3303/*
3304 * Serialises the authentication (private) key to a blob, encrypting it with
3305 * passphrase. The identification of the blob (lowest 64 bits of n) will
3306 * precede the key to provide identification of the key without needing a
3307 * passphrase.
3308 */
3309static int
3310sshkey_private_rsa1_to_blob(struct sshkey *key, struct sshbuf *blob,
3311 const char *passphrase, const char *comment)
3312{
3313 struct sshbuf *buffer = NULL, *encrypted = NULL;
3314 u_char buf[8];
3315 int r, cipher_num;
3316 struct sshcipher_ctx ciphercontext;
3317 const struct sshcipher *cipher;
3318 u_char *cp;
3319
3320 /*
3321 * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting
3322 * to another cipher; otherwise use SSH_AUTHFILE_CIPHER.
3323 */
3324 cipher_num = (strcmp(passphrase, "") == 0) ?
3325 SSH_CIPHER_NONE : SSH_CIPHER_3DES;
3326 if ((cipher = cipher_by_number(cipher_num)) == NULL)
3327 return SSH_ERR_INTERNAL_ERROR;
3328
3329 /* This buffer is used to build the secret part of the private key. */
3330 if ((buffer = sshbuf_new()) == NULL)
3331 return SSH_ERR_ALLOC_FAIL;
3332
3333 /* Put checkbytes for checking passphrase validity. */
3334 if ((r = sshbuf_reserve(buffer, 4, &cp)) != 0)
3335 goto out;
3336 arc4random_buf(cp, 2);
3337 memcpy(cp + 2, cp, 2);
3338
3339 /*
3340 * Store the private key (n and e will not be stored because they
3341 * will be stored in plain text, and storing them also in encrypted
3342 * format would just give known plaintext).
3343 * Note: q and p are stored in reverse order to SSL.
3344 */
3345 if ((r = sshbuf_put_bignum1(buffer, key->rsa->d)) != 0 ||
3346 (r = sshbuf_put_bignum1(buffer, key->rsa->iqmp)) != 0 ||
3347 (r = sshbuf_put_bignum1(buffer, key->rsa->q)) != 0 ||
3348 (r = sshbuf_put_bignum1(buffer, key->rsa->p)) != 0)
3349 goto out;
3350
3351 /* Pad the part to be encrypted to a size that is a multiple of 8. */
3352 explicit_bzero(buf, 8);
3353 if ((r = sshbuf_put(buffer, buf, 8 - (sshbuf_len(buffer) % 8))) != 0)
3354 goto out;
3355
3356 /* This buffer will be used to contain the data in the file. */
3357 if ((encrypted = sshbuf_new()) == NULL) {
3358 r = SSH_ERR_ALLOC_FAIL;
3359 goto out;
3360 }
3361
3362 /* First store keyfile id string. */
3363 if ((r = sshbuf_put(encrypted, LEGACY_BEGIN,
3364 sizeof(LEGACY_BEGIN))) != 0)
3365 goto out;
3366
3367 /* Store cipher type and "reserved" field. */
3368 if ((r = sshbuf_put_u8(encrypted, cipher_num)) != 0 ||
3369 (r = sshbuf_put_u32(encrypted, 0)) != 0)
3370 goto out;
3371
3372 /* Store public key. This will be in plain text. */
3373 if ((r = sshbuf_put_u32(encrypted, BN_num_bits(key->rsa->n))) != 0 ||
3374 (r = sshbuf_put_bignum1(encrypted, key->rsa->n) != 0) ||
3375 (r = sshbuf_put_bignum1(encrypted, key->rsa->e) != 0) ||
3376 (r = sshbuf_put_cstring(encrypted, comment) != 0))
3377 goto out;
3378
3379 /* Allocate space for the private part of the key in the buffer. */
3380 if ((r = sshbuf_reserve(encrypted, sshbuf_len(buffer), &cp)) != 0)
3381 goto out;
3382
3383 if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase,
3384 CIPHER_ENCRYPT)) != 0)
3385 goto out;
3386 if ((r = cipher_crypt(&ciphercontext, 0, cp,
3387 sshbuf_ptr(buffer), sshbuf_len(buffer), 0, 0)) != 0)
3388 goto out;
3389 if ((r = cipher_cleanup(&ciphercontext)) != 0)
3390 goto out;
3391
3392 r = sshbuf_putb(blob, encrypted);
3393
3394 out:
3395 explicit_bzero(&ciphercontext, sizeof(ciphercontext));
3396 explicit_bzero(buf, sizeof(buf));
3397 if (buffer != NULL)
3398 sshbuf_free(buffer);
3399 if (encrypted != NULL)
3400 sshbuf_free(encrypted);
3401
3402 return r;
3403}
3404#endif /* WITH_SSH1 */
3405
3406#ifdef WITH_OPENSSL
3407/* convert SSH v2 key in OpenSSL PEM format */
3408static int
3409sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob,
3410 const char *_passphrase, const char *comment)
3411{
3412 int success, r;
3413 int blen, len = strlen(_passphrase);
3414 u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;
3415#if (OPENSSL_VERSION_NUMBER < 0x00907000L)
3416 const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL;
3417#else
3418 const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
3419#endif
3420 const u_char *bptr;
3421 BIO *bio = NULL;
3422
3423 if (len > 0 && len <= 4)
3424 return SSH_ERR_PASSPHRASE_TOO_SHORT;
3425 if ((bio = BIO_new(BIO_s_mem())) == NULL)
3426 return SSH_ERR_ALLOC_FAIL;
3427
3428 switch (key->type) {
3429 case KEY_DSA:
3430 success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
3431 cipher, passphrase, len, NULL, NULL);
3432 break;
3433#ifdef OPENSSL_HAS_ECC
3434 case KEY_ECDSA:
3435 success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
3436 cipher, passphrase, len, NULL, NULL);
3437 break;
3438#endif
3439 case KEY_RSA:
3440 success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
3441 cipher, passphrase, len, NULL, NULL);
3442 break;
3443 default:
3444 success = 0;
3445 break;
3446 }
3447 if (success == 0) {
3448 r = SSH_ERR_LIBCRYPTO_ERROR;
3449 goto out;
3450 }
3451 if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) {
3452 r = SSH_ERR_INTERNAL_ERROR;
3453 goto out;
3454 }
3455 if ((r = sshbuf_put(blob, bptr, blen)) != 0)
3456 goto out;
3457 r = 0;
3458 out:
3459 BIO_free(bio);
3460 return r;
3461}
3462#endif /* WITH_OPENSSL */
3463
3464/* Serialise "key" to buffer "blob" */
3465int
3466sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
3467 const char *passphrase, const char *comment,
3468 int force_new_format, const char *new_format_cipher, int new_format_rounds)
3469{
3470 switch (key->type) {
3471#ifdef WITH_OPENSSL
3472 case KEY_RSA1:
3473 return sshkey_private_rsa1_to_blob(key, blob,
3474 passphrase, comment);
3475 case KEY_DSA:
3476 case KEY_ECDSA:
3477 case KEY_RSA:
3478 if (force_new_format) {
3479 return sshkey_private_to_blob2(key, blob, passphrase,
3480 comment, new_format_cipher, new_format_rounds);
3481 }
3482 return sshkey_private_pem_to_blob(key, blob,
3483 passphrase, comment);
3484#endif /* WITH_OPENSSL */
3485 case KEY_ED25519:
3486 return sshkey_private_to_blob2(key, blob, passphrase,
3487 comment, new_format_cipher, new_format_rounds);
3488 default:
3489 return SSH_ERR_KEY_TYPE_UNKNOWN;
3490 }
3491}
3492
3493#ifdef WITH_SSH1
3494/*
3495 * Parse the public, unencrypted portion of a RSA1 key.
3496 */
3497int
3498sshkey_parse_public_rsa1_fileblob(struct sshbuf *blob,
3499 struct sshkey **keyp, char **commentp)
3500{
3501 int r;
3502 struct sshkey *pub = NULL;
3503 struct sshbuf *copy = NULL;
3504
3505 if (keyp != NULL)
3506 *keyp = NULL;
3507 if (commentp != NULL)
3508 *commentp = NULL;
3509
3510 /* Check that it is at least big enough to contain the ID string. */
3511 if (sshbuf_len(blob) < sizeof(LEGACY_BEGIN))
3512 return SSH_ERR_INVALID_FORMAT;
3513
3514 /*
3515 * Make sure it begins with the id string. Consume the id string
3516 * from the buffer.
3517 */
3518 if (memcmp(sshbuf_ptr(blob), LEGACY_BEGIN, sizeof(LEGACY_BEGIN)) != 0)
3519 return SSH_ERR_INVALID_FORMAT;
3520 /* Make a working copy of the keyblob and skip past the magic */
3521 if ((copy = sshbuf_fromb(blob)) == NULL)
3522 return SSH_ERR_ALLOC_FAIL;
3523 if ((r = sshbuf_consume(copy, sizeof(LEGACY_BEGIN))) != 0)
3524 goto out;
3525
3526 /* Skip cipher type, reserved data and key bits. */
3527 if ((r = sshbuf_get_u8(copy, NULL)) != 0 || /* cipher type */
3528 (r = sshbuf_get_u32(copy, NULL)) != 0 || /* reserved */
3529 (r = sshbuf_get_u32(copy, NULL)) != 0) /* key bits */
3530 goto out;
3531
3532 /* Read the public key from the buffer. */
3533 if ((pub = sshkey_new(KEY_RSA1)) == NULL ||
3534 (r = sshbuf_get_bignum1(copy, pub->rsa->n)) != 0 ||
3535 (r = sshbuf_get_bignum1(copy, pub->rsa->e)) != 0)
3536 goto out;
3537
3538 /* Finally, the comment */
3539 if ((r = sshbuf_get_string(copy, (u_char**)commentp, NULL)) != 0)
3540 goto out;
3541
3542 /* The encrypted private part is not parsed by this function. */
3543
3544 r = 0;
3545 if (keyp != NULL)
3546 *keyp = pub;
3547 else
3548 sshkey_free(pub);
3549 pub = NULL;
3550
3551 out:
3552 if (copy != NULL)
3553 sshbuf_free(copy);
3554 if (pub != NULL)
3555 sshkey_free(pub);
3556 return r;
3557}
3558
3559static int
3560sshkey_parse_private_rsa1(struct sshbuf *blob, const char *passphrase,
3561 struct sshkey **keyp, char **commentp)
3562{
3563 int r;
3564 u_int16_t check1, check2;
3565 u_int8_t cipher_type;
3566 struct sshbuf *decrypted = NULL, *copy = NULL;
3567 u_char *cp;
3568 char *comment = NULL;
3569 struct sshcipher_ctx ciphercontext;
3570 const struct sshcipher *cipher;
3571 struct sshkey *prv = NULL;
3572
3573 *keyp = NULL;
3574 if (commentp != NULL)
3575 *commentp = NULL;
3576
3577 /* Check that it is at least big enough to contain the ID string. */
3578 if (sshbuf_len(blob) < sizeof(LEGACY_BEGIN))
3579 return SSH_ERR_INVALID_FORMAT;
3580
3581 /*
3582 * Make sure it begins with the id string. Consume the id string
3583 * from the buffer.
3584 */
3585 if (memcmp(sshbuf_ptr(blob), LEGACY_BEGIN, sizeof(LEGACY_BEGIN)) != 0)
3586 return SSH_ERR_INVALID_FORMAT;
3587
3588 if ((prv = sshkey_new_private(KEY_RSA1)) == NULL) {
3589 r = SSH_ERR_ALLOC_FAIL;
3590 goto out;
3591 }
3592 if ((copy = sshbuf_fromb(blob)) == NULL ||
3593 (decrypted = sshbuf_new()) == NULL) {
3594 r = SSH_ERR_ALLOC_FAIL;
3595 goto out;
3596 }
3597 if ((r = sshbuf_consume(copy, sizeof(LEGACY_BEGIN))) != 0)
3598 goto out;
3599
3600 /* Read cipher type. */
3601 if ((r = sshbuf_get_u8(copy, &cipher_type)) != 0 ||
3602 (r = sshbuf_get_u32(copy, NULL)) != 0) /* reserved */
3603 goto out;
3604
3605 /* Read the public key and comment from the buffer. */
3606 if ((r = sshbuf_get_u32(copy, NULL)) != 0 || /* key bits */
3607 (r = sshbuf_get_bignum1(copy, prv->rsa->n)) != 0 ||
3608 (r = sshbuf_get_bignum1(copy, prv->rsa->e)) != 0 ||
3609 (r = sshbuf_get_cstring(copy, &comment, NULL)) != 0)
3610 goto out;
3611
3612 /* Check that it is a supported cipher. */
3613 cipher = cipher_by_number(cipher_type);
3614 if (cipher == NULL) {
3615 r = SSH_ERR_KEY_UNKNOWN_CIPHER;
3616 goto out;
3617 }
3618 /* Initialize space for decrypted data. */
3619 if ((r = sshbuf_reserve(decrypted, sshbuf_len(copy), &cp)) != 0)
3620 goto out;
3621
3622 /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */
3623 if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase,
3624 CIPHER_DECRYPT)) != 0)
3625 goto out;
3626 if ((r = cipher_crypt(&ciphercontext, 0, cp,
3627 sshbuf_ptr(copy), sshbuf_len(copy), 0, 0)) != 0) {
3628 cipher_cleanup(&ciphercontext);
3629 goto out;
3630 }
3631 if ((r = cipher_cleanup(&ciphercontext)) != 0)
3632 goto out;
3633
3634 if ((r = sshbuf_get_u16(decrypted, &check1)) != 0 ||
3635 (r = sshbuf_get_u16(decrypted, &check2)) != 0)
3636 goto out;
3637 if (check1 != check2) {
3638 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3639 goto out;
3640 }
3641
3642 /* Read the rest of the private key. */
3643 if ((r = sshbuf_get_bignum1(decrypted, prv->rsa->d)) != 0 ||
3644 (r = sshbuf_get_bignum1(decrypted, prv->rsa->iqmp)) != 0 ||
3645 (r = sshbuf_get_bignum1(decrypted, prv->rsa->q)) != 0 ||
3646 (r = sshbuf_get_bignum1(decrypted, prv->rsa->p)) != 0)
3647 goto out;
3648
3649 /* calculate p-1 and q-1 */
3650 if ((r = rsa_generate_additional_parameters(prv->rsa)) != 0)
3651 goto out;
3652
3653 /* enable blinding */
3654 if (RSA_blinding_on(prv->rsa, NULL) != 1) {
3655 r = SSH_ERR_LIBCRYPTO_ERROR;
3656 goto out;
3657 }
3658 r = 0;
3659 *keyp = prv;
3660 prv = NULL;
3661 if (commentp != NULL) {
3662 *commentp = comment;
3663 comment = NULL;
3664 }
3665 out:
3666 explicit_bzero(&ciphercontext, sizeof(ciphercontext));
3667 if (comment != NULL)
3668 free(comment);
3669 if (prv != NULL)
3670 sshkey_free(prv);
3671 if (copy != NULL)
3672 sshbuf_free(copy);
3673 if (decrypted != NULL)
3674 sshbuf_free(decrypted);
3675 return r;
3676}
3677#endif /* WITH_SSH1 */
3678
3679#ifdef WITH_OPENSSL
3680/* XXX make private once ssh-keysign.c fixed */
3681int
3682sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3683 const char *passphrase, struct sshkey **keyp, char **commentp)
3684{
3685 EVP_PKEY *pk = NULL;
3686 struct sshkey *prv = NULL;
3687 char *name = "<no key>";
3688 BIO *bio = NULL;
3689 int r;
3690
3691 *keyp = NULL;
3692 if (commentp != NULL)
3693 *commentp = NULL;
3694
3695 if ((bio = BIO_new(BIO_s_mem())) == NULL || sshbuf_len(blob) > INT_MAX)
3696 return SSH_ERR_ALLOC_FAIL;
3697 if (BIO_write(bio, sshbuf_ptr(blob), sshbuf_len(blob)) !=
3698 (int)sshbuf_len(blob)) {
3699 r = SSH_ERR_ALLOC_FAIL;
3700 goto out;
3701 }
3702
3703 if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL,
3704 (char *)passphrase)) == NULL) {
3705 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3706 goto out;
3707 }
3708 if (pk->type == EVP_PKEY_RSA &&
3709 (type == KEY_UNSPEC || type == KEY_RSA)) {
3710 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
3711 r = SSH_ERR_ALLOC_FAIL;
3712 goto out;
3713 }
3714 prv->rsa = EVP_PKEY_get1_RSA(pk);
3715 prv->type = KEY_RSA;
3716 name = "rsa w/o comment";
3717#ifdef DEBUG_PK
3718 RSA_print_fp(stderr, prv->rsa, 8);
3719#endif
3720 if (RSA_blinding_on(prv->rsa, NULL) != 1) {
3721 r = SSH_ERR_LIBCRYPTO_ERROR;
3722 goto out;
3723 }
3724 } else if (pk->type == EVP_PKEY_DSA &&
3725 (type == KEY_UNSPEC || type == KEY_DSA)) {
3726 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
3727 r = SSH_ERR_ALLOC_FAIL;
3728 goto out;
3729 }
3730 prv->dsa = EVP_PKEY_get1_DSA(pk);
3731 prv->type = KEY_DSA;
3732 name = "dsa w/o comment";
3733#ifdef DEBUG_PK
3734 DSA_print_fp(stderr, prv->dsa, 8);
3735#endif
3736#ifdef OPENSSL_HAS_ECC
3737 } else if (pk->type == EVP_PKEY_EC &&
3738 (type == KEY_UNSPEC || type == KEY_ECDSA)) {
3739 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
3740 r = SSH_ERR_ALLOC_FAIL;
3741 goto out;
3742 }
3743 prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk);
3744 prv->type = KEY_ECDSA;
3745 prv->ecdsa_nid = sshkey_ecdsa_key_to_nid(prv->ecdsa);
3746 if (prv->ecdsa_nid == -1 ||
3747 sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL ||
3748 sshkey_ec_validate_public(EC_KEY_get0_group(prv->ecdsa),
3749 EC_KEY_get0_public_key(prv->ecdsa)) != 0 ||
3750 sshkey_ec_validate_private(prv->ecdsa) != 0) {
3751 r = SSH_ERR_INVALID_FORMAT;
3752 goto out;
3753 }
3754 name = "ecdsa w/o comment";
3755# ifdef DEBUG_PK
3756 if (prv != NULL && prv->ecdsa != NULL)
3757 sshkey_dump_ec_key(prv->ecdsa);
3758# endif
3759#endif /* OPENSSL_HAS_ECC */
3760 } else {
3761 r = SSH_ERR_INVALID_FORMAT;
3762 goto out;
3763 }
3764 if (commentp != NULL &&
3765 (*commentp = strdup(name)) == NULL) {
3766 r = SSH_ERR_ALLOC_FAIL;
3767 goto out;
3768 }
3769 r = 0;
3770 *keyp = prv;
3771 prv = NULL;
3772 out:
3773 BIO_free(bio);
3774 if (pk != NULL)
3775 EVP_PKEY_free(pk);
3776 if (prv != NULL)
3777 sshkey_free(prv);
3778 return r;
3779}
3780#endif /* WITH_OPENSSL */
3781
3782int
3783sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
3784 const char *passphrase, struct sshkey **keyp, char **commentp)
3785{
3786 int r;
3787
3788 *keyp = NULL;
3789 if (commentp != NULL)
3790 *commentp = NULL;
3791
3792 switch (type) {
3793#ifdef WITH_OPENSSL
3794 case KEY_RSA1:
3795 return sshkey_parse_private_rsa1(blob, passphrase,
3796 keyp, commentp);
3797 case KEY_DSA:
3798 case KEY_ECDSA:
3799 case KEY_RSA:
3800 return sshkey_parse_private_pem_fileblob(blob, type, passphrase,
3801 keyp, commentp);
3802#endif /* WITH_OPENSSL */
3803 case KEY_ED25519:
3804 return sshkey_parse_private2(blob, type, passphrase,
3805 keyp, commentp);
3806 case KEY_UNSPEC:
3807 if ((r = sshkey_parse_private2(blob, type, passphrase, keyp,
3808 commentp)) == 0)
3809 return 0;
3810#ifdef WITH_OPENSSL
3811 return sshkey_parse_private_pem_fileblob(blob, type, passphrase,
3812 keyp, commentp);
3813#else
3814 return SSH_ERR_INVALID_FORMAT;
3815#endif /* WITH_OPENSSL */
3816 default:
3817 return SSH_ERR_KEY_TYPE_UNKNOWN;
3818 }
3819}
3820
3821int
3822sshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase,
3823 const char *filename, struct sshkey **keyp, char **commentp)
3824{
3825 int r;
3826
3827 if (keyp != NULL)
3828 *keyp = NULL;
3829 if (commentp != NULL)
3830 *commentp = NULL;
3831
3832#ifdef WITH_SSH1
3833 /* it's a SSH v1 key if the public key part is readable */
3834 if ((r = sshkey_parse_public_rsa1_fileblob(buffer, NULL, NULL)) == 0) {
3835 return sshkey_parse_private_fileblob_type(buffer, KEY_RSA1,
3836 passphrase, keyp, commentp);
3837 }
3838#endif /* WITH_SSH1 */
3839 if ((r = sshkey_parse_private_fileblob_type(buffer, KEY_UNSPEC,
3840 passphrase, keyp, commentp)) == 0)
3841 return 0;
3842 return r;
3843}
diff --git a/sshkey.h b/sshkey.h
new file mode 100644
index 000000000..4127db244
--- /dev/null
+++ b/sshkey.h
@@ -0,0 +1,222 @@
1/* $OpenBSD: sshkey.h,v 1.1 2014/06/24 01:16:58 djm Exp $ */
2
3/*
4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26#ifndef SSHKEY_H
27#define SSHKEY_H
28
29#include <sys/types.h>
30
31#ifdef WITH_OPENSSL
32#include <openssl/rsa.h>
33#include <openssl/dsa.h>
34#include <openssl/ec.h>
35#else /* OPENSSL */
36#define RSA void
37#define DSA void
38#define EC_KEY void
39#define EC_GROUP void
40#define EC_POINT void
41#endif /* WITH_OPENSSL */
42
43#define SSH_RSA_MINIMUM_MODULUS_SIZE 768
44#define SSH_KEY_MAX_SIGN_DATA_SIZE (1 << 20)
45
46struct sshbuf;
47
48/* Key types */
49enum sshkey_types {
50 KEY_RSA1,
51 KEY_RSA,
52 KEY_DSA,
53 KEY_ECDSA,
54 KEY_ED25519,
55 KEY_RSA_CERT,
56 KEY_DSA_CERT,
57 KEY_ECDSA_CERT,
58 KEY_ED25519_CERT,
59 KEY_RSA_CERT_V00,
60 KEY_DSA_CERT_V00,
61 KEY_UNSPEC
62};
63
64/* Fingerprint hash algorithms */
65enum sshkey_fp_type {
66 SSH_FP_SHA1,
67 SSH_FP_MD5,
68 SSH_FP_SHA256
69};
70
71/* Fingerprint representation formats */
72enum sshkey_fp_rep {
73 SSH_FP_HEX,
74 SSH_FP_BUBBLEBABBLE,
75 SSH_FP_RANDOMART
76};
77
78/* key is stored in external hardware */
79#define SSHKEY_FLAG_EXT 0x0001
80
81#define SSHKEY_CERT_MAX_PRINCIPALS 256
82/* XXX opaquify? */
83struct sshkey_cert {
84 struct sshbuf *certblob; /* Kept around for use on wire */
85 u_int type; /* SSH2_CERT_TYPE_USER or SSH2_CERT_TYPE_HOST */
86 u_int64_t serial;
87 char *key_id;
88 u_int nprincipals;
89 char **principals;
90 u_int64_t valid_after, valid_before;
91 struct sshbuf *critical;
92 struct sshbuf *extensions;
93 struct sshkey *signature_key;
94};
95
96/* XXX opaquify? */
97struct sshkey {
98 int type;
99 int flags;
100 RSA *rsa;
101 DSA *dsa;
102 int ecdsa_nid; /* NID of curve */
103 EC_KEY *ecdsa;
104 u_char *ed25519_sk;
105 u_char *ed25519_pk;
106 struct sshkey_cert *cert;
107};
108
109#define ED25519_SK_SZ crypto_sign_ed25519_SECRETKEYBYTES
110#define ED25519_PK_SZ crypto_sign_ed25519_PUBLICKEYBYTES
111
112struct sshkey *sshkey_new(int);
113int sshkey_add_private(struct sshkey *);
114struct sshkey *sshkey_new_private(int);
115void sshkey_free(struct sshkey *);
116int sshkey_demote(const struct sshkey *, struct sshkey **);
117int sshkey_equal_public(const struct sshkey *,
118 const struct sshkey *);
119int sshkey_equal(const struct sshkey *, const struct sshkey *);
120char *sshkey_fingerprint(const struct sshkey *,
121 enum sshkey_fp_type, enum sshkey_fp_rep);
122int sshkey_fingerprint_raw(const struct sshkey *k,
123 enum sshkey_fp_type dgst_type, u_char **retp, size_t *lenp);
124const char *sshkey_type(const struct sshkey *);
125const char *sshkey_cert_type(const struct sshkey *);
126int sshkey_write(const struct sshkey *, FILE *);
127int sshkey_read(struct sshkey *, char **);
128u_int sshkey_size(const struct sshkey *);
129
130int sshkey_generate(int type, u_int bits, struct sshkey **keyp);
131int sshkey_from_private(const struct sshkey *, struct sshkey **);
132int sshkey_type_from_name(const char *);
133int sshkey_is_cert(const struct sshkey *);
134int sshkey_type_is_cert(int);
135int sshkey_type_plain(int);
136int sshkey_to_certified(struct sshkey *, int);
137int sshkey_drop_cert(struct sshkey *);
138int sshkey_certify(struct sshkey *, struct sshkey *);
139int sshkey_cert_copy(const struct sshkey *, struct sshkey *);
140int sshkey_cert_check_authority(const struct sshkey *, int, int,
141 const char *, const char **);
142int sshkey_cert_is_legacy(const struct sshkey *);
143
144int sshkey_ecdsa_nid_from_name(const char *);
145int sshkey_curve_name_to_nid(const char *);
146const char * sshkey_curve_nid_to_name(int);
147u_int sshkey_curve_nid_to_bits(int);
148int sshkey_ecdsa_bits_to_nid(int);
149int sshkey_ecdsa_key_to_nid(EC_KEY *);
150int sshkey_ec_nid_to_hash_alg(int nid);
151int sshkey_ec_validate_public(const EC_GROUP *, const EC_POINT *);
152int sshkey_ec_validate_private(const EC_KEY *);
153const char *sshkey_ssh_name(const struct sshkey *);
154const char *sshkey_ssh_name_plain(const struct sshkey *);
155int sshkey_names_valid2(const char *);
156char *key_alg_list(int, int);
157
158int sshkey_from_blob(const u_char *, size_t, struct sshkey **);
159int sshkey_to_blob_buf(const struct sshkey *, struct sshbuf *);
160int sshkey_to_blob(const struct sshkey *, u_char **, size_t *);
161int sshkey_plain_to_blob_buf(const struct sshkey *, struct sshbuf *);
162int sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *);
163
164int sshkey_sign(const struct sshkey *, u_char **, size_t *,
165 const u_char *, size_t, u_int);
166int sshkey_verify(const struct sshkey *, const u_char *, size_t,
167 const u_char *, size_t, u_int);
168
169/* for debug */
170void sshkey_dump_ec_point(const EC_GROUP *, const EC_POINT *);
171void sshkey_dump_ec_key(const EC_KEY *);
172
173/* private key parsing and serialisation */
174int sshkey_private_serialize(const struct sshkey *key, struct sshbuf *buf);
175int sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **keyp);
176
177/* private key file format parsing and serialisation */
178int sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
179 const char *passphrase, const char *comment,
180 int force_new_format, const char *new_format_cipher, int new_format_rounds);
181int sshkey_parse_public_rsa1_fileblob(struct sshbuf *blob,
182 struct sshkey **keyp, char **commentp);
183int sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
184 const char *passphrase, struct sshkey **keyp, char **commentp);
185int sshkey_parse_private_fileblob(struct sshbuf *buffer,
186 const char *passphrase, const char *filename, struct sshkey **keyp,
187 char **commentp);
188int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
189 const char *passphrase, struct sshkey **keyp, char **commentp);
190
191#ifdef SSHKEY_INTERNAL
192int ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
193 const u_char *data, size_t datalen, u_int compat);
194int ssh_rsa_verify(const struct sshkey *key,
195 const u_char *signature, size_t signaturelen,
196 const u_char *data, size_t datalen, u_int compat);
197int ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
198 const u_char *data, size_t datalen, u_int compat);
199int ssh_dss_verify(const struct sshkey *key,
200 const u_char *signature, size_t signaturelen,
201 const u_char *data, size_t datalen, u_int compat);
202int ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
203 const u_char *data, size_t datalen, u_int compat);
204int ssh_ecdsa_verify(const struct sshkey *key,
205 const u_char *signature, size_t signaturelen,
206 const u_char *data, size_t datalen, u_int compat);
207int ssh_ed25519_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
208 const u_char *data, size_t datalen, u_int compat);
209int ssh_ed25519_verify(const struct sshkey *key,
210 const u_char *signature, size_t signaturelen,
211 const u_char *data, size_t datalen, u_int compat);
212#endif
213
214#ifndef WITH_OPENSSL
215#undef RSA
216#undef DSA
217#undef EC_KEY
218#undef EC_GROUP
219#undef EC_POINT
220#endif /* WITH_OPENSSL */
221
222#endif /* SSHKEY_H */