Mercurial > dropbear
comparison keyimport.c @ 836:d7d9f1612d51 ecc
writing out openssh ecc keys works
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sun, 20 Oct 2013 21:06:18 +0800 |
parents | 75509065db53 |
children | 774ad9b112ef |
comparison
equal
deleted
inserted
replaced
807:75509065db53 | 836:d7d9f1612d51 |
---|---|
1 /* | 1 /* |
2 * Based on PuTTY's import.c for importing/exporting OpenSSH and SSH.com | 2 * Based on PuTTY's import.c for importing/exporting OpenSSH and SSH.com |
3 * keyfiles. | 3 * keyfiles. |
4 * | |
5 * The horribleness of the code is probably mine (matt). | |
6 * | 4 * |
7 * Modifications copyright 2003 Matt Johnston | 5 * Modifications copyright 2003 Matt Johnston |
8 * | 6 * |
9 * PuTTY is copyright 1997-2003 Simon Tatham. | 7 * PuTTY is copyright 1997-2003 Simon Tatham. |
10 * | 8 * |
36 #include "bignum.h" | 34 #include "bignum.h" |
37 #include "buffer.h" | 35 #include "buffer.h" |
38 #include "dbutil.h" | 36 #include "dbutil.h" |
39 #include "ecc.h" | 37 #include "ecc.h" |
40 | 38 |
41 const unsigned char OID_SEC256R1_BLOB[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07}; | 39 static const unsigned char OID_SEC256R1_BLOB[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07}; |
42 const unsigned char OID_SEC384R1_BLOB[] = {0x2b, 0x81, 0x04, 0x00, 0x22}; | 40 static const unsigned char OID_SEC384R1_BLOB[] = {0x2b, 0x81, 0x04, 0x00, 0x22}; |
43 const unsigned char OID_SEC521R1_BLOB[] = {0x2b, 0x81, 0x04, 0x00, 0x23}; | 41 static const unsigned char OID_SEC521R1_BLOB[] = {0x2b, 0x81, 0x04, 0x00, 0x23}; |
44 | 42 |
45 #define PUT_32BIT(cp, value) do { \ | 43 #define PUT_32BIT(cp, value) do { \ |
46 (cp)[3] = (unsigned char)(value); \ | 44 (cp)[3] = (unsigned char)(value); \ |
47 (cp)[2] = (unsigned char)((value) >> 8); \ | 45 (cp)[2] = (unsigned char)((value) >> 8); \ |
48 (cp)[1] = (unsigned char)((value) >> 16); \ | 46 (cp)[1] = (unsigned char)((value) >> 16); \ |
128 if (buf_get_priv_key(buf, ret, &type) == DROPBEAR_FAILURE){ | 126 if (buf_get_priv_key(buf, ret, &type) == DROPBEAR_FAILURE){ |
129 goto error; | 127 goto error; |
130 } | 128 } |
131 buf_free(buf); | 129 buf_free(buf); |
132 | 130 |
131 ret->type = type; | |
132 | |
133 return ret; | 133 return ret; |
134 | 134 |
135 error: | 135 error: |
136 if (buf) { | 136 if (buf) { |
137 buf_free(buf); | 137 buf_free(buf); |
143 } | 143 } |
144 | 144 |
145 /* returns 0 on fail, 1 on success */ | 145 /* returns 0 on fail, 1 on success */ |
146 static int dropbear_write(const char*filename, sign_key * key) { | 146 static int dropbear_write(const char*filename, sign_key * key) { |
147 | 147 |
148 int keytype = -1; | |
149 buffer * buf; | 148 buffer * buf; |
150 FILE*fp; | 149 FILE*fp; |
151 int len; | 150 int len; |
152 int ret; | 151 int ret; |
153 | |
154 #ifdef DROPBEAR_RSA | |
155 if (key->rsakey != NULL) { | |
156 keytype = DROPBEAR_SIGNKEY_RSA; | |
157 } | |
158 #endif | |
159 #ifdef DROPBEAR_DSS | |
160 if (key->dsskey != NULL) { | |
161 keytype = DROPBEAR_SIGNKEY_DSS; | |
162 } | |
163 #endif | |
164 | 152 |
165 buf = buf_new(MAX_PRIVKEY_SIZE); | 153 buf = buf_new(MAX_PRIVKEY_SIZE); |
166 buf_put_priv_key(buf, key, key->type); | 154 buf_put_priv_key(buf, key, key->type); |
167 | 155 |
168 fp = fopen(filename, "w"); | 156 fp = fopen(filename, "w"); |
614 */ | 602 */ |
615 blobbuf = buf_new(3000); | 603 blobbuf = buf_new(3000); |
616 | 604 |
617 if (key->type == OSSH_DSA) { | 605 if (key->type == OSSH_DSA) { |
618 buf_putstring(blobbuf, "ssh-dss", 7); | 606 buf_putstring(blobbuf, "ssh-dss", 7); |
607 retkey->type = DROPBEAR_SIGNKEY_DSS; | |
619 } else if (key->type == OSSH_RSA) { | 608 } else if (key->type == OSSH_RSA) { |
620 buf_putstring(blobbuf, "ssh-rsa", 7); | 609 buf_putstring(blobbuf, "ssh-rsa", 7); |
610 retkey->type = DROPBEAR_SIGNKEY_RSA; | |
621 } | 611 } |
622 | 612 |
623 for (i = 0; i < num_integers; i++) { | 613 for (i = 0; i < num_integers; i++) { |
624 ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, | 614 ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p, |
625 &id, &len, &flags); | 615 &id, &len, &flags); |
673 p += len; | 663 p += len; |
674 } | 664 } |
675 | 665 |
676 #ifdef DROPBEAR_ECDSA | 666 #ifdef DROPBEAR_ECDSA |
677 if (key->type == OSSH_EC) { | 667 if (key->type == OSSH_EC) { |
678 const char* ecdsa_name; | |
679 unsigned char* private_key_bytes = NULL; | 668 unsigned char* private_key_bytes = NULL; |
680 int private_key_len = 0; | 669 int private_key_len = 0; |
681 unsigned char* public_key_bytes = NULL; | 670 unsigned char* public_key_bytes = NULL; |
682 int public_key_len = 0; | 671 int public_key_len = 0; |
683 ecc_key *ecc = NULL; | 672 ecc_key *ecc = NULL; |
825 int nnumbers = -1, pos, len, seqlen, i; | 814 int nnumbers = -1, pos, len, seqlen, i; |
826 char *header = NULL, *footer = NULL; | 815 char *header = NULL, *footer = NULL; |
827 char zero[1]; | 816 char zero[1]; |
828 int ret = 0; | 817 int ret = 0; |
829 FILE *fp; | 818 FILE *fp; |
830 int keytype = -1; | |
831 | 819 |
832 #ifdef DROPBEAR_RSA | 820 #ifdef DROPBEAR_RSA |
833 mp_int dmp1, dmq1, iqmp, tmpval; /* for rsa */ | 821 mp_int dmp1, dmq1, iqmp, tmpval; /* for rsa */ |
834 | |
835 if (key->rsakey != NULL) { | |
836 keytype = DROPBEAR_SIGNKEY_RSA; | |
837 } | |
838 #endif | 822 #endif |
839 #ifdef DROPBEAR_DSS | 823 |
840 if (key->dsskey != NULL) { | 824 if (key->type == DROPBEAR_SIGNKEY_RSA || key->type == DROPBEAR_SIGNKEY_DSS) |
841 keytype = DROPBEAR_SIGNKEY_DSS; | 825 { |
826 /* | |
827 * Fetch the key blobs. | |
828 */ | |
829 keyblob = buf_new(3000); | |
830 buf_put_priv_key(keyblob, key, key->type); | |
831 | |
832 buf_setpos(keyblob, 0); | |
833 /* skip the "ssh-rsa" or "ssh-dss" header */ | |
834 buf_incrpos(keyblob, buf_getint(keyblob)); | |
835 | |
836 /* | |
837 * Find the sequence of integers to be encoded into the OpenSSH | |
838 * key blob, and also decide on the header line. | |
839 */ | |
840 numbers[0].start = zero; numbers[0].bytes = 1; zero[0] = '\0'; | |
841 | |
842 #ifdef DROPBEAR_RSA | |
843 if (key->type == DROPBEAR_SIGNKEY_RSA) { | |
844 | |
845 if (key->rsakey->p == NULL || key->rsakey->q == NULL) { | |
846 fprintf(stderr, "Pre-0.33 Dropbear keys cannot be converted to OpenSSH keys.\n"); | |
847 goto error; | |
848 } | |
849 | |
850 /* e */ | |
851 numbers[2].bytes = buf_getint(keyblob); | |
852 numbers[2].start = buf_getptr(keyblob, numbers[2].bytes); | |
853 buf_incrpos(keyblob, numbers[2].bytes); | |
854 | |
855 /* n */ | |
856 numbers[1].bytes = buf_getint(keyblob); | |
857 numbers[1].start = buf_getptr(keyblob, numbers[1].bytes); | |
858 buf_incrpos(keyblob, numbers[1].bytes); | |
859 | |
860 /* d */ | |
861 numbers[3].bytes = buf_getint(keyblob); | |
862 numbers[3].start = buf_getptr(keyblob, numbers[3].bytes); | |
863 buf_incrpos(keyblob, numbers[3].bytes); | |
864 | |
865 /* p */ | |
866 numbers[4].bytes = buf_getint(keyblob); | |
867 numbers[4].start = buf_getptr(keyblob, numbers[4].bytes); | |
868 buf_incrpos(keyblob, numbers[4].bytes); | |
869 | |
870 /* q */ | |
871 numbers[5].bytes = buf_getint(keyblob); | |
872 numbers[5].start = buf_getptr(keyblob, numbers[5].bytes); | |
873 buf_incrpos(keyblob, numbers[5].bytes); | |
874 | |
875 /* now calculate some extra parameters: */ | |
876 m_mp_init(&tmpval); | |
877 m_mp_init(&dmp1); | |
878 m_mp_init(&dmq1); | |
879 m_mp_init(&iqmp); | |
880 | |
881 /* dmp1 = d mod (p-1) */ | |
882 if (mp_sub_d(key->rsakey->p, 1, &tmpval) != MP_OKAY) { | |
883 fprintf(stderr, "Bignum error for p-1\n"); | |
884 goto error; | |
885 } | |
886 if (mp_mod(key->rsakey->d, &tmpval, &dmp1) != MP_OKAY) { | |
887 fprintf(stderr, "Bignum error for dmp1\n"); | |
888 goto error; | |
889 } | |
890 | |
891 /* dmq1 = d mod (q-1) */ | |
892 if (mp_sub_d(key->rsakey->q, 1, &tmpval) != MP_OKAY) { | |
893 fprintf(stderr, "Bignum error for q-1\n"); | |
894 goto error; | |
895 } | |
896 if (mp_mod(key->rsakey->d, &tmpval, &dmq1) != MP_OKAY) { | |
897 fprintf(stderr, "Bignum error for dmq1\n"); | |
898 goto error; | |
899 } | |
900 | |
901 /* iqmp = (q^-1) mod p */ | |
902 if (mp_invmod(key->rsakey->q, key->rsakey->p, &iqmp) != MP_OKAY) { | |
903 fprintf(stderr, "Bignum error for iqmp\n"); | |
904 goto error; | |
905 } | |
906 | |
907 extrablob = buf_new(2000); | |
908 buf_putmpint(extrablob, &dmp1); | |
909 buf_putmpint(extrablob, &dmq1); | |
910 buf_putmpint(extrablob, &iqmp); | |
911 buf_setpos(extrablob, 0); | |
912 mp_clear(&dmp1); | |
913 mp_clear(&dmq1); | |
914 mp_clear(&iqmp); | |
915 mp_clear(&tmpval); | |
916 | |
917 /* dmp1 */ | |
918 numbers[6].bytes = buf_getint(extrablob); | |
919 numbers[6].start = buf_getptr(extrablob, numbers[6].bytes); | |
920 buf_incrpos(extrablob, numbers[6].bytes); | |
921 | |
922 /* dmq1 */ | |
923 numbers[7].bytes = buf_getint(extrablob); | |
924 numbers[7].start = buf_getptr(extrablob, numbers[7].bytes); | |
925 buf_incrpos(extrablob, numbers[7].bytes); | |
926 | |
927 /* iqmp */ | |
928 numbers[8].bytes = buf_getint(extrablob); | |
929 numbers[8].start = buf_getptr(extrablob, numbers[8].bytes); | |
930 buf_incrpos(extrablob, numbers[8].bytes); | |
931 | |
932 nnumbers = 9; | |
933 header = "-----BEGIN RSA PRIVATE KEY-----\n"; | |
934 footer = "-----END RSA PRIVATE KEY-----\n"; | |
935 } | |
936 #endif /* DROPBEAR_RSA */ | |
937 | |
938 #ifdef DROPBEAR_DSS | |
939 if (key->type == DROPBEAR_SIGNKEY_DSS) { | |
940 | |
941 /* p */ | |
942 numbers[1].bytes = buf_getint(keyblob); | |
943 numbers[1].start = buf_getptr(keyblob, numbers[1].bytes); | |
944 buf_incrpos(keyblob, numbers[1].bytes); | |
945 | |
946 /* q */ | |
947 numbers[2].bytes = buf_getint(keyblob); | |
948 numbers[2].start = buf_getptr(keyblob, numbers[2].bytes); | |
949 buf_incrpos(keyblob, numbers[2].bytes); | |
950 | |
951 /* g */ | |
952 numbers[3].bytes = buf_getint(keyblob); | |
953 numbers[3].start = buf_getptr(keyblob, numbers[3].bytes); | |
954 buf_incrpos(keyblob, numbers[3].bytes); | |
955 | |
956 /* y */ | |
957 numbers[4].bytes = buf_getint(keyblob); | |
958 numbers[4].start = buf_getptr(keyblob, numbers[4].bytes); | |
959 buf_incrpos(keyblob, numbers[4].bytes); | |
960 | |
961 /* x */ | |
962 numbers[5].bytes = buf_getint(keyblob); | |
963 numbers[5].start = buf_getptr(keyblob, numbers[5].bytes); | |
964 buf_incrpos(keyblob, numbers[5].bytes); | |
965 | |
966 nnumbers = 6; | |
967 header = "-----BEGIN DSA PRIVATE KEY-----\n"; | |
968 footer = "-----END DSA PRIVATE KEY-----\n"; | |
969 } | |
970 #endif /* DROPBEAR_DSS */ | |
971 | |
972 /* | |
973 * Now count up the total size of the ASN.1 encoded integers, | |
974 * so as to determine the length of the containing SEQUENCE. | |
975 */ | |
976 len = 0; | |
977 for (i = 0; i < nnumbers; i++) { | |
978 len += ber_write_id_len(NULL, 2, numbers[i].bytes, 0); | |
979 len += numbers[i].bytes; | |
980 } | |
981 seqlen = len; | |
982 /* Now add on the SEQUENCE header. */ | |
983 len += ber_write_id_len(NULL, 16, seqlen, ASN1_CONSTRUCTED); | |
984 /* Round up to the cipher block size, ensuring we have at least one | |
985 * byte of padding (see below). */ | |
986 outlen = len; | |
987 if (passphrase) | |
988 outlen = (outlen+8) &~ 7; | |
989 | |
990 /* | |
991 * Now we know how big outblob needs to be. Allocate it. | |
992 */ | |
993 outblob = (unsigned char*)m_malloc(outlen); | |
994 | |
995 /* | |
996 * And write the data into it. | |
997 */ | |
998 pos = 0; | |
999 pos += ber_write_id_len(outblob+pos, 16, seqlen, ASN1_CONSTRUCTED); | |
1000 for (i = 0; i < nnumbers; i++) { | |
1001 pos += ber_write_id_len(outblob+pos, 2, numbers[i].bytes, 0); | |
1002 memcpy(outblob+pos, numbers[i].start, numbers[i].bytes); | |
1003 pos += numbers[i].bytes; | |
1004 } | |
1005 } // end RSA and DSS handling | |
1006 | |
1007 #ifdef DROPBEAR_ECDSA | |
1008 if (key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP256 | |
1009 || key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP384 | |
1010 || key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP521) { | |
1011 | |
1012 /* SEC1 V2 appendix c.4 | |
1013 ECPrivateKey ::= SEQUENCE { | |
1014 version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), | |
1015 privateKey OCTET STRING, | |
1016 parameters [0] ECDomainParameters {{ SECGCurveNames }} OPTIONAL, | |
1017 publicKey [1] BIT STRING OPTIONAL | |
1018 } | |
1019 */ | |
1020 buffer *seq_buf = buf_new(400); | |
1021 ecc_key **eck = signkey_ecc_key_ptr(key, key->type); | |
1022 const unsigned long curve_size = (*eck)->dp->size; | |
1023 int curve_oid_len = 0; | |
1024 const void* curve_oid = NULL; | |
1025 unsigned long pubkey_size = 2*curve_size+1; | |
1026 | |
1027 /* version. less than 10 bytes */ | |
1028 buf_incrwritepos(seq_buf, | |
1029 ber_write_id_len(buf_getwriteptr(seq_buf, 10), 2, 1, 0)); | |
1030 buf_putbyte(seq_buf, 1); | |
1031 | |
1032 /* privateKey */ | |
1033 dropbear_assert(mp_unsigned_bin_size((*eck)->k) == curve_size); | |
1034 buf_incrwritepos(seq_buf, | |
1035 ber_write_id_len(buf_getwriteptr(seq_buf, 10), 4, curve_size, 0)); | |
1036 mp_to_unsigned_bin((*eck)->k, buf_getwriteptr(seq_buf, curve_size)); | |
1037 buf_incrwritepos(seq_buf, curve_size); | |
1038 | |
1039 /* SECGCurveNames */ | |
1040 switch (key->type) | |
1041 { | |
1042 case DROPBEAR_SIGNKEY_ECDSA_NISTP256: | |
1043 curve_oid_len = sizeof(OID_SEC256R1_BLOB); | |
1044 curve_oid = OID_SEC256R1_BLOB; | |
1045 break; | |
1046 case DROPBEAR_SIGNKEY_ECDSA_NISTP384: | |
1047 curve_oid_len = sizeof(OID_SEC384R1_BLOB); | |
1048 curve_oid = OID_SEC384R1_BLOB; | |
1049 break; | |
1050 case DROPBEAR_SIGNKEY_ECDSA_NISTP521: | |
1051 curve_oid_len = sizeof(OID_SEC521R1_BLOB); | |
1052 curve_oid = OID_SEC521R1_BLOB; | |
1053 break; | |
1054 default: | |
1055 dropbear_exit("Internal error"); | |
1056 } | |
1057 | |
1058 buf_incrwritepos(seq_buf, | |
1059 ber_write_id_len(buf_getwriteptr(seq_buf, 10), 0, 2+curve_oid_len, 0xa0)); | |
1060 // object == 6 | |
1061 buf_incrwritepos(seq_buf, | |
1062 ber_write_id_len(buf_getwriteptr(seq_buf, 10), 6, curve_oid_len, 0)); | |
1063 buf_putbytes(seq_buf, curve_oid, curve_oid_len); | |
1064 | |
1065 buf_incrwritepos(seq_buf, | |
1066 ber_write_id_len(buf_getwriteptr(seq_buf, 10), 1, 2+1+pubkey_size, 0xa0)); | |
1067 buf_incrwritepos(seq_buf, | |
1068 ber_write_id_len(buf_getwriteptr(seq_buf, 10), 3, 1+pubkey_size, 0)); | |
1069 buf_putbyte(seq_buf, 0); | |
1070 int err = ecc_ansi_x963_export(*eck, buf_getwriteptr(seq_buf, pubkey_size), &pubkey_size); | |
1071 if (err != CRYPT_OK) { | |
1072 dropbear_exit("ECC error"); | |
1073 } | |
1074 buf_incrwritepos(seq_buf, pubkey_size); | |
1075 | |
1076 buf_setpos(seq_buf, 0); | |
1077 | |
1078 outblob = (unsigned char*)m_malloc(200); | |
1079 | |
1080 pos = 0; | |
1081 pos += ber_write_id_len(outblob+pos, 16, seq_buf->len, ASN1_CONSTRUCTED); | |
1082 memcpy(&outblob[pos], seq_buf->data, seq_buf->len); | |
1083 pos += seq_buf->len; | |
1084 len = pos; | |
1085 outlen = len; | |
1086 | |
1087 buf_burn(seq_buf); | |
1088 buf_free(seq_buf); | |
1089 seq_buf = NULL; | |
1090 | |
1091 header = "-----BEGIN EC PRIVATE KEY-----\n"; | |
1092 footer = "-----END EC PRIVATE KEY-----\n"; | |
842 } | 1093 } |
843 #endif | 1094 #endif |
844 | |
845 dropbear_assert(keytype != -1); | |
846 | |
847 /* | |
848 * Fetch the key blobs. | |
849 */ | |
850 keyblob = buf_new(3000); | |
851 buf_put_priv_key(keyblob, key, keytype); | |
852 | |
853 buf_setpos(keyblob, 0); | |
854 /* skip the "ssh-rsa" or "ssh-dss" header */ | |
855 buf_incrpos(keyblob, buf_getint(keyblob)); | |
856 | |
857 /* | |
858 * Find the sequence of integers to be encoded into the OpenSSH | |
859 * key blob, and also decide on the header line. | |
860 */ | |
861 numbers[0].start = zero; numbers[0].bytes = 1; zero[0] = '\0'; | |
862 | |
863 #ifdef DROPBEAR_RSA | |
864 if (keytype == DROPBEAR_SIGNKEY_RSA) { | |
865 | |
866 if (key->rsakey->p == NULL || key->rsakey->q == NULL) { | |
867 fprintf(stderr, "Pre-0.33 Dropbear keys cannot be converted to OpenSSH keys.\n"); | |
868 goto error; | |
869 } | |
870 | |
871 /* e */ | |
872 numbers[2].bytes = buf_getint(keyblob); | |
873 numbers[2].start = buf_getptr(keyblob, numbers[2].bytes); | |
874 buf_incrpos(keyblob, numbers[2].bytes); | |
875 | |
876 /* n */ | |
877 numbers[1].bytes = buf_getint(keyblob); | |
878 numbers[1].start = buf_getptr(keyblob, numbers[1].bytes); | |
879 buf_incrpos(keyblob, numbers[1].bytes); | |
880 | |
881 /* d */ | |
882 numbers[3].bytes = buf_getint(keyblob); | |
883 numbers[3].start = buf_getptr(keyblob, numbers[3].bytes); | |
884 buf_incrpos(keyblob, numbers[3].bytes); | |
885 | |
886 /* p */ | |
887 numbers[4].bytes = buf_getint(keyblob); | |
888 numbers[4].start = buf_getptr(keyblob, numbers[4].bytes); | |
889 buf_incrpos(keyblob, numbers[4].bytes); | |
890 | |
891 /* q */ | |
892 numbers[5].bytes = buf_getint(keyblob); | |
893 numbers[5].start = buf_getptr(keyblob, numbers[5].bytes); | |
894 buf_incrpos(keyblob, numbers[5].bytes); | |
895 | |
896 /* now calculate some extra parameters: */ | |
897 m_mp_init(&tmpval); | |
898 m_mp_init(&dmp1); | |
899 m_mp_init(&dmq1); | |
900 m_mp_init(&iqmp); | |
901 | |
902 /* dmp1 = d mod (p-1) */ | |
903 if (mp_sub_d(key->rsakey->p, 1, &tmpval) != MP_OKAY) { | |
904 fprintf(stderr, "Bignum error for p-1\n"); | |
905 goto error; | |
906 } | |
907 if (mp_mod(key->rsakey->d, &tmpval, &dmp1) != MP_OKAY) { | |
908 fprintf(stderr, "Bignum error for dmp1\n"); | |
909 goto error; | |
910 } | |
911 | |
912 /* dmq1 = d mod (q-1) */ | |
913 if (mp_sub_d(key->rsakey->q, 1, &tmpval) != MP_OKAY) { | |
914 fprintf(stderr, "Bignum error for q-1\n"); | |
915 goto error; | |
916 } | |
917 if (mp_mod(key->rsakey->d, &tmpval, &dmq1) != MP_OKAY) { | |
918 fprintf(stderr, "Bignum error for dmq1\n"); | |
919 goto error; | |
920 } | |
921 | |
922 /* iqmp = (q^-1) mod p */ | |
923 if (mp_invmod(key->rsakey->q, key->rsakey->p, &iqmp) != MP_OKAY) { | |
924 fprintf(stderr, "Bignum error for iqmp\n"); | |
925 goto error; | |
926 } | |
927 | |
928 extrablob = buf_new(2000); | |
929 buf_putmpint(extrablob, &dmp1); | |
930 buf_putmpint(extrablob, &dmq1); | |
931 buf_putmpint(extrablob, &iqmp); | |
932 buf_setpos(extrablob, 0); | |
933 mp_clear(&dmp1); | |
934 mp_clear(&dmq1); | |
935 mp_clear(&iqmp); | |
936 mp_clear(&tmpval); | |
937 | |
938 /* dmp1 */ | |
939 numbers[6].bytes = buf_getint(extrablob); | |
940 numbers[6].start = buf_getptr(extrablob, numbers[6].bytes); | |
941 buf_incrpos(extrablob, numbers[6].bytes); | |
942 | |
943 /* dmq1 */ | |
944 numbers[7].bytes = buf_getint(extrablob); | |
945 numbers[7].start = buf_getptr(extrablob, numbers[7].bytes); | |
946 buf_incrpos(extrablob, numbers[7].bytes); | |
947 | |
948 /* iqmp */ | |
949 numbers[8].bytes = buf_getint(extrablob); | |
950 numbers[8].start = buf_getptr(extrablob, numbers[8].bytes); | |
951 buf_incrpos(extrablob, numbers[8].bytes); | |
952 | |
953 nnumbers = 9; | |
954 header = "-----BEGIN RSA PRIVATE KEY-----\n"; | |
955 footer = "-----END RSA PRIVATE KEY-----\n"; | |
956 } | |
957 #endif /* DROPBEAR_RSA */ | |
958 | |
959 #ifdef DROPBEAR_DSS | |
960 if (keytype == DROPBEAR_SIGNKEY_DSS) { | |
961 | |
962 /* p */ | |
963 numbers[1].bytes = buf_getint(keyblob); | |
964 numbers[1].start = buf_getptr(keyblob, numbers[1].bytes); | |
965 buf_incrpos(keyblob, numbers[1].bytes); | |
966 | |
967 /* q */ | |
968 numbers[2].bytes = buf_getint(keyblob); | |
969 numbers[2].start = buf_getptr(keyblob, numbers[2].bytes); | |
970 buf_incrpos(keyblob, numbers[2].bytes); | |
971 | |
972 /* g */ | |
973 numbers[3].bytes = buf_getint(keyblob); | |
974 numbers[3].start = buf_getptr(keyblob, numbers[3].bytes); | |
975 buf_incrpos(keyblob, numbers[3].bytes); | |
976 | |
977 /* y */ | |
978 numbers[4].bytes = buf_getint(keyblob); | |
979 numbers[4].start = buf_getptr(keyblob, numbers[4].bytes); | |
980 buf_incrpos(keyblob, numbers[4].bytes); | |
981 | |
982 /* x */ | |
983 numbers[5].bytes = buf_getint(keyblob); | |
984 numbers[5].start = buf_getptr(keyblob, numbers[5].bytes); | |
985 buf_incrpos(keyblob, numbers[5].bytes); | |
986 | |
987 nnumbers = 6; | |
988 header = "-----BEGIN DSA PRIVATE KEY-----\n"; | |
989 footer = "-----END DSA PRIVATE KEY-----\n"; | |
990 } | |
991 #endif /* DROPBEAR_DSS */ | |
992 | |
993 /* | |
994 * Now count up the total size of the ASN.1 encoded integers, | |
995 * so as to determine the length of the containing SEQUENCE. | |
996 */ | |
997 len = 0; | |
998 for (i = 0; i < nnumbers; i++) { | |
999 len += ber_write_id_len(NULL, 2, numbers[i].bytes, 0); | |
1000 len += numbers[i].bytes; | |
1001 } | |
1002 seqlen = len; | |
1003 /* Now add on the SEQUENCE header. */ | |
1004 len += ber_write_id_len(NULL, 16, seqlen, ASN1_CONSTRUCTED); | |
1005 /* Round up to the cipher block size, ensuring we have at least one | |
1006 * byte of padding (see below). */ | |
1007 outlen = len; | |
1008 if (passphrase) | |
1009 outlen = (outlen+8) &~ 7; | |
1010 | |
1011 /* | |
1012 * Now we know how big outblob needs to be. Allocate it. | |
1013 */ | |
1014 outblob = (unsigned char*)m_malloc(outlen); | |
1015 | |
1016 /* | |
1017 * And write the data into it. | |
1018 */ | |
1019 pos = 0; | |
1020 pos += ber_write_id_len(outblob+pos, 16, seqlen, ASN1_CONSTRUCTED); | |
1021 for (i = 0; i < nnumbers; i++) { | |
1022 pos += ber_write_id_len(outblob+pos, 2, numbers[i].bytes, 0); | |
1023 memcpy(outblob+pos, numbers[i].start, numbers[i].bytes); | |
1024 pos += numbers[i].bytes; | |
1025 } | |
1026 | 1095 |
1027 /* | 1096 /* |
1028 * Padding on OpenSSH keys is deterministic. The number of | 1097 * Padding on OpenSSH keys is deterministic. The number of |
1029 * padding bytes is always more than zero, and always at most | 1098 * padding bytes is always more than zero, and always at most |
1030 * the cipher block length. The value of each padding byte is | 1099 * the cipher block length. The value of each padding byte is |