|
Packit Service |
31306d |
/*
|
|
Packit Service |
31306d |
* pki_ed25519 .c - PKI infrastructure using ed25519
|
|
Packit Service |
31306d |
*
|
|
Packit Service |
31306d |
* This file is part of the SSH Library
|
|
Packit Service |
31306d |
*
|
|
Packit Service |
31306d |
* Copyright (c) 2014 by Aris Adamantiadis
|
|
Packit Service |
31306d |
*
|
|
Packit Service |
31306d |
* The SSH Library is free software; you can redistribute it and/or modify
|
|
Packit Service |
31306d |
* it under the terms of the GNU Lesser General Public License as published by
|
|
Packit Service |
31306d |
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
|
Packit Service |
31306d |
* option) any later version.
|
|
Packit Service |
31306d |
*
|
|
Packit Service |
31306d |
* The SSH Library is distributed in the hope that it will be useful, but
|
|
Packit Service |
31306d |
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
Packit Service |
31306d |
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
Packit Service |
31306d |
* License for more details.
|
|
Packit Service |
31306d |
*
|
|
Packit Service |
31306d |
* You should have received a copy of the GNU Lesser General Public License
|
|
Packit Service |
31306d |
* along with the SSH Library; see the file COPYING. If not, write to
|
|
Packit Service |
31306d |
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
|
Packit Service |
31306d |
* MA 02111-1307, USA.
|
|
Packit Service |
31306d |
*/
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
#include "config.h"
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
#include "libssh/pki.h"
|
|
Packit Service |
31306d |
#include "libssh/pki_priv.h"
|
|
Packit Service |
31306d |
#include "libssh/ed25519.h"
|
|
Packit Service |
31306d |
#include "libssh/buffer.h"
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
int pki_key_generate_ed25519(ssh_key key)
|
|
Packit Service |
31306d |
{
|
|
Packit Service |
31306d |
int rc;
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
key->ed25519_privkey = malloc(sizeof (ed25519_privkey));
|
|
Packit Service |
31306d |
if (key->ed25519_privkey == NULL) {
|
|
Packit Service |
31306d |
goto error;
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
key->ed25519_pubkey = malloc(sizeof (ed25519_pubkey));
|
|
Packit Service |
31306d |
if (key->ed25519_pubkey == NULL) {
|
|
Packit Service |
31306d |
goto error;
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
rc = crypto_sign_ed25519_keypair(*key->ed25519_pubkey,
|
|
Packit Service |
31306d |
*key->ed25519_privkey);
|
|
Packit Service |
31306d |
if (rc != 0) {
|
|
Packit Service |
31306d |
goto error;
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
return SSH_OK;
|
|
Packit Service |
31306d |
error:
|
|
Packit Service |
31306d |
SAFE_FREE(key->ed25519_privkey);
|
|
Packit Service |
31306d |
SAFE_FREE(key->ed25519_pubkey);
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
return SSH_ERROR;
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
int pki_ed25519_sign(const ssh_key privkey,
|
|
Packit Service |
31306d |
ssh_signature sig,
|
|
Packit Service |
31306d |
const unsigned char *hash,
|
|
Packit Service |
31306d |
size_t hlen)
|
|
Packit Service |
31306d |
{
|
|
Packit Service |
31306d |
int rc;
|
|
Packit Service |
31306d |
uint8_t *buffer;
|
|
Packit Service |
31306d |
uint64_t dlen = 0;
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
buffer = malloc(hlen + ED25519_SIG_LEN);
|
|
Packit Service |
31306d |
if (buffer == NULL) {
|
|
Packit Service |
31306d |
return SSH_ERROR;
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
rc = crypto_sign_ed25519(buffer,
|
|
Packit Service |
31306d |
&dlen,
|
|
Packit Service |
31306d |
hash,
|
|
Packit Service |
31306d |
hlen,
|
|
Packit Service |
31306d |
*privkey->ed25519_privkey);
|
|
Packit Service |
31306d |
if (rc != 0) {
|
|
Packit Service |
31306d |
goto error;
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
/* This shouldn't happen */
|
|
Packit Service |
31306d |
if (dlen - hlen != ED25519_SIG_LEN) {
|
|
Packit Service |
31306d |
goto error;
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
sig->ed25519_sig = malloc(ED25519_SIG_LEN);
|
|
Packit Service |
31306d |
if (sig->ed25519_sig == NULL) {
|
|
Packit Service |
31306d |
goto error;
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
memcpy(sig->ed25519_sig, buffer, ED25519_SIG_LEN);
|
|
Packit Service |
31306d |
SAFE_FREE(buffer);
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
return SSH_OK;
|
|
Packit Service |
31306d |
error:
|
|
Packit Service |
31306d |
SAFE_FREE(buffer);
|
|
Packit Service |
31306d |
return SSH_ERROR;
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
int pki_ed25519_verify(const ssh_key pubkey,
|
|
Packit Service |
31306d |
ssh_signature sig,
|
|
Packit Service |
31306d |
const unsigned char *hash,
|
|
Packit Service |
31306d |
size_t hlen)
|
|
Packit Service |
31306d |
{
|
|
Packit Service |
31306d |
uint64_t mlen = 0;
|
|
Packit Service |
31306d |
uint8_t *buffer;
|
|
Packit Service |
31306d |
uint8_t *buffer2;
|
|
Packit Service |
31306d |
int rc;
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
if (pubkey == NULL || sig == NULL ||
|
|
Packit Service |
31306d |
hash == NULL || sig->ed25519_sig == NULL) {
|
|
Packit Service |
31306d |
return SSH_ERROR;
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
buffer = malloc(hlen + ED25519_SIG_LEN);
|
|
Packit Service |
31306d |
if (buffer == NULL) {
|
|
Packit Service |
31306d |
return SSH_ERROR;
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
buffer2 = malloc(hlen + ED25519_SIG_LEN);
|
|
Packit Service |
31306d |
if (buffer2 == NULL) {
|
|
Packit Service |
31306d |
goto error;
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
memcpy(buffer, sig->ed25519_sig, ED25519_SIG_LEN);
|
|
Packit Service |
31306d |
memcpy(buffer + ED25519_SIG_LEN, hash, hlen);
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
rc = crypto_sign_ed25519_open(buffer2,
|
|
Packit Service |
31306d |
&mlen,
|
|
Packit Service |
31306d |
buffer,
|
|
Packit Service |
31306d |
hlen + ED25519_SIG_LEN,
|
|
Packit Service |
31306d |
*pubkey->ed25519_pubkey);
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
explicit_bzero(buffer, hlen + ED25519_SIG_LEN);
|
|
Packit Service |
31306d |
explicit_bzero(buffer2, hlen);
|
|
Packit Service |
31306d |
SAFE_FREE(buffer);
|
|
Packit Service |
31306d |
SAFE_FREE(buffer2);
|
|
Packit Service |
31306d |
if (rc == 0) {
|
|
Packit Service |
31306d |
return SSH_OK;
|
|
Packit Service |
31306d |
} else {
|
|
Packit Service |
31306d |
return SSH_ERROR;
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
error:
|
|
Packit Service |
31306d |
SAFE_FREE(buffer);
|
|
Packit Service |
31306d |
SAFE_FREE(buffer2);
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
return SSH_ERROR;
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
|