diff options
Diffstat (limited to 'key.c')
-rw-r--r-- | key.c | 182 |
1 files changed, 149 insertions, 33 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: key.c,v 1.86 2010/03/15 19:40:02 stevesk Exp $ */ | 1 | /* $OpenBSD: key.c,v 1.90 2010/07/13 23:13:16 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * read_bignum(): | 3 | * read_bignum(): |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -52,6 +52,7 @@ | |||
52 | #include "uuencode.h" | 52 | #include "uuencode.h" |
53 | #include "buffer.h" | 53 | #include "buffer.h" |
54 | #include "log.h" | 54 | #include "log.h" |
55 | #include "misc.h" | ||
55 | #include "ssh2.h" | 56 | #include "ssh2.h" |
56 | 57 | ||
57 | static struct KeyCert * | 58 | static struct KeyCert * |
@@ -61,7 +62,8 @@ cert_new(void) | |||
61 | 62 | ||
62 | cert = xcalloc(1, sizeof(*cert)); | 63 | cert = xcalloc(1, sizeof(*cert)); |
63 | buffer_init(&cert->certblob); | 64 | buffer_init(&cert->certblob); |
64 | buffer_init(&cert->constraints); | 65 | buffer_init(&cert->critical); |
66 | buffer_init(&cert->extensions); | ||
65 | cert->key_id = NULL; | 67 | cert->key_id = NULL; |
66 | cert->principals = NULL; | 68 | cert->principals = NULL; |
67 | cert->signature_key = NULL; | 69 | cert->signature_key = NULL; |
@@ -82,6 +84,7 @@ key_new(int type) | |||
82 | switch (k->type) { | 84 | switch (k->type) { |
83 | case KEY_RSA1: | 85 | case KEY_RSA1: |
84 | case KEY_RSA: | 86 | case KEY_RSA: |
87 | case KEY_RSA_CERT_V00: | ||
85 | case KEY_RSA_CERT: | 88 | case KEY_RSA_CERT: |
86 | if ((rsa = RSA_new()) == NULL) | 89 | if ((rsa = RSA_new()) == NULL) |
87 | fatal("key_new: RSA_new failed"); | 90 | fatal("key_new: RSA_new failed"); |
@@ -92,6 +95,7 @@ key_new(int type) | |||
92 | k->rsa = rsa; | 95 | k->rsa = rsa; |
93 | break; | 96 | break; |
94 | case KEY_DSA: | 97 | case KEY_DSA: |
98 | case KEY_DSA_CERT_V00: | ||
95 | case KEY_DSA_CERT: | 99 | case KEY_DSA_CERT: |
96 | if ((dsa = DSA_new()) == NULL) | 100 | if ((dsa = DSA_new()) == NULL) |
97 | fatal("key_new: DSA_new failed"); | 101 | fatal("key_new: DSA_new failed"); |
@@ -124,6 +128,7 @@ key_add_private(Key *k) | |||
124 | switch (k->type) { | 128 | switch (k->type) { |
125 | case KEY_RSA1: | 129 | case KEY_RSA1: |
126 | case KEY_RSA: | 130 | case KEY_RSA: |
131 | case KEY_RSA_CERT_V00: | ||
127 | case KEY_RSA_CERT: | 132 | case KEY_RSA_CERT: |
128 | if ((k->rsa->d = BN_new()) == NULL) | 133 | if ((k->rsa->d = BN_new()) == NULL) |
129 | fatal("key_new_private: BN_new failed"); | 134 | fatal("key_new_private: BN_new failed"); |
@@ -139,6 +144,7 @@ key_add_private(Key *k) | |||
139 | fatal("key_new_private: BN_new failed"); | 144 | fatal("key_new_private: BN_new failed"); |
140 | break; | 145 | break; |
141 | case KEY_DSA: | 146 | case KEY_DSA: |
147 | case KEY_DSA_CERT_V00: | ||
142 | case KEY_DSA_CERT: | 148 | case KEY_DSA_CERT: |
143 | if ((k->dsa->priv_key = BN_new()) == NULL) | 149 | if ((k->dsa->priv_key = BN_new()) == NULL) |
144 | fatal("key_new_private: BN_new failed"); | 150 | fatal("key_new_private: BN_new failed"); |
@@ -165,7 +171,8 @@ cert_free(struct KeyCert *cert) | |||
165 | u_int i; | 171 | u_int i; |
166 | 172 | ||
167 | buffer_free(&cert->certblob); | 173 | buffer_free(&cert->certblob); |
168 | buffer_free(&cert->constraints); | 174 | buffer_free(&cert->critical); |
175 | buffer_free(&cert->extensions); | ||
169 | if (cert->key_id != NULL) | 176 | if (cert->key_id != NULL) |
170 | xfree(cert->key_id); | 177 | xfree(cert->key_id); |
171 | for (i = 0; i < cert->nprincipals; i++) | 178 | for (i = 0; i < cert->nprincipals; i++) |
@@ -184,12 +191,14 @@ key_free(Key *k) | |||
184 | switch (k->type) { | 191 | switch (k->type) { |
185 | case KEY_RSA1: | 192 | case KEY_RSA1: |
186 | case KEY_RSA: | 193 | case KEY_RSA: |
194 | case KEY_RSA_CERT_V00: | ||
187 | case KEY_RSA_CERT: | 195 | case KEY_RSA_CERT: |
188 | if (k->rsa != NULL) | 196 | if (k->rsa != NULL) |
189 | RSA_free(k->rsa); | 197 | RSA_free(k->rsa); |
190 | k->rsa = NULL; | 198 | k->rsa = NULL; |
191 | break; | 199 | break; |
192 | case KEY_DSA: | 200 | case KEY_DSA: |
201 | case KEY_DSA_CERT_V00: | ||
193 | case KEY_DSA_CERT: | 202 | case KEY_DSA_CERT: |
194 | if (k->dsa != NULL) | 203 | if (k->dsa != NULL) |
195 | DSA_free(k->dsa); | 204 | DSA_free(k->dsa); |
@@ -219,7 +228,7 @@ cert_compare(struct KeyCert *a, struct KeyCert *b) | |||
219 | return 0; | 228 | return 0; |
220 | if (buffer_len(&a->certblob) != buffer_len(&b->certblob)) | 229 | if (buffer_len(&a->certblob) != buffer_len(&b->certblob)) |
221 | return 0; | 230 | return 0; |
222 | if (memcmp(buffer_ptr(&a->certblob), buffer_ptr(&b->certblob), | 231 | if (timingsafe_bcmp(buffer_ptr(&a->certblob), buffer_ptr(&b->certblob), |
223 | buffer_len(&a->certblob)) != 0) | 232 | buffer_len(&a->certblob)) != 0) |
224 | return 0; | 233 | return 0; |
225 | return 1; | 234 | return 1; |
@@ -238,11 +247,13 @@ key_equal_public(const Key *a, const Key *b) | |||
238 | 247 | ||
239 | switch (a->type) { | 248 | switch (a->type) { |
240 | case KEY_RSA1: | 249 | case KEY_RSA1: |
250 | case KEY_RSA_CERT_V00: | ||
241 | case KEY_RSA_CERT: | 251 | case KEY_RSA_CERT: |
242 | case KEY_RSA: | 252 | case KEY_RSA: |
243 | return a->rsa != NULL && b->rsa != NULL && | 253 | return a->rsa != NULL && b->rsa != NULL && |
244 | BN_cmp(a->rsa->e, b->rsa->e) == 0 && | 254 | BN_cmp(a->rsa->e, b->rsa->e) == 0 && |
245 | BN_cmp(a->rsa->n, b->rsa->n) == 0; | 255 | BN_cmp(a->rsa->n, b->rsa->n) == 0; |
256 | case KEY_DSA_CERT_V00: | ||
246 | case KEY_DSA_CERT: | 257 | case KEY_DSA_CERT: |
247 | case KEY_DSA: | 258 | case KEY_DSA: |
248 | return a->dsa != NULL && b->dsa != NULL && | 259 | return a->dsa != NULL && b->dsa != NULL && |
@@ -304,6 +315,8 @@ key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length) | |||
304 | case KEY_RSA: | 315 | case KEY_RSA: |
305 | key_to_blob(k, &blob, &len); | 316 | key_to_blob(k, &blob, &len); |
306 | break; | 317 | break; |
318 | case KEY_DSA_CERT_V00: | ||
319 | case KEY_RSA_CERT_V00: | ||
307 | case KEY_DSA_CERT: | 320 | case KEY_DSA_CERT: |
308 | case KEY_RSA_CERT: | 321 | case KEY_RSA_CERT: |
309 | /* We want a fingerprint of the _key_ not of the cert */ | 322 | /* We want a fingerprint of the _key_ not of the cert */ |
@@ -631,6 +644,8 @@ key_read(Key *ret, char **cpp) | |||
631 | case KEY_UNSPEC: | 644 | case KEY_UNSPEC: |
632 | case KEY_RSA: | 645 | case KEY_RSA: |
633 | case KEY_DSA: | 646 | case KEY_DSA: |
647 | case KEY_DSA_CERT_V00: | ||
648 | case KEY_RSA_CERT_V00: | ||
634 | case KEY_DSA_CERT: | 649 | case KEY_DSA_CERT: |
635 | case KEY_RSA_CERT: | 650 | case KEY_RSA_CERT: |
636 | space = strchr(cp, ' '); | 651 | space = strchr(cp, ' '); |
@@ -757,11 +772,13 @@ key_write(const Key *key, FILE *f) | |||
757 | error("key_write: failed for RSA key"); | 772 | error("key_write: failed for RSA key"); |
758 | return 0; | 773 | return 0; |
759 | case KEY_DSA: | 774 | case KEY_DSA: |
775 | case KEY_DSA_CERT_V00: | ||
760 | case KEY_DSA_CERT: | 776 | case KEY_DSA_CERT: |
761 | if (key->dsa == NULL) | 777 | if (key->dsa == NULL) |
762 | return 0; | 778 | return 0; |
763 | break; | 779 | break; |
764 | case KEY_RSA: | 780 | case KEY_RSA: |
781 | case KEY_RSA_CERT_V00: | ||
765 | case KEY_RSA_CERT: | 782 | case KEY_RSA_CERT: |
766 | if (key->rsa == NULL) | 783 | if (key->rsa == NULL) |
767 | return 0; | 784 | return 0; |
@@ -793,6 +810,10 @@ key_type(const Key *k) | |||
793 | return "RSA"; | 810 | return "RSA"; |
794 | case KEY_DSA: | 811 | case KEY_DSA: |
795 | return "DSA"; | 812 | return "DSA"; |
813 | case KEY_RSA_CERT_V00: | ||
814 | return "RSA-CERT-V00"; | ||
815 | case KEY_DSA_CERT_V00: | ||
816 | return "DSA-CERT-V00"; | ||
796 | case KEY_RSA_CERT: | 817 | case KEY_RSA_CERT: |
797 | return "RSA-CERT"; | 818 | return "RSA-CERT"; |
798 | case KEY_DSA_CERT: | 819 | case KEY_DSA_CERT: |
@@ -822,10 +843,14 @@ key_ssh_name(const Key *k) | |||
822 | return "ssh-rsa"; | 843 | return "ssh-rsa"; |
823 | case KEY_DSA: | 844 | case KEY_DSA: |
824 | return "ssh-dss"; | 845 | return "ssh-dss"; |
825 | case KEY_RSA_CERT: | 846 | case KEY_RSA_CERT_V00: |
826 | return "ssh-rsa-cert-v00@openssh.com"; | 847 | return "ssh-rsa-cert-v00@openssh.com"; |
827 | case KEY_DSA_CERT: | 848 | case KEY_DSA_CERT_V00: |
828 | return "ssh-dss-cert-v00@openssh.com"; | 849 | return "ssh-dss-cert-v00@openssh.com"; |
850 | case KEY_RSA_CERT: | ||
851 | return "ssh-rsa-cert-v01@openssh.com"; | ||
852 | case KEY_DSA_CERT: | ||
853 | return "ssh-dss-cert-v01@openssh.com"; | ||
829 | } | 854 | } |
830 | return "ssh-unknown"; | 855 | return "ssh-unknown"; |
831 | } | 856 | } |
@@ -836,9 +861,11 @@ key_size(const Key *k) | |||
836 | switch (k->type) { | 861 | switch (k->type) { |
837 | case KEY_RSA1: | 862 | case KEY_RSA1: |
838 | case KEY_RSA: | 863 | case KEY_RSA: |
864 | case KEY_RSA_CERT_V00: | ||
839 | case KEY_RSA_CERT: | 865 | case KEY_RSA_CERT: |
840 | return BN_num_bits(k->rsa->n); | 866 | return BN_num_bits(k->rsa->n); |
841 | case KEY_DSA: | 867 | case KEY_DSA: |
868 | case KEY_DSA_CERT_V00: | ||
842 | case KEY_DSA_CERT: | 869 | case KEY_DSA_CERT: |
843 | return BN_num_bits(k->dsa->p); | 870 | return BN_num_bits(k->dsa->p); |
844 | } | 871 | } |
@@ -882,6 +909,8 @@ key_generate(int type, u_int bits) | |||
882 | case KEY_RSA1: | 909 | case KEY_RSA1: |
883 | k->rsa = rsa_generate_private_key(bits); | 910 | k->rsa = rsa_generate_private_key(bits); |
884 | break; | 911 | break; |
912 | case KEY_RSA_CERT_V00: | ||
913 | case KEY_DSA_CERT_V00: | ||
885 | case KEY_RSA_CERT: | 914 | case KEY_RSA_CERT: |
886 | case KEY_DSA_CERT: | 915 | case KEY_DSA_CERT: |
887 | fatal("key_generate: cert keys cannot be generated directly"); | 916 | fatal("key_generate: cert keys cannot be generated directly"); |
@@ -912,9 +941,12 @@ key_cert_copy(const Key *from_key, struct Key *to_key) | |||
912 | buffer_append(&to->certblob, buffer_ptr(&from->certblob), | 941 | buffer_append(&to->certblob, buffer_ptr(&from->certblob), |
913 | buffer_len(&from->certblob)); | 942 | buffer_len(&from->certblob)); |
914 | 943 | ||
915 | buffer_append(&to->constraints, buffer_ptr(&from->constraints), | 944 | buffer_append(&to->critical, |
916 | buffer_len(&from->constraints)); | 945 | buffer_ptr(&from->critical), buffer_len(&from->critical)); |
946 | buffer_append(&to->extensions, | ||
947 | buffer_ptr(&from->extensions), buffer_len(&from->extensions)); | ||
917 | 948 | ||
949 | to->serial = from->serial; | ||
918 | to->type = from->type; | 950 | to->type = from->type; |
919 | to->key_id = from->key_id == NULL ? NULL : xstrdup(from->key_id); | 951 | to->key_id = from->key_id == NULL ? NULL : xstrdup(from->key_id); |
920 | to->valid_after = from->valid_after; | 952 | to->valid_after = from->valid_after; |
@@ -940,6 +972,7 @@ key_from_private(const Key *k) | |||
940 | Key *n = NULL; | 972 | Key *n = NULL; |
941 | switch (k->type) { | 973 | switch (k->type) { |
942 | case KEY_DSA: | 974 | case KEY_DSA: |
975 | case KEY_DSA_CERT_V00: | ||
943 | case KEY_DSA_CERT: | 976 | case KEY_DSA_CERT: |
944 | n = key_new(k->type); | 977 | n = key_new(k->type); |
945 | if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) || | 978 | if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) || |
@@ -950,6 +983,7 @@ key_from_private(const Key *k) | |||
950 | break; | 983 | break; |
951 | case KEY_RSA: | 984 | case KEY_RSA: |
952 | case KEY_RSA1: | 985 | case KEY_RSA1: |
986 | case KEY_RSA_CERT_V00: | ||
953 | case KEY_RSA_CERT: | 987 | case KEY_RSA_CERT: |
954 | n = key_new(k->type); | 988 | n = key_new(k->type); |
955 | if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) || | 989 | if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) || |
@@ -979,8 +1013,12 @@ key_type_from_name(char *name) | |||
979 | } else if (strcmp(name, "ssh-dss") == 0) { | 1013 | } else if (strcmp(name, "ssh-dss") == 0) { |
980 | return KEY_DSA; | 1014 | return KEY_DSA; |
981 | } else if (strcmp(name, "ssh-rsa-cert-v00@openssh.com") == 0) { | 1015 | } else if (strcmp(name, "ssh-rsa-cert-v00@openssh.com") == 0) { |
982 | return KEY_RSA_CERT; | 1016 | return KEY_RSA_CERT_V00; |
983 | } else if (strcmp(name, "ssh-dss-cert-v00@openssh.com") == 0) { | 1017 | } else if (strcmp(name, "ssh-dss-cert-v00@openssh.com") == 0) { |
1018 | return KEY_DSA_CERT_V00; | ||
1019 | } else if (strcmp(name, "ssh-rsa-cert-v01@openssh.com") == 0) { | ||
1020 | return KEY_RSA_CERT; | ||
1021 | } else if (strcmp(name, "ssh-dss-cert-v01@openssh.com") == 0) { | ||
984 | return KEY_DSA_CERT; | 1022 | return KEY_DSA_CERT; |
985 | } else if (strcmp(name, "null") == 0) { | 1023 | } else if (strcmp(name, "null") == 0) { |
986 | return KEY_NULL; | 1024 | return KEY_NULL; |
@@ -1014,26 +1052,31 @@ key_names_valid2(const char *names) | |||
1014 | static int | 1052 | static int |
1015 | cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) | 1053 | cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) |
1016 | { | 1054 | { |
1017 | u_char *principals, *constraints, *sig_key, *sig; | 1055 | u_char *principals, *critical, *exts, *sig_key, *sig; |
1018 | u_int signed_len, plen, clen, sklen, slen, kidlen; | 1056 | u_int signed_len, plen, clen, sklen, slen, kidlen, elen; |
1019 | Buffer tmp; | 1057 | Buffer tmp; |
1020 | char *principal; | 1058 | char *principal; |
1021 | int ret = -1; | 1059 | int ret = -1; |
1060 | int v00 = key->type == KEY_DSA_CERT_V00 || | ||
1061 | key->type == KEY_RSA_CERT_V00; | ||
1022 | 1062 | ||
1023 | buffer_init(&tmp); | 1063 | buffer_init(&tmp); |
1024 | 1064 | ||
1025 | /* Copy the entire key blob for verification and later serialisation */ | 1065 | /* Copy the entire key blob for verification and later serialisation */ |
1026 | buffer_append(&key->cert->certblob, blob, blen); | 1066 | buffer_append(&key->cert->certblob, blob, blen); |
1027 | 1067 | ||
1028 | principals = constraints = sig_key = sig = NULL; | 1068 | elen = 0; /* Not touched for v00 certs */ |
1029 | if (buffer_get_int_ret(&key->cert->type, b) != 0 || | 1069 | principals = exts = critical = sig_key = sig = NULL; |
1070 | if ((!v00 && buffer_get_int64_ret(&key->cert->serial, b) != 0) || | ||
1071 | buffer_get_int_ret(&key->cert->type, b) != 0 || | ||
1030 | (key->cert->key_id = buffer_get_string_ret(b, &kidlen)) == NULL || | 1072 | (key->cert->key_id = buffer_get_string_ret(b, &kidlen)) == NULL || |
1031 | (principals = buffer_get_string_ret(b, &plen)) == NULL || | 1073 | (principals = buffer_get_string_ret(b, &plen)) == NULL || |
1032 | buffer_get_int64_ret(&key->cert->valid_after, b) != 0 || | 1074 | buffer_get_int64_ret(&key->cert->valid_after, b) != 0 || |
1033 | buffer_get_int64_ret(&key->cert->valid_before, b) != 0 || | 1075 | buffer_get_int64_ret(&key->cert->valid_before, b) != 0 || |
1034 | (constraints = buffer_get_string_ret(b, &clen)) == NULL || | 1076 | (critical = buffer_get_string_ret(b, &clen)) == NULL || |
1035 | /* skip nonce */ buffer_get_string_ptr_ret(b, NULL) == NULL || | 1077 | (!v00 && (exts = buffer_get_string_ret(b, &elen)) == NULL) || |
1036 | /* skip reserved */ buffer_get_string_ptr_ret(b, NULL) == NULL || | 1078 | (v00 && buffer_get_string_ptr_ret(b, NULL) == NULL) || /* nonce */ |
1079 | buffer_get_string_ptr_ret(b, NULL) == NULL || /* reserved */ | ||
1037 | (sig_key = buffer_get_string_ret(b, &sklen)) == NULL) { | 1080 | (sig_key = buffer_get_string_ret(b, &sklen)) == NULL) { |
1038 | error("%s: parse error", __func__); | 1081 | error("%s: parse error", __func__); |
1039 | goto out; | 1082 | goto out; |
@@ -1080,13 +1123,25 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) | |||
1080 | 1123 | ||
1081 | buffer_clear(&tmp); | 1124 | buffer_clear(&tmp); |
1082 | 1125 | ||
1083 | buffer_append(&key->cert->constraints, constraints, clen); | 1126 | buffer_append(&key->cert->critical, critical, clen); |
1084 | buffer_append(&tmp, constraints, clen); | 1127 | buffer_append(&tmp, critical, clen); |
1085 | /* validate structure */ | 1128 | /* validate structure */ |
1086 | while (buffer_len(&tmp) != 0) { | 1129 | while (buffer_len(&tmp) != 0) { |
1087 | if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL || | 1130 | if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL || |
1088 | buffer_get_string_ptr_ret(&tmp, NULL) == NULL) { | 1131 | buffer_get_string_ptr_ret(&tmp, NULL) == NULL) { |
1089 | error("%s: Constraints data invalid", __func__); | 1132 | error("%s: critical option data invalid", __func__); |
1133 | goto out; | ||
1134 | } | ||
1135 | } | ||
1136 | buffer_clear(&tmp); | ||
1137 | |||
1138 | buffer_append(&key->cert->extensions, exts, elen); | ||
1139 | buffer_append(&tmp, exts, elen); | ||
1140 | /* validate structure */ | ||
1141 | while (buffer_len(&tmp) != 0) { | ||
1142 | if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL || | ||
1143 | buffer_get_string_ptr_ret(&tmp, NULL) == NULL) { | ||
1144 | error("%s: extension data invalid", __func__); | ||
1090 | goto out; | 1145 | goto out; |
1091 | } | 1146 | } |
1092 | } | 1147 | } |
@@ -1123,8 +1178,10 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) | |||
1123 | buffer_free(&tmp); | 1178 | buffer_free(&tmp); |
1124 | if (principals != NULL) | 1179 | if (principals != NULL) |
1125 | xfree(principals); | 1180 | xfree(principals); |
1126 | if (constraints != NULL) | 1181 | if (critical != NULL) |
1127 | xfree(constraints); | 1182 | xfree(critical); |
1183 | if (exts != NULL) | ||
1184 | xfree(exts); | ||
1128 | if (sig_key != NULL) | 1185 | if (sig_key != NULL) |
1129 | xfree(sig_key); | 1186 | xfree(sig_key); |
1130 | if (sig != NULL) | 1187 | if (sig != NULL) |
@@ -1153,8 +1210,11 @@ key_from_blob(const u_char *blob, u_int blen) | |||
1153 | type = key_type_from_name(ktype); | 1210 | type = key_type_from_name(ktype); |
1154 | 1211 | ||
1155 | switch (type) { | 1212 | switch (type) { |
1156 | case KEY_RSA: | ||
1157 | case KEY_RSA_CERT: | 1213 | case KEY_RSA_CERT: |
1214 | (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ | ||
1215 | /* FALLTHROUGH */ | ||
1216 | case KEY_RSA: | ||
1217 | case KEY_RSA_CERT_V00: | ||
1158 | key = key_new(type); | 1218 | key = key_new(type); |
1159 | if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 || | 1219 | if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 || |
1160 | buffer_get_bignum2_ret(&b, key->rsa->n) == -1) { | 1220 | buffer_get_bignum2_ret(&b, key->rsa->n) == -1) { |
@@ -1168,8 +1228,11 @@ key_from_blob(const u_char *blob, u_int blen) | |||
1168 | RSA_print_fp(stderr, key->rsa, 8); | 1228 | RSA_print_fp(stderr, key->rsa, 8); |
1169 | #endif | 1229 | #endif |
1170 | break; | 1230 | break; |
1171 | case KEY_DSA: | ||
1172 | case KEY_DSA_CERT: | 1231 | case KEY_DSA_CERT: |
1232 | (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ | ||
1233 | /* FALLTHROUGH */ | ||
1234 | case KEY_DSA: | ||
1235 | case KEY_DSA_CERT_V00: | ||
1173 | key = key_new(type); | 1236 | key = key_new(type); |
1174 | if (buffer_get_bignum2_ret(&b, key->dsa->p) == -1 || | 1237 | if (buffer_get_bignum2_ret(&b, key->dsa->p) == -1 || |
1175 | buffer_get_bignum2_ret(&b, key->dsa->q) == -1 || | 1238 | buffer_get_bignum2_ret(&b, key->dsa->q) == -1 || |
@@ -1215,6 +1278,8 @@ key_to_blob(const Key *key, u_char **blobp, u_int *lenp) | |||
1215 | } | 1278 | } |
1216 | buffer_init(&b); | 1279 | buffer_init(&b); |
1217 | switch (key->type) { | 1280 | switch (key->type) { |
1281 | case KEY_DSA_CERT_V00: | ||
1282 | case KEY_RSA_CERT_V00: | ||
1218 | case KEY_DSA_CERT: | 1283 | case KEY_DSA_CERT: |
1219 | case KEY_RSA_CERT: | 1284 | case KEY_RSA_CERT: |
1220 | /* Use the existing blob */ | 1285 | /* Use the existing blob */ |
@@ -1257,9 +1322,11 @@ key_sign( | |||
1257 | const u_char *data, u_int datalen) | 1322 | const u_char *data, u_int datalen) |
1258 | { | 1323 | { |
1259 | switch (key->type) { | 1324 | switch (key->type) { |
1325 | case KEY_DSA_CERT_V00: | ||
1260 | case KEY_DSA_CERT: | 1326 | case KEY_DSA_CERT: |
1261 | case KEY_DSA: | 1327 | case KEY_DSA: |
1262 | return ssh_dss_sign(key, sigp, lenp, data, datalen); | 1328 | return ssh_dss_sign(key, sigp, lenp, data, datalen); |
1329 | case KEY_RSA_CERT_V00: | ||
1263 | case KEY_RSA_CERT: | 1330 | case KEY_RSA_CERT: |
1264 | case KEY_RSA: | 1331 | case KEY_RSA: |
1265 | return ssh_rsa_sign(key, sigp, lenp, data, datalen); | 1332 | return ssh_rsa_sign(key, sigp, lenp, data, datalen); |
@@ -1283,9 +1350,11 @@ key_verify( | |||
1283 | return -1; | 1350 | return -1; |
1284 | 1351 | ||
1285 | switch (key->type) { | 1352 | switch (key->type) { |
1353 | case KEY_DSA_CERT_V00: | ||
1286 | case KEY_DSA_CERT: | 1354 | case KEY_DSA_CERT: |
1287 | case KEY_DSA: | 1355 | case KEY_DSA: |
1288 | return ssh_dss_verify(key, signature, signaturelen, data, datalen); | 1356 | return ssh_dss_verify(key, signature, signaturelen, data, datalen); |
1357 | case KEY_RSA_CERT_V00: | ||
1289 | case KEY_RSA_CERT: | 1358 | case KEY_RSA_CERT: |
1290 | case KEY_RSA: | 1359 | case KEY_RSA: |
1291 | return ssh_rsa_verify(key, signature, signaturelen, data, datalen); | 1360 | return ssh_rsa_verify(key, signature, signaturelen, data, datalen); |
@@ -1308,6 +1377,7 @@ key_demote(const Key *k) | |||
1308 | pk->rsa = NULL; | 1377 | pk->rsa = NULL; |
1309 | 1378 | ||
1310 | switch (k->type) { | 1379 | switch (k->type) { |
1380 | case KEY_RSA_CERT_V00: | ||
1311 | case KEY_RSA_CERT: | 1381 | case KEY_RSA_CERT: |
1312 | key_cert_copy(k, pk); | 1382 | key_cert_copy(k, pk); |
1313 | /* FALLTHROUGH */ | 1383 | /* FALLTHROUGH */ |
@@ -1320,6 +1390,7 @@ key_demote(const Key *k) | |||
1320 | if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL) | 1390 | if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL) |
1321 | fatal("key_demote: BN_dup failed"); | 1391 | fatal("key_demote: BN_dup failed"); |
1322 | break; | 1392 | break; |
1393 | case KEY_DSA_CERT_V00: | ||
1323 | case KEY_DSA_CERT: | 1394 | case KEY_DSA_CERT: |
1324 | key_cert_copy(k, pk); | 1395 | key_cert_copy(k, pk); |
1325 | /* FALLTHROUGH */ | 1396 | /* FALLTHROUGH */ |
@@ -1346,8 +1417,17 @@ key_demote(const Key *k) | |||
1346 | int | 1417 | int |
1347 | key_is_cert(const Key *k) | 1418 | key_is_cert(const Key *k) |
1348 | { | 1419 | { |
1349 | return k != NULL && | 1420 | if (k == NULL) |
1350 | (k->type == KEY_RSA_CERT || k->type == KEY_DSA_CERT); | 1421 | return 0; |
1422 | switch (k->type) { | ||
1423 | case KEY_RSA_CERT_V00: | ||
1424 | case KEY_DSA_CERT_V00: | ||
1425 | case KEY_RSA_CERT: | ||
1426 | case KEY_DSA_CERT: | ||
1427 | return 1; | ||
1428 | default: | ||
1429 | return 0; | ||
1430 | } | ||
1351 | } | 1431 | } |
1352 | 1432 | ||
1353 | /* Return the cert-less equivalent to a certified key type */ | 1433 | /* Return the cert-less equivalent to a certified key type */ |
@@ -1355,8 +1435,10 @@ int | |||
1355 | key_type_plain(int type) | 1435 | key_type_plain(int type) |
1356 | { | 1436 | { |
1357 | switch (type) { | 1437 | switch (type) { |
1438 | case KEY_RSA_CERT_V00: | ||
1358 | case KEY_RSA_CERT: | 1439 | case KEY_RSA_CERT: |
1359 | return KEY_RSA; | 1440 | return KEY_RSA; |
1441 | case KEY_DSA_CERT_V00: | ||
1360 | case KEY_DSA_CERT: | 1442 | case KEY_DSA_CERT: |
1361 | return KEY_DSA; | 1443 | return KEY_DSA; |
1362 | default: | 1444 | default: |
@@ -1366,16 +1448,16 @@ key_type_plain(int type) | |||
1366 | 1448 | ||
1367 | /* Convert a KEY_RSA or KEY_DSA to their _CERT equivalent */ | 1449 | /* Convert a KEY_RSA or KEY_DSA to their _CERT equivalent */ |
1368 | int | 1450 | int |
1369 | key_to_certified(Key *k) | 1451 | key_to_certified(Key *k, int legacy) |
1370 | { | 1452 | { |
1371 | switch (k->type) { | 1453 | switch (k->type) { |
1372 | case KEY_RSA: | 1454 | case KEY_RSA: |
1373 | k->cert = cert_new(); | 1455 | k->cert = cert_new(); |
1374 | k->type = KEY_RSA_CERT; | 1456 | k->type = legacy ? KEY_RSA_CERT_V00 : KEY_RSA_CERT; |
1375 | return 0; | 1457 | return 0; |
1376 | case KEY_DSA: | 1458 | case KEY_DSA: |
1377 | k->cert = cert_new(); | 1459 | k->cert = cert_new(); |
1378 | k->type = KEY_DSA_CERT; | 1460 | k->type = legacy ? KEY_DSA_CERT_V00 : KEY_DSA_CERT; |
1379 | return 0; | 1461 | return 0; |
1380 | default: | 1462 | default: |
1381 | error("%s: key has incorrect type %s", __func__, key_type(k)); | 1463 | error("%s: key has incorrect type %s", __func__, key_type(k)); |
@@ -1388,10 +1470,12 @@ int | |||
1388 | key_drop_cert(Key *k) | 1470 | key_drop_cert(Key *k) |
1389 | { | 1471 | { |
1390 | switch (k->type) { | 1472 | switch (k->type) { |
1473 | case KEY_RSA_CERT_V00: | ||
1391 | case KEY_RSA_CERT: | 1474 | case KEY_RSA_CERT: |
1392 | cert_free(k->cert); | 1475 | cert_free(k->cert); |
1393 | k->type = KEY_RSA; | 1476 | k->type = KEY_RSA; |
1394 | return 0; | 1477 | return 0; |
1478 | case KEY_DSA_CERT_V00: | ||
1395 | case KEY_DSA_CERT: | 1479 | case KEY_DSA_CERT: |
1396 | cert_free(k->cert); | 1480 | cert_free(k->cert); |
1397 | k->type = KEY_DSA; | 1481 | k->type = KEY_DSA; |
@@ -1432,13 +1516,21 @@ key_certify(Key *k, Key *ca) | |||
1432 | buffer_clear(&k->cert->certblob); | 1516 | buffer_clear(&k->cert->certblob); |
1433 | buffer_put_cstring(&k->cert->certblob, key_ssh_name(k)); | 1517 | buffer_put_cstring(&k->cert->certblob, key_ssh_name(k)); |
1434 | 1518 | ||
1519 | /* -v01 certs put nonce first */ | ||
1520 | if (k->type == KEY_DSA_CERT || k->type == KEY_RSA_CERT) { | ||
1521 | arc4random_buf(&nonce, sizeof(nonce)); | ||
1522 | buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce)); | ||
1523 | } | ||
1524 | |||
1435 | switch (k->type) { | 1525 | switch (k->type) { |
1526 | case KEY_DSA_CERT_V00: | ||
1436 | case KEY_DSA_CERT: | 1527 | case KEY_DSA_CERT: |
1437 | buffer_put_bignum2(&k->cert->certblob, k->dsa->p); | 1528 | buffer_put_bignum2(&k->cert->certblob, k->dsa->p); |
1438 | buffer_put_bignum2(&k->cert->certblob, k->dsa->q); | 1529 | buffer_put_bignum2(&k->cert->certblob, k->dsa->q); |
1439 | buffer_put_bignum2(&k->cert->certblob, k->dsa->g); | 1530 | buffer_put_bignum2(&k->cert->certblob, k->dsa->g); |
1440 | buffer_put_bignum2(&k->cert->certblob, k->dsa->pub_key); | 1531 | buffer_put_bignum2(&k->cert->certblob, k->dsa->pub_key); |
1441 | break; | 1532 | break; |
1533 | case KEY_RSA_CERT_V00: | ||
1442 | case KEY_RSA_CERT: | 1534 | case KEY_RSA_CERT: |
1443 | buffer_put_bignum2(&k->cert->certblob, k->rsa->e); | 1535 | buffer_put_bignum2(&k->cert->certblob, k->rsa->e); |
1444 | buffer_put_bignum2(&k->cert->certblob, k->rsa->n); | 1536 | buffer_put_bignum2(&k->cert->certblob, k->rsa->n); |
@@ -1450,6 +1542,10 @@ key_certify(Key *k, Key *ca) | |||
1450 | return -1; | 1542 | return -1; |
1451 | } | 1543 | } |
1452 | 1544 | ||
1545 | /* -v01 certs have a serial number next */ | ||
1546 | if (k->type == KEY_DSA_CERT || k->type == KEY_RSA_CERT) | ||
1547 | buffer_put_int64(&k->cert->certblob, k->cert->serial); | ||
1548 | |||
1453 | buffer_put_int(&k->cert->certblob, k->cert->type); | 1549 | buffer_put_int(&k->cert->certblob, k->cert->type); |
1454 | buffer_put_cstring(&k->cert->certblob, k->cert->key_id); | 1550 | buffer_put_cstring(&k->cert->certblob, k->cert->key_id); |
1455 | 1551 | ||
@@ -1463,11 +1559,19 @@ key_certify(Key *k, Key *ca) | |||
1463 | buffer_put_int64(&k->cert->certblob, k->cert->valid_after); | 1559 | buffer_put_int64(&k->cert->certblob, k->cert->valid_after); |
1464 | buffer_put_int64(&k->cert->certblob, k->cert->valid_before); | 1560 | buffer_put_int64(&k->cert->certblob, k->cert->valid_before); |
1465 | buffer_put_string(&k->cert->certblob, | 1561 | buffer_put_string(&k->cert->certblob, |
1466 | buffer_ptr(&k->cert->constraints), | 1562 | buffer_ptr(&k->cert->critical), buffer_len(&k->cert->critical)); |
1467 | buffer_len(&k->cert->constraints)); | 1563 | |
1564 | /* -v01 certs have non-critical options here */ | ||
1565 | if (k->type == KEY_DSA_CERT || k->type == KEY_RSA_CERT) { | ||
1566 | buffer_put_string(&k->cert->certblob, | ||
1567 | buffer_ptr(&k->cert->extensions), | ||
1568 | buffer_len(&k->cert->extensions)); | ||
1569 | } | ||
1570 | |||
1571 | /* -v00 certs put the nonce at the end */ | ||
1572 | if (k->type == KEY_DSA_CERT_V00 || k->type == KEY_RSA_CERT_V00) | ||
1573 | buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce)); | ||
1468 | 1574 | ||
1469 | arc4random_buf(&nonce, sizeof(nonce)); | ||
1470 | buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce)); | ||
1471 | buffer_put_string(&k->cert->certblob, NULL, 0); /* reserved */ | 1575 | buffer_put_string(&k->cert->certblob, NULL, 0); /* reserved */ |
1472 | buffer_put_string(&k->cert->certblob, ca_blob, ca_len); | 1576 | buffer_put_string(&k->cert->certblob, ca_blob, ca_len); |
1473 | xfree(ca_blob); | 1577 | xfree(ca_blob); |
@@ -1522,7 +1626,7 @@ key_cert_check_authority(const Key *k, int want_host, int require_principal, | |||
1522 | *reason = "Certificate lacks principal list"; | 1626 | *reason = "Certificate lacks principal list"; |
1523 | return -1; | 1627 | return -1; |
1524 | } | 1628 | } |
1525 | } else { | 1629 | } else if (name != NULL) { |
1526 | principal_matches = 0; | 1630 | principal_matches = 0; |
1527 | for (i = 0; i < k->cert->nprincipals; i++) { | 1631 | for (i = 0; i < k->cert->nprincipals; i++) { |
1528 | if (strcmp(name, k->cert->principals[i]) == 0) { | 1632 | if (strcmp(name, k->cert->principals[i]) == 0) { |
@@ -1538,3 +1642,15 @@ key_cert_check_authority(const Key *k, int want_host, int require_principal, | |||
1538 | } | 1642 | } |
1539 | return 0; | 1643 | return 0; |
1540 | } | 1644 | } |
1645 | |||
1646 | int | ||
1647 | key_cert_is_legacy(Key *k) | ||
1648 | { | ||
1649 | switch (k->type) { | ||
1650 | case KEY_DSA_CERT_V00: | ||
1651 | case KEY_RSA_CERT_V00: | ||
1652 | return 1; | ||
1653 | default: | ||
1654 | return 0; | ||
1655 | } | ||
1656 | } | ||