1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-07-28 01:41:48 +03:00

src: Reformat pki_gcrypt.c

clang-format -i pki_gcrypt.c

Reviewed-by: Jakub Jelen <jjelen@redhat.com>
This commit is contained in:
Andreas Schneider
2025-06-23 15:23:34 +02:00
parent 937552aed2
commit 1229ad650b

View File

@ -28,19 +28,19 @@
#ifdef HAVE_LIBGCRYPT #ifdef HAVE_LIBGCRYPT
#include <assert.h> #include <assert.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <gcrypt.h> #include <gcrypt.h>
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "libssh/priv.h"
#include "libssh/buffer.h" #include "libssh/buffer.h"
#include "libssh/session.h"
#include "libssh/wrapper.h"
#include "libssh/misc.h" #include "libssh/misc.h"
#include "libssh/pki.h" #include "libssh/pki.h"
#include "libssh/pki_priv.h" #include "libssh/pki_priv.h"
#include "libssh/priv.h"
#include "libssh/session.h"
#include "libssh/wrapper.h"
#define MAXLINESIZE 80 #define MAXLINESIZE 80
#define RSA_HEADER_BEGIN "-----BEGIN RSA PRIVATE KEY-----" #define RSA_HEADER_BEGIN "-----BEGIN RSA PRIVATE KEY-----"
@ -57,27 +57,28 @@
#define ASN1_SEQUENCE 48 #define ASN1_SEQUENCE 48
#define PKCS5_SALT_LEN 8 #define PKCS5_SALT_LEN 8
static int load_iv(const char *header, unsigned char *iv, int iv_len) { static int load_iv(const char *header, unsigned char *iv, int iv_len)
{
int i; int i;
int j; int j;
int k; int k;
memset(iv, 0, iv_len); memset(iv, 0, iv_len);
for (i = 0; i < iv_len; i++) { for (i = 0; i < iv_len; i++) {
if ((header[2*i] >= '0') && (header[2*i] <= '9')) if ((header[2 * i] >= '0') && (header[2 * i] <= '9'))
j = header[2*i] - '0'; j = header[2 * i] - '0';
else if ((header[2*i] >= 'A') && (header[2*i] <= 'F')) else if ((header[2 * i] >= 'A') && (header[2 * i] <= 'F'))
j = header[2*i] - 'A' + 10; j = header[2 * i] - 'A' + 10;
else if ((header[2*i] >= 'a') && (header[2*i] <= 'f')) else if ((header[2 * i] >= 'a') && (header[2 * i] <= 'f'))
j = header[2*i] - 'a' + 10; j = header[2 * i] - 'a' + 10;
else else
return -1; return -1;
if ((header[2*i+1] >= '0') && (header[2*i+1] <= '9')) if ((header[2 * i + 1] >= '0') && (header[2 * i + 1] <= '9'))
k = header[2*i+1] - '0'; k = header[2 * i + 1] - '0';
else if ((header[2*i+1] >= 'A') && (header[2*i+1] <= 'F')) else if ((header[2 * i + 1] >= 'A') && (header[2 * i + 1] <= 'F'))
k = header[2*i+1] - 'A' + 10; k = header[2 * i + 1] - 'A' + 10;
else if ((header[2*i+1] >= 'a') && (header[2*i+1] <= 'f')) else if ((header[2 * i + 1] >= 'a') && (header[2 * i + 1] <= 'f'))
k = header[2*i+1] - 'a' + 10; k = header[2 * i + 1] - 'a' + 10;
else else
return -1; return -1;
iv[i] = (j << 4) + k; iv[i] = (j << 4) + k;
@ -85,7 +86,8 @@ static int load_iv(const char *header, unsigned char *iv, int iv_len) {
return 0; return 0;
} }
static uint32_t char_to_u32(unsigned char *data, uint32_t size) { static uint32_t char_to_u32(unsigned char *data, uint32_t size)
{
uint32_t ret; uint32_t ret;
uint32_t i; uint32_t i;
@ -94,11 +96,12 @@ static uint32_t char_to_u32(unsigned char *data, uint32_t size) {
return ret; return ret;
} }
static uint32_t asn1_get_len(ssh_buffer buffer) { static uint32_t asn1_get_len(ssh_buffer buffer)
{
uint32_t len; uint32_t len;
unsigned char tmp[4]; unsigned char tmp[4];
if (ssh_buffer_get_data(buffer,tmp,1) == 0) { if (ssh_buffer_get_data(buffer, tmp, 1) == 0) {
return 0; return 0;
} }
@ -107,7 +110,7 @@ static uint32_t asn1_get_len(ssh_buffer buffer) {
if (len > 4) { if (len > 4) {
return 0; /* Length doesn't fit in u32. Can this really happen? */ return 0; /* Length doesn't fit in u32. Can this really happen? */
} }
if (ssh_buffer_get_data(buffer,tmp,len) == 0) { if (ssh_buffer_get_data(buffer, tmp, len) == 0) {
return 0; return 0;
} }
len = char_to_u32(tmp, len); len = char_to_u32(tmp, len);
@ -118,7 +121,8 @@ static uint32_t asn1_get_len(ssh_buffer buffer) {
return len; return len;
} }
static ssh_string asn1_get(ssh_buffer buffer, unsigned char want) { static ssh_string asn1_get(ssh_buffer buffer, unsigned char want)
{
ssh_string str; ssh_string str;
unsigned char type; unsigned char type;
uint32_t size; uint32_t size;
@ -144,7 +148,8 @@ static ssh_string asn1_get(ssh_buffer buffer, unsigned char want) {
return str; return str;
} }
static ssh_string asn1_get_int(ssh_buffer buffer) { static ssh_string asn1_get_int(ssh_buffer buffer)
{
return asn1_get(buffer, ASN1_INTEGER); return asn1_get(buffer, ASN1_INTEGER);
} }
@ -205,7 +210,8 @@ static ssh_string asn1_get_bit_string(ssh_buffer buffer)
return str; return str;
} }
static int asn1_check_sequence(ssh_buffer buffer) { static int asn1_check_sequence(ssh_buffer buffer)
{
unsigned char *j = NULL; unsigned char *j = NULL;
unsigned char tmp; unsigned char tmp;
int i; int i;
@ -219,10 +225,9 @@ static int asn1_check_sequence(ssh_buffer buffer) {
size = asn1_get_len(buffer); size = asn1_get_len(buffer);
if ((padding = ssh_buffer_get_len(buffer) - size) > 0) { if ((padding = ssh_buffer_get_len(buffer) - size) > 0) {
for (i = ssh_buffer_get_len(buffer) - size, for (i = ssh_buffer_get_len(buffer) - size,
j = (unsigned char*)ssh_buffer_get(buffer) + size; j = (unsigned char *)ssh_buffer_get(buffer) + size;
i; i;
i--, j++) i--, j++) {
{
if (*j != padding) { /* padding is allowed */ if (*j != padding) { /* padding is allowed */
return 0; /* but nothing else */ return 0; /* but nothing else */
} }
@ -232,7 +237,8 @@ static int asn1_check_sequence(ssh_buffer buffer) {
return 1; return 1;
} }
static int asn1_check_tag(ssh_buffer buffer, unsigned char tag) { static int asn1_check_tag(ssh_buffer buffer, unsigned char tag)
{
unsigned char tmp; unsigned char tmp;
uint32_t len; uint32_t len;
@ -241,19 +247,23 @@ static int asn1_check_tag(ssh_buffer buffer, unsigned char tag) {
return 0; return 0;
} }
(void) asn1_get_len(buffer); (void)asn1_get_len(buffer);
return 1; return 1;
} }
static int passphrase_to_key(char *data, unsigned int datalen, static int passphrase_to_key(char *data,
unsigned char *salt, unsigned char *key, unsigned int keylen) { unsigned int datalen,
unsigned char *salt,
unsigned char *key,
unsigned int keylen)
{
MD5CTX md; MD5CTX md;
unsigned char digest[MD5_DIGEST_LEN] = {0}; unsigned char digest[MD5_DIGEST_LEN] = {0};
unsigned int i; unsigned int i;
unsigned int j; unsigned int j;
unsigned int md_not_empty; unsigned int md_not_empty;
for (j = 0, md_not_empty = 0; j < keylen; ) { for (j = 0, md_not_empty = 0; j < keylen;) {
md = md5_init(); md = md5_init();
if (md == NULL) { if (md == NULL) {
return -1; return -1;
@ -295,9 +305,13 @@ void pki_key_clean(ssh_key key)
key->ecdsa = NULL; key->ecdsa = NULL;
} }
static int privatekey_decrypt(int algo, int mode, unsigned int key_len, static int privatekey_decrypt(int algo,
unsigned char *iv, unsigned int iv_len, int mode,
ssh_buffer data, ssh_auth_callback cb, unsigned int key_len,
unsigned char *iv,
unsigned int iv_len,
ssh_buffer data,
ssh_auth_callback cb,
void *userdata, void *userdata,
const char *desc) const char *desc)
{ {
@ -317,19 +331,24 @@ static int privatekey_decrypt(int algo, int mode, unsigned int key_len,
return -1; return -1;
} }
} else if (cb == NULL && userdata != NULL) { } else if (cb == NULL && userdata != NULL) {
snprintf(passphrase, MAX_PASSPHRASE_SIZE, "%s", (char *) userdata); snprintf(passphrase, MAX_PASSPHRASE_SIZE, "%s", (char *)userdata);
} }
if (passphrase_to_key(passphrase, strlen(passphrase), iv, key, key_len) < 0) { if (passphrase_to_key(passphrase, strlen(passphrase), iv, key, key_len) <
0) {
return -1; return -1;
} }
if (gcry_cipher_open(&cipher, algo, mode, 0) if (gcry_cipher_open(&cipher, algo, mode, 0) ||
|| gcry_cipher_setkey(cipher, key, key_len) gcry_cipher_setkey(cipher, key, key_len) ||
|| gcry_cipher_setiv(cipher, iv, iv_len) gcry_cipher_setiv(cipher, iv, iv_len) ||
|| (tmp = calloc(ssh_buffer_get_len(data), sizeof(unsigned char))) == NULL (tmp = calloc(ssh_buffer_get_len(data), sizeof(unsigned char))) ==
|| gcry_cipher_decrypt(cipher, tmp, ssh_buffer_get_len(data), NULL ||
ssh_buffer_get(data), ssh_buffer_get_len(data))) { gcry_cipher_decrypt(cipher,
tmp,
ssh_buffer_get_len(data),
ssh_buffer_get(data),
ssh_buffer_get_len(data))) {
gcry_cipher_close(cipher); gcry_cipher_close(cipher);
return -1; return -1;
} }
@ -342,45 +361,41 @@ static int privatekey_decrypt(int algo, int mode, unsigned int key_len,
return 0; return 0;
} }
static int privatekey_dek_header(const char *header, unsigned int header_len, static int privatekey_dek_header(const char *header,
int *algo, int *mode, unsigned int *key_len, unsigned char **iv, unsigned int header_len,
unsigned int *iv_len) { int *algo,
int *mode,
unsigned int *key_len,
unsigned char **iv,
unsigned int *iv_len)
{
unsigned int iv_pos; unsigned int iv_pos;
if (header_len > 13 && !strncmp("DES-EDE3-CBC", header, 12)) if (header_len > 13 && !strncmp("DES-EDE3-CBC", header, 12)) {
{
*algo = GCRY_CIPHER_3DES; *algo = GCRY_CIPHER_3DES;
iv_pos = 13; iv_pos = 13;
*mode = GCRY_CIPHER_MODE_CBC; *mode = GCRY_CIPHER_MODE_CBC;
*key_len = 24; *key_len = 24;
*iv_len = 8; *iv_len = 8;
} } else if (header_len > 8 && !strncmp("DES-CBC", header, 7)) {
else if (header_len > 8 && !strncmp("DES-CBC", header, 7))
{
*algo = GCRY_CIPHER_DES; *algo = GCRY_CIPHER_DES;
iv_pos = 8; iv_pos = 8;
*mode = GCRY_CIPHER_MODE_CBC; *mode = GCRY_CIPHER_MODE_CBC;
*key_len = 8; *key_len = 8;
*iv_len = 8; *iv_len = 8;
} } else if (header_len > 12 && !strncmp("AES-128-CBC", header, 11)) {
else if (header_len > 12 && !strncmp("AES-128-CBC", header, 11))
{
*algo = GCRY_CIPHER_AES128; *algo = GCRY_CIPHER_AES128;
iv_pos = 12; iv_pos = 12;
*mode = GCRY_CIPHER_MODE_CBC; *mode = GCRY_CIPHER_MODE_CBC;
*key_len = 16; *key_len = 16;
*iv_len = 16; *iv_len = 16;
} } else if (header_len > 12 && !strncmp("AES-192-CBC", header, 11)) {
else if (header_len > 12 && !strncmp("AES-192-CBC", header, 11))
{
*algo = GCRY_CIPHER_AES192; *algo = GCRY_CIPHER_AES192;
iv_pos = 12; iv_pos = 12;
*mode = GCRY_CIPHER_MODE_CBC; *mode = GCRY_CIPHER_MODE_CBC;
*key_len = 24; *key_len = 24;
*iv_len = 16; *iv_len = 16;
} } else if (header_len > 12 && !strncmp("AES-256-CBC", header, 11)) {
else if (header_len > 12 && !strncmp("AES-256-CBC", header, 11))
{
*algo = GCRY_CIPHER_AES256; *algo = GCRY_CIPHER_AES256;
iv_pos = 12; iv_pos = 12;
*mode = GCRY_CIPHER_MODE_CBC; *mode = GCRY_CIPHER_MODE_CBC;
@ -398,18 +413,25 @@ static int privatekey_dek_header(const char *header, unsigned int header_len,
return load_iv(header + iv_pos, *iv, *iv_len); return load_iv(header + iv_pos, *iv, *iv_len);
} }
#define get_next_line(p, len) { \ #define get_next_line(p, len) \
while(p[len] == '\n' || p[len] == '\r') /* skip empty lines */ \ { \
while (p[len] == '\n' || p[len] == '\r') /* skip empty lines */ \
len++; \ len++; \
if(p[len] == '\0') /* EOL */ \ if (p[len] == '\0') /* EOL */ \
eol = true; \ eol = true; \
else /* calculate length */ \ else /* calculate length */ \
for(p += len, len = 0; p[len] && p[len] != '\n' \ for (p += len, len = 0; \
&& p[len] != '\r'; len++); \ p[len] && p[len] != '\n' && p[len] != '\r'; \
len++) \
; \
} }
static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type, static ssh_buffer privatekey_string_to_buffer(const char *pkey,
ssh_auth_callback cb, void *userdata, const char *desc) { int type,
ssh_auth_callback cb,
void *userdata,
const char *desc)
{
ssh_buffer buffer = NULL; ssh_buffer buffer = NULL;
ssh_buffer out = NULL; ssh_buffer out = NULL;
const char *p = NULL; const char *p = NULL;
@ -430,7 +452,7 @@ static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type,
return NULL; return NULL;
} }
switch(type) { switch (type) {
case SSH_KEYTYPE_RSA: case SSH_KEYTYPE_RSA:
header_begin = RSA_HEADER_BEGIN; header_begin = RSA_HEADER_BEGIN;
header_end = RSA_HEADER_END; header_end = RSA_HEADER_END;
@ -453,7 +475,7 @@ static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type,
len = 0; len = 0;
get_next_line(p, len); get_next_line(p, len);
while(!eol && strncmp(p, header_begin, header_begin_size)) { while (!eol && strncmp(p, header_begin, header_begin_size)) {
/* skip line */ /* skip line */
get_next_line(p, len); get_next_line(p, len);
} }
@ -485,8 +507,13 @@ static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type,
SSH_BUFFER_FREE(buffer); SSH_BUFFER_FREE(buffer);
return NULL; return NULL;
} }
if (privatekey_dek_header(p, len, &algo, &mode, &key_len, if (privatekey_dek_header(p,
&iv, &iv_len) < 0) { len,
&algo,
&mode,
&key_len,
&iv,
&iv_len) < 0) {
SSH_BUFFER_FREE(buffer); SSH_BUFFER_FREE(buffer);
SAFE_FREE(iv); SAFE_FREE(iv);
return NULL; return NULL;
@ -497,7 +524,7 @@ static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type,
return NULL; return NULL;
} }
} else { } else {
if(len > 0) { if (len > 0) {
if (ssh_buffer_add_data(buffer, p, len) < 0) { if (ssh_buffer_add_data(buffer, p, len) < 0) {
SSH_BUFFER_FREE(buffer); SSH_BUFFER_FREE(buffer);
SAFE_FREE(iv); SAFE_FREE(iv);
@ -507,7 +534,7 @@ static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type,
} }
get_next_line(p, len); get_next_line(p, len);
while(!eol && strncmp(p, header_end, header_end_size) != 0) { while (!eol && strncmp(p, header_end, header_end_size) != 0) {
if (ssh_buffer_add_data(buffer, p, len) < 0) { if (ssh_buffer_add_data(buffer, p, len) < 0) {
SSH_BUFFER_FREE(buffer); SSH_BUFFER_FREE(buffer);
SAFE_FREE(iv); SAFE_FREE(iv);
@ -536,8 +563,15 @@ static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type,
} }
if (algo) { if (algo) {
if (privatekey_decrypt(algo, mode, key_len, iv, iv_len, out, if (privatekey_decrypt(algo,
cb, userdata, desc) < 0) { mode,
key_len,
iv,
iv_len,
out,
cb,
userdata,
desc) < 0) {
SSH_BUFFER_FREE(out); SSH_BUFFER_FREE(out);
SAFE_FREE(iv); SAFE_FREE(iv);
return NULL; return NULL;
@ -548,8 +582,7 @@ static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type,
return out; return out;
} }
static int static int b64decode_rsa_privatekey(const char *pkey,
b64decode_rsa_privatekey(const char *pkey,
gcry_sexp_t *r, gcry_sexp_t *r,
ssh_auth_callback cb, ssh_auth_callback cb,
void *userdata, void *userdata,
@ -569,11 +602,8 @@ b64decode_rsa_privatekey(const char *pkey,
int rc = 1; int rc = 1;
gcry_error_t rv = 0; gcry_error_t rv = 0;
buffer = privatekey_string_to_buffer(pkey, buffer =
SSH_KEYTYPE_RSA, privatekey_string_to_buffer(pkey, SSH_KEYTYPE_RSA, cb, userdata, desc);
cb,
userdata,
desc);
if (buffer == NULL) { if (buffer == NULL) {
return 0; return 0;
} }
@ -725,7 +755,6 @@ static const char *pki_key_ecdsa_nid_to_gcrypt_name(int nid)
return "unknown"; return "unknown";
} }
const char *pki_key_ecdsa_nid_to_name(int nid) const char *pki_key_ecdsa_nid_to_name(int nid)
{ {
switch (nid) { switch (nid) {
@ -792,15 +821,16 @@ static int asn1_oi_to_nid(const ssh_string oi)
}; };
size_t len = ssh_string_len(oi); size_t len = ssh_string_len(oi);
for (e = mapping; e->length; e++) { for (e = mapping; e->length; e++) {
if (len == e->length if (len == e->length &&
&& memcmp(ssh_string_data(oi), e->identifier, len) == 0) { memcmp(ssh_string_data(oi), e->identifier, len) == 0) {
return e->nid; return e->nid;
} }
} }
return -1; return -1;
} }
static int b64decode_ecdsa_privatekey(const char *pkey, gcry_sexp_t *r, static int b64decode_ecdsa_privatekey(const char *pkey,
gcry_sexp_t *r,
ssh_auth_callback cb, ssh_auth_callback cb,
void *userdata, void *userdata,
const char *desc) const char *desc)
@ -869,7 +899,7 @@ static int b64decode_ecdsa_privatekey(const char *pkey, gcry_sexp_t *r,
valid = 1; valid = 1;
} }
error: error:
SSH_BUFFER_FREE(buffer); SSH_BUFFER_FREE(buffer);
SSH_STRING_FREE(v); SSH_STRING_FREE(v);
ssh_string_burn(d); ssh_string_burn(d);
@ -887,10 +917,10 @@ ssh_string pki_private_key_to_pem(const ssh_key key,
ssh_auth_callback auth_fn, ssh_auth_callback auth_fn,
void *auth_data) void *auth_data)
{ {
(void) key; (void)key;
(void) passphrase; (void)passphrase;
(void) auth_fn; (void)auth_fn;
(void) auth_data; (void)auth_data;
SSH_LOG(SSH_LOG_TRACE, "PEM export not supported by gcrypt backend!"); SSH_LOG(SSH_LOG_TRACE, "PEM export not supported by gcrypt backend!");
@ -918,15 +948,21 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
case SSH_KEYTYPE_RSA: case SSH_KEYTYPE_RSA:
if (passphrase == NULL) { if (passphrase == NULL) {
if (auth_fn) { if (auth_fn) {
valid = b64decode_rsa_privatekey(b64_key, &rsa, auth_fn, valid = b64decode_rsa_privatekey(b64_key,
auth_data, "Passphrase for private key:"); &rsa,
auth_fn,
auth_data,
"Passphrase for private key:");
} else { } else {
valid = b64decode_rsa_privatekey(b64_key, &rsa, NULL, NULL, valid =
NULL); b64decode_rsa_privatekey(b64_key, &rsa, NULL, NULL, NULL);
} }
} else { } else {
valid = b64decode_rsa_privatekey(b64_key, &rsa, NULL, valid = b64decode_rsa_privatekey(b64_key,
(void *)passphrase, NULL); &rsa,
NULL,
(void *)passphrase,
NULL);
} }
if (!valid) { if (!valid) {
@ -940,7 +976,8 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
#if HAVE_GCRYPT_ECC #if HAVE_GCRYPT_ECC
if (passphrase == NULL) { if (passphrase == NULL) {
if (auth_fn != NULL) { if (auth_fn != NULL) {
valid = b64decode_ecdsa_privatekey(b64_key, valid =
b64decode_ecdsa_privatekey(b64_key,
&ecdsa, &ecdsa,
auth_fn, auth_fn,
auth_data, auth_data,
@ -1019,14 +1056,21 @@ int pki_privkey_build_rsa(ssh_key key,
/* in gcrypt, there is no iqmp (inverse of q mod p) argument, /* in gcrypt, there is no iqmp (inverse of q mod p) argument,
* but it is ipmq (inverse of p mod q) so we need to swap * but it is ipmq (inverse of p mod q) so we need to swap
* the p and q arguments */ * the p and q arguments */
gcry_sexp_build(&key->rsa, NULL, gcry_sexp_build(&key->rsa,
NULL,
"(private-key(rsa(n %b)(e %b)(d %b)(p %b)(q %b)(u %b)))", "(private-key(rsa(n %b)(e %b)(d %b)(p %b)(q %b)(u %b)))",
ssh_string_len(n), ssh_string_data(n), ssh_string_len(n),
ssh_string_len(e), ssh_string_data(e), ssh_string_data(n),
ssh_string_len(d), ssh_string_data(d), ssh_string_len(e),
ssh_string_len(q), ssh_string_data(q), ssh_string_data(e),
ssh_string_len(p), ssh_string_data(p), ssh_string_len(d),
ssh_string_len(iqmp), ssh_string_data(iqmp)); ssh_string_data(d),
ssh_string_len(q),
ssh_string_data(q),
ssh_string_len(p),
ssh_string_data(p),
ssh_string_len(iqmp),
ssh_string_data(iqmp));
if (key->rsa == NULL) { if (key->rsa == NULL) {
return SSH_ERROR; return SSH_ERROR;
} }
@ -1034,13 +1078,15 @@ int pki_privkey_build_rsa(ssh_key key,
return SSH_OK; return SSH_OK;
} }
int pki_pubkey_build_rsa(ssh_key key, int pki_pubkey_build_rsa(ssh_key key, ssh_string e, ssh_string n)
ssh_string e, {
ssh_string n) { gcry_sexp_build(&key->rsa,
gcry_sexp_build(&key->rsa, NULL, NULL,
"(public-key(rsa(n %b)(e %b)))", "(public-key(rsa(n %b)(e %b)))",
ssh_string_len(n), ssh_string_data(n), ssh_string_len(n),
ssh_string_len(e),ssh_string_data(e)); ssh_string_data(n),
ssh_string_len(e),
ssh_string_data(e));
if (key->rsa == NULL) { if (key->rsa == NULL) {
return SSH_ERROR; return SSH_ERROR;
} }
@ -1056,11 +1102,14 @@ int pki_privkey_build_ecdsa(ssh_key key, int nid, ssh_string e, ssh_string exp)
key->ecdsa_nid = nid; key->ecdsa_nid = nid;
key->type_c = pki_key_ecdsa_nid_to_name(nid); key->type_c = pki_key_ecdsa_nid_to_name(nid);
err = gcry_sexp_build(&key->ecdsa, NULL, err = gcry_sexp_build(&key->ecdsa,
NULL,
"(private-key(ecdsa(curve %s)(d %b)(q %b)))", "(private-key(ecdsa(curve %s)(d %b)(q %b)))",
pki_key_ecdsa_nid_to_gcrypt_name(nid), pki_key_ecdsa_nid_to_gcrypt_name(nid),
ssh_string_len(exp), ssh_string_data(exp), ssh_string_len(exp),
ssh_string_len(e), ssh_string_data(e)); ssh_string_data(exp),
ssh_string_len(e),
ssh_string_data(e));
if (err) { if (err) {
return SSH_ERROR; return SSH_ERROR;
} }
@ -1075,10 +1124,12 @@ int pki_pubkey_build_ecdsa(ssh_key key, int nid, ssh_string e)
key->ecdsa_nid = nid; key->ecdsa_nid = nid;
key->type_c = pki_key_ecdsa_nid_to_name(nid); key->type_c = pki_key_ecdsa_nid_to_name(nid);
err = gcry_sexp_build(&key->ecdsa, NULL, err = gcry_sexp_build(&key->ecdsa,
NULL,
"(public-key(ecdsa(curve %s)(q %b)))", "(public-key(ecdsa(curve %s)(q %b)))",
pki_key_ecdsa_nid_to_gcrypt_name(nid), pki_key_ecdsa_nid_to_gcrypt_name(nid),
ssh_string_len(e), ssh_string_data(e)); ssh_string_len(e),
ssh_string_data(e));
if (err) { if (err) {
return SSH_ERROR; return SSH_ERROR;
} }
@ -1118,7 +1169,7 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
new->flags = key->flags; new->flags = key->flags;
} }
switch(key->type) { switch (key->type) {
case SSH_KEYTYPE_RSA: case SSH_KEYTYPE_RSA:
err = gcry_sexp_extract_param(key->rsa, err = gcry_sexp_extract_param(key->rsa,
NULL, NULL,
@ -1135,15 +1186,22 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
} }
if (!demote && (key->flags & SSH_KEY_FLAG_PRIVATE)) { if (!demote && (key->flags & SSH_KEY_FLAG_PRIVATE)) {
err = gcry_sexp_build(&new->rsa, err = gcry_sexp_build(
&new->rsa,
NULL, NULL,
"(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)(u %m)))", "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)(u %m)))",
n, e, d, p, q, u); n,
e,
d,
p,
q,
u);
} else { } else {
err = gcry_sexp_build(&new->rsa, err = gcry_sexp_build(&new->rsa,
NULL, NULL,
"(public-key(rsa(n %m)(e %m)))", "(public-key(rsa(n %m)(e %m)))",
n, e); n,
e);
} }
break; break;
case SSH_KEYTYPE_ED25519: case SSH_KEYTYPE_ED25519:
@ -1160,12 +1218,7 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
#ifdef HAVE_GCRYPT_ECC #ifdef HAVE_GCRYPT_ECC
new->ecdsa_nid = key->ecdsa_nid; new->ecdsa_nid = key->ecdsa_nid;
err = gcry_sexp_extract_param(key->ecdsa, err = gcry_sexp_extract_param(key->ecdsa, NULL, "qd?", &q, &d, NULL);
NULL,
"qd?",
&q,
&d,
NULL);
if (err) { if (err) {
break; break;
} }
@ -1243,7 +1296,7 @@ pki_key_generate(ssh_key key, int parameter, const char *type_s, int type)
rc = gcry_pk_genkey(&key->ecdsa, params); rc = gcry_pk_genkey(&key->ecdsa, params);
break; break;
default: default:
assert (! "reached"); assert(!"reached");
} }
gcry_sexp_release(params); gcry_sexp_release(params);
if (rc != 0) if (rc != 0)
@ -1251,38 +1304,43 @@ pki_key_generate(ssh_key key, int parameter, const char *type_s, int type)
return SSH_OK; return SSH_OK;
} }
int int pki_key_generate_rsa(ssh_key key, int parameter)
pki_key_generate_rsa(ssh_key key, int parameter)
{ {
return pki_key_generate(key, parameter, "rsa", SSH_KEYTYPE_RSA); return pki_key_generate(key, parameter, "rsa", SSH_KEYTYPE_RSA);
} }
#ifdef HAVE_GCRYPT_ECC #ifdef HAVE_GCRYPT_ECC
int pki_key_generate_ecdsa(ssh_key key, int parameter) { int pki_key_generate_ecdsa(ssh_key key, int parameter)
{
switch (parameter) { switch (parameter) {
case 384: case 384:
key->ecdsa_nid = NID_gcrypt_nistp384; key->ecdsa_nid = NID_gcrypt_nistp384;
key->type = SSH_KEYTYPE_ECDSA_P384; key->type = SSH_KEYTYPE_ECDSA_P384;
return pki_key_generate(key, parameter, "ecdsa", return pki_key_generate(key,
parameter,
"ecdsa",
SSH_KEYTYPE_ECDSA_P384); SSH_KEYTYPE_ECDSA_P384);
case 521: case 521:
key->ecdsa_nid = NID_gcrypt_nistp521; key->ecdsa_nid = NID_gcrypt_nistp521;
key->type = SSH_KEYTYPE_ECDSA_P521; key->type = SSH_KEYTYPE_ECDSA_P521;
return pki_key_generate(key, parameter, "ecdsa", return pki_key_generate(key,
parameter,
"ecdsa",
SSH_KEYTYPE_ECDSA_P521); SSH_KEYTYPE_ECDSA_P521);
case 256: case 256:
default: default:
key->ecdsa_nid = NID_gcrypt_nistp256; key->ecdsa_nid = NID_gcrypt_nistp256;
key->type = SSH_KEYTYPE_ECDSA_P256; key->type = SSH_KEYTYPE_ECDSA_P256;
return pki_key_generate(key, parameter, "ecdsa", return pki_key_generate(key,
parameter,
"ecdsa",
SSH_KEYTYPE_ECDSA_P256); SSH_KEYTYPE_ECDSA_P256);
} }
} }
#endif #endif
static int _bignum_cmp(const gcry_sexp_t s1, static int
const gcry_sexp_t s2, _bignum_cmp(const gcry_sexp_t s1, const gcry_sexp_t s2, const char *what)
const char *what)
{ {
gcry_sexp_t sexp = NULL; gcry_sexp_t sexp = NULL;
bignum b1 = NULL; bignum b1 = NULL;
@ -1311,15 +1369,13 @@ static int _bignum_cmp(const gcry_sexp_t s1,
return 1; return 1;
} }
result = !! bignum_cmp(b1, b2); result = !!bignum_cmp(b1, b2);
bignum_safe_free(b1); bignum_safe_free(b1);
bignum_safe_free(b2); bignum_safe_free(b2);
return result; return result;
} }
int pki_key_compare(const ssh_key k1, int pki_key_compare(const ssh_key k1, const ssh_key k2, enum ssh_keycmp_e what)
const ssh_key k2,
enum ssh_keycmp_e what)
{ {
switch (k1->type) { switch (k1->type) {
case SSH_KEYTYPE_RSA: case SSH_KEYTYPE_RSA:
@ -1561,8 +1617,8 @@ ssh_string pki_key_to_blob(const ssh_key key, enum ssh_key_e type)
case SSH_KEYTYPE_ECDSA_P521: case SSH_KEYTYPE_ECDSA_P521:
case SSH_KEYTYPE_SK_ECDSA: case SSH_KEYTYPE_SK_ECDSA:
#ifdef HAVE_GCRYPT_ECC #ifdef HAVE_GCRYPT_ECC
type_s = ssh_string_from_char( type_s =
pki_key_ecdsa_nid_to_char(key->ecdsa_nid)); ssh_string_from_char(pki_key_ecdsa_nid_to_char(key->ecdsa_nid));
if (type_s == NULL) { if (type_s == NULL) {
goto fail; goto fail;
} }
@ -1573,7 +1629,9 @@ ssh_string pki_key_to_blob(const ssh_key key, enum ssh_key_e type)
goto fail; goto fail;
} }
e = ssh_sexp_extract_mpi(key->ecdsa, "q", GCRYMPI_FMT_STD, e = ssh_sexp_extract_mpi(key->ecdsa,
"q",
GCRYMPI_FMT_STD,
GCRYMPI_FMT_STD); GCRYMPI_FMT_STD);
if (e == NULL) { if (e == NULL) {
goto fail; goto fail;
@ -1589,7 +1647,9 @@ ssh_string pki_key_to_blob(const ssh_key key, enum ssh_key_e type)
e = NULL; e = NULL;
if (type == SSH_KEY_PRIVATE) { if (type == SSH_KEY_PRIVATE) {
d = ssh_sexp_extract_mpi(key->ecdsa, "d", GCRYMPI_FMT_STD, d = ssh_sexp_extract_mpi(key->ecdsa,
"d",
GCRYMPI_FMT_STD,
GCRYMPI_FMT_STD); GCRYMPI_FMT_STD);
if (d == NULL) { if (d == NULL) {
goto fail; goto fail;
@ -1625,7 +1685,9 @@ makestring:
goto fail; goto fail;
} }
rc = ssh_string_fill(str, ssh_buffer_get(buffer), ssh_buffer_get_len(buffer)); rc = ssh_string_fill(str,
ssh_buffer_get(buffer),
ssh_buffer_get_len(buffer));
if (rc < 0) { if (rc < 0) {
goto fail; goto fail;
} }
@ -1659,7 +1721,7 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
ssh_string sig_blob = NULL; ssh_string sig_blob = NULL;
int rc; int rc;
switch(sig->type) { switch (sig->type) {
case SSH_KEYTYPE_RSA: case SSH_KEYTYPE_RSA:
sexp = gcry_sexp_find_token(sig->rsa_sig, "s", 0); sexp = gcry_sexp_find_token(sig->rsa_sig, "s", 0);
if (sexp == NULL) { if (sexp == NULL) {
@ -1705,8 +1767,10 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
return NULL; return NULL;
} }
R = ssh_sexp_extract_mpi(sig->ecdsa_sig, "r", R = ssh_sexp_extract_mpi(sig->ecdsa_sig,
GCRYMPI_FMT_USG, GCRYMPI_FMT_STD); "r",
GCRYMPI_FMT_USG,
GCRYMPI_FMT_STD);
if (R == NULL) { if (R == NULL) {
SSH_BUFFER_FREE(b); SSH_BUFFER_FREE(b);
return NULL; return NULL;
@ -1719,8 +1783,10 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
return NULL; return NULL;
} }
S = ssh_sexp_extract_mpi(sig->ecdsa_sig, "s", S = ssh_sexp_extract_mpi(sig->ecdsa_sig,
GCRYMPI_FMT_USG, GCRYMPI_FMT_STD); "s",
GCRYMPI_FMT_USG,
GCRYMPI_FMT_STD);
if (S == NULL) { if (S == NULL) {
SSH_BUFFER_FREE(b); SSH_BUFFER_FREE(b);
return NULL; return NULL;
@ -1739,8 +1805,8 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
return NULL; return NULL;
} }
rc = ssh_string_fill(sig_blob, rc =
ssh_buffer_get(b), ssh_buffer_get_len(b)); ssh_string_fill(sig_blob, ssh_buffer_get(b), ssh_buffer_get_len(b));
SSH_BUFFER_FREE(b); SSH_BUFFER_FREE(b);
if (rc < 0) { if (rc < 0) {
SSH_STRING_FREE(sig_blob); SSH_STRING_FREE(sig_blob);
@ -1790,7 +1856,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
len = ssh_string_len(sig_blob); len = ssh_string_len(sig_blob);
switch(type) { switch (type) {
case SSH_KEYTYPE_RSA: case SSH_KEYTYPE_RSA:
rsalen = (gcry_pk_get_nbits(pubkey->rsa) + 7) / 8; rsalen = (gcry_pk_get_nbits(pubkey->rsa) + 7) / 8;
@ -1828,7 +1894,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
case SSH_KEYTYPE_ED25519: case SSH_KEYTYPE_ED25519:
case SSH_KEYTYPE_SK_ED25519: case SSH_KEYTYPE_SK_ED25519:
rc = pki_signature_from_ed25519_blob(sig, sig_blob); rc = pki_signature_from_ed25519_blob(sig, sig_blob);
if (rc != SSH_OK){ if (rc != SSH_OK) {
ssh_signature_free(sig); ssh_signature_free(sig);
return NULL; return NULL;
} }
@ -1910,8 +1976,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
ssh_signature_free(sig); ssh_signature_free(sig);
return NULL; return NULL;
} }
} } break;
break;
#endif #endif
case SSH_KEYTYPE_RSA1: case SSH_KEYTYPE_RSA1:
case SSH_KEYTYPE_UNKNOWN: case SSH_KEYTYPE_UNKNOWN:
@ -1977,7 +2042,7 @@ ssh_signature pki_do_sign_hash(const ssh_key privkey,
break; break;
case SSH_KEYTYPE_ED25519: case SSH_KEYTYPE_ED25519:
err = pki_ed25519_sign(privkey, sig, hash, hlen); err = pki_ed25519_sign(privkey, sig, hash, hlen);
if (err != SSH_OK){ if (err != SSH_OK) {
ssh_signature_free(sig); ssh_signature_free(sig);
return NULL; return NULL;
} }
@ -2038,7 +2103,8 @@ ssh_signature pki_sign_data(const ssh_key privkey,
int rc; int rc;
if (privkey == NULL || !ssh_key_is_private(privkey) || input == NULL) { if (privkey == NULL || !ssh_key_is_private(privkey) || input == NULL) {
SSH_LOG(SSH_LOG_TRACE, "Bad parameter provided to " SSH_LOG(SSH_LOG_TRACE,
"Bad parameter provided to "
"pki_sign_data()"); "pki_sign_data()");
return NULL; return NULL;
} }
@ -2079,7 +2145,8 @@ ssh_signature pki_sign_data(const ssh_key privkey,
} }
FALL_THROUGH; FALL_THROUGH;
default: default:
SSH_LOG(SSH_LOG_TRACE, "Unknown hash algorithm for type: %d", SSH_LOG(SSH_LOG_TRACE,
"Unknown hash algorithm for type: %d",
hash_type); hash_type);
return NULL; return NULL;
} }
@ -2118,9 +2185,9 @@ int pki_verify_data_signature(ssh_signature signature,
int rc; int rc;
if (pubkey == NULL || ssh_key_is_private(pubkey) || input == NULL || if (pubkey == NULL || ssh_key_is_private(pubkey) || input == NULL ||
signature == NULL) signature == NULL) {
{ SSH_LOG(SSH_LOG_TRACE,
SSH_LOG(SSH_LOG_TRACE, "Bad parameter provided to " "Bad parameter provided to "
"pki_verify_data_signature()"); "pki_verify_data_signature()");
return SSH_ERROR; return SSH_ERROR;
} }
@ -2160,29 +2227,30 @@ int pki_verify_data_signature(ssh_signature signature,
if (pubkey->type == SSH_KEYTYPE_ED25519 || if (pubkey->type == SSH_KEYTYPE_ED25519 ||
pubkey->type == SSH_KEYTYPE_ED25519_CERT01 || pubkey->type == SSH_KEYTYPE_ED25519_CERT01 ||
pubkey->type == SSH_KEYTYPE_SK_ED25519 || pubkey->type == SSH_KEYTYPE_SK_ED25519 ||
pubkey->type == SSH_KEYTYPE_SK_ED25519_CERT01) pubkey->type == SSH_KEYTYPE_SK_ED25519_CERT01) {
{
verify_input = input; verify_input = input;
hlen = input_len; hlen = input_len;
break; break;
} }
FALL_THROUGH; FALL_THROUGH;
default: default:
SSH_LOG(SSH_LOG_TRACE, "Unknown sig->hash_type: %d", signature->hash_type); SSH_LOG(SSH_LOG_TRACE,
"Unknown sig->hash_type: %d",
signature->hash_type);
return SSH_ERROR; return SSH_ERROR;
} }
switch(pubkey->type) { switch (pubkey->type) {
case SSH_KEYTYPE_RSA: case SSH_KEYTYPE_RSA:
case SSH_KEYTYPE_RSA_CERT01: case SSH_KEYTYPE_RSA_CERT01:
err = gcry_sexp_build(&sexp, err = gcry_sexp_build(&sexp,
NULL, NULL,
"(data(flags pkcs1)(hash %s %b))", "(data(flags pkcs1)(hash %s %b))",
hash_type, hlen, hash); hash_type,
hlen,
hash);
if (err) { if (err) {
SSH_LOG(SSH_LOG_TRACE, SSH_LOG(SSH_LOG_TRACE, "RSA hash error: %s", gcry_strerror(err));
"RSA hash error: %s",
gcry_strerror(err));
return SSH_ERROR; return SSH_ERROR;
} }
err = gcry_pk_verify(signature->rsa_sig, sexp, pubkey->rsa); err = gcry_pk_verify(signature->rsa_sig, sexp, pubkey->rsa);
@ -2212,9 +2280,7 @@ int pki_verify_data_signature(ssh_signature signature,
hlen, hlen,
hash); hash);
if (err) { if (err) {
SSH_LOG(SSH_LOG_TRACE, SSH_LOG(SSH_LOG_TRACE, "ECDSA hash error: %s", gcry_strerror(err));
"ECDSA hash error: %s",
gcry_strerror(err));
return SSH_ERROR; return SSH_ERROR;
} }
err = gcry_pk_verify(signature->ecdsa_sig, sexp, pubkey->ecdsa); err = gcry_pk_verify(signature->ecdsa_sig, sexp, pubkey->ecdsa);
@ -2283,11 +2349,10 @@ int ssh_key_size(ssh_key key)
#ifdef WITH_PKCS11_URI #ifdef WITH_PKCS11_URI
int pki_uri_import(const char *uri_name, ssh_key *key, enum ssh_key_e key_type) int pki_uri_import(const char *uri_name, ssh_key *key, enum ssh_key_e key_type)
{ {
(void) uri_name; (void)uri_name;
(void) key; (void)key;
(void) key_type; (void)key_type;
SSH_LOG(SSH_LOG_TRACE, SSH_LOG(SSH_LOG_TRACE, "gcrypt does not support PKCS #11");
"gcrypt does not support PKCS #11");
return SSH_ERROR; return SSH_ERROR;
} }
#endif /* WITH_PKCS11_URI */ #endif /* WITH_PKCS11_URI */