Mercurial > dropbear
comparison keyimport.c @ 1911:ced53051e200
Add ecdsa OpenSSH format for dropbearconvert
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Tue, 29 Mar 2022 23:27:55 +0800 |
parents | eadd023fde4d |
children | 8b4274d34fe8 |
comparison
equal
deleted
inserted
replaced
1910:54a85bbe5017 | 1911:ced53051e200 |
---|---|
37 #include "ecc.h" | 37 #include "ecc.h" |
38 #include "ssh.h" | 38 #include "ssh.h" |
39 #include "rsa.h" | 39 #include "rsa.h" |
40 #include "dss.h" | 40 #include "dss.h" |
41 #include "ed25519.h" | 41 #include "ed25519.h" |
42 #include "ecdsa.h" | |
42 #include "signkey_ossh.h" | 43 #include "signkey_ossh.h" |
43 | 44 |
44 static const unsigned char OSSH_PKEY_BLOB[] = | 45 static const unsigned char OSSH_PKEY_BLOB[] = |
45 "openssh-key-v1\0" /* AUTH_MAGIC */ | 46 "openssh-key-v1\0" /* AUTH_MAGIC */ |
46 "\0\0\0\4none" /* cipher name*/ | 47 "\0\0\0\4none" /* cipher name*/ |
618 } | 619 } |
619 #endif | 620 #endif |
620 #if DROPBEAR_ED25519 | 621 #if DROPBEAR_ED25519 |
621 if (type == DROPBEAR_SIGNKEY_ED25519) { | 622 if (type == DROPBEAR_SIGNKEY_ED25519) { |
622 if (buf_get_ed25519_priv_ossh(blobbuf, retkey) | 623 if (buf_get_ed25519_priv_ossh(blobbuf, retkey) |
624 == DROPBEAR_SUCCESS) { | |
625 errmsg = NULL; | |
626 retval = retkey; | |
627 goto error; | |
628 } else { | |
629 errmsg = "Error parsing OpenSSH ed25519 key"; | |
630 goto ossh_error; | |
631 } | |
632 } | |
633 #endif | |
634 #if DROPBEAR_ECDSA | |
635 if (signkey_is_ecdsa(type)) { | |
636 if (buf_get_ecdsa_priv_ossh(blobbuf, retkey) | |
623 == DROPBEAR_SUCCESS) { | 637 == DROPBEAR_SUCCESS) { |
624 errmsg = NULL; | 638 errmsg = NULL; |
625 retval = retkey; | 639 retval = retkey; |
626 goto error; | 640 goto error; |
627 } else { | 641 } else { |
909 char *header = NULL, *footer = NULL; | 923 char *header = NULL, *footer = NULL; |
910 char zero[1]; | 924 char zero[1]; |
911 int ret = 0; | 925 int ret = 0; |
912 FILE *fp; | 926 FILE *fp; |
913 | 927 |
914 if ( | |
915 #if DROPBEAR_DSS | 928 #if DROPBEAR_DSS |
916 key->type == DROPBEAR_SIGNKEY_DSS || | 929 if (key->type == DROPBEAR_SIGNKEY_DSS) { |
917 #endif | |
918 0) | |
919 { | |
920 /* | 930 /* |
921 * Fetch the key blobs. | 931 * Fetch the key blobs. |
922 */ | 932 */ |
923 keyblob = buf_new(3000); | 933 keyblob = buf_new(3000); |
924 buf_put_priv_key(keyblob, key, key->type); | 934 buf_put_priv_key(keyblob, key, key->type); |
999 pos += ber_write_id_len(outblob+pos, 2, numbers[i].bytes, 0); | 1009 pos += ber_write_id_len(outblob+pos, 2, numbers[i].bytes, 0); |
1000 memcpy(outblob+pos, numbers[i].start, numbers[i].bytes); | 1010 memcpy(outblob+pos, numbers[i].start, numbers[i].bytes); |
1001 pos += numbers[i].bytes; | 1011 pos += numbers[i].bytes; |
1002 } | 1012 } |
1003 } /* end DSS handling */ | 1013 } /* end DSS handling */ |
1004 | 1014 #endif /* DROPBEAR_DSS */ |
1005 #if DROPBEAR_ECDSA | |
1006 if (key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP256 | |
1007 || key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP384 | |
1008 || key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP521) { | |
1009 | |
1010 /* SEC1 V2 appendix c.4 | |
1011 ECPrivateKey ::= SEQUENCE { | |
1012 version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), | |
1013 privateKey OCTET STRING, | |
1014 parameters [0] ECDomainParameters {{ SECGCurveNames }} OPTIONAL, | |
1015 publicKey [1] BIT STRING OPTIONAL | |
1016 } | |
1017 */ | |
1018 buffer *seq_buf = buf_new(400); | |
1019 ecc_key **eck = (ecc_key**)signkey_key_ptr(key, key->type); | |
1020 const long curve_size = (*eck)->dp->size; | |
1021 int curve_oid_len = 0; | |
1022 const void* curve_oid = NULL; | |
1023 unsigned long pubkey_size = 2*curve_size+1; | |
1024 int k_size; | |
1025 int err = 0; | |
1026 size_t written; | |
1027 | |
1028 /* version. less than 10 bytes */ | |
1029 buf_incrwritepos(seq_buf, | |
1030 ber_write_id_len(buf_getwriteptr(seq_buf, 10), 2, 1, 0)); | |
1031 buf_putbyte(seq_buf, 1); | |
1032 | |
1033 /* privateKey */ | |
1034 k_size = mp_ubin_size((*eck)->k); | |
1035 dropbear_assert(k_size <= curve_size); | |
1036 buf_incrwritepos(seq_buf, | |
1037 ber_write_id_len(buf_getwriteptr(seq_buf, 10), 4, k_size, 0)); | |
1038 if (mp_to_ubin((*eck)->k, buf_getwriteptr(seq_buf, k_size), k_size, &written) != MP_OKAY) { | |
1039 dropbear_exit("ECC error"); | |
1040 } | |
1041 buf_incrwritepos(seq_buf, written); | |
1042 | |
1043 /* SECGCurveNames */ | |
1044 switch (key->type) | |
1045 { | |
1046 case DROPBEAR_SIGNKEY_ECDSA_NISTP256: | |
1047 curve_oid_len = sizeof(OID_SEC256R1_BLOB); | |
1048 curve_oid = OID_SEC256R1_BLOB; | |
1049 break; | |
1050 case DROPBEAR_SIGNKEY_ECDSA_NISTP384: | |
1051 curve_oid_len = sizeof(OID_SEC384R1_BLOB); | |
1052 curve_oid = OID_SEC384R1_BLOB; | |
1053 break; | |
1054 case DROPBEAR_SIGNKEY_ECDSA_NISTP521: | |
1055 curve_oid_len = sizeof(OID_SEC521R1_BLOB); | |
1056 curve_oid = OID_SEC521R1_BLOB; | |
1057 break; | |
1058 default: | |
1059 dropbear_exit("Internal error"); | |
1060 } | |
1061 | |
1062 buf_incrwritepos(seq_buf, | |
1063 ber_write_id_len(buf_getwriteptr(seq_buf, 10), 0, 2+curve_oid_len, 0xa0)); | |
1064 /* object == 6 */ | |
1065 buf_incrwritepos(seq_buf, | |
1066 ber_write_id_len(buf_getwriteptr(seq_buf, 10), 6, curve_oid_len, 0)); | |
1067 buf_putbytes(seq_buf, curve_oid, curve_oid_len); | |
1068 | |
1069 buf_incrwritepos(seq_buf, | |
1070 ber_write_id_len(buf_getwriteptr(seq_buf, 10), 1, | |
1071 (pubkey_size +1 < 128 ? 2 : 3 ) +1 +pubkey_size, 0xa0)); | |
1072 | |
1073 buf_incrwritepos(seq_buf, | |
1074 ber_write_id_len(buf_getwriteptr(seq_buf, 10), 3, 1+pubkey_size, 0)); | |
1075 buf_putbyte(seq_buf, 0); | |
1076 err = ecc_ansi_x963_export(*eck, buf_getwriteptr(seq_buf, pubkey_size), &pubkey_size); | |
1077 if (err != CRYPT_OK) { | |
1078 dropbear_exit("ECC error"); | |
1079 } | |
1080 buf_incrwritepos(seq_buf, pubkey_size); | |
1081 | |
1082 buf_setpos(seq_buf, 0); | |
1083 | |
1084 outblob = (unsigned char*)m_malloc(1000); | |
1085 | |
1086 pos = 0; | |
1087 pos += ber_write_id_len(outblob+pos, 16, seq_buf->len, ASN1_CONSTRUCTED); | |
1088 memcpy(&outblob[pos], seq_buf->data, seq_buf->len); | |
1089 pos += seq_buf->len; | |
1090 len = pos; | |
1091 outlen = len; | |
1092 | |
1093 buf_burn(seq_buf); | |
1094 buf_free(seq_buf); | |
1095 seq_buf = NULL; | |
1096 | |
1097 header = "-----BEGIN EC PRIVATE KEY-----\n"; | |
1098 footer = "-----END EC PRIVATE KEY-----\n"; | |
1099 } | |
1100 #endif | |
1101 | 1015 |
1102 if (0 | 1016 if (0 |
1103 #if DROPBEAR_RSA | 1017 #if DROPBEAR_RSA |
1104 || key->type == DROPBEAR_SIGNKEY_RSA | 1018 || key->type == DROPBEAR_SIGNKEY_RSA |
1105 #endif | 1019 #endif |
1106 #if DROPBEAR_ED25519 | 1020 #if DROPBEAR_ED25519 |
1107 || key->type == DROPBEAR_SIGNKEY_ED25519 | 1021 || key->type == DROPBEAR_SIGNKEY_ED25519 |
1108 #endif | 1022 #endif |
1023 #if DROPBEAR_ECDSA | |
1024 || signkey_is_ecdsa(key->type) | |
1025 #endif | |
1109 ) { | 1026 ) { |
1110 buffer *buf = buf_new(3200); | 1027 buffer *buf = buf_new(3200); |
1111 keyblob = buf_new(3000); | 1028 keyblob = buf_new(3000); |
1112 extrablob = buf_new(3100); | 1029 extrablob = buf_new(3100); |
1113 | 1030 |
1118 } | 1035 } |
1119 #endif | 1036 #endif |
1120 #if DROPBEAR_ED25519 | 1037 #if DROPBEAR_ED25519 |
1121 if (key->type == DROPBEAR_SIGNKEY_ED25519) { | 1038 if (key->type == DROPBEAR_SIGNKEY_ED25519) { |
1122 buf_put_ed25519_priv_ossh(keyblob, key); | 1039 buf_put_ed25519_priv_ossh(keyblob, key); |
1040 } | |
1041 #endif | |
1042 #if DROPBEAR_ECDSA | |
1043 if (signkey_is_ecdsa(key->type)) { | |
1044 buf_put_ecdsa_priv_ossh(keyblob, key); | |
1123 } | 1045 } |
1124 #endif | 1046 #endif |
1125 | 1047 |
1126 /* header */ | 1048 /* header */ |
1127 buf_putbytes(buf, OSSH_PKEY_BLOB, OSSH_PKEY_BLOBLEN); | 1049 buf_putbytes(buf, OSSH_PKEY_BLOB, OSSH_PKEY_BLOBLEN); |