summaryrefslogtreecommitdiff
path: root/sshkey.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2015-08-19 14:23:51 +0100
committerColin Watson <cjwatson@debian.org>2015-08-19 16:48:11 +0100
commit0f0841b2d28b7463267d4d91577e72e3340a1d3a (patch)
treeba55fcd2b6e2cc22b30f5afb561dbb3da4c8b6c7 /sshkey.c
parentf2a5f5dae656759efb0b76c3d94890b65c197a02 (diff)
parent8698446b972003b63dfe5dcbdb86acfe986afb85 (diff)
New upstream release (6.8p1).
Diffstat (limited to 'sshkey.c')
-rw-r--r--sshkey.c415
1 files changed, 250 insertions, 165 deletions
diff --git a/sshkey.c b/sshkey.c
index 1a96eae19..cd5992ecb 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshkey.c,v 1.3 2014/07/03 01:45:38 djm Exp $ */ 1/* $OpenBSD: sshkey.c,v 1.15 2015/03/06 01:40:56 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Alexander von Gernler. All rights reserved. 4 * Copyright (c) 2008 Alexander von Gernler. All rights reserved.
@@ -27,18 +27,23 @@
27 27
28#include "includes.h" 28#include "includes.h"
29 29
30#include <sys/param.h> 30#include <sys/param.h> /* MIN MAX */
31#include <sys/types.h> 31#include <sys/types.h>
32#include <netinet/in.h>
32 33
34#ifdef WITH_OPENSSL
33#include <openssl/evp.h> 35#include <openssl/evp.h>
34#include <openssl/err.h> 36#include <openssl/err.h>
35#include <openssl/pem.h> 37#include <openssl/pem.h>
38#endif
36 39
37#include "crypto_api.h" 40#include "crypto_api.h"
38 41
39#include <errno.h> 42#include <errno.h>
43#include <limits.h>
40#include <stdio.h> 44#include <stdio.h>
41#include <string.h> 45#include <string.h>
46#include <resolv.h>
42#ifdef HAVE_UTIL_H 47#ifdef HAVE_UTIL_H
43#include <util.h> 48#include <util.h>
44#endif /* HAVE_UTIL_H */ 49#endif /* HAVE_UTIL_H */
@@ -52,6 +57,7 @@
52#include "digest.h" 57#include "digest.h"
53#define SSHKEY_INTERNAL 58#define SSHKEY_INTERNAL
54#include "sshkey.h" 59#include "sshkey.h"
60#include "match.h"
55 61
56/* openssh private key file format */ 62/* openssh private key file format */
57#define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n" 63#define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n"
@@ -67,7 +73,7 @@
67/* Version identification string for SSH v1 identity files. */ 73/* Version identification string for SSH v1 identity files. */
68#define LEGACY_BEGIN "SSH PRIVATE KEY FILE FORMAT 1.1\n" 74#define LEGACY_BEGIN "SSH PRIVATE KEY FILE FORMAT 1.1\n"
69 75
70static int sshkey_from_blob_internal(const u_char *blob, size_t blen, 76static int sshkey_from_blob_internal(struct sshbuf *buf,
71 struct sshkey **keyp, int allow_cert); 77 struct sshkey **keyp, int allow_cert);
72 78
73/* Supported key types */ 79/* Supported key types */
@@ -182,12 +188,12 @@ sshkey_ecdsa_nid_from_name(const char *name)
182{ 188{
183 const struct keytype *kt; 189 const struct keytype *kt;
184 190
185 for (kt = keytypes; kt->type != -1; kt++) { 191 for (kt = keytypes; kt->type != -1; kt++) {
186 if (kt->type != KEY_ECDSA && kt->type != KEY_ECDSA_CERT) 192 if (kt->type != KEY_ECDSA && kt->type != KEY_ECDSA_CERT)
187 continue; 193 continue;
188 if (kt->name != NULL && strcmp(name, kt->name) == 0) 194 if (kt->name != NULL && strcmp(name, kt->name) == 0)
189 return kt->nid; 195 return kt->nid;
190 } 196 }
191 return -1; 197 return -1;
192} 198}
193 199
@@ -218,9 +224,11 @@ key_alg_list(int certs_only, int plain_only)
218} 224}
219 225
220int 226int
221sshkey_names_valid2(const char *names) 227sshkey_names_valid2(const char *names, int allow_wildcard)
222{ 228{
223 char *s, *cp, *p; 229 char *s, *cp, *p;
230 const struct keytype *kt;
231 int type;
224 232
225 if (names == NULL || strcmp(names, "") == 0) 233 if (names == NULL || strcmp(names, "") == 0)
226 return 0; 234 return 0;
@@ -228,9 +236,28 @@ sshkey_names_valid2(const char *names)
228 return 0; 236 return 0;
229 for ((p = strsep(&cp, ",")); p && *p != '\0'; 237 for ((p = strsep(&cp, ",")); p && *p != '\0';
230 (p = strsep(&cp, ","))) { 238 (p = strsep(&cp, ","))) {
231 switch (sshkey_type_from_name(p)) { 239 type = sshkey_type_from_name(p);
232 case KEY_RSA1: 240 if (type == KEY_RSA1) {
233 case KEY_UNSPEC: 241 free(s);
242 return 0;
243 }
244 if (type == KEY_UNSPEC) {
245 if (allow_wildcard) {
246 /*
247 * Try matching key types against the string.
248 * If any has a positive or negative match then
249 * the component is accepted.
250 */
251 for (kt = keytypes; kt->type != -1; kt++) {
252 if (kt->type == KEY_RSA1)
253 continue;
254 if (match_pattern_list(kt->name,
255 p, strlen(p), 0) != 0)
256 break;
257 }
258 if (kt->type != -1)
259 continue;
260 }
234 free(s); 261 free(s);
235 return 0; 262 return 0;
236 } 263 }
@@ -798,13 +825,28 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain)
798} 825}
799 826
800int 827int
801sshkey_to_blob_buf(const struct sshkey *key, struct sshbuf *b) 828sshkey_putb(const struct sshkey *key, struct sshbuf *b)
802{ 829{
803 return to_blob_buf(key, b, 0); 830 return to_blob_buf(key, b, 0);
804} 831}
805 832
806int 833int
807sshkey_plain_to_blob_buf(const struct sshkey *key, struct sshbuf *b) 834sshkey_puts(const struct sshkey *key, struct sshbuf *b)
835{
836 struct sshbuf *tmp;
837 int r;
838
839 if ((tmp = sshbuf_new()) == NULL)
840 return SSH_ERR_ALLOC_FAIL;
841 r = to_blob_buf(key, tmp, 0);
842 if (r == 0)
843 r = sshbuf_put_stringb(b, tmp);
844 sshbuf_free(tmp);
845 return r;
846}
847
848int
849sshkey_putb_plain(const struct sshkey *key, struct sshbuf *b)
808{ 850{
809 return to_blob_buf(key, b, 1); 851 return to_blob_buf(key, b, 1);
810} 852}
@@ -853,29 +895,18 @@ sshkey_plain_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp)
853} 895}
854 896
855int 897int
856sshkey_fingerprint_raw(const struct sshkey *k, enum sshkey_fp_type dgst_type, 898sshkey_fingerprint_raw(const struct sshkey *k, int dgst_alg,
857 u_char **retp, size_t *lenp) 899 u_char **retp, size_t *lenp)
858{ 900{
859 u_char *blob = NULL, *ret = NULL; 901 u_char *blob = NULL, *ret = NULL;
860 size_t blob_len = 0; 902 size_t blob_len = 0;
861 int hash_alg = -1, r = SSH_ERR_INTERNAL_ERROR; 903 int r = SSH_ERR_INTERNAL_ERROR;
862 904
863 if (retp != NULL) 905 if (retp != NULL)
864 *retp = NULL; 906 *retp = NULL;
865 if (lenp != NULL) 907 if (lenp != NULL)
866 *lenp = 0; 908 *lenp = 0;
867 909 if (ssh_digest_bytes(dgst_alg) == 0) {
868 switch (dgst_type) {
869 case SSH_FP_MD5:
870 hash_alg = SSH_DIGEST_MD5;
871 break;
872 case SSH_FP_SHA1:
873 hash_alg = SSH_DIGEST_SHA1;
874 break;
875 case SSH_FP_SHA256:
876 hash_alg = SSH_DIGEST_SHA256;
877 break;
878 default:
879 r = SSH_ERR_INVALID_ARGUMENT; 910 r = SSH_ERR_INVALID_ARGUMENT;
880 goto out; 911 goto out;
881 } 912 }
@@ -900,7 +931,7 @@ sshkey_fingerprint_raw(const struct sshkey *k, enum sshkey_fp_type dgst_type,
900 r = SSH_ERR_ALLOC_FAIL; 931 r = SSH_ERR_ALLOC_FAIL;
901 goto out; 932 goto out;
902 } 933 }
903 if ((r = ssh_digest_memory(hash_alg, blob, blob_len, 934 if ((r = ssh_digest_memory(dgst_alg, blob, blob_len,
904 ret, SSH_DIGEST_MAX_LENGTH)) != 0) 935 ret, SSH_DIGEST_MAX_LENGTH)) != 0)
905 goto out; 936 goto out;
906 /* success */ 937 /* success */
@@ -909,7 +940,7 @@ sshkey_fingerprint_raw(const struct sshkey *k, enum sshkey_fp_type dgst_type,
909 ret = NULL; 940 ret = NULL;
910 } 941 }
911 if (lenp != NULL) 942 if (lenp != NULL)
912 *lenp = ssh_digest_bytes(hash_alg); 943 *lenp = ssh_digest_bytes(dgst_alg);
913 r = 0; 944 r = 0;
914 out: 945 out:
915 free(ret); 946 free(ret);
@@ -921,21 +952,45 @@ sshkey_fingerprint_raw(const struct sshkey *k, enum sshkey_fp_type dgst_type,
921} 952}
922 953
923static char * 954static char *
924fingerprint_hex(u_char *dgst_raw, size_t dgst_raw_len) 955fingerprint_b64(const char *alg, u_char *dgst_raw, size_t dgst_raw_len)
925{ 956{
926 char *retval; 957 char *ret;
927 size_t i; 958 size_t plen = strlen(alg) + 1;
959 size_t rlen = ((dgst_raw_len + 2) / 3) * 4 + plen + 1;
960 int r;
928 961
929 if ((retval = calloc(1, dgst_raw_len * 3 + 1)) == NULL) 962 if (dgst_raw_len > 65536 || (ret = calloc(1, rlen)) == NULL)
963 return NULL;
964 strlcpy(ret, alg, rlen);
965 strlcat(ret, ":", rlen);
966 if (dgst_raw_len == 0)
967 return ret;
968 if ((r = b64_ntop(dgst_raw, dgst_raw_len,
969 ret + plen, rlen - plen)) == -1) {
970 explicit_bzero(ret, rlen);
971 free(ret);
930 return NULL; 972 return NULL;
931 for (i = 0; i < dgst_raw_len; i++) {
932 char hex[4];
933 snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]);
934 strlcat(retval, hex, dgst_raw_len * 3 + 1);
935 } 973 }
974 /* Trim padding characters from end */
975 ret[strcspn(ret, "=")] = '\0';
976 return ret;
977}
978
979static char *
980fingerprint_hex(const char *alg, u_char *dgst_raw, size_t dgst_raw_len)
981{
982 char *retval, hex[5];
983 size_t i, rlen = dgst_raw_len * 3 + strlen(alg) + 2;
936 984
937 /* Remove the trailing ':' character */ 985 if (dgst_raw_len > 65536 || (retval = calloc(1, rlen)) == NULL)
938 retval[(dgst_raw_len * 3) - 1] = '\0'; 986 return NULL;
987 strlcpy(retval, alg, rlen);
988 strlcat(retval, ":", rlen);
989 for (i = 0; i < dgst_raw_len; i++) {
990 snprintf(hex, sizeof(hex), "%s%02x",
991 i > 0 ? ":" : "", dgst_raw[i]);
992 strlcat(retval, hex, rlen);
993 }
939 return retval; 994 return retval;
940} 995}
941 996
@@ -1021,7 +1076,7 @@ fingerprint_bubblebabble(u_char *dgst_raw, size_t dgst_raw_len)
1021#define FLDSIZE_Y (FLDBASE + 1) 1076#define FLDSIZE_Y (FLDBASE + 1)
1022#define FLDSIZE_X (FLDBASE * 2 + 1) 1077#define FLDSIZE_X (FLDBASE * 2 + 1)
1023static char * 1078static char *
1024fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, 1079fingerprint_randomart(const char *alg, u_char *dgst_raw, size_t dgst_raw_len,
1025 const struct sshkey *k) 1080 const struct sshkey *k)
1026{ 1081{
1027 /* 1082 /*
@@ -1029,9 +1084,9 @@ fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len,
1029 * intersects with itself. Matter of taste. 1084 * intersects with itself. Matter of taste.
1030 */ 1085 */
1031 char *augmentation_string = " .o+=*BOX@%&#/^SE"; 1086 char *augmentation_string = " .o+=*BOX@%&#/^SE";
1032 char *retval, *p, title[FLDSIZE_X]; 1087 char *retval, *p, title[FLDSIZE_X], hash[FLDSIZE_X];
1033 u_char field[FLDSIZE_X][FLDSIZE_Y]; 1088 u_char field[FLDSIZE_X][FLDSIZE_Y];
1034 size_t i, tlen; 1089 size_t i, tlen, hlen;
1035 u_int b; 1090 u_int b;
1036 int x, y, r; 1091 int x, y, r;
1037 size_t len = strlen(augmentation_string) - 1; 1092 size_t len = strlen(augmentation_string) - 1;
@@ -1076,8 +1131,12 @@ fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len,
1076 sshkey_type(k), sshkey_size(k)); 1131 sshkey_type(k), sshkey_size(k));
1077 /* If [type size] won't fit, then try [type]; fits "[ED25519-CERT]" */ 1132 /* If [type size] won't fit, then try [type]; fits "[ED25519-CERT]" */
1078 if (r < 0 || r > (int)sizeof(title)) 1133 if (r < 0 || r > (int)sizeof(title))
1079 snprintf(title, sizeof(title), "[%s]", sshkey_type(k)); 1134 r = snprintf(title, sizeof(title), "[%s]", sshkey_type(k));
1080 tlen = strlen(title); 1135 tlen = (r <= 0) ? 0 : strlen(title);
1136
1137 /* assemble hash ID. */
1138 r = snprintf(hash, sizeof(hash), "[%s]", alg);
1139 hlen = (r <= 0) ? 0 : strlen(hash);
1081 1140
1082 /* output upper border */ 1141 /* output upper border */
1083 p = retval; 1142 p = retval;
@@ -1086,7 +1145,7 @@ fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len,
1086 *p++ = '-'; 1145 *p++ = '-';
1087 memcpy(p, title, tlen); 1146 memcpy(p, title, tlen);
1088 p += tlen; 1147 p += tlen;
1089 for (i = p - retval - 1; i < FLDSIZE_X; i++) 1148 for (i += tlen; i < FLDSIZE_X; i++)
1090 *p++ = '-'; 1149 *p++ = '-';
1091 *p++ = '+'; 1150 *p++ = '+';
1092 *p++ = '\n'; 1151 *p++ = '\n';
@@ -1102,7 +1161,11 @@ fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len,
1102 1161
1103 /* output lower border */ 1162 /* output lower border */
1104 *p++ = '+'; 1163 *p++ = '+';
1105 for (i = 0; i < FLDSIZE_X; i++) 1164 for (i = 0; i < (FLDSIZE_X - hlen) / 2; i++)
1165 *p++ = '-';
1166 memcpy(p, hash, hlen);
1167 p += hlen;
1168 for (i += hlen; i < FLDSIZE_X; i++)
1106 *p++ = '-'; 1169 *p++ = '-';
1107 *p++ = '+'; 1170 *p++ = '+';
1108 1171
@@ -1110,24 +1173,39 @@ fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len,
1110} 1173}
1111 1174
1112char * 1175char *
1113sshkey_fingerprint(const struct sshkey *k, enum sshkey_fp_type dgst_type, 1176sshkey_fingerprint(const struct sshkey *k, int dgst_alg,
1114 enum sshkey_fp_rep dgst_rep) 1177 enum sshkey_fp_rep dgst_rep)
1115{ 1178{
1116 char *retval = NULL; 1179 char *retval = NULL;
1117 u_char *dgst_raw; 1180 u_char *dgst_raw;
1118 size_t dgst_raw_len; 1181 size_t dgst_raw_len;
1119 1182
1120 if (sshkey_fingerprint_raw(k, dgst_type, &dgst_raw, &dgst_raw_len) != 0) 1183 if (sshkey_fingerprint_raw(k, dgst_alg, &dgst_raw, &dgst_raw_len) != 0)
1121 return NULL; 1184 return NULL;
1122 switch (dgst_rep) { 1185 switch (dgst_rep) {
1186 case SSH_FP_DEFAULT:
1187 if (dgst_alg == SSH_DIGEST_MD5) {
1188 retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg),
1189 dgst_raw, dgst_raw_len);
1190 } else {
1191 retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg),
1192 dgst_raw, dgst_raw_len);
1193 }
1194 break;
1123 case SSH_FP_HEX: 1195 case SSH_FP_HEX:
1124 retval = fingerprint_hex(dgst_raw, dgst_raw_len); 1196 retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg),
1197 dgst_raw, dgst_raw_len);
1198 break;
1199 case SSH_FP_BASE64:
1200 retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg),
1201 dgst_raw, dgst_raw_len);
1125 break; 1202 break;
1126 case SSH_FP_BUBBLEBABBLE: 1203 case SSH_FP_BUBBLEBABBLE:
1127 retval = fingerprint_bubblebabble(dgst_raw, dgst_raw_len); 1204 retval = fingerprint_bubblebabble(dgst_raw, dgst_raw_len);
1128 break; 1205 break;
1129 case SSH_FP_RANDOMART: 1206 case SSH_FP_RANDOMART:
1130 retval = fingerprint_randomart(dgst_raw, dgst_raw_len, k); 1207 retval = fingerprint_randomart(ssh_digest_alg_name(dgst_alg),
1208 dgst_raw, dgst_raw_len, k);
1131 break; 1209 break;
1132 default: 1210 default:
1133 explicit_bzero(dgst_raw, dgst_raw_len); 1211 explicit_bzero(dgst_raw, dgst_raw_len);
@@ -1234,16 +1312,20 @@ sshkey_read(struct sshkey *ret, char **cpp)
1234 cp = space+1; 1312 cp = space+1;
1235 if (*cp == '\0') 1313 if (*cp == '\0')
1236 return SSH_ERR_INVALID_FORMAT; 1314 return SSH_ERR_INVALID_FORMAT;
1237 if (ret->type == KEY_UNSPEC) { 1315 if (ret->type != KEY_UNSPEC && ret->type != type)
1238 ret->type = type;
1239 } else if (ret->type != type)
1240 return SSH_ERR_KEY_TYPE_MISMATCH; 1316 return SSH_ERR_KEY_TYPE_MISMATCH;
1241 if ((blob = sshbuf_new()) == NULL) 1317 if ((blob = sshbuf_new()) == NULL)
1242 return SSH_ERR_ALLOC_FAIL; 1318 return SSH_ERR_ALLOC_FAIL;
1243 /* trim comment */ 1319 /* trim comment */
1244 space = strchr(cp, ' '); 1320 space = strchr(cp, ' ');
1245 if (space) 1321 if (space) {
1246 *space = '\0'; 1322 /* advance 'space': skip whitespace */
1323 *space++ = '\0';
1324 while (*space == ' ' || *space == '\t')
1325 space++;
1326 *cpp = space;
1327 } else
1328 *cpp = cp + strlen(cp);
1247 if ((r = sshbuf_b64tod(blob, cp)) != 0) { 1329 if ((r = sshbuf_b64tod(blob, cp)) != 0) {
1248 sshbuf_free(blob); 1330 sshbuf_free(blob);
1249 return r; 1331 return r;
@@ -1263,7 +1345,7 @@ sshkey_read(struct sshkey *ret, char **cpp)
1263 sshkey_free(k); 1345 sshkey_free(k);
1264 return SSH_ERR_EC_CURVE_MISMATCH; 1346 return SSH_ERR_EC_CURVE_MISMATCH;
1265 } 1347 }
1266/*XXXX*/ 1348 ret->type = type;
1267 if (sshkey_is_cert(ret)) { 1349 if (sshkey_is_cert(ret)) {
1268 if (!sshkey_is_cert(k)) { 1350 if (!sshkey_is_cert(k)) {
1269 sshkey_free(k); 1351 sshkey_free(k);
@@ -1320,12 +1402,6 @@ sshkey_read(struct sshkey *ret, char **cpp)
1320 sshkey_free(k); 1402 sshkey_free(k);
1321 if (retval != 0) 1403 if (retval != 0)
1322 break; 1404 break;
1323 /* advance cp: skip whitespace and data */
1324 while (*cp == ' ' || *cp == '\t')
1325 cp++;
1326 while (*cp != '\0' && *cp != ' ' && *cp != '\t')
1327 cp++;
1328 *cpp = cp;
1329 break; 1405 break;
1330 default: 1406 default:
1331 return SSH_ERR_INVALID_ARGUMENT; 1407 return SSH_ERR_INVALID_ARGUMENT;
@@ -1390,7 +1466,7 @@ sshkey_write(const struct sshkey *key, FILE *f)
1390 ret = SSH_ERR_ALLOC_FAIL; 1466 ret = SSH_ERR_ALLOC_FAIL;
1391 goto out; 1467 goto out;
1392 } 1468 }
1393 if ((ret = sshkey_to_blob_buf(key, bb)) != 0) 1469 if ((ret = sshkey_putb(key, bb)) != 0)
1394 goto out; 1470 goto out;
1395 if ((uu = sshbuf_dtob64(bb)) == NULL) { 1471 if ((uu = sshbuf_dtob64(bb)) == NULL) {
1396 ret = SSH_ERR_ALLOC_FAIL; 1472 ret = SSH_ERR_ALLOC_FAIL;
@@ -1767,38 +1843,30 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
1767} 1843}
1768 1844
1769static int 1845static int
1770cert_parse(struct sshbuf *b, struct sshkey *key, const u_char *blob, 1846cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
1771 size_t blen)
1772{ 1847{
1773 u_char *principals = NULL, *critical = NULL, *exts = NULL; 1848 struct sshbuf *principals = NULL, *crit = NULL;
1774 u_char *sig_key = NULL, *sig = NULL; 1849 struct sshbuf *exts = NULL, *ca = NULL;
1775 size_t signed_len, plen, clen, sklen, slen, kidlen, elen; 1850 u_char *sig = NULL;
1776 struct sshbuf *tmp; 1851 size_t signed_len = 0, slen = 0, kidlen = 0;
1777 char *principal;
1778 int ret = SSH_ERR_INTERNAL_ERROR; 1852 int ret = SSH_ERR_INTERNAL_ERROR;
1779 int v00 = sshkey_cert_is_legacy(key); 1853 int v00 = sshkey_cert_is_legacy(key);
1780 char **oprincipals;
1781
1782 if ((tmp = sshbuf_new()) == NULL)
1783 return SSH_ERR_ALLOC_FAIL;
1784 1854
1785 /* Copy the entire key blob for verification and later serialisation */ 1855 /* Copy the entire key blob for verification and later serialisation */
1786 if ((ret = sshbuf_put(key->cert->certblob, blob, blen)) != 0) 1856 if ((ret = sshbuf_putb(key->cert->certblob, certbuf)) != 0)
1787 return ret; 1857 return ret;
1788 1858
1789 elen = 0; /* Not touched for v00 certs */
1790 principals = exts = critical = sig_key = sig = NULL;
1791 if ((!v00 && (ret = sshbuf_get_u64(b, &key->cert->serial)) != 0) || 1859 if ((!v00 && (ret = sshbuf_get_u64(b, &key->cert->serial)) != 0) ||
1792 (ret = sshbuf_get_u32(b, &key->cert->type)) != 0 || 1860 (ret = sshbuf_get_u32(b, &key->cert->type)) != 0 ||
1793 (ret = sshbuf_get_cstring(b, &key->cert->key_id, &kidlen)) != 0 || 1861 (ret = sshbuf_get_cstring(b, &key->cert->key_id, &kidlen)) != 0 ||
1794 (ret = sshbuf_get_string(b, &principals, &plen)) != 0 || 1862 (ret = sshbuf_froms(b, &principals)) != 0 ||
1795 (ret = sshbuf_get_u64(b, &key->cert->valid_after)) != 0 || 1863 (ret = sshbuf_get_u64(b, &key->cert->valid_after)) != 0 ||
1796 (ret = sshbuf_get_u64(b, &key->cert->valid_before)) != 0 || 1864 (ret = sshbuf_get_u64(b, &key->cert->valid_before)) != 0 ||
1797 (ret = sshbuf_get_string(b, &critical, &clen)) != 0 || 1865 (ret = sshbuf_froms(b, &crit)) != 0 ||
1798 (!v00 && (ret = sshbuf_get_string(b, &exts, &elen)) != 0) || 1866 (!v00 && (ret = sshbuf_froms(b, &exts)) != 0) ||
1799 (v00 && (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0) || 1867 (v00 && (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0) ||
1800 (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0 || 1868 (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0 ||
1801 (ret = sshbuf_get_string(b, &sig_key, &sklen)) != 0) { 1869 (ret = sshbuf_froms(b, &ca)) != 0) {
1802 /* XXX debug print error for ret */ 1870 /* XXX debug print error for ret */
1803 ret = SSH_ERR_INVALID_FORMAT; 1871 ret = SSH_ERR_INVALID_FORMAT;
1804 goto out; 1872 goto out;
@@ -1818,14 +1886,17 @@ cert_parse(struct sshbuf *b, struct sshkey *key, const u_char *blob,
1818 goto out; 1886 goto out;
1819 } 1887 }
1820 1888
1821 if ((ret = sshbuf_put(tmp, principals, plen)) != 0) 1889 /* Parse principals section */
1822 goto out; 1890 while (sshbuf_len(principals) > 0) {
1823 while (sshbuf_len(tmp) > 0) { 1891 char *principal = NULL;
1892 char **oprincipals = NULL;
1893
1824 if (key->cert->nprincipals >= SSHKEY_CERT_MAX_PRINCIPALS) { 1894 if (key->cert->nprincipals >= SSHKEY_CERT_MAX_PRINCIPALS) {
1825 ret = SSH_ERR_INVALID_FORMAT; 1895 ret = SSH_ERR_INVALID_FORMAT;
1826 goto out; 1896 goto out;
1827 } 1897 }
1828 if ((ret = sshbuf_get_cstring(tmp, &principal, &plen)) != 0) { 1898 if ((ret = sshbuf_get_cstring(principals, &principal,
1899 NULL)) != 0) {
1829 ret = SSH_ERR_INVALID_FORMAT; 1900 ret = SSH_ERR_INVALID_FORMAT;
1830 goto out; 1901 goto out;
1831 } 1902 }
@@ -1842,38 +1913,38 @@ cert_parse(struct sshbuf *b, struct sshkey *key, const u_char *blob,
1842 key->cert->principals[key->cert->nprincipals++] = principal; 1913 key->cert->principals[key->cert->nprincipals++] = principal;
1843 } 1914 }
1844 1915
1845 sshbuf_reset(tmp); 1916 /*
1846 1917 * Stash a copies of the critical options and extensions sections
1847 if ((ret = sshbuf_put(key->cert->critical, critical, clen)) != 0 || 1918 * for later use.
1848 (ret = sshbuf_put(tmp, critical, clen)) != 0) 1919 */
1920 if ((ret = sshbuf_putb(key->cert->critical, crit)) != 0 ||
1921 (exts != NULL &&
1922 (ret = sshbuf_putb(key->cert->extensions, exts)) != 0))
1849 goto out; 1923 goto out;
1850 1924
1851 /* validate structure */ 1925 /*
1852 while (sshbuf_len(tmp) != 0) { 1926 * Validate critical options and extensions sections format.
1853 if ((ret = sshbuf_get_string_direct(tmp, NULL, NULL)) != 0 || 1927 * NB. extensions are not present in v00 certs.
1854 (ret = sshbuf_get_string_direct(tmp, NULL, NULL)) != 0) { 1928 */
1929 while (sshbuf_len(crit) != 0) {
1930 if ((ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0 ||
1931 (ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0) {
1932 sshbuf_reset(key->cert->critical);
1855 ret = SSH_ERR_INVALID_FORMAT; 1933 ret = SSH_ERR_INVALID_FORMAT;
1856 goto out; 1934 goto out;
1857 } 1935 }
1858 } 1936 }
1859 sshbuf_reset(tmp); 1937 while (exts != NULL && sshbuf_len(exts) != 0) {
1860 1938 if ((ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0 ||
1861 if ((ret = sshbuf_put(key->cert->extensions, exts, elen)) != 0 || 1939 (ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0) {
1862 (ret = sshbuf_put(tmp, exts, elen)) != 0) 1940 sshbuf_reset(key->cert->extensions);
1863 goto out;
1864
1865 /* validate structure */
1866 while (sshbuf_len(tmp) != 0) {
1867 if ((ret = sshbuf_get_string_direct(tmp, NULL, NULL)) != 0 ||
1868 (ret = sshbuf_get_string_direct(tmp, NULL, NULL)) != 0) {
1869 ret = SSH_ERR_INVALID_FORMAT; 1941 ret = SSH_ERR_INVALID_FORMAT;
1870 goto out; 1942 goto out;
1871 } 1943 }
1872 } 1944 }
1873 sshbuf_reset(tmp);
1874 1945
1875 if (sshkey_from_blob_internal(sig_key, sklen, 1946 /* Parse CA key and check signature */
1876 &key->cert->signature_key, 0) != 0) { 1947 if (sshkey_from_blob_internal(ca, &key->cert->signature_key, 0) != 0) {
1877 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; 1948 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
1878 goto out; 1949 goto out;
1879 } 1950 }
@@ -1881,50 +1952,49 @@ cert_parse(struct sshbuf *b, struct sshkey *key, const u_char *blob,
1881 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; 1952 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
1882 goto out; 1953 goto out;
1883 } 1954 }
1884
1885 if ((ret = sshkey_verify(key->cert->signature_key, sig, slen, 1955 if ((ret = sshkey_verify(key->cert->signature_key, sig, slen,
1886 sshbuf_ptr(key->cert->certblob), signed_len, 0)) != 0) 1956 sshbuf_ptr(key->cert->certblob), signed_len, 0)) != 0)
1887 goto out; 1957 goto out;
1888 ret = 0;
1889 1958
1959 /* Success */
1960 ret = 0;
1890 out: 1961 out:
1891 sshbuf_free(tmp); 1962 sshbuf_free(ca);
1892 free(principals); 1963 sshbuf_free(crit);
1893 free(critical); 1964 sshbuf_free(exts);
1894 free(exts); 1965 sshbuf_free(principals);
1895 free(sig_key);
1896 free(sig); 1966 free(sig);
1897 return ret; 1967 return ret;
1898} 1968}
1899 1969
1900static int 1970static int
1901sshkey_from_blob_internal(const u_char *blob, size_t blen, 1971sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
1902 struct sshkey **keyp, int allow_cert) 1972 int allow_cert)
1903{ 1973{
1904 struct sshbuf *b = NULL; 1974 int type, ret = SSH_ERR_INTERNAL_ERROR;
1905 int type, nid = -1, ret = SSH_ERR_INTERNAL_ERROR;
1906 char *ktype = NULL, *curve = NULL; 1975 char *ktype = NULL, *curve = NULL;
1907 struct sshkey *key = NULL; 1976 struct sshkey *key = NULL;
1908 size_t len; 1977 size_t len;
1909 u_char *pk = NULL; 1978 u_char *pk = NULL;
1979 struct sshbuf *copy;
1910#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) 1980#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
1911 EC_POINT *q = NULL; 1981 EC_POINT *q = NULL;
1912#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ 1982#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */
1913 1983
1914#ifdef DEBUG_PK /* XXX */ 1984#ifdef DEBUG_PK /* XXX */
1915 dump_base64(stderr, blob, blen); 1985 sshbuf_dump(b, stderr);
1916#endif 1986#endif
1917 *keyp = NULL; 1987 *keyp = NULL;
1918 if ((b = sshbuf_from(blob, blen)) == NULL) 1988 if ((copy = sshbuf_fromb(b)) == NULL) {
1919 return SSH_ERR_ALLOC_FAIL; 1989 ret = SSH_ERR_ALLOC_FAIL;
1990 goto out;
1991 }
1920 if (sshbuf_get_cstring(b, &ktype, NULL) != 0) { 1992 if (sshbuf_get_cstring(b, &ktype, NULL) != 0) {
1921 ret = SSH_ERR_INVALID_FORMAT; 1993 ret = SSH_ERR_INVALID_FORMAT;
1922 goto out; 1994 goto out;
1923 } 1995 }
1924 1996
1925 type = sshkey_type_from_name(ktype); 1997 type = sshkey_type_from_name(ktype);
1926 if (sshkey_type_plain(type) == KEY_ECDSA)
1927 nid = sshkey_ecdsa_nid_from_name(ktype);
1928 if (!allow_cert && sshkey_type_is_cert(type)) { 1998 if (!allow_cert && sshkey_type_is_cert(type)) {
1929 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; 1999 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
1930 goto out; 2000 goto out;
@@ -1932,6 +2002,7 @@ sshkey_from_blob_internal(const u_char *blob, size_t blen,
1932 switch (type) { 2002 switch (type) {
1933#ifdef WITH_OPENSSL 2003#ifdef WITH_OPENSSL
1934 case KEY_RSA_CERT: 2004 case KEY_RSA_CERT:
2005 /* Skip nonce */
1935 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { 2006 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
1936 ret = SSH_ERR_INVALID_FORMAT; 2007 ret = SSH_ERR_INVALID_FORMAT;
1937 goto out; 2008 goto out;
@@ -1953,6 +2024,7 @@ sshkey_from_blob_internal(const u_char *blob, size_t blen,
1953#endif 2024#endif
1954 break; 2025 break;
1955 case KEY_DSA_CERT: 2026 case KEY_DSA_CERT:
2027 /* Skip nonce */
1956 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { 2028 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
1957 ret = SSH_ERR_INVALID_FORMAT; 2029 ret = SSH_ERR_INVALID_FORMAT;
1958 goto out; 2030 goto out;
@@ -1976,6 +2048,7 @@ sshkey_from_blob_internal(const u_char *blob, size_t blen,
1976#endif 2048#endif
1977 break; 2049 break;
1978 case KEY_ECDSA_CERT: 2050 case KEY_ECDSA_CERT:
2051 /* Skip nonce */
1979 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { 2052 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
1980 ret = SSH_ERR_INVALID_FORMAT; 2053 ret = SSH_ERR_INVALID_FORMAT;
1981 goto out; 2054 goto out;
@@ -1987,7 +2060,7 @@ sshkey_from_blob_internal(const u_char *blob, size_t blen,
1987 ret = SSH_ERR_ALLOC_FAIL; 2060 ret = SSH_ERR_ALLOC_FAIL;
1988 goto out; 2061 goto out;
1989 } 2062 }
1990 key->ecdsa_nid = nid; 2063 key->ecdsa_nid = sshkey_ecdsa_nid_from_name(ktype);
1991 if (sshbuf_get_cstring(b, &curve, NULL) != 0) { 2064 if (sshbuf_get_cstring(b, &curve, NULL) != 0) {
1992 ret = SSH_ERR_INVALID_FORMAT; 2065 ret = SSH_ERR_INVALID_FORMAT;
1993 goto out; 2066 goto out;
@@ -2028,6 +2101,7 @@ sshkey_from_blob_internal(const u_char *blob, size_t blen,
2028# endif /* OPENSSL_HAS_ECC */ 2101# endif /* OPENSSL_HAS_ECC */
2029#endif /* WITH_OPENSSL */ 2102#endif /* WITH_OPENSSL */
2030 case KEY_ED25519_CERT: 2103 case KEY_ED25519_CERT:
2104 /* Skip nonce */
2031 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { 2105 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
2032 ret = SSH_ERR_INVALID_FORMAT; 2106 ret = SSH_ERR_INVALID_FORMAT;
2033 goto out; 2107 goto out;
@@ -2059,8 +2133,7 @@ sshkey_from_blob_internal(const u_char *blob, size_t blen,
2059 } 2133 }
2060 2134
2061 /* Parse certificate potion */ 2135 /* Parse certificate potion */
2062 if (sshkey_is_cert(key) && 2136 if (sshkey_is_cert(key) && (ret = cert_parse(b, key, copy)) != 0)
2063 (ret = cert_parse(b, key, blob, blen)) != 0)
2064 goto out; 2137 goto out;
2065 2138
2066 if (key != NULL && sshbuf_len(b) != 0) { 2139 if (key != NULL && sshbuf_len(b) != 0) {
@@ -2071,7 +2144,7 @@ sshkey_from_blob_internal(const u_char *blob, size_t blen,
2071 *keyp = key; 2144 *keyp = key;
2072 key = NULL; 2145 key = NULL;
2073 out: 2146 out:
2074 sshbuf_free(b); 2147 sshbuf_free(copy);
2075 sshkey_free(key); 2148 sshkey_free(key);
2076 free(ktype); 2149 free(ktype);
2077 free(curve); 2150 free(curve);
@@ -2086,7 +2159,33 @@ sshkey_from_blob_internal(const u_char *blob, size_t blen,
2086int 2159int
2087sshkey_from_blob(const u_char *blob, size_t blen, struct sshkey **keyp) 2160sshkey_from_blob(const u_char *blob, size_t blen, struct sshkey **keyp)
2088{ 2161{
2089 return sshkey_from_blob_internal(blob, blen, keyp, 1); 2162 struct sshbuf *b;
2163 int r;
2164
2165 if ((b = sshbuf_from(blob, blen)) == NULL)
2166 return SSH_ERR_ALLOC_FAIL;
2167 r = sshkey_from_blob_internal(b, keyp, 1);
2168 sshbuf_free(b);
2169 return r;
2170}
2171
2172int
2173sshkey_fromb(struct sshbuf *b, struct sshkey **keyp)
2174{
2175 return sshkey_from_blob_internal(b, keyp, 1);
2176}
2177
2178int
2179sshkey_froms(struct sshbuf *buf, struct sshkey **keyp)
2180{
2181 struct sshbuf *b;
2182 int r;
2183
2184 if ((r = sshbuf_froms(buf, &b)) != 0)
2185 return r;
2186 r = sshkey_from_blob_internal(b, keyp, 1);
2187 sshbuf_free(b);
2188 return r;
2090} 2189}
2091 2190
2092int 2191int
@@ -2132,10 +2231,7 @@ sshkey_verify(const struct sshkey *key,
2132 const u_char *sig, size_t siglen, 2231 const u_char *sig, size_t siglen,
2133 const u_char *data, size_t dlen, u_int compat) 2232 const u_char *data, size_t dlen, u_int compat)
2134{ 2233{
2135 if (siglen == 0) 2234 if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE)
2136 return -1;
2137
2138 if (dlen > SSH_KEY_MAX_SIGN_DATA_SIZE)
2139 return SSH_ERR_INVALID_ARGUMENT; 2235 return SSH_ERR_INVALID_ARGUMENT;
2140 switch (key->type) { 2236 switch (key->type) {
2141#ifdef WITH_OPENSSL 2237#ifdef WITH_OPENSSL
@@ -2369,6 +2465,7 @@ sshkey_certify(struct sshkey *k, struct sshkey *ca)
2369 break; 2465 break;
2370 default: 2466 default:
2371 ret = SSH_ERR_INVALID_ARGUMENT; 2467 ret = SSH_ERR_INVALID_ARGUMENT;
2468 goto out;
2372 } 2469 }
2373 2470
2374 /* -v01 certs have a serial number next */ 2471 /* -v01 certs have a serial number next */
@@ -2594,8 +2691,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2594{ 2691{
2595 char *tname = NULL, *curve = NULL; 2692 char *tname = NULL, *curve = NULL;
2596 struct sshkey *k = NULL; 2693 struct sshkey *k = NULL;
2597 const u_char *cert; 2694 size_t pklen = 0, sklen = 0;
2598 size_t len, pklen = 0, sklen = 0;
2599 int type, r = SSH_ERR_INTERNAL_ERROR; 2695 int type, r = SSH_ERR_INTERNAL_ERROR;
2600 u_char *ed25519_pk = NULL, *ed25519_sk = NULL; 2696 u_char *ed25519_pk = NULL, *ed25519_sk = NULL;
2601#ifdef WITH_OPENSSL 2697#ifdef WITH_OPENSSL
@@ -2623,8 +2719,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2623 break; 2719 break;
2624 case KEY_DSA_CERT_V00: 2720 case KEY_DSA_CERT_V00:
2625 case KEY_DSA_CERT: 2721 case KEY_DSA_CERT:
2626 if ((r = sshbuf_get_string_direct(buf, &cert, &len)) != 0 || 2722 if ((r = sshkey_froms(buf, &k)) != 0 ||
2627 (r = sshkey_from_blob(cert, len, &k)) != 0 ||
2628 (r = sshkey_add_private(k)) != 0 || 2723 (r = sshkey_add_private(k)) != 0 ||
2629 (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0) 2724 (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0)
2630 goto out; 2725 goto out;
@@ -2667,8 +2762,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2667 r = SSH_ERR_LIBCRYPTO_ERROR; 2762 r = SSH_ERR_LIBCRYPTO_ERROR;
2668 goto out; 2763 goto out;
2669 } 2764 }
2670 if ((r = sshbuf_get_string_direct(buf, &cert, &len)) != 0 || 2765 if ((r = sshkey_froms(buf, &k)) != 0 ||
2671 (r = sshkey_from_blob(cert, len, &k)) != 0 ||
2672 (r = sshkey_add_private(k)) != 0 || 2766 (r = sshkey_add_private(k)) != 0 ||
2673 (r = sshbuf_get_bignum2(buf, exponent)) != 0) 2767 (r = sshbuf_get_bignum2(buf, exponent)) != 0)
2674 goto out; 2768 goto out;
@@ -2698,8 +2792,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2698 break; 2792 break;
2699 case KEY_RSA_CERT_V00: 2793 case KEY_RSA_CERT_V00:
2700 case KEY_RSA_CERT: 2794 case KEY_RSA_CERT:
2701 if ((r = sshbuf_get_string_direct(buf, &cert, &len)) != 0 || 2795 if ((r = sshkey_froms(buf, &k)) != 0 ||
2702 (r = sshkey_from_blob(cert, len, &k)) != 0 ||
2703 (r = sshkey_add_private(k)) != 0 || 2796 (r = sshkey_add_private(k)) != 0 ||
2704 (r = sshbuf_get_bignum2(buf, k->rsa->d) != 0) || 2797 (r = sshbuf_get_bignum2(buf, k->rsa->d) != 0) ||
2705 (r = sshbuf_get_bignum2(buf, k->rsa->iqmp) != 0) || 2798 (r = sshbuf_get_bignum2(buf, k->rsa->iqmp) != 0) ||
@@ -2726,8 +2819,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2726 ed25519_pk = ed25519_sk = NULL; 2819 ed25519_pk = ed25519_sk = NULL;
2727 break; 2820 break;
2728 case KEY_ED25519_CERT: 2821 case KEY_ED25519_CERT:
2729 if ((r = sshbuf_get_string_direct(buf, &cert, &len)) != 0 || 2822 if ((r = sshkey_froms(buf, &k)) != 0 ||
2730 (r = sshkey_from_blob(cert, len, &k)) != 0 ||
2731 (r = sshkey_add_private(k)) != 0 || 2823 (r = sshkey_add_private(k)) != 0 ||
2732 (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 || 2824 (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 ||
2733 (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0) 2825 (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0)
@@ -2953,8 +3045,9 @@ sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob,
2953 const char *passphrase, const char *comment, const char *ciphername, 3045 const char *passphrase, const char *comment, const char *ciphername,
2954 int rounds) 3046 int rounds)
2955{ 3047{
2956 u_char *cp, *b64 = NULL, *key = NULL, *pubkeyblob = NULL; 3048 u_char *cp, *key = NULL, *pubkeyblob = NULL;
2957 u_char salt[SALT_LEN]; 3049 u_char salt[SALT_LEN];
3050 char *b64 = NULL;
2958 size_t i, pubkeylen, keylen, ivlen, blocksize, authlen; 3051 size_t i, pubkeylen, keylen, ivlen, blocksize, authlen;
2959 u_int check; 3052 u_int check;
2960 int r = SSH_ERR_INTERNAL_ERROR; 3053 int r = SSH_ERR_INTERNAL_ERROR;
@@ -3166,7 +3259,7 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
3166 } 3259 }
3167 3260
3168 /* decode base64 */ 3261 /* decode base64 */
3169 if ((r = sshbuf_b64tod(decoded, sshbuf_ptr(encoded))) != 0) 3262 if ((r = sshbuf_b64tod(decoded, (char *)sshbuf_ptr(encoded))) != 0)
3170 goto out; 3263 goto out;
3171 3264
3172 /* check magic */ 3265 /* check magic */
@@ -3482,10 +3575,12 @@ sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
3482 int force_new_format, const char *new_format_cipher, int new_format_rounds) 3575 int force_new_format, const char *new_format_cipher, int new_format_rounds)
3483{ 3576{
3484 switch (key->type) { 3577 switch (key->type) {
3485#ifdef WITH_OPENSSL 3578#ifdef WITH_SSH1
3486 case KEY_RSA1: 3579 case KEY_RSA1:
3487 return sshkey_private_rsa1_to_blob(key, blob, 3580 return sshkey_private_rsa1_to_blob(key, blob,
3488 passphrase, comment); 3581 passphrase, comment);
3582#endif /* WITH_SSH1 */
3583#ifdef WITH_OPENSSL
3489 case KEY_DSA: 3584 case KEY_DSA:
3490 case KEY_ECDSA: 3585 case KEY_ECDSA:
3491 case KEY_RSA: 3586 case KEY_RSA:
@@ -3691,20 +3786,16 @@ sshkey_parse_private_rsa1(struct sshbuf *blob, const char *passphrase,
3691#endif /* WITH_SSH1 */ 3786#endif /* WITH_SSH1 */
3692 3787
3693#ifdef WITH_OPENSSL 3788#ifdef WITH_OPENSSL
3694/* XXX make private once ssh-keysign.c fixed */ 3789static int
3695int
3696sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, 3790sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3697 const char *passphrase, struct sshkey **keyp, char **commentp) 3791 const char *passphrase, struct sshkey **keyp)
3698{ 3792{
3699 EVP_PKEY *pk = NULL; 3793 EVP_PKEY *pk = NULL;
3700 struct sshkey *prv = NULL; 3794 struct sshkey *prv = NULL;
3701 char *name = "<no key>";
3702 BIO *bio = NULL; 3795 BIO *bio = NULL;
3703 int r; 3796 int r;
3704 3797
3705 *keyp = NULL; 3798 *keyp = NULL;
3706 if (commentp != NULL)
3707 *commentp = NULL;
3708 3799
3709 if ((bio = BIO_new(BIO_s_mem())) == NULL || sshbuf_len(blob) > INT_MAX) 3800 if ((bio = BIO_new(BIO_s_mem())) == NULL || sshbuf_len(blob) > INT_MAX)
3710 return SSH_ERR_ALLOC_FAIL; 3801 return SSH_ERR_ALLOC_FAIL;
@@ -3727,7 +3818,6 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3727 } 3818 }
3728 prv->rsa = EVP_PKEY_get1_RSA(pk); 3819 prv->rsa = EVP_PKEY_get1_RSA(pk);
3729 prv->type = KEY_RSA; 3820 prv->type = KEY_RSA;
3730 name = "rsa w/o comment";
3731#ifdef DEBUG_PK 3821#ifdef DEBUG_PK
3732 RSA_print_fp(stderr, prv->rsa, 8); 3822 RSA_print_fp(stderr, prv->rsa, 8);
3733#endif 3823#endif
@@ -3743,7 +3833,6 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3743 } 3833 }
3744 prv->dsa = EVP_PKEY_get1_DSA(pk); 3834 prv->dsa = EVP_PKEY_get1_DSA(pk);
3745 prv->type = KEY_DSA; 3835 prv->type = KEY_DSA;
3746 name = "dsa w/o comment";
3747#ifdef DEBUG_PK 3836#ifdef DEBUG_PK
3748 DSA_print_fp(stderr, prv->dsa, 8); 3837 DSA_print_fp(stderr, prv->dsa, 8);
3749#endif 3838#endif
@@ -3765,7 +3854,6 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3765 r = SSH_ERR_INVALID_FORMAT; 3854 r = SSH_ERR_INVALID_FORMAT;
3766 goto out; 3855 goto out;
3767 } 3856 }
3768 name = "ecdsa w/o comment";
3769# ifdef DEBUG_PK 3857# ifdef DEBUG_PK
3770 if (prv != NULL && prv->ecdsa != NULL) 3858 if (prv != NULL && prv->ecdsa != NULL)
3771 sshkey_dump_ec_key(prv->ecdsa); 3859 sshkey_dump_ec_key(prv->ecdsa);
@@ -3775,11 +3863,6 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3775 r = SSH_ERR_INVALID_FORMAT; 3863 r = SSH_ERR_INVALID_FORMAT;
3776 goto out; 3864 goto out;
3777 } 3865 }
3778 if (commentp != NULL &&
3779 (*commentp = strdup(name)) == NULL) {
3780 r = SSH_ERR_ALLOC_FAIL;
3781 goto out;
3782 }
3783 r = 0; 3866 r = 0;
3784 *keyp = prv; 3867 *keyp = prv;
3785 prv = NULL; 3868 prv = NULL;
@@ -3804,15 +3887,17 @@ sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
3804 *commentp = NULL; 3887 *commentp = NULL;
3805 3888
3806 switch (type) { 3889 switch (type) {
3807#ifdef WITH_OPENSSL 3890#ifdef WITH_SSH1
3808 case KEY_RSA1: 3891 case KEY_RSA1:
3809 return sshkey_parse_private_rsa1(blob, passphrase, 3892 return sshkey_parse_private_rsa1(blob, passphrase,
3810 keyp, commentp); 3893 keyp, commentp);
3894#endif /* WITH_SSH1 */
3895#ifdef WITH_OPENSSL
3811 case KEY_DSA: 3896 case KEY_DSA:
3812 case KEY_ECDSA: 3897 case KEY_ECDSA:
3813 case KEY_RSA: 3898 case KEY_RSA:
3814 return sshkey_parse_private_pem_fileblob(blob, type, passphrase, 3899 return sshkey_parse_private_pem_fileblob(blob, type,
3815 keyp, commentp); 3900 passphrase, keyp);
3816#endif /* WITH_OPENSSL */ 3901#endif /* WITH_OPENSSL */
3817 case KEY_ED25519: 3902 case KEY_ED25519:
3818 return sshkey_parse_private2(blob, type, passphrase, 3903 return sshkey_parse_private2(blob, type, passphrase,
@@ -3822,8 +3907,8 @@ sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
3822 commentp)) == 0) 3907 commentp)) == 0)
3823 return 0; 3908 return 0;
3824#ifdef WITH_OPENSSL 3909#ifdef WITH_OPENSSL
3825 return sshkey_parse_private_pem_fileblob(blob, type, passphrase, 3910 return sshkey_parse_private_pem_fileblob(blob, type,
3826 keyp, commentp); 3911 passphrase, keyp);
3827#else 3912#else
3828 return SSH_ERR_INVALID_FORMAT; 3913 return SSH_ERR_INVALID_FORMAT;
3829#endif /* WITH_OPENSSL */ 3914#endif /* WITH_OPENSSL */