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