pkcs15-tool: added support for reading NIST ssh keys
'pkcs15-tool --read-ssh-key' is now able to read NIST ECC keys from card. Only 256, 384 and 521 field lengths are supported (same as allowed in ssh-keygen -t ecdsa). Issue #803 is partialy fixed by this patch. Openssh PKCS11 interface patches for ECC are now available, please check https://bugzilla.mindrot.org/show_bug.cgi?id=2474
This commit is contained in:
parent
1f352d4c6d
commit
5dcea4440e
|
@ -918,9 +918,9 @@ static void print_ssh_key(FILE *outf, const char * alg, struct sc_pkcs15_object
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj->label[0] != '\0')
|
if (obj->label[0] != '\0')
|
||||||
fprintf(outf,"ssh-%s %s %.*s\n", alg, uu, (int) sizeof obj->label, obj->label);
|
fprintf(outf,"%s %s %.*s\n", alg, uu, (int) sizeof obj->label, obj->label);
|
||||||
else
|
else
|
||||||
fprintf(outf,"ssh-%s %s\n", alg, uu);
|
fprintf(outf,"%s %s\n", alg, uu);
|
||||||
}
|
}
|
||||||
free(uu);
|
free(uu);
|
||||||
return;
|
return;
|
||||||
|
@ -982,6 +982,70 @@ static int read_ssh_key(void)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pubkey->algorithm == SC_ALGORITHM_EC) {
|
||||||
|
// support only for NIST
|
||||||
|
// 'ssh-keygen -t ecdsa' allow only field lengths 256/384/521
|
||||||
|
|
||||||
|
static struct supported_ec_curves {
|
||||||
|
char *curve_name;
|
||||||
|
struct sc_object_id curve_oid;
|
||||||
|
size_t size;
|
||||||
|
} ec_curves[] = {
|
||||||
|
{"secp256r1", {{1, 2, 840, 10045, 3, 1, 7, -1}},256},
|
||||||
|
{"secp384r1", {{1, 3, 132, 0, 34, -1}}, 384},
|
||||||
|
{"secp521r1", {{1, 3, 132, 0, 35, -1}}, 521},
|
||||||
|
{NULL, {{-1}}, 0},
|
||||||
|
};
|
||||||
|
char alg[20];
|
||||||
|
/* Large enough to fit the following:
|
||||||
|
* 3 x 4B item length headers
|
||||||
|
* max 20B algorithm name, 9B curve name, max 256B key data */
|
||||||
|
unsigned char buf[300];
|
||||||
|
unsigned int i, len, tmp, n;
|
||||||
|
|
||||||
|
for (n = 0,i = 0; ec_curves[i].curve_name != NULL; i++) {
|
||||||
|
if(sc_compare_oid (&ec_curves[i].curve_oid,&pubkey->u.ec.params.id))
|
||||||
|
n = ec_curves[i].size;
|
||||||
|
}
|
||||||
|
if (!n) {
|
||||||
|
fprintf(stderr, "Unsupported curve\n");
|
||||||
|
goto fail2;
|
||||||
|
}
|
||||||
|
if (n != pubkey->u.ec.params.field_length) {
|
||||||
|
fprintf(stderr, "Wrong field length\n");
|
||||||
|
goto fail2;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[0] = 0;
|
||||||
|
buf[1] = 0;
|
||||||
|
buf[2] = 0;
|
||||||
|
len = snprintf((char *) buf+4, 20, "ecdsa-sha2-nistp%d", n);
|
||||||
|
strncpy(alg, (char *) buf+4, 20);
|
||||||
|
buf[3] = len;
|
||||||
|
|
||||||
|
len += 4;
|
||||||
|
buf[len++] = 0;
|
||||||
|
buf[len++] = 0;
|
||||||
|
buf[len++] = 0;
|
||||||
|
tmp = snprintf((char *) buf+len+1, 9, "nistp%d", n);
|
||||||
|
buf[len++] = tmp;
|
||||||
|
len += tmp;
|
||||||
|
|
||||||
|
n = pubkey->u.ec.ecpointQ.len;
|
||||||
|
if(n > 255) {
|
||||||
|
fprintf(stderr, "Wrong public key length\n");
|
||||||
|
goto fail2;
|
||||||
|
}
|
||||||
|
buf[len++] = 0;
|
||||||
|
buf[len++] = 0;
|
||||||
|
buf[len++] = 0;
|
||||||
|
buf[len++] = n & 0xff;
|
||||||
|
memcpy(buf+len,pubkey->u.ec.ecpointQ.value,n);
|
||||||
|
len += n;
|
||||||
|
|
||||||
|
print_ssh_key(outf, alg, obj, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
if (pubkey->algorithm == SC_ALGORITHM_RSA) {
|
if (pubkey->algorithm == SC_ALGORITHM_RSA) {
|
||||||
unsigned char buf[2048];
|
unsigned char buf[2048];
|
||||||
uint32_t len, n;
|
uint32_t len, n;
|
||||||
|
@ -1034,7 +1098,7 @@ static int read_ssh_key(void)
|
||||||
memcpy(buf+len,pubkey->u.rsa.modulus.data, pubkey->u.rsa.modulus.len);
|
memcpy(buf+len,pubkey->u.rsa.modulus.data, pubkey->u.rsa.modulus.len);
|
||||||
len += pubkey->u.rsa.modulus.len;
|
len += pubkey->u.rsa.modulus.len;
|
||||||
|
|
||||||
print_ssh_key(outf, "rsa", obj, buf, len);
|
print_ssh_key(outf, "ssh-rsa", obj, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pubkey->algorithm == SC_ALGORITHM_DSA) {
|
if (pubkey->algorithm == SC_ALGORITHM_DSA) {
|
||||||
|
@ -1125,7 +1189,7 @@ static int read_ssh_key(void)
|
||||||
memcpy(buf+len,pubkey->u.dsa.pub.data, pubkey->u.dsa.pub.len);
|
memcpy(buf+len,pubkey->u.dsa.pub.data, pubkey->u.dsa.pub.len);
|
||||||
len += pubkey->u.dsa.pub.len;
|
len += pubkey->u.dsa.pub.len;
|
||||||
|
|
||||||
print_ssh_key(outf, "dss", obj, buf, len);
|
print_ssh_key(outf, "ssh-dss", obj, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outf != stdout)
|
if (outf != stdout)
|
||||||
|
|
Loading…
Reference in New Issue