diff options
author | Colin Watson <cjwatson@debian.org> | 2011-01-24 11:46:57 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2011-01-24 11:46:57 +0000 |
commit | 0970072c89b079b022538e3c366fbfa2c53fc821 (patch) | |
tree | b7024712d74234bb5a8b036ccbc9109e2e211296 /key.c | |
parent | 4e8aa4da57000c7bba8e5c49163bc0c0ca383f78 (diff) | |
parent | 478ff799463ca926a8dfbabf058f4e84aaffc65a (diff) |
merge 5.7p1
Diffstat (limited to 'key.c')
-rw-r--r-- | key.c | 673 |
1 files changed, 645 insertions, 28 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: key.c,v 1.90 2010/07/13 23:13:16 djm Exp $ */ | 1 | /* $OpenBSD: key.c,v 1.95 2010/11/10 01:33:07 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 |
@@ -78,6 +78,8 @@ key_new(int type) | |||
78 | DSA *dsa; | 78 | DSA *dsa; |
79 | k = xcalloc(1, sizeof(*k)); | 79 | k = xcalloc(1, sizeof(*k)); |
80 | k->type = type; | 80 | k->type = type; |
81 | k->ecdsa = NULL; | ||
82 | k->ecdsa_nid = -1; | ||
81 | k->dsa = NULL; | 83 | k->dsa = NULL; |
82 | k->rsa = NULL; | 84 | k->rsa = NULL; |
83 | k->cert = NULL; | 85 | k->cert = NULL; |
@@ -109,6 +111,12 @@ key_new(int type) | |||
109 | fatal("key_new: BN_new failed"); | 111 | fatal("key_new: BN_new failed"); |
110 | k->dsa = dsa; | 112 | k->dsa = dsa; |
111 | break; | 113 | break; |
114 | #ifdef OPENSSL_HAS_ECC | ||
115 | case KEY_ECDSA: | ||
116 | case KEY_ECDSA_CERT: | ||
117 | /* Cannot do anything until we know the group */ | ||
118 | break; | ||
119 | #endif | ||
112 | case KEY_UNSPEC: | 120 | case KEY_UNSPEC: |
113 | break; | 121 | break; |
114 | default: | 122 | default: |
@@ -149,6 +157,10 @@ key_add_private(Key *k) | |||
149 | if ((k->dsa->priv_key = BN_new()) == NULL) | 157 | if ((k->dsa->priv_key = BN_new()) == NULL) |
150 | fatal("key_new_private: BN_new failed"); | 158 | fatal("key_new_private: BN_new failed"); |
151 | break; | 159 | break; |
160 | case KEY_ECDSA: | ||
161 | case KEY_ECDSA_CERT: | ||
162 | /* Cannot do anything until we know the group */ | ||
163 | break; | ||
152 | case KEY_UNSPEC: | 164 | case KEY_UNSPEC: |
153 | break; | 165 | break; |
154 | default: | 166 | default: |
@@ -204,6 +216,14 @@ key_free(Key *k) | |||
204 | DSA_free(k->dsa); | 216 | DSA_free(k->dsa); |
205 | k->dsa = NULL; | 217 | k->dsa = NULL; |
206 | break; | 218 | break; |
219 | #ifdef OPENSSL_HAS_ECC | ||
220 | case KEY_ECDSA: | ||
221 | case KEY_ECDSA_CERT: | ||
222 | if (k->ecdsa != NULL) | ||
223 | EC_KEY_free(k->ecdsa); | ||
224 | k->ecdsa = NULL; | ||
225 | break; | ||
226 | #endif | ||
207 | case KEY_UNSPEC: | 227 | case KEY_UNSPEC: |
208 | break; | 228 | break; |
209 | default: | 229 | default: |
@@ -241,6 +261,10 @@ cert_compare(struct KeyCert *a, struct KeyCert *b) | |||
241 | int | 261 | int |
242 | key_equal_public(const Key *a, const Key *b) | 262 | key_equal_public(const Key *a, const Key *b) |
243 | { | 263 | { |
264 | #ifdef OPENSSL_HAS_ECC | ||
265 | BN_CTX *bnctx; | ||
266 | #endif | ||
267 | |||
244 | if (a == NULL || b == NULL || | 268 | if (a == NULL || b == NULL || |
245 | key_type_plain(a->type) != key_type_plain(b->type)) | 269 | key_type_plain(a->type) != key_type_plain(b->type)) |
246 | return 0; | 270 | return 0; |
@@ -261,6 +285,26 @@ key_equal_public(const Key *a, const Key *b) | |||
261 | BN_cmp(a->dsa->q, b->dsa->q) == 0 && | 285 | BN_cmp(a->dsa->q, b->dsa->q) == 0 && |
262 | BN_cmp(a->dsa->g, b->dsa->g) == 0 && | 286 | BN_cmp(a->dsa->g, b->dsa->g) == 0 && |
263 | BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; | 287 | BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; |
288 | #ifdef OPENSSL_HAS_ECC | ||
289 | case KEY_ECDSA_CERT: | ||
290 | case KEY_ECDSA: | ||
291 | if (a->ecdsa == NULL || b->ecdsa == NULL || | ||
292 | EC_KEY_get0_public_key(a->ecdsa) == NULL || | ||
293 | EC_KEY_get0_public_key(b->ecdsa) == NULL) | ||
294 | return 0; | ||
295 | if ((bnctx = BN_CTX_new()) == NULL) | ||
296 | fatal("%s: BN_CTX_new failed", __func__); | ||
297 | if (EC_GROUP_cmp(EC_KEY_get0_group(a->ecdsa), | ||
298 | EC_KEY_get0_group(b->ecdsa), bnctx) != 0 || | ||
299 | EC_POINT_cmp(EC_KEY_get0_group(a->ecdsa), | ||
300 | EC_KEY_get0_public_key(a->ecdsa), | ||
301 | EC_KEY_get0_public_key(b->ecdsa), bnctx) != 0) { | ||
302 | BN_CTX_free(bnctx); | ||
303 | return 0; | ||
304 | } | ||
305 | BN_CTX_free(bnctx); | ||
306 | return 1; | ||
307 | #endif /* OPENSSL_HAS_ECC */ | ||
264 | default: | 308 | default: |
265 | fatal("key_equal: bad key type %d", a->type); | 309 | fatal("key_equal: bad key type %d", a->type); |
266 | } | 310 | } |
@@ -312,12 +356,14 @@ key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length) | |||
312 | BN_bn2bin(k->rsa->e, blob + nlen); | 356 | BN_bn2bin(k->rsa->e, blob + nlen); |
313 | break; | 357 | break; |
314 | case KEY_DSA: | 358 | case KEY_DSA: |
359 | case KEY_ECDSA: | ||
315 | case KEY_RSA: | 360 | case KEY_RSA: |
316 | key_to_blob(k, &blob, &len); | 361 | key_to_blob(k, &blob, &len); |
317 | break; | 362 | break; |
318 | case KEY_DSA_CERT_V00: | 363 | case KEY_DSA_CERT_V00: |
319 | case KEY_RSA_CERT_V00: | 364 | case KEY_RSA_CERT_V00: |
320 | case KEY_DSA_CERT: | 365 | case KEY_DSA_CERT: |
366 | case KEY_ECDSA_CERT: | ||
321 | case KEY_RSA_CERT: | 367 | case KEY_RSA_CERT: |
322 | /* We want a fingerprint of the _key_ not of the cert */ | 368 | /* We want a fingerprint of the _key_ not of the cert */ |
323 | otype = k->type; | 369 | otype = k->type; |
@@ -615,6 +661,9 @@ key_read(Key *ret, char **cpp) | |||
615 | int len, n, type; | 661 | int len, n, type; |
616 | u_int bits; | 662 | u_int bits; |
617 | u_char *blob; | 663 | u_char *blob; |
664 | #ifdef OPENSSL_HAS_ECC | ||
665 | int curve_nid = -1; | ||
666 | #endif | ||
618 | 667 | ||
619 | cp = *cpp; | 668 | cp = *cpp; |
620 | 669 | ||
@@ -644,9 +693,11 @@ key_read(Key *ret, char **cpp) | |||
644 | case KEY_UNSPEC: | 693 | case KEY_UNSPEC: |
645 | case KEY_RSA: | 694 | case KEY_RSA: |
646 | case KEY_DSA: | 695 | case KEY_DSA: |
696 | case KEY_ECDSA: | ||
647 | case KEY_DSA_CERT_V00: | 697 | case KEY_DSA_CERT_V00: |
648 | case KEY_RSA_CERT_V00: | 698 | case KEY_RSA_CERT_V00: |
649 | case KEY_DSA_CERT: | 699 | case KEY_DSA_CERT: |
700 | case KEY_ECDSA_CERT: | ||
650 | case KEY_RSA_CERT: | 701 | case KEY_RSA_CERT: |
651 | space = strchr(cp, ' '); | 702 | space = strchr(cp, ' '); |
652 | if (space == NULL) { | 703 | if (space == NULL) { |
@@ -655,6 +706,13 @@ key_read(Key *ret, char **cpp) | |||
655 | } | 706 | } |
656 | *space = '\0'; | 707 | *space = '\0'; |
657 | type = key_type_from_name(cp); | 708 | type = key_type_from_name(cp); |
709 | #ifdef OPENSSL_HAS_ECC | ||
710 | if (key_type_plain(type) == KEY_ECDSA && | ||
711 | (curve_nid = key_ecdsa_nid_from_name(cp)) == -1) { | ||
712 | debug("key_read: invalid curve"); | ||
713 | return -1; | ||
714 | } | ||
715 | #endif | ||
658 | *space = ' '; | 716 | *space = ' '; |
659 | if (type == KEY_UNSPEC) { | 717 | if (type == KEY_UNSPEC) { |
660 | debug3("key_read: missing keytype"); | 718 | debug3("key_read: missing keytype"); |
@@ -691,6 +749,14 @@ key_read(Key *ret, char **cpp) | |||
691 | key_free(k); | 749 | key_free(k); |
692 | return -1; | 750 | return -1; |
693 | } | 751 | } |
752 | #ifdef OPENSSL_HAS_ECC | ||
753 | if (key_type_plain(type) == KEY_ECDSA && | ||
754 | curve_nid != k->ecdsa_nid) { | ||
755 | error("key_read: type mismatch: EC curve mismatch"); | ||
756 | key_free(k); | ||
757 | return -1; | ||
758 | } | ||
759 | #endif | ||
694 | /*XXXX*/ | 760 | /*XXXX*/ |
695 | if (key_is_cert(ret)) { | 761 | if (key_is_cert(ret)) { |
696 | if (!key_is_cert(k)) { | 762 | if (!key_is_cert(k)) { |
@@ -721,6 +787,19 @@ key_read(Key *ret, char **cpp) | |||
721 | DSA_print_fp(stderr, ret->dsa, 8); | 787 | DSA_print_fp(stderr, ret->dsa, 8); |
722 | #endif | 788 | #endif |
723 | } | 789 | } |
790 | #ifdef OPENSSL_HAS_ECC | ||
791 | if (key_type_plain(ret->type) == KEY_ECDSA) { | ||
792 | if (ret->ecdsa != NULL) | ||
793 | EC_KEY_free(ret->ecdsa); | ||
794 | ret->ecdsa = k->ecdsa; | ||
795 | ret->ecdsa_nid = k->ecdsa_nid; | ||
796 | k->ecdsa = NULL; | ||
797 | k->ecdsa_nid = -1; | ||
798 | #ifdef DEBUG_PK | ||
799 | key_dump_ec_key(ret->ecdsa); | ||
800 | #endif | ||
801 | } | ||
802 | #endif | ||
724 | success = 1; | 803 | success = 1; |
725 | /*XXXX*/ | 804 | /*XXXX*/ |
726 | key_free(k); | 805 | key_free(k); |
@@ -777,6 +856,13 @@ key_write(const Key *key, FILE *f) | |||
777 | if (key->dsa == NULL) | 856 | if (key->dsa == NULL) |
778 | return 0; | 857 | return 0; |
779 | break; | 858 | break; |
859 | #ifdef OPENSSL_HAS_ECC | ||
860 | case KEY_ECDSA: | ||
861 | case KEY_ECDSA_CERT: | ||
862 | if (key->ecdsa == NULL) | ||
863 | return 0; | ||
864 | break; | ||
865 | #endif | ||
780 | case KEY_RSA: | 866 | case KEY_RSA: |
781 | case KEY_RSA_CERT_V00: | 867 | case KEY_RSA_CERT_V00: |
782 | case KEY_RSA_CERT: | 868 | case KEY_RSA_CERT: |
@@ -810,6 +896,10 @@ key_type(const Key *k) | |||
810 | return "RSA"; | 896 | return "RSA"; |
811 | case KEY_DSA: | 897 | case KEY_DSA: |
812 | return "DSA"; | 898 | return "DSA"; |
899 | #ifdef OPENSSL_HAS_ECC | ||
900 | case KEY_ECDSA: | ||
901 | return "ECDSA"; | ||
902 | #endif | ||
813 | case KEY_RSA_CERT_V00: | 903 | case KEY_RSA_CERT_V00: |
814 | return "RSA-CERT-V00"; | 904 | return "RSA-CERT-V00"; |
815 | case KEY_DSA_CERT_V00: | 905 | case KEY_DSA_CERT_V00: |
@@ -818,6 +908,10 @@ key_type(const Key *k) | |||
818 | return "RSA-CERT"; | 908 | return "RSA-CERT"; |
819 | case KEY_DSA_CERT: | 909 | case KEY_DSA_CERT: |
820 | return "DSA-CERT"; | 910 | return "DSA-CERT"; |
911 | #ifdef OPENSSL_HAS_ECC | ||
912 | case KEY_ECDSA_CERT: | ||
913 | return "ECDSA-CERT"; | ||
914 | #endif | ||
821 | } | 915 | } |
822 | return "unknown"; | 916 | return "unknown"; |
823 | } | 917 | } |
@@ -835,10 +929,10 @@ key_cert_type(const Key *k) | |||
835 | } | 929 | } |
836 | } | 930 | } |
837 | 931 | ||
838 | const char * | 932 | static const char * |
839 | key_ssh_name(const Key *k) | 933 | key_ssh_name_from_type_nid(int type, int nid) |
840 | { | 934 | { |
841 | switch (k->type) { | 935 | switch (type) { |
842 | case KEY_RSA: | 936 | case KEY_RSA: |
843 | return "ssh-rsa"; | 937 | return "ssh-rsa"; |
844 | case KEY_DSA: | 938 | case KEY_DSA: |
@@ -851,12 +945,51 @@ key_ssh_name(const Key *k) | |||
851 | return "ssh-rsa-cert-v01@openssh.com"; | 945 | return "ssh-rsa-cert-v01@openssh.com"; |
852 | case KEY_DSA_CERT: | 946 | case KEY_DSA_CERT: |
853 | return "ssh-dss-cert-v01@openssh.com"; | 947 | return "ssh-dss-cert-v01@openssh.com"; |
948 | #ifdef OPENSSL_HAS_ECC | ||
949 | case KEY_ECDSA: | ||
950 | switch (nid) { | ||
951 | case NID_X9_62_prime256v1: | ||
952 | return "ecdsa-sha2-nistp256"; | ||
953 | case NID_secp384r1: | ||
954 | return "ecdsa-sha2-nistp384"; | ||
955 | case NID_secp521r1: | ||
956 | return "ecdsa-sha2-nistp521"; | ||
957 | default: | ||
958 | break; | ||
959 | } | ||
960 | break; | ||
961 | case KEY_ECDSA_CERT: | ||
962 | switch (nid) { | ||
963 | case NID_X9_62_prime256v1: | ||
964 | return "ecdsa-sha2-nistp256-cert-v01@openssh.com"; | ||
965 | case NID_secp384r1: | ||
966 | return "ecdsa-sha2-nistp384-cert-v01@openssh.com"; | ||
967 | case NID_secp521r1: | ||
968 | return "ecdsa-sha2-nistp521-cert-v01@openssh.com"; | ||
969 | default: | ||
970 | break; | ||
971 | } | ||
972 | break; | ||
973 | #endif /* OPENSSL_HAS_ECC */ | ||
854 | case KEY_NULL: | 974 | case KEY_NULL: |
855 | return "null"; | 975 | return "null"; |
856 | } | 976 | } |
857 | return "ssh-unknown"; | 977 | return "ssh-unknown"; |
858 | } | 978 | } |
859 | 979 | ||
980 | const char * | ||
981 | key_ssh_name(const Key *k) | ||
982 | { | ||
983 | return key_ssh_name_from_type_nid(k->type, k->ecdsa_nid); | ||
984 | } | ||
985 | |||
986 | const char * | ||
987 | key_ssh_name_plain(const Key *k) | ||
988 | { | ||
989 | return key_ssh_name_from_type_nid(key_type_plain(k->type), | ||
990 | k->ecdsa_nid); | ||
991 | } | ||
992 | |||
860 | u_int | 993 | u_int |
861 | key_size(const Key *k) | 994 | key_size(const Key *k) |
862 | { | 995 | { |
@@ -870,6 +1003,11 @@ key_size(const Key *k) | |||
870 | case KEY_DSA_CERT_V00: | 1003 | case KEY_DSA_CERT_V00: |
871 | case KEY_DSA_CERT: | 1004 | case KEY_DSA_CERT: |
872 | return BN_num_bits(k->dsa->p); | 1005 | return BN_num_bits(k->dsa->p); |
1006 | #ifdef OPENSSL_HAS_ECC | ||
1007 | case KEY_ECDSA: | ||
1008 | case KEY_ECDSA_CERT: | ||
1009 | return key_curve_nid_to_bits(k->ecdsa_nid); | ||
1010 | #endif | ||
873 | } | 1011 | } |
874 | return 0; | 1012 | return 0; |
875 | } | 1013 | } |
@@ -877,27 +1015,115 @@ key_size(const Key *k) | |||
877 | static RSA * | 1015 | static RSA * |
878 | rsa_generate_private_key(u_int bits) | 1016 | rsa_generate_private_key(u_int bits) |
879 | { | 1017 | { |
880 | RSA *private; | 1018 | RSA *private = RSA_new(); |
1019 | BIGNUM *f4 = BN_new(); | ||
881 | 1020 | ||
882 | private = RSA_generate_key(bits, RSA_F4, NULL, NULL); | ||
883 | if (private == NULL) | 1021 | if (private == NULL) |
884 | fatal("rsa_generate_private_key: key generation failed."); | 1022 | fatal("%s: RSA_new failed", __func__); |
1023 | if (f4 == NULL) | ||
1024 | fatal("%s: BN_new failed", __func__); | ||
1025 | if (!BN_set_word(f4, RSA_F4)) | ||
1026 | fatal("%s: BN_new failed", __func__); | ||
1027 | if (!RSA_generate_key_ex(private, bits, f4, NULL)) | ||
1028 | fatal("%s: key generation failed.", __func__); | ||
1029 | BN_free(f4); | ||
885 | return private; | 1030 | return private; |
886 | } | 1031 | } |
887 | 1032 | ||
888 | static DSA* | 1033 | static DSA* |
889 | dsa_generate_private_key(u_int bits) | 1034 | dsa_generate_private_key(u_int bits) |
890 | { | 1035 | { |
891 | DSA *private = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL); | 1036 | DSA *private = DSA_new(); |
892 | 1037 | ||
893 | if (private == NULL) | 1038 | if (private == NULL) |
894 | fatal("dsa_generate_private_key: DSA_generate_parameters failed"); | 1039 | fatal("%s: DSA_new failed", __func__); |
1040 | if (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL, | ||
1041 | NULL, NULL)) | ||
1042 | fatal("%s: DSA_generate_parameters failed", __func__); | ||
895 | if (!DSA_generate_key(private)) | 1043 | if (!DSA_generate_key(private)) |
896 | fatal("dsa_generate_private_key: DSA_generate_key failed."); | 1044 | fatal("%s: DSA_generate_key failed.", __func__); |
897 | if (private == NULL) | 1045 | return private; |
898 | fatal("dsa_generate_private_key: NULL."); | 1046 | } |
1047 | |||
1048 | int | ||
1049 | key_ecdsa_bits_to_nid(int bits) | ||
1050 | { | ||
1051 | switch (bits) { | ||
1052 | #ifdef OPENSSL_HAS_ECC | ||
1053 | case 256: | ||
1054 | return NID_X9_62_prime256v1; | ||
1055 | case 384: | ||
1056 | return NID_secp384r1; | ||
1057 | case 521: | ||
1058 | return NID_secp521r1; | ||
1059 | #endif | ||
1060 | default: | ||
1061 | return -1; | ||
1062 | } | ||
1063 | } | ||
1064 | |||
1065 | #ifdef OPENSSL_HAS_ECC | ||
1066 | int | ||
1067 | key_ecdsa_key_to_nid(EC_KEY *k) | ||
1068 | { | ||
1069 | EC_GROUP *eg; | ||
1070 | int nids[] = { | ||
1071 | NID_X9_62_prime256v1, | ||
1072 | NID_secp384r1, | ||
1073 | NID_secp521r1, | ||
1074 | -1 | ||
1075 | }; | ||
1076 | int nid; | ||
1077 | u_int i; | ||
1078 | BN_CTX *bnctx; | ||
1079 | const EC_GROUP *g = EC_KEY_get0_group(k); | ||
1080 | |||
1081 | /* | ||
1082 | * The group may be stored in a ASN.1 encoded private key in one of two | ||
1083 | * ways: as a "named group", which is reconstituted by ASN.1 object ID | ||
1084 | * or explicit group parameters encoded into the key blob. Only the | ||
1085 | * "named group" case sets the group NID for us, but we can figure | ||
1086 | * it out for the other case by comparing against all the groups that | ||
1087 | * are supported. | ||
1088 | */ | ||
1089 | if ((nid = EC_GROUP_get_curve_name(g)) > 0) | ||
1090 | return nid; | ||
1091 | if ((bnctx = BN_CTX_new()) == NULL) | ||
1092 | fatal("%s: BN_CTX_new() failed", __func__); | ||
1093 | for (i = 0; nids[i] != -1; i++) { | ||
1094 | if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) | ||
1095 | fatal("%s: EC_GROUP_new_by_curve_name failed", | ||
1096 | __func__); | ||
1097 | if (EC_GROUP_cmp(g, eg, bnctx) == 0) | ||
1098 | break; | ||
1099 | EC_GROUP_free(eg); | ||
1100 | } | ||
1101 | BN_CTX_free(bnctx); | ||
1102 | debug3("%s: nid = %d", __func__, nids[i]); | ||
1103 | if (nids[i] != -1) { | ||
1104 | /* Use the group with the NID attached */ | ||
1105 | EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE); | ||
1106 | if (EC_KEY_set_group(k, eg) != 1) | ||
1107 | fatal("%s: EC_KEY_set_group", __func__); | ||
1108 | } | ||
1109 | return nids[i]; | ||
1110 | } | ||
1111 | |||
1112 | static EC_KEY* | ||
1113 | ecdsa_generate_private_key(u_int bits, int *nid) | ||
1114 | { | ||
1115 | EC_KEY *private; | ||
1116 | |||
1117 | if ((*nid = key_ecdsa_bits_to_nid(bits)) == -1) | ||
1118 | fatal("%s: invalid key length", __func__); | ||
1119 | if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) | ||
1120 | fatal("%s: EC_KEY_new_by_curve_name failed", __func__); | ||
1121 | if (EC_KEY_generate_key(private) != 1) | ||
1122 | fatal("%s: EC_KEY_generate_key failed", __func__); | ||
1123 | EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE); | ||
899 | return private; | 1124 | return private; |
900 | } | 1125 | } |
1126 | #endif /* OPENSSL_HAS_ECC */ | ||
901 | 1127 | ||
902 | Key * | 1128 | Key * |
903 | key_generate(int type, u_int bits) | 1129 | key_generate(int type, u_int bits) |
@@ -907,6 +1133,11 @@ key_generate(int type, u_int bits) | |||
907 | case KEY_DSA: | 1133 | case KEY_DSA: |
908 | k->dsa = dsa_generate_private_key(bits); | 1134 | k->dsa = dsa_generate_private_key(bits); |
909 | break; | 1135 | break; |
1136 | #ifdef OPENSSL_HAS_ECC | ||
1137 | case KEY_ECDSA: | ||
1138 | k->ecdsa = ecdsa_generate_private_key(bits, &k->ecdsa_nid); | ||
1139 | break; | ||
1140 | #endif | ||
910 | case KEY_RSA: | 1141 | case KEY_RSA: |
911 | case KEY_RSA1: | 1142 | case KEY_RSA1: |
912 | k->rsa = rsa_generate_private_key(bits); | 1143 | k->rsa = rsa_generate_private_key(bits); |
@@ -983,6 +1214,18 @@ key_from_private(const Key *k) | |||
983 | (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL)) | 1214 | (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL)) |
984 | fatal("key_from_private: BN_copy failed"); | 1215 | fatal("key_from_private: BN_copy failed"); |
985 | break; | 1216 | break; |
1217 | #ifdef OPENSSL_HAS_ECC | ||
1218 | case KEY_ECDSA: | ||
1219 | case KEY_ECDSA_CERT: | ||
1220 | n = key_new(k->type); | ||
1221 | n->ecdsa_nid = k->ecdsa_nid; | ||
1222 | if ((n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid)) == NULL) | ||
1223 | fatal("%s: EC_KEY_new_by_curve_name failed", __func__); | ||
1224 | if (EC_KEY_set_public_key(n->ecdsa, | ||
1225 | EC_KEY_get0_public_key(k->ecdsa)) != 1) | ||
1226 | fatal("%s: EC_KEY_set_public_key failed", __func__); | ||
1227 | break; | ||
1228 | #endif | ||
986 | case KEY_RSA: | 1229 | case KEY_RSA: |
987 | case KEY_RSA1: | 1230 | case KEY_RSA1: |
988 | case KEY_RSA_CERT_V00: | 1231 | case KEY_RSA_CERT_V00: |
@@ -1014,6 +1257,13 @@ key_type_from_name(char *name) | |||
1014 | return KEY_RSA; | 1257 | return KEY_RSA; |
1015 | } else if (strcmp(name, "ssh-dss") == 0) { | 1258 | } else if (strcmp(name, "ssh-dss") == 0) { |
1016 | return KEY_DSA; | 1259 | return KEY_DSA; |
1260 | #ifdef OPENSSL_HAS_ECC | ||
1261 | } else if (strcmp(name, "ecdsa") == 0 || | ||
1262 | strcmp(name, "ecdsa-sha2-nistp256") == 0 || | ||
1263 | strcmp(name, "ecdsa-sha2-nistp384") == 0 || | ||
1264 | strcmp(name, "ecdsa-sha2-nistp521") == 0) { | ||
1265 | return KEY_ECDSA; | ||
1266 | #endif | ||
1017 | } else if (strcmp(name, "ssh-rsa-cert-v00@openssh.com") == 0) { | 1267 | } else if (strcmp(name, "ssh-rsa-cert-v00@openssh.com") == 0) { |
1018 | return KEY_RSA_CERT_V00; | 1268 | return KEY_RSA_CERT_V00; |
1019 | } else if (strcmp(name, "ssh-dss-cert-v00@openssh.com") == 0) { | 1269 | } else if (strcmp(name, "ssh-dss-cert-v00@openssh.com") == 0) { |
@@ -1022,14 +1272,40 @@ key_type_from_name(char *name) | |||
1022 | return KEY_RSA_CERT; | 1272 | return KEY_RSA_CERT; |
1023 | } else if (strcmp(name, "ssh-dss-cert-v01@openssh.com") == 0) { | 1273 | } else if (strcmp(name, "ssh-dss-cert-v01@openssh.com") == 0) { |
1024 | return KEY_DSA_CERT; | 1274 | return KEY_DSA_CERT; |
1275 | #ifdef OPENSSL_HAS_ECC | ||
1276 | } else if (strcmp(name, "ecdsa-sha2-nistp256-cert-v01@openssh.com") == 0 || | ||
1277 | strcmp(name, "ecdsa-sha2-nistp384-cert-v01@openssh.com") == 0 || | ||
1278 | strcmp(name, "ecdsa-sha2-nistp521-cert-v01@openssh.com") == 0) { | ||
1279 | return KEY_ECDSA_CERT; | ||
1280 | #endif | ||
1025 | } else if (strcmp(name, "null") == 0) { | 1281 | } else if (strcmp(name, "null") == 0) { |
1026 | return KEY_NULL; | 1282 | return KEY_NULL; |
1027 | } | 1283 | } |
1284 | |||
1028 | debug2("key_type_from_name: unknown key type '%s'", name); | 1285 | debug2("key_type_from_name: unknown key type '%s'", name); |
1029 | return KEY_UNSPEC; | 1286 | return KEY_UNSPEC; |
1030 | } | 1287 | } |
1031 | 1288 | ||
1032 | int | 1289 | int |
1290 | key_ecdsa_nid_from_name(const char *name) | ||
1291 | { | ||
1292 | #ifdef OPENSSL_HAS_ECC | ||
1293 | if (strcmp(name, "ecdsa-sha2-nistp256") == 0 || | ||
1294 | strcmp(name, "ecdsa-sha2-nistp256-cert-v01@openssh.com") == 0) | ||
1295 | return NID_X9_62_prime256v1; | ||
1296 | if (strcmp(name, "ecdsa-sha2-nistp384") == 0 || | ||
1297 | strcmp(name, "ecdsa-sha2-nistp384-cert-v01@openssh.com") == 0) | ||
1298 | return NID_secp384r1; | ||
1299 | if (strcmp(name, "ecdsa-sha2-nistp521") == 0 || | ||
1300 | strcmp(name, "ecdsa-sha2-nistp521-cert-v01@openssh.com") == 0) | ||
1301 | return NID_secp521r1; | ||
1302 | #endif /* OPENSSL_HAS_ECC */ | ||
1303 | |||
1304 | debug2("%s: unknown/non-ECDSA key type '%s'", __func__, name); | ||
1305 | return -1; | ||
1306 | } | ||
1307 | |||
1308 | int | ||
1033 | key_names_valid2(const char *names) | 1309 | key_names_valid2(const char *names) |
1034 | { | 1310 | { |
1035 | char *s, *cp, *p; | 1311 | char *s, *cp, *p; |
@@ -1071,7 +1347,7 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) | |||
1071 | principals = exts = critical = sig_key = sig = NULL; | 1347 | principals = exts = critical = sig_key = sig = NULL; |
1072 | if ((!v00 && buffer_get_int64_ret(&key->cert->serial, b) != 0) || | 1348 | if ((!v00 && buffer_get_int64_ret(&key->cert->serial, b) != 0) || |
1073 | buffer_get_int_ret(&key->cert->type, b) != 0 || | 1349 | buffer_get_int_ret(&key->cert->type, b) != 0 || |
1074 | (key->cert->key_id = buffer_get_string_ret(b, &kidlen)) == NULL || | 1350 | (key->cert->key_id = buffer_get_cstring_ret(b, &kidlen)) == NULL || |
1075 | (principals = buffer_get_string_ret(b, &plen)) == NULL || | 1351 | (principals = buffer_get_string_ret(b, &plen)) == NULL || |
1076 | buffer_get_int64_ret(&key->cert->valid_after, b) != 0 || | 1352 | buffer_get_int64_ret(&key->cert->valid_after, b) != 0 || |
1077 | buffer_get_int64_ret(&key->cert->valid_before, b) != 0 || | 1353 | buffer_get_int64_ret(&key->cert->valid_before, b) != 0 || |
@@ -1109,15 +1385,10 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) | |||
1109 | error("%s: Too many principals", __func__); | 1385 | error("%s: Too many principals", __func__); |
1110 | goto out; | 1386 | goto out; |
1111 | } | 1387 | } |
1112 | if ((principal = buffer_get_string_ret(&tmp, &plen)) == NULL) { | 1388 | if ((principal = buffer_get_cstring_ret(&tmp, &plen)) == NULL) { |
1113 | error("%s: Principals data invalid", __func__); | 1389 | error("%s: Principals data invalid", __func__); |
1114 | goto out; | 1390 | goto out; |
1115 | } | 1391 | } |
1116 | if (strlen(principal) != plen) { | ||
1117 | error("%s: Principal contains \\0 character", | ||
1118 | __func__); | ||
1119 | goto out; | ||
1120 | } | ||
1121 | key->cert->principals = xrealloc(key->cert->principals, | 1392 | key->cert->principals = xrealloc(key->cert->principals, |
1122 | key->cert->nprincipals + 1, sizeof(*key->cert->principals)); | 1393 | key->cert->nprincipals + 1, sizeof(*key->cert->principals)); |
1123 | key->cert->principals[key->cert->nprincipals++] = principal; | 1394 | key->cert->principals[key->cert->nprincipals++] = principal; |
@@ -1155,7 +1426,8 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) | |||
1155 | goto out; | 1426 | goto out; |
1156 | } | 1427 | } |
1157 | if (key->cert->signature_key->type != KEY_RSA && | 1428 | if (key->cert->signature_key->type != KEY_RSA && |
1158 | key->cert->signature_key->type != KEY_DSA) { | 1429 | key->cert->signature_key->type != KEY_DSA && |
1430 | key->cert->signature_key->type != KEY_ECDSA) { | ||
1159 | error("%s: Invalid signature key type %s (%d)", __func__, | 1431 | error("%s: Invalid signature key type %s (%d)", __func__, |
1160 | key_type(key->cert->signature_key), | 1432 | key_type(key->cert->signature_key), |
1161 | key->cert->signature_key->type); | 1433 | key->cert->signature_key->type); |
@@ -1196,20 +1468,28 @@ key_from_blob(const u_char *blob, u_int blen) | |||
1196 | { | 1468 | { |
1197 | Buffer b; | 1469 | Buffer b; |
1198 | int rlen, type; | 1470 | int rlen, type; |
1199 | char *ktype = NULL; | 1471 | char *ktype = NULL, *curve = NULL; |
1200 | Key *key = NULL; | 1472 | Key *key = NULL; |
1473 | #ifdef OPENSSL_HAS_ECC | ||
1474 | EC_POINT *q = NULL; | ||
1475 | int nid = -1; | ||
1476 | #endif | ||
1201 | 1477 | ||
1202 | #ifdef DEBUG_PK | 1478 | #ifdef DEBUG_PK |
1203 | dump_base64(stderr, blob, blen); | 1479 | dump_base64(stderr, blob, blen); |
1204 | #endif | 1480 | #endif |
1205 | buffer_init(&b); | 1481 | buffer_init(&b); |
1206 | buffer_append(&b, blob, blen); | 1482 | buffer_append(&b, blob, blen); |
1207 | if ((ktype = buffer_get_string_ret(&b, NULL)) == NULL) { | 1483 | if ((ktype = buffer_get_cstring_ret(&b, NULL)) == NULL) { |
1208 | error("key_from_blob: can't read key type"); | 1484 | error("key_from_blob: can't read key type"); |
1209 | goto out; | 1485 | goto out; |
1210 | } | 1486 | } |
1211 | 1487 | ||
1212 | type = key_type_from_name(ktype); | 1488 | type = key_type_from_name(ktype); |
1489 | #ifdef OPENSSL_HAS_ECC | ||
1490 | if (key_type_plain(type) == KEY_ECDSA) | ||
1491 | nid = key_ecdsa_nid_from_name(ktype); | ||
1492 | #endif | ||
1213 | 1493 | ||
1214 | switch (type) { | 1494 | switch (type) { |
1215 | case KEY_RSA_CERT: | 1495 | case KEY_RSA_CERT: |
@@ -1247,6 +1527,43 @@ key_from_blob(const u_char *blob, u_int blen) | |||
1247 | DSA_print_fp(stderr, key->dsa, 8); | 1527 | DSA_print_fp(stderr, key->dsa, 8); |
1248 | #endif | 1528 | #endif |
1249 | break; | 1529 | break; |
1530 | #ifdef OPENSSL_HAS_ECC | ||
1531 | case KEY_ECDSA_CERT: | ||
1532 | (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ | ||
1533 | /* FALLTHROUGH */ | ||
1534 | case KEY_ECDSA: | ||
1535 | key = key_new(type); | ||
1536 | key->ecdsa_nid = nid; | ||
1537 | if ((curve = buffer_get_string_ret(&b, NULL)) == NULL) { | ||
1538 | error("key_from_blob: can't read ecdsa curve"); | ||
1539 | goto badkey; | ||
1540 | } | ||
1541 | if (key->ecdsa_nid != key_curve_name_to_nid(curve)) { | ||
1542 | error("key_from_blob: ecdsa curve doesn't match type"); | ||
1543 | goto badkey; | ||
1544 | } | ||
1545 | if (key->ecdsa != NULL) | ||
1546 | EC_KEY_free(key->ecdsa); | ||
1547 | if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) | ||
1548 | == NULL) | ||
1549 | fatal("key_from_blob: EC_KEY_new_by_curve_name failed"); | ||
1550 | if ((q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL) | ||
1551 | fatal("key_from_blob: EC_POINT_new failed"); | ||
1552 | if (buffer_get_ecpoint_ret(&b, EC_KEY_get0_group(key->ecdsa), | ||
1553 | q) == -1) { | ||
1554 | error("key_from_blob: can't read ecdsa key point"); | ||
1555 | goto badkey; | ||
1556 | } | ||
1557 | if (key_ec_validate_public(EC_KEY_get0_group(key->ecdsa), | ||
1558 | q) != 0) | ||
1559 | goto badkey; | ||
1560 | if (EC_KEY_set_public_key(key->ecdsa, q) != 1) | ||
1561 | fatal("key_from_blob: EC_KEY_set_public_key failed"); | ||
1562 | #ifdef DEBUG_PK | ||
1563 | key_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q); | ||
1564 | #endif | ||
1565 | break; | ||
1566 | #endif /* OPENSSL_HAS_ECC */ | ||
1250 | case KEY_UNSPEC: | 1567 | case KEY_UNSPEC: |
1251 | key = key_new(type); | 1568 | key = key_new(type); |
1252 | break; | 1569 | break; |
@@ -1264,6 +1581,12 @@ key_from_blob(const u_char *blob, u_int blen) | |||
1264 | out: | 1581 | out: |
1265 | if (ktype != NULL) | 1582 | if (ktype != NULL) |
1266 | xfree(ktype); | 1583 | xfree(ktype); |
1584 | if (curve != NULL) | ||
1585 | xfree(curve); | ||
1586 | #ifdef OPENSSL_HAS_ECC | ||
1587 | if (q != NULL) | ||
1588 | EC_POINT_free(q); | ||
1589 | #endif | ||
1267 | buffer_free(&b); | 1590 | buffer_free(&b); |
1268 | return key; | 1591 | return key; |
1269 | } | 1592 | } |
@@ -1283,6 +1606,7 @@ key_to_blob(const Key *key, u_char **blobp, u_int *lenp) | |||
1283 | case KEY_DSA_CERT_V00: | 1606 | case KEY_DSA_CERT_V00: |
1284 | case KEY_RSA_CERT_V00: | 1607 | case KEY_RSA_CERT_V00: |
1285 | case KEY_DSA_CERT: | 1608 | case KEY_DSA_CERT: |
1609 | case KEY_ECDSA_CERT: | ||
1286 | case KEY_RSA_CERT: | 1610 | case KEY_RSA_CERT: |
1287 | /* Use the existing blob */ | 1611 | /* Use the existing blob */ |
1288 | buffer_append(&b, buffer_ptr(&key->cert->certblob), | 1612 | buffer_append(&b, buffer_ptr(&key->cert->certblob), |
@@ -1295,6 +1619,14 @@ key_to_blob(const Key *key, u_char **blobp, u_int *lenp) | |||
1295 | buffer_put_bignum2(&b, key->dsa->g); | 1619 | buffer_put_bignum2(&b, key->dsa->g); |
1296 | buffer_put_bignum2(&b, key->dsa->pub_key); | 1620 | buffer_put_bignum2(&b, key->dsa->pub_key); |
1297 | break; | 1621 | break; |
1622 | #ifdef OPENSSL_HAS_ECC | ||
1623 | case KEY_ECDSA: | ||
1624 | buffer_put_cstring(&b, key_ssh_name(key)); | ||
1625 | buffer_put_cstring(&b, key_curve_nid_to_name(key->ecdsa_nid)); | ||
1626 | buffer_put_ecpoint(&b, EC_KEY_get0_group(key->ecdsa), | ||
1627 | EC_KEY_get0_public_key(key->ecdsa)); | ||
1628 | break; | ||
1629 | #endif | ||
1298 | case KEY_RSA: | 1630 | case KEY_RSA: |
1299 | buffer_put_cstring(&b, key_ssh_name(key)); | 1631 | buffer_put_cstring(&b, key_ssh_name(key)); |
1300 | buffer_put_bignum2(&b, key->rsa->e); | 1632 | buffer_put_bignum2(&b, key->rsa->e); |
@@ -1328,6 +1660,11 @@ key_sign( | |||
1328 | case KEY_DSA_CERT: | 1660 | case KEY_DSA_CERT: |
1329 | case KEY_DSA: | 1661 | case KEY_DSA: |
1330 | return ssh_dss_sign(key, sigp, lenp, data, datalen); | 1662 | return ssh_dss_sign(key, sigp, lenp, data, datalen); |
1663 | #ifdef OPENSSL_HAS_ECC | ||
1664 | case KEY_ECDSA_CERT: | ||
1665 | case KEY_ECDSA: | ||
1666 | return ssh_ecdsa_sign(key, sigp, lenp, data, datalen); | ||
1667 | #endif | ||
1331 | case KEY_RSA_CERT_V00: | 1668 | case KEY_RSA_CERT_V00: |
1332 | case KEY_RSA_CERT: | 1669 | case KEY_RSA_CERT: |
1333 | case KEY_RSA: | 1670 | case KEY_RSA: |
@@ -1356,6 +1693,11 @@ key_verify( | |||
1356 | case KEY_DSA_CERT: | 1693 | case KEY_DSA_CERT: |
1357 | case KEY_DSA: | 1694 | case KEY_DSA: |
1358 | return ssh_dss_verify(key, signature, signaturelen, data, datalen); | 1695 | return ssh_dss_verify(key, signature, signaturelen, data, datalen); |
1696 | #ifdef OPENSSL_HAS_ECC | ||
1697 | case KEY_ECDSA_CERT: | ||
1698 | case KEY_ECDSA: | ||
1699 | return ssh_ecdsa_verify(key, signature, signaturelen, data, datalen); | ||
1700 | #endif | ||
1359 | case KEY_RSA_CERT_V00: | 1701 | case KEY_RSA_CERT_V00: |
1360 | case KEY_RSA_CERT: | 1702 | case KEY_RSA_CERT: |
1361 | case KEY_RSA: | 1703 | case KEY_RSA: |
@@ -1375,7 +1717,9 @@ key_demote(const Key *k) | |||
1375 | pk = xcalloc(1, sizeof(*pk)); | 1717 | pk = xcalloc(1, sizeof(*pk)); |
1376 | pk->type = k->type; | 1718 | pk->type = k->type; |
1377 | pk->flags = k->flags; | 1719 | pk->flags = k->flags; |
1720 | pk->ecdsa_nid = k->ecdsa_nid; | ||
1378 | pk->dsa = NULL; | 1721 | pk->dsa = NULL; |
1722 | pk->ecdsa = NULL; | ||
1379 | pk->rsa = NULL; | 1723 | pk->rsa = NULL; |
1380 | 1724 | ||
1381 | switch (k->type) { | 1725 | switch (k->type) { |
@@ -1408,6 +1752,18 @@ key_demote(const Key *k) | |||
1408 | if ((pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) | 1752 | if ((pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) |
1409 | fatal("key_demote: BN_dup failed"); | 1753 | fatal("key_demote: BN_dup failed"); |
1410 | break; | 1754 | break; |
1755 | #ifdef OPENSSL_HAS_ECC | ||
1756 | case KEY_ECDSA_CERT: | ||
1757 | key_cert_copy(k, pk); | ||
1758 | /* FALLTHROUGH */ | ||
1759 | case KEY_ECDSA: | ||
1760 | if ((pk->ecdsa = EC_KEY_new_by_curve_name(pk->ecdsa_nid)) == NULL) | ||
1761 | fatal("key_demote: EC_KEY_new_by_curve_name failed"); | ||
1762 | if (EC_KEY_set_public_key(pk->ecdsa, | ||
1763 | EC_KEY_get0_public_key(k->ecdsa)) != 1) | ||
1764 | fatal("key_demote: EC_KEY_set_public_key failed"); | ||
1765 | break; | ||
1766 | #endif | ||
1411 | default: | 1767 | default: |
1412 | fatal("key_free: bad key type %d", k->type); | 1768 | fatal("key_free: bad key type %d", k->type); |
1413 | break; | 1769 | break; |
@@ -1426,6 +1782,7 @@ key_is_cert(const Key *k) | |||
1426 | case KEY_DSA_CERT_V00: | 1782 | case KEY_DSA_CERT_V00: |
1427 | case KEY_RSA_CERT: | 1783 | case KEY_RSA_CERT: |
1428 | case KEY_DSA_CERT: | 1784 | case KEY_DSA_CERT: |
1785 | case KEY_ECDSA_CERT: | ||
1429 | return 1; | 1786 | return 1; |
1430 | default: | 1787 | default: |
1431 | return 0; | 1788 | return 0; |
@@ -1443,6 +1800,8 @@ key_type_plain(int type) | |||
1443 | case KEY_DSA_CERT_V00: | 1800 | case KEY_DSA_CERT_V00: |
1444 | case KEY_DSA_CERT: | 1801 | case KEY_DSA_CERT: |
1445 | return KEY_DSA; | 1802 | return KEY_DSA; |
1803 | case KEY_ECDSA_CERT: | ||
1804 | return KEY_ECDSA; | ||
1446 | default: | 1805 | default: |
1447 | return type; | 1806 | return type; |
1448 | } | 1807 | } |
@@ -1461,6 +1820,10 @@ key_to_certified(Key *k, int legacy) | |||
1461 | k->cert = cert_new(); | 1820 | k->cert = cert_new(); |
1462 | k->type = legacy ? KEY_DSA_CERT_V00 : KEY_DSA_CERT; | 1821 | k->type = legacy ? KEY_DSA_CERT_V00 : KEY_DSA_CERT; |
1463 | return 0; | 1822 | return 0; |
1823 | case KEY_ECDSA: | ||
1824 | k->cert = cert_new(); | ||
1825 | k->type = KEY_ECDSA_CERT; | ||
1826 | return 0; | ||
1464 | default: | 1827 | default: |
1465 | error("%s: key has incorrect type %s", __func__, key_type(k)); | 1828 | error("%s: key has incorrect type %s", __func__, key_type(k)); |
1466 | return -1; | 1829 | return -1; |
@@ -1482,13 +1845,20 @@ key_drop_cert(Key *k) | |||
1482 | cert_free(k->cert); | 1845 | cert_free(k->cert); |
1483 | k->type = KEY_DSA; | 1846 | k->type = KEY_DSA; |
1484 | return 0; | 1847 | return 0; |
1848 | case KEY_ECDSA_CERT: | ||
1849 | cert_free(k->cert); | ||
1850 | k->type = KEY_ECDSA; | ||
1851 | return 0; | ||
1485 | default: | 1852 | default: |
1486 | error("%s: key has incorrect type %s", __func__, key_type(k)); | 1853 | error("%s: key has incorrect type %s", __func__, key_type(k)); |
1487 | return -1; | 1854 | return -1; |
1488 | } | 1855 | } |
1489 | } | 1856 | } |
1490 | 1857 | ||
1491 | /* Sign a KEY_RSA_CERT or KEY_DSA_CERT, (re-)generating the signed certblob */ | 1858 | /* |
1859 | * Sign a KEY_RSA_CERT, KEY_DSA_CERT or KEY_ECDSA_CERT, (re-)generating | ||
1860 | * the signed certblob | ||
1861 | */ | ||
1492 | int | 1862 | int |
1493 | key_certify(Key *k, Key *ca) | 1863 | key_certify(Key *k, Key *ca) |
1494 | { | 1864 | { |
@@ -1507,7 +1877,8 @@ key_certify(Key *k, Key *ca) | |||
1507 | return -1; | 1877 | return -1; |
1508 | } | 1878 | } |
1509 | 1879 | ||
1510 | if (ca->type != KEY_RSA && ca->type != KEY_DSA) { | 1880 | if (ca->type != KEY_RSA && ca->type != KEY_DSA && |
1881 | ca->type != KEY_ECDSA) { | ||
1511 | error("%s: CA key has unsupported type %s", __func__, | 1882 | error("%s: CA key has unsupported type %s", __func__, |
1512 | key_type(ca)); | 1883 | key_type(ca)); |
1513 | return -1; | 1884 | return -1; |
@@ -1519,7 +1890,7 @@ key_certify(Key *k, Key *ca) | |||
1519 | buffer_put_cstring(&k->cert->certblob, key_ssh_name(k)); | 1890 | buffer_put_cstring(&k->cert->certblob, key_ssh_name(k)); |
1520 | 1891 | ||
1521 | /* -v01 certs put nonce first */ | 1892 | /* -v01 certs put nonce first */ |
1522 | if (k->type == KEY_DSA_CERT || k->type == KEY_RSA_CERT) { | 1893 | if (!key_cert_is_legacy(k)) { |
1523 | arc4random_buf(&nonce, sizeof(nonce)); | 1894 | arc4random_buf(&nonce, sizeof(nonce)); |
1524 | buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce)); | 1895 | buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce)); |
1525 | } | 1896 | } |
@@ -1532,6 +1903,15 @@ key_certify(Key *k, Key *ca) | |||
1532 | buffer_put_bignum2(&k->cert->certblob, k->dsa->g); | 1903 | buffer_put_bignum2(&k->cert->certblob, k->dsa->g); |
1533 | buffer_put_bignum2(&k->cert->certblob, k->dsa->pub_key); | 1904 | buffer_put_bignum2(&k->cert->certblob, k->dsa->pub_key); |
1534 | break; | 1905 | break; |
1906 | #ifdef OPENSSL_HAS_ECC | ||
1907 | case KEY_ECDSA_CERT: | ||
1908 | buffer_put_cstring(&k->cert->certblob, | ||
1909 | key_curve_nid_to_name(k->ecdsa_nid)); | ||
1910 | buffer_put_ecpoint(&k->cert->certblob, | ||
1911 | EC_KEY_get0_group(k->ecdsa), | ||
1912 | EC_KEY_get0_public_key(k->ecdsa)); | ||
1913 | break; | ||
1914 | #endif | ||
1535 | case KEY_RSA_CERT_V00: | 1915 | case KEY_RSA_CERT_V00: |
1536 | case KEY_RSA_CERT: | 1916 | case KEY_RSA_CERT: |
1537 | buffer_put_bignum2(&k->cert->certblob, k->rsa->e); | 1917 | buffer_put_bignum2(&k->cert->certblob, k->rsa->e); |
@@ -1545,7 +1925,7 @@ key_certify(Key *k, Key *ca) | |||
1545 | } | 1925 | } |
1546 | 1926 | ||
1547 | /* -v01 certs have a serial number next */ | 1927 | /* -v01 certs have a serial number next */ |
1548 | if (k->type == KEY_DSA_CERT || k->type == KEY_RSA_CERT) | 1928 | if (!key_cert_is_legacy(k)) |
1549 | buffer_put_int64(&k->cert->certblob, k->cert->serial); | 1929 | buffer_put_int64(&k->cert->certblob, k->cert->serial); |
1550 | 1930 | ||
1551 | buffer_put_int(&k->cert->certblob, k->cert->type); | 1931 | buffer_put_int(&k->cert->certblob, k->cert->type); |
@@ -1564,14 +1944,14 @@ key_certify(Key *k, Key *ca) | |||
1564 | buffer_ptr(&k->cert->critical), buffer_len(&k->cert->critical)); | 1944 | buffer_ptr(&k->cert->critical), buffer_len(&k->cert->critical)); |
1565 | 1945 | ||
1566 | /* -v01 certs have non-critical options here */ | 1946 | /* -v01 certs have non-critical options here */ |
1567 | if (k->type == KEY_DSA_CERT || k->type == KEY_RSA_CERT) { | 1947 | if (!key_cert_is_legacy(k)) { |
1568 | buffer_put_string(&k->cert->certblob, | 1948 | buffer_put_string(&k->cert->certblob, |
1569 | buffer_ptr(&k->cert->extensions), | 1949 | buffer_ptr(&k->cert->extensions), |
1570 | buffer_len(&k->cert->extensions)); | 1950 | buffer_len(&k->cert->extensions)); |
1571 | } | 1951 | } |
1572 | 1952 | ||
1573 | /* -v00 certs put the nonce at the end */ | 1953 | /* -v00 certs put the nonce at the end */ |
1574 | if (k->type == KEY_DSA_CERT_V00 || k->type == KEY_RSA_CERT_V00) | 1954 | if (key_cert_is_legacy(k)) |
1575 | buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce)); | 1955 | buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce)); |
1576 | 1956 | ||
1577 | buffer_put_string(&k->cert->certblob, NULL, 0); /* reserved */ | 1957 | buffer_put_string(&k->cert->certblob, NULL, 0); /* reserved */ |
@@ -1656,3 +2036,240 @@ key_cert_is_legacy(Key *k) | |||
1656 | return 0; | 2036 | return 0; |
1657 | } | 2037 | } |
1658 | } | 2038 | } |
2039 | |||
2040 | /* XXX: these are really begging for a table-driven approach */ | ||
2041 | int | ||
2042 | key_curve_name_to_nid(const char *name) | ||
2043 | { | ||
2044 | #ifdef OPENSSL_HAS_ECC | ||
2045 | if (strcmp(name, "nistp256") == 0) | ||
2046 | return NID_X9_62_prime256v1; | ||
2047 | else if (strcmp(name, "nistp384") == 0) | ||
2048 | return NID_secp384r1; | ||
2049 | else if (strcmp(name, "nistp521") == 0) | ||
2050 | return NID_secp521r1; | ||
2051 | #endif | ||
2052 | |||
2053 | debug("%s: unsupported EC curve name \"%.100s\"", __func__, name); | ||
2054 | return -1; | ||
2055 | } | ||
2056 | |||
2057 | u_int | ||
2058 | key_curve_nid_to_bits(int nid) | ||
2059 | { | ||
2060 | switch (nid) { | ||
2061 | #ifdef OPENSSL_HAS_ECC | ||
2062 | case NID_X9_62_prime256v1: | ||
2063 | return 256; | ||
2064 | case NID_secp384r1: | ||
2065 | return 384; | ||
2066 | case NID_secp521r1: | ||
2067 | return 521; | ||
2068 | #endif | ||
2069 | default: | ||
2070 | error("%s: unsupported EC curve nid %d", __func__, nid); | ||
2071 | return 0; | ||
2072 | } | ||
2073 | } | ||
2074 | |||
2075 | const char * | ||
2076 | key_curve_nid_to_name(int nid) | ||
2077 | { | ||
2078 | #ifdef OPENSSL_HAS_ECC | ||
2079 | if (nid == NID_X9_62_prime256v1) | ||
2080 | return "nistp256"; | ||
2081 | else if (nid == NID_secp384r1) | ||
2082 | return "nistp384"; | ||
2083 | else if (nid == NID_secp521r1) | ||
2084 | return "nistp521"; | ||
2085 | #endif | ||
2086 | error("%s: unsupported EC curve nid %d", __func__, nid); | ||
2087 | return NULL; | ||
2088 | } | ||
2089 | |||
2090 | #ifdef OPENSSL_HAS_ECC | ||
2091 | const EVP_MD * | ||
2092 | key_ec_nid_to_evpmd(int nid) | ||
2093 | { | ||
2094 | int kbits = key_curve_nid_to_bits(nid); | ||
2095 | |||
2096 | if (kbits == 0) | ||
2097 | fatal("%s: invalid nid %d", __func__, nid); | ||
2098 | /* RFC5656 section 6.2.1 */ | ||
2099 | if (kbits <= 256) | ||
2100 | return EVP_sha256(); | ||
2101 | else if (kbits <= 384) | ||
2102 | return EVP_sha384(); | ||
2103 | else | ||
2104 | return EVP_sha512(); | ||
2105 | } | ||
2106 | |||
2107 | int | ||
2108 | key_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) | ||
2109 | { | ||
2110 | BN_CTX *bnctx; | ||
2111 | EC_POINT *nq = NULL; | ||
2112 | BIGNUM *order, *x, *y, *tmp; | ||
2113 | int ret = -1; | ||
2114 | |||
2115 | if ((bnctx = BN_CTX_new()) == NULL) | ||
2116 | fatal("%s: BN_CTX_new failed", __func__); | ||
2117 | BN_CTX_start(bnctx); | ||
2118 | |||
2119 | /* | ||
2120 | * We shouldn't ever hit this case because bignum_get_ecpoint() | ||
2121 | * refuses to load GF2m points. | ||
2122 | */ | ||
2123 | if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != | ||
2124 | NID_X9_62_prime_field) { | ||
2125 | error("%s: group is not a prime field", __func__); | ||
2126 | goto out; | ||
2127 | } | ||
2128 | |||
2129 | /* Q != infinity */ | ||
2130 | if (EC_POINT_is_at_infinity(group, public)) { | ||
2131 | error("%s: received degenerate public key (infinity)", | ||
2132 | __func__); | ||
2133 | goto out; | ||
2134 | } | ||
2135 | |||
2136 | if ((x = BN_CTX_get(bnctx)) == NULL || | ||
2137 | (y = BN_CTX_get(bnctx)) == NULL || | ||
2138 | (order = BN_CTX_get(bnctx)) == NULL || | ||
2139 | (tmp = BN_CTX_get(bnctx)) == NULL) | ||
2140 | fatal("%s: BN_CTX_get failed", __func__); | ||
2141 | |||
2142 | /* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */ | ||
2143 | if (EC_GROUP_get_order(group, order, bnctx) != 1) | ||
2144 | fatal("%s: EC_GROUP_get_order failed", __func__); | ||
2145 | if (EC_POINT_get_affine_coordinates_GFp(group, public, | ||
2146 | x, y, bnctx) != 1) | ||
2147 | fatal("%s: EC_POINT_get_affine_coordinates_GFp", __func__); | ||
2148 | if (BN_num_bits(x) <= BN_num_bits(order) / 2) { | ||
2149 | error("%s: public key x coordinate too small: " | ||
2150 | "bits(x) = %d, bits(order)/2 = %d", __func__, | ||
2151 | BN_num_bits(x), BN_num_bits(order) / 2); | ||
2152 | goto out; | ||
2153 | } | ||
2154 | if (BN_num_bits(y) <= BN_num_bits(order) / 2) { | ||
2155 | error("%s: public key y coordinate too small: " | ||
2156 | "bits(y) = %d, bits(order)/2 = %d", __func__, | ||
2157 | BN_num_bits(x), BN_num_bits(order) / 2); | ||
2158 | goto out; | ||
2159 | } | ||
2160 | |||
2161 | /* nQ == infinity (n == order of subgroup) */ | ||
2162 | if ((nq = EC_POINT_new(group)) == NULL) | ||
2163 | fatal("%s: BN_CTX_tmp failed", __func__); | ||
2164 | if (EC_POINT_mul(group, nq, NULL, public, order, bnctx) != 1) | ||
2165 | fatal("%s: EC_GROUP_mul failed", __func__); | ||
2166 | if (EC_POINT_is_at_infinity(group, nq) != 1) { | ||
2167 | error("%s: received degenerate public key (nQ != infinity)", | ||
2168 | __func__); | ||
2169 | goto out; | ||
2170 | } | ||
2171 | |||
2172 | /* x < order - 1, y < order - 1 */ | ||
2173 | if (!BN_sub(tmp, order, BN_value_one())) | ||
2174 | fatal("%s: BN_sub failed", __func__); | ||
2175 | if (BN_cmp(x, tmp) >= 0) { | ||
2176 | error("%s: public key x coordinate >= group order - 1", | ||
2177 | __func__); | ||
2178 | goto out; | ||
2179 | } | ||
2180 | if (BN_cmp(y, tmp) >= 0) { | ||
2181 | error("%s: public key y coordinate >= group order - 1", | ||
2182 | __func__); | ||
2183 | goto out; | ||
2184 | } | ||
2185 | ret = 0; | ||
2186 | out: | ||
2187 | BN_CTX_free(bnctx); | ||
2188 | EC_POINT_free(nq); | ||
2189 | return ret; | ||
2190 | } | ||
2191 | |||
2192 | int | ||
2193 | key_ec_validate_private(const EC_KEY *key) | ||
2194 | { | ||
2195 | BN_CTX *bnctx; | ||
2196 | BIGNUM *order, *tmp; | ||
2197 | int ret = -1; | ||
2198 | |||
2199 | if ((bnctx = BN_CTX_new()) == NULL) | ||
2200 | fatal("%s: BN_CTX_new failed", __func__); | ||
2201 | BN_CTX_start(bnctx); | ||
2202 | |||
2203 | if ((order = BN_CTX_get(bnctx)) == NULL || | ||
2204 | (tmp = BN_CTX_get(bnctx)) == NULL) | ||
2205 | fatal("%s: BN_CTX_get failed", __func__); | ||
2206 | |||
2207 | /* log2(private) > log2(order)/2 */ | ||
2208 | if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1) | ||
2209 | fatal("%s: EC_GROUP_get_order failed", __func__); | ||
2210 | if (BN_num_bits(EC_KEY_get0_private_key(key)) <= | ||
2211 | BN_num_bits(order) / 2) { | ||
2212 | error("%s: private key too small: " | ||
2213 | "bits(y) = %d, bits(order)/2 = %d", __func__, | ||
2214 | BN_num_bits(EC_KEY_get0_private_key(key)), | ||
2215 | BN_num_bits(order) / 2); | ||
2216 | goto out; | ||
2217 | } | ||
2218 | |||
2219 | /* private < order - 1 */ | ||
2220 | if (!BN_sub(tmp, order, BN_value_one())) | ||
2221 | fatal("%s: BN_sub failed", __func__); | ||
2222 | if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0) { | ||
2223 | error("%s: private key >= group order - 1", __func__); | ||
2224 | goto out; | ||
2225 | } | ||
2226 | ret = 0; | ||
2227 | out: | ||
2228 | BN_CTX_free(bnctx); | ||
2229 | return ret; | ||
2230 | } | ||
2231 | |||
2232 | #if defined(DEBUG_KEXECDH) || defined(DEBUG_PK) | ||
2233 | void | ||
2234 | key_dump_ec_point(const EC_GROUP *group, const EC_POINT *point) | ||
2235 | { | ||
2236 | BIGNUM *x, *y; | ||
2237 | BN_CTX *bnctx; | ||
2238 | |||
2239 | if (point == NULL) { | ||
2240 | fputs("point=(NULL)\n", stderr); | ||
2241 | return; | ||
2242 | } | ||
2243 | if ((bnctx = BN_CTX_new()) == NULL) | ||
2244 | fatal("%s: BN_CTX_new failed", __func__); | ||
2245 | BN_CTX_start(bnctx); | ||
2246 | if ((x = BN_CTX_get(bnctx)) == NULL || (y = BN_CTX_get(bnctx)) == NULL) | ||
2247 | fatal("%s: BN_CTX_get failed", __func__); | ||
2248 | if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != | ||
2249 | NID_X9_62_prime_field) | ||
2250 | fatal("%s: group is not a prime field", __func__); | ||
2251 | if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y, bnctx) != 1) | ||
2252 | fatal("%s: EC_POINT_get_affine_coordinates_GFp", __func__); | ||
2253 | fputs("x=", stderr); | ||
2254 | BN_print_fp(stderr, x); | ||
2255 | fputs("\ny=", stderr); | ||
2256 | BN_print_fp(stderr, y); | ||
2257 | fputs("\n", stderr); | ||
2258 | BN_CTX_free(bnctx); | ||
2259 | } | ||
2260 | |||
2261 | void | ||
2262 | key_dump_ec_key(const EC_KEY *key) | ||
2263 | { | ||
2264 | const BIGNUM *exponent; | ||
2265 | |||
2266 | key_dump_ec_point(EC_KEY_get0_group(key), EC_KEY_get0_public_key(key)); | ||
2267 | fputs("exponent=", stderr); | ||
2268 | if ((exponent = EC_KEY_get0_private_key(key)) == NULL) | ||
2269 | fputs("(NULL)", stderr); | ||
2270 | else | ||
2271 | BN_print_fp(stderr, EC_KEY_get0_private_key(key)); | ||
2272 | fputs("\n", stderr); | ||
2273 | } | ||
2274 | #endif /* defined(DEBUG_KEXECDH) || defined(DEBUG_PK) */ | ||
2275 | #endif /* OPENSSL_HAS_ECC */ | ||