version 1.89, 2019/11/12 19:31:18 |
version 1.90, 2019/11/12 19:33:08 |
|
|
{ "ssh-ed25519", "ED25519", NULL, KEY_ED25519, 0, 0, 0 }, |
{ "ssh-ed25519", "ED25519", NULL, KEY_ED25519, 0, 0, 0 }, |
{ "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", NULL, |
{ "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", NULL, |
KEY_ED25519_CERT, 0, 1, 0 }, |
KEY_ED25519_CERT, 0, 1, 0 }, |
|
{ "sk-ssh-ed25519@openssh.com", "ED25519-SK", NULL, |
|
KEY_ED25519_SK, 0, 0, 0 }, |
|
{ "sk-ssh-ed25519-cert-v01@openssh.com", "ED25519-SK-CERT", NULL, |
|
KEY_ED25519_SK_CERT, 0, 1, 0 }, |
#ifdef WITH_XMSS |
#ifdef WITH_XMSS |
{ "ssh-xmss@openssh.com", "XMSS", NULL, KEY_XMSS, 0, 0, 0 }, |
{ "ssh-xmss@openssh.com", "XMSS", NULL, KEY_XMSS, 0, 0, 0 }, |
{ "ssh-xmss-cert-v01@openssh.com", "XMSS-CERT", NULL, |
{ "ssh-xmss-cert-v01@openssh.com", "XMSS-CERT", NULL, |
|
|
#endif /* WITH_OPENSSL */ |
#endif /* WITH_OPENSSL */ |
case KEY_ED25519: |
case KEY_ED25519: |
case KEY_ED25519_CERT: |
case KEY_ED25519_CERT: |
|
case KEY_ED25519_SK: |
|
case KEY_ED25519_SK_CERT: |
case KEY_XMSS: |
case KEY_XMSS: |
case KEY_XMSS_CERT: |
case KEY_XMSS_CERT: |
return 256; /* XXX */ |
return 256; /* XXX */ |
|
|
case KEY_ECDSA: |
case KEY_ECDSA: |
case KEY_ECDSA_SK: |
case KEY_ECDSA_SK: |
case KEY_ED25519: |
case KEY_ED25519: |
|
case KEY_ED25519_SK: |
case KEY_XMSS: |
case KEY_XMSS: |
return 1; |
return 1; |
default: |
default: |
|
|
return sshkey_type_is_cert(k->type); |
return sshkey_type_is_cert(k->type); |
} |
} |
|
|
|
int |
|
sshkey_is_sk(const struct sshkey *k) |
|
{ |
|
if (k == NULL) |
|
return 0; |
|
switch (sshkey_type_plain(k->type)) { |
|
case KEY_ECDSA_SK: |
|
case KEY_ED25519_SK: |
|
return 1; |
|
default: |
|
return 0; |
|
} |
|
} |
|
|
/* Return the cert-less equivalent to a certified key type */ |
/* Return the cert-less equivalent to a certified key type */ |
int |
int |
sshkey_type_plain(int type) |
sshkey_type_plain(int type) |
|
|
return KEY_ECDSA_SK; |
return KEY_ECDSA_SK; |
case KEY_ED25519_CERT: |
case KEY_ED25519_CERT: |
return KEY_ED25519; |
return KEY_ED25519; |
|
case KEY_ED25519_SK_CERT: |
|
return KEY_ED25519_SK; |
case KEY_XMSS_CERT: |
case KEY_XMSS_CERT: |
return KEY_XMSS; |
return KEY_XMSS; |
default: |
default: |
|
|
#endif /* WITH_OPENSSL */ |
#endif /* WITH_OPENSSL */ |
case KEY_ED25519: |
case KEY_ED25519: |
case KEY_ED25519_CERT: |
case KEY_ED25519_CERT: |
|
case KEY_ED25519_SK: |
|
case KEY_ED25519_SK_CERT: |
case KEY_XMSS: |
case KEY_XMSS: |
case KEY_XMSS_CERT: |
case KEY_XMSS_CERT: |
/* no need to prealloc */ |
/* no need to prealloc */ |
|
|
k->ecdsa = NULL; |
k->ecdsa = NULL; |
break; |
break; |
#endif /* WITH_OPENSSL */ |
#endif /* WITH_OPENSSL */ |
|
case KEY_ED25519_SK: |
|
case KEY_ED25519_SK_CERT: |
|
free(k->sk_application); |
|
sshbuf_free(k->sk_key_handle); |
|
sshbuf_free(k->sk_reserved); |
|
/* FALLTHROUGH */ |
case KEY_ED25519: |
case KEY_ED25519: |
case KEY_ED25519_CERT: |
case KEY_ED25519_CERT: |
freezero(k->ed25519_pk, ED25519_PK_SZ); |
freezero(k->ed25519_pk, ED25519_PK_SZ); |
|
|
BN_CTX_free(bnctx); |
BN_CTX_free(bnctx); |
return 1; |
return 1; |
#endif /* WITH_OPENSSL */ |
#endif /* WITH_OPENSSL */ |
|
case KEY_ED25519_SK: |
|
case KEY_ED25519_SK_CERT: |
|
if (a->sk_application == NULL || b->sk_application == NULL) |
|
return 0; |
|
if (strcmp(a->sk_application, b->sk_application) != 0) |
|
return 0; |
|
/* FALLTHROUGH */ |
case KEY_ED25519: |
case KEY_ED25519: |
case KEY_ED25519_CERT: |
case KEY_ED25519_CERT: |
return a->ed25519_pk != NULL && b->ed25519_pk != NULL && |
return a->ed25519_pk != NULL && b->ed25519_pk != NULL && |
|
|
break; |
break; |
#endif /* WITH_OPENSSL */ |
#endif /* WITH_OPENSSL */ |
case KEY_ED25519: |
case KEY_ED25519: |
|
case KEY_ED25519_SK: |
if (key->ed25519_pk == NULL) |
if (key->ed25519_pk == NULL) |
return SSH_ERR_INVALID_ARGUMENT; |
return SSH_ERR_INVALID_ARGUMENT; |
if ((ret = sshbuf_put_cstring(b, typename)) != 0 || |
if ((ret = sshbuf_put_cstring(b, typename)) != 0 || |
(ret = sshbuf_put_string(b, |
(ret = sshbuf_put_string(b, |
key->ed25519_pk, ED25519_PK_SZ)) != 0) |
key->ed25519_pk, ED25519_PK_SZ)) != 0) |
return ret; |
return ret; |
|
if (type == KEY_ED25519_SK) { |
|
if ((ret = sshbuf_put_cstring(b, |
|
key->sk_application)) != 0) |
|
return ret; |
|
} |
break; |
break; |
#ifdef WITH_XMSS |
#ifdef WITH_XMSS |
case KEY_XMSS: |
case KEY_XMSS: |
|
|
case KEY_ECDSA: |
case KEY_ECDSA: |
case KEY_ECDSA_SK: |
case KEY_ECDSA_SK: |
case KEY_ED25519: |
case KEY_ED25519: |
|
case KEY_ED25519_SK: |
case KEY_DSA_CERT: |
case KEY_DSA_CERT: |
case KEY_ECDSA_CERT: |
case KEY_ECDSA_CERT: |
case KEY_ECDSA_SK_CERT: |
case KEY_ECDSA_SK_CERT: |
case KEY_RSA_CERT: |
case KEY_RSA_CERT: |
case KEY_ED25519_CERT: |
case KEY_ED25519_CERT: |
|
case KEY_ED25519_SK_CERT: |
#ifdef WITH_XMSS |
#ifdef WITH_XMSS |
case KEY_XMSS: |
case KEY_XMSS: |
case KEY_XMSS_CERT: |
case KEY_XMSS_CERT: |
|
|
/* XXX */ |
/* XXX */ |
#endif |
#endif |
break; |
break; |
|
case KEY_ED25519_SK: |
|
freezero(ret->ed25519_pk, ED25519_PK_SZ); |
|
ret->ed25519_pk = k->ed25519_pk; |
|
ret->sk_application = k->sk_application; |
|
k->ed25519_pk = NULL; |
|
k->sk_application = NULL; |
|
break; |
#ifdef WITH_XMSS |
#ifdef WITH_XMSS |
case KEY_XMSS: |
case KEY_XMSS: |
free(ret->xmss_pk); |
free(ret->xmss_pk); |
|
|
#endif /* WITH_OPENSSL */ |
#endif /* WITH_OPENSSL */ |
case KEY_ED25519: |
case KEY_ED25519: |
case KEY_ED25519_CERT: |
case KEY_ED25519_CERT: |
|
case KEY_ED25519_SK: |
|
case KEY_ED25519_SK_CERT: |
if (k->ed25519_pk != NULL) { |
if (k->ed25519_pk != NULL) { |
if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) { |
if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) { |
r = SSH_ERR_ALLOC_FAIL; |
r = SSH_ERR_ALLOC_FAIL; |
|
|
} |
} |
memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ); |
memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ); |
} |
} |
|
if (k->type != KEY_ED25519_SK && |
|
k->type != KEY_ED25519_SK_CERT) |
|
break; |
|
/* Append security-key application string */ |
|
if ((n->sk_application = strdup(k->sk_application)) == NULL) |
|
goto out; |
break; |
break; |
#ifdef WITH_XMSS |
#ifdef WITH_XMSS |
case KEY_XMSS: |
case KEY_XMSS: |
|
|
break; |
break; |
#endif /* WITH_OPENSSL */ |
#endif /* WITH_OPENSSL */ |
case KEY_ED25519_CERT: |
case KEY_ED25519_CERT: |
|
case KEY_ED25519_SK_CERT: |
/* Skip nonce */ |
/* Skip nonce */ |
if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { |
if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { |
ret = SSH_ERR_INVALID_FORMAT; |
ret = SSH_ERR_INVALID_FORMAT; |
|
|
} |
} |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
case KEY_ED25519: |
case KEY_ED25519: |
|
case KEY_ED25519_SK: |
if ((ret = sshbuf_get_string(b, &pk, &len)) != 0) |
if ((ret = sshbuf_get_string(b, &pk, &len)) != 0) |
goto out; |
goto out; |
if (len != ED25519_PK_SZ) { |
if (len != ED25519_PK_SZ) { |
|
|
ret = SSH_ERR_ALLOC_FAIL; |
ret = SSH_ERR_ALLOC_FAIL; |
goto out; |
goto out; |
} |
} |
|
if (type == KEY_ED25519_SK || type == KEY_ED25519_SK_CERT) { |
|
/* Parse additional security-key application string */ |
|
if (sshbuf_get_cstring(b, &key->sk_application, |
|
NULL) != 0) { |
|
ret = SSH_ERR_INVALID_FORMAT; |
|
goto out; |
|
} |
|
#ifdef DEBUG_PK |
|
fprintf(stderr, "App: %s\n", key->sk_application); |
|
#endif |
|
} |
key->ed25519_pk = pk; |
key->ed25519_pk = pk; |
pk = NULL; |
pk = NULL; |
break; |
break; |
|
|
newtype = KEY_ECDSA_SK_CERT; |
newtype = KEY_ECDSA_SK_CERT; |
break; |
break; |
#endif /* WITH_OPENSSL */ |
#endif /* WITH_OPENSSL */ |
|
case KEY_ED25519_SK: |
|
newtype = KEY_ED25519_SK_CERT; |
|
break; |
case KEY_ED25519: |
case KEY_ED25519: |
newtype = KEY_ED25519_CERT; |
newtype = KEY_ED25519_CERT; |
break; |
break; |
|
|
ED25519_SK_SZ)) != 0) |
ED25519_SK_SZ)) != 0) |
goto out; |
goto out; |
break; |
break; |
|
case KEY_ED25519_SK: |
|
if ((r = sshbuf_put_string(b, key->ed25519_pk, |
|
ED25519_PK_SZ)) != 0 || |
|
(r = sshbuf_put_cstring(b, key->sk_application)) != 0 || |
|
(r = sshbuf_put_u8(b, key->sk_flags)) != 0 || |
|
(r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 || |
|
(r = sshbuf_put_stringb(b, key->sk_reserved)) != 0) |
|
goto out; |
|
break; |
|
case KEY_ED25519_SK_CERT: |
|
if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { |
|
r = SSH_ERR_INVALID_ARGUMENT; |
|
goto out; |
|
} |
|
if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || |
|
(r = sshbuf_put_string(b, key->ed25519_pk, |
|
ED25519_PK_SZ)) != 0 || |
|
(r = sshbuf_put_cstring(b, key->sk_application)) != 0 || |
|
(r = sshbuf_put_u8(b, key->sk_flags)) != 0 || |
|
(r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 || |
|
(r = sshbuf_put_stringb(b, key->sk_reserved)) != 0) |
|
goto out; |
|
break; |
#ifdef WITH_XMSS |
#ifdef WITH_XMSS |
case KEY_XMSS: |
case KEY_XMSS: |
if (key->xmss_name == NULL) { |
if (key->xmss_name == NULL) { |
|
|
k->ed25519_sk = ed25519_sk; |
k->ed25519_sk = ed25519_sk; |
ed25519_pk = ed25519_sk = NULL; /* transferred */ |
ed25519_pk = ed25519_sk = NULL; /* transferred */ |
break; |
break; |
|
case KEY_ED25519_SK: |
|
if ((k = sshkey_new(type)) == NULL) { |
|
r = SSH_ERR_ALLOC_FAIL; |
|
goto out; |
|
} |
|
if ((r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0) |
|
goto out; |
|
if (pklen != ED25519_PK_SZ) { |
|
r = SSH_ERR_INVALID_FORMAT; |
|
goto out; |
|
} |
|
if ((k->sk_key_handle = sshbuf_new()) == NULL || |
|
(k->sk_reserved = sshbuf_new()) == NULL) { |
|
r = SSH_ERR_ALLOC_FAIL; |
|
goto out; |
|
} |
|
if ((r = sshbuf_get_cstring(buf, &k->sk_application, |
|
NULL)) != 0 || |
|
(r = sshbuf_get_u8(buf, &k->sk_flags)) != 0 || |
|
(r = sshbuf_get_stringb(buf, k->sk_key_handle)) != 0 || |
|
(r = sshbuf_get_stringb(buf, k->sk_reserved)) != 0) |
|
goto out; |
|
k->ed25519_pk = ed25519_pk; |
|
ed25519_pk = NULL; |
|
break; |
|
case KEY_ED25519_SK_CERT: |
|
if ((r = sshkey_froms(buf, &k)) != 0 || |
|
(r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0) |
|
goto out; |
|
if (k->type != type) { |
|
r = SSH_ERR_INVALID_FORMAT; |
|
goto out; |
|
} |
|
if (pklen != ED25519_PK_SZ) { |
|
r = SSH_ERR_INVALID_FORMAT; |
|
goto out; |
|
} |
|
if ((k->sk_key_handle = sshbuf_new()) == NULL || |
|
(k->sk_reserved = sshbuf_new()) == NULL) { |
|
r = SSH_ERR_ALLOC_FAIL; |
|
goto out; |
|
} |
|
if ((r = sshbuf_get_cstring(buf, &k->sk_application, |
|
NULL)) != 0 || |
|
(r = sshbuf_get_u8(buf, &k->sk_flags)) != 0 || |
|
(r = sshbuf_get_stringb(buf, k->sk_key_handle)) != 0 || |
|
(r = sshbuf_get_stringb(buf, k->sk_reserved)) != 0) |
|
goto out; |
|
k->ed25519_pk = ed25519_pk; |
|
ed25519_pk = NULL; /* transferred */ |
|
break; |
#ifdef WITH_XMSS |
#ifdef WITH_XMSS |
case KEY_XMSS: |
case KEY_XMSS: |
if ((k = sshkey_new(type)) == NULL) { |
if ((k = sshkey_new(type)) == NULL) { |
|
|
break; /* see below */ |
break; /* see below */ |
#endif /* WITH_OPENSSL */ |
#endif /* WITH_OPENSSL */ |
case KEY_ED25519: |
case KEY_ED25519: |
|
case KEY_ED25519_SK: |
#ifdef WITH_XMSS |
#ifdef WITH_XMSS |
case KEY_XMSS: |
case KEY_XMSS: |
#endif /* WITH_XMSS */ |
#endif /* WITH_XMSS */ |