diff options
Diffstat (limited to 'src/pki_ed25519_common.c')
-rw-r--r-- | src/pki_ed25519_common.c | 81 |
1 files changed, 67 insertions, 14 deletions
diff --git a/src/pki_ed25519_common.c b/src/pki_ed25519_common.c index 25585874..738825f5 100644 --- a/src/pki_ed25519_common.c +++ b/src/pki_ed25519_common.c @@ -31,27 +31,40 @@ int pki_privkey_build_ed25519(ssh_key key, ssh_string pubkey, ssh_string privkey) { - if (ssh_string_len(pubkey) != ED25519_PK_LEN || - ssh_string_len(privkey) != ED25519_SK_LEN) + if (ssh_string_len(pubkey) != ED25519_KEY_LEN || + ssh_string_len(privkey) != (2 * ED25519_KEY_LEN)) { SSH_LOG(SSH_LOG_WARN, "Invalid ed25519 key len"); return SSH_ERROR; } - key->ed25519_privkey = malloc(2 * ED25519_SK_LEN); +#ifdef HAVE_OPENSSL_ED25519 + /* In OpenSSL implementation, the private key is the original private seed, + * without the public key. */ + key->ed25519_privkey = malloc(ED25519_KEY_LEN); +#else + /* In the internal implementation, the private key is the concatenation of + * the private seed with the public key. */ + key->ed25519_privkey = malloc(2 * ED25519_KEY_LEN); +#endif if (key->ed25519_privkey == NULL) { goto error; } - key->ed25519_pubkey = malloc(ED25519_PK_LEN); + key->ed25519_pubkey = malloc(ED25519_KEY_LEN); if (key->ed25519_pubkey == NULL) { goto error; } +#ifdef HAVE_OPENSSL_ED25519 memcpy(key->ed25519_privkey, ssh_string_data(privkey), - ED25519_SK_LEN); + ED25519_KEY_LEN); +#else + memcpy(key->ed25519_privkey, ssh_string_data(privkey), + 2 * ED25519_KEY_LEN); +#endif memcpy(key->ed25519_pubkey, ssh_string_data(pubkey), - ED25519_PK_LEN); + ED25519_KEY_LEN); return SSH_OK; @@ -86,7 +99,16 @@ int pki_ed25519_key_cmp(const ssh_key k1, if (k1->ed25519_privkey == NULL || k2->ed25519_privkey == NULL) { return 1; } - cmp = memcmp(k1->ed25519_privkey, k2->ed25519_privkey, ED25519_SK_LEN); +#ifdef HAVE_OPENSSL_ED25519 + /* In OpenSSL implementation, the private key is the original private + * seed, without the public key. */ + cmp = memcmp(k1->ed25519_privkey, k2->ed25519_privkey, ED25519_KEY_LEN); +#else + /* In the internal implementation, the private key is the concatenation + * of the private seed with the public key. */ + cmp = memcmp(k1->ed25519_privkey, k2->ed25519_privkey, + 2 * ED25519_KEY_LEN); +#endif if (cmp != 0) { return 1; } @@ -95,7 +117,7 @@ int pki_ed25519_key_cmp(const ssh_key k1, if (k1->ed25519_pubkey == NULL || k2->ed25519_pubkey == NULL) { return 1; } - cmp = memcmp(k1->ed25519_pubkey, k2->ed25519_pubkey, ED25519_PK_LEN); + cmp = memcmp(k1->ed25519_pubkey, k2->ed25519_pubkey, ED25519_KEY_LEN); if (cmp != 0) { return 1; } @@ -122,20 +144,32 @@ int pki_ed25519_key_dup(ssh_key new, const ssh_key key) } if (key->ed25519_privkey != NULL) { - new->ed25519_privkey = malloc(ED25519_SK_LEN); +#ifdef HAVE_OPENSSL_ED25519 + /* In OpenSSL implementation, the private key is the original private + * seed, without the public key. */ + new->ed25519_privkey = malloc(ED25519_KEY_LEN); +#else + /* In the internal implementation, the private key is the concatenation + * of the private seed with the public key. */ + new->ed25519_privkey = malloc(2 * ED25519_KEY_LEN); +#endif if (new->ed25519_privkey == NULL) { return SSH_ERROR; } - memcpy(new->ed25519_privkey, key->ed25519_privkey, ED25519_SK_LEN); +#ifdef HAVE_OPENSSL_ED25519 + memcpy(new->ed25519_privkey, key->ed25519_privkey, ED25519_KEY_LEN); +#else + memcpy(new->ed25519_privkey, key->ed25519_privkey, 2 * ED25519_KEY_LEN); +#endif } if (key->ed25519_pubkey != NULL) { - new->ed25519_pubkey = malloc(ED25519_PK_LEN); + new->ed25519_pubkey = malloc(ED25519_KEY_LEN); if (new->ed25519_pubkey == NULL) { SAFE_FREE(new->ed25519_privkey); return SSH_ERROR; } - memcpy(new->ed25519_pubkey, key->ed25519_pubkey, ED25519_PK_LEN); + memcpy(new->ed25519_pubkey, key->ed25519_pubkey, ED25519_KEY_LEN); } return SSH_OK; @@ -162,8 +196,8 @@ int pki_ed25519_public_key_to_blob(ssh_buffer buffer, ssh_key key) rc = ssh_buffer_pack(buffer, "dP", - (uint32_t)ED25519_PK_LEN, - (size_t)ED25519_PK_LEN, key->ed25519_pubkey); + (uint32_t)ED25519_KEY_LEN, + (size_t)ED25519_KEY_LEN, key->ed25519_pubkey); return rc; } @@ -181,16 +215,31 @@ ssh_string pki_ed25519_signature_to_blob(ssh_signature sig) { ssh_string sig_blob; +#ifdef HAVE_OPENSSL_ED25519 + /* When using the OpenSSL implementation, the signature is stored in raw_sig + * which is shared by all algorithms.*/ + if (sig->raw_sig == NULL) { + return NULL; + } +#else + /* When using the internal implementation, the signature is stored in an + * algorithm specific field. */ if (sig->ed25519_sig == NULL) { return NULL; } +#endif sig_blob = ssh_string_new(ED25519_SIG_LEN); if (sig_blob == NULL) { return NULL; } +#ifdef HAVE_OPENSSL_ED25519 + ssh_string_fill(sig_blob, ssh_string_data(sig->raw_sig), + ssh_string_len(sig->raw_sig)); +#else ssh_string_fill(sig_blob, sig->ed25519_sig, ED25519_SIG_LEN); +#endif return sig_blob; } @@ -216,11 +265,15 @@ int pki_signature_from_ed25519_blob(ssh_signature sig, ssh_string sig_blob) return SSH_ERROR; } +#ifdef HAVE_OPENSSL_ED25519 + sig->raw_sig = ssh_string_copy(sig_blob); +#else sig->ed25519_sig = malloc(ED25519_SIG_LEN); if (sig->ed25519_sig == NULL){ return SSH_ERROR; } memcpy(sig->ed25519_sig, ssh_string_data(sig_blob), ED25519_SIG_LEN); +#endif return SSH_OK; } |