Net-Dropbear
view release on metacpan or search on metacpan
dropbear/keyimport.c view on Meta::CPAN
buf_putstring(blobbuf, "ssh-rsa", 7);
retkey->type = DROPBEAR_SIGNKEY_RSA;
}
#endif
for (i = 0; i < num_integers; i++) {
ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
&id, &len, &flags);
p += ret;
if (ret < 0 || id != 2 || len < 0 ||
key->keyblob+key->keyblob_len-p < len) {
errmsg = "ASN.1 decoding failure";
goto error;
}
if (i == 0) {
/* First integer is a version indicator */
int expected = -1;
switch (key->type) {
case OSSH_RSA:
case OSSH_DSA:
expected = 0;
break;
case OSSH_EC:
expected = 1;
break;
}
if (len != 1 || p[0] != expected) {
errmsg = "Version number mismatch";
goto error;
}
} else if (key->type == OSSH_RSA) {
/*
* OpenSSH key order is n, e, d, p, q, dmp1, dmq1, iqmp
* but we want e, n, d, p, q
*/
if (i == 1) {
/* Save the details for after we deal with number 2. */
modptr = p;
modlen = len;
} else if (i >= 2 && i <= 5) {
buf_putstring(blobbuf, (const char*)p, len);
if (i == 2) {
buf_putstring(blobbuf, (const char*)modptr, modlen);
}
}
} else if (key->type == OSSH_DSA) {
/*
* OpenSSH key order is p, q, g, y, x,
* we want the same.
*/
buf_putstring(blobbuf, (const char*)p, len);
}
/* Skip past the number. */
p += len;
}
#if DROPBEAR_ECDSA
if (key->type == OSSH_EC) {
unsigned char* private_key_bytes = NULL;
int private_key_len = 0;
unsigned char* public_key_bytes = NULL;
int public_key_len = 0;
ecc_key *ecc = NULL;
const struct dropbear_ecc_curve *curve = NULL;
/* See SEC1 v2, Appendix C.4 */
/* OpenSSL (so OpenSSH) seems to include the optional parts. */
/* privateKey OCTET STRING, */
ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
&id, &len, &flags);
p += ret;
/* id==4 for octet string */
if (ret < 0 || id != 4 || len < 0 ||
key->keyblob+key->keyblob_len-p < len) {
errmsg = "ASN.1 decoding failure";
goto error;
}
private_key_bytes = p;
private_key_len = len;
p += len;
/* parameters [0] ECDomainParameters {{ SECGCurveNames }} OPTIONAL, */
ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
&id, &len, &flags);
p += ret;
/* id==0 */
if (ret < 0 || id != 0 || len < 0) {
errmsg = "ASN.1 decoding failure";
goto error;
}
ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
&id, &len, &flags);
p += ret;
/* id==6 for object */
if (ret < 0 || id != 6 || len < 0 ||
key->keyblob+key->keyblob_len-p < len) {
errmsg = "ASN.1 decoding failure";
goto error;
}
if (0) {}
#if DROPBEAR_ECC_256
else if (len == sizeof(OID_SEC256R1_BLOB)
&& memcmp(p, OID_SEC256R1_BLOB, len) == 0) {
retkey->type = DROPBEAR_SIGNKEY_ECDSA_NISTP256;
curve = &ecc_curve_nistp256;
}
#endif
#if DROPBEAR_ECC_384
else if (len == sizeof(OID_SEC384R1_BLOB)
&& memcmp(p, OID_SEC384R1_BLOB, len) == 0) {
retkey->type = DROPBEAR_SIGNKEY_ECDSA_NISTP384;
curve = &ecc_curve_nistp384;
}
#endif
#if DROPBEAR_ECC_521
else if (len == sizeof(OID_SEC521R1_BLOB)
&& memcmp(p, OID_SEC521R1_BLOB, len) == 0) {
retkey->type = DROPBEAR_SIGNKEY_ECDSA_NISTP521;
curve = &ecc_curve_nistp521;
}
#endif
else {
errmsg = "Unknown ECC key type";
goto error;
}
p += len;
/* publicKey [1] BIT STRING OPTIONAL */
ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
&id, &len, &flags);
p += ret;
/* id==1 */
if (ret < 0 || id != 1 || len < 0) {
errmsg = "ASN.1 decoding failure";
goto error;
}
ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
&id, &len, &flags);
p += ret;
/* id==3 for bit string */
if (ret < 0 || id != 3 || len < 0 ||
key->keyblob+key->keyblob_len-p < len) {
errmsg = "ASN.1 decoding failure";
goto error;
}
public_key_bytes = p+1;
public_key_len = len-1;
p += len;
buf_putbytes(blobbuf, public_key_bytes, public_key_len);
ecc = buf_get_ecc_raw_pubkey(blobbuf, curve);
if (!ecc) {
errmsg = "Error parsing ECC key";
goto error;
}
m_mp_alloc_init_multi((mp_int**)&ecc->k, NULL);
if (mp_from_ubin(ecc->k, private_key_bytes, private_key_len)
!= MP_OKAY) {
errmsg = "Error parsing ECC key";
goto error;
}
*signkey_key_ptr(retkey, retkey->type) = ecc;
}
#endif /* DROPBEAR_ECDSA */
/*
* Now put together the actual key. Simplest way to do this is
* to assemble our own key blobs and feed them to the createkey
* functions; this is a bit faffy but it does mean we get all
* the sanity checks for free.
*/
if (key->type == OSSH_RSA || key->type == OSSH_DSA) {
buf_setpos(blobbuf, 0);
type = DROPBEAR_SIGNKEY_ANY;
if (buf_get_priv_key(blobbuf, retkey, &type)
!= DROPBEAR_SUCCESS) {
errmsg = "unable to create key structure";
sign_key_free(retkey);
retkey = NULL;
goto error;
}
}
errmsg = NULL; /* no error */
retval = retkey;
error:
if (blobbuf) {
buf_burn_free(blobbuf);
}
m_burn(key->keyblob, key->keyblob_size);
m_free(key->keyblob);
m_burn(key, sizeof(*key));
m_free(key);
if (errmsg) {
fprintf(stderr, "Error: %s\n", errmsg);
}
return retval;
}
static int openssh_write(const char *filename, sign_key *key,
const char *passphrase)
{
buffer * keyblob = NULL;
buffer * extrablob = NULL; /* used for calculated values to write */
unsigned char *outblob = NULL;
int outlen = -9999;
struct mpint_pos numbers[9];
int nnumbers = -1, pos = 0, len = 0, seqlen, i;
char *header = NULL, *footer = NULL;
char zero[1];
int ret = 0;
FILE *fp;
#if DROPBEAR_DSS
if (key->type == DROPBEAR_SIGNKEY_DSS) {
( run in 1.357 second using v1.01-cache-2.11-cpan-39bf76dae61 )