Import Upstream version 1.1~pre17
This commit is contained in:
parent
bc8ca65653
commit
b511a112e6
216 changed files with 43313 additions and 18448 deletions
|
|
@ -55,7 +55,7 @@ static struct {
|
|||
static bool nametocipher(const char *name, int *algo, int *mode) {
|
||||
size_t i;
|
||||
|
||||
for(i = 0; i < sizeof ciphertable / sizeof *ciphertable; i++) {
|
||||
for(i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) {
|
||||
if(ciphertable[i].name && !strcasecmp(name, ciphertable[i].name)) {
|
||||
*algo = ciphertable[i].algo;
|
||||
*mode = ciphertable[i].mode;
|
||||
|
|
@ -69,7 +69,7 @@ static bool nametocipher(const char *name, int *algo, int *mode) {
|
|||
static bool nidtocipher(int nid, int *algo, int *mode) {
|
||||
size_t i;
|
||||
|
||||
for(i = 0; i < sizeof ciphertable / sizeof *ciphertable; i++) {
|
||||
for(i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) {
|
||||
if(nid == ciphertable[i].nid) {
|
||||
*algo = ciphertable[i].algo;
|
||||
*mode = ciphertable[i].mode;
|
||||
|
|
@ -83,7 +83,7 @@ static bool nidtocipher(int nid, int *algo, int *mode) {
|
|||
static bool ciphertonid(int algo, int mode, int *nid) {
|
||||
size_t i;
|
||||
|
||||
for(i = 0; i < sizeof ciphertable / sizeof *ciphertable; i++) {
|
||||
for(i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) {
|
||||
if(algo == ciphertable[i].algo && mode == ciphertable[i].mode) {
|
||||
*nid = ciphertable[i].nid;
|
||||
return true;
|
||||
|
|
@ -102,7 +102,7 @@ static bool cipher_open(cipher_t *cipher, int algo, int mode) {
|
|||
}
|
||||
|
||||
if((err = gcry_cipher_open(&cipher->handle, algo, mode, 0))) {
|
||||
logger(DEBUG_ALWAYS, LOG_DEBUG, "Unable to intialise cipher %d mode %d: %s", algo, mode, gcry_strerror(err));
|
||||
logger(DEBUG_ALWAYS, LOG_DEBUG, "Unable to initialise cipher %d mode %d: %s", algo, mode, gcry_strerror(err));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -146,10 +146,8 @@ void cipher_close(cipher_t *cipher) {
|
|||
cipher->handle = NULL;
|
||||
}
|
||||
|
||||
if(cipher->key) {
|
||||
free(cipher->key);
|
||||
cipher->key = NULL;
|
||||
}
|
||||
free(cipher->key);
|
||||
cipher->key = NULL;
|
||||
}
|
||||
|
||||
size_t cipher_keylength(const cipher_t *cipher) {
|
||||
|
|
@ -193,8 +191,9 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
|
|||
uint8_t pad[cipher->blklen];
|
||||
|
||||
if(cipher->padding) {
|
||||
if(!oneshot)
|
||||
if(!oneshot) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t reqlen = ((inlen + cipher->blklen) / cipher->blklen) * cipher->blklen;
|
||||
|
||||
|
|
@ -207,14 +206,16 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
|
|||
inlen = reqlen - cipher->blklen;
|
||||
|
||||
for(int i = 0; i < cipher->blklen; i++)
|
||||
if(i < cipher->blklen - padbyte)
|
||||
if(i < cipher->blklen - padbyte) {
|
||||
pad[i] = ((uint8_t *)indata)[inlen + i];
|
||||
else
|
||||
} else {
|
||||
pad[i] = padbyte;
|
||||
}
|
||||
}
|
||||
|
||||
if(oneshot)
|
||||
if(oneshot) {
|
||||
gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen);
|
||||
}
|
||||
|
||||
if((err = gcry_cipher_encrypt(cipher->handle, outdata, *outlen, indata, inlen))) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", gcry_strerror(err));
|
||||
|
|
@ -237,8 +238,9 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
|
|||
bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) {
|
||||
gcry_error_t err;
|
||||
|
||||
if(oneshot)
|
||||
if(oneshot) {
|
||||
gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen);
|
||||
}
|
||||
|
||||
if((err = gcry_cipher_decrypt(cipher->handle, outdata, *outlen, indata, inlen))) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: %s", gcry_strerror(err));
|
||||
|
|
@ -246,8 +248,9 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
|
|||
}
|
||||
|
||||
if(cipher->padding) {
|
||||
if(!oneshot)
|
||||
if(!oneshot) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t padbyte = ((uint8_t *)outdata)[inlen - 1];
|
||||
|
||||
|
|
@ -265,8 +268,9 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
|
|||
}
|
||||
|
||||
*outlen = origlen;
|
||||
} else
|
||||
} else {
|
||||
*outlen = inlen;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ static struct {
|
|||
static bool nametodigest(const char *name, int *algo) {
|
||||
int i;
|
||||
|
||||
for(i = 0; i < sizeof digesttable / sizeof *digesttable; i++) {
|
||||
for(i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) {
|
||||
if(digesttable[i].name && !strcasecmp(name, digesttable[i].name)) {
|
||||
*algo = digesttable[i].algo;
|
||||
return true;
|
||||
|
|
@ -50,7 +50,7 @@ static bool nametodigest(const char *name, int *algo) {
|
|||
static bool nidtodigest(int nid, int *algo) {
|
||||
int i;
|
||||
|
||||
for(i = 0; i < sizeof digesttable / sizeof *digesttable; i++) {
|
||||
for(i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) {
|
||||
if(nid == digesttable[i].nid) {
|
||||
*algo = digesttable[i].algo;
|
||||
return true;
|
||||
|
|
@ -63,7 +63,7 @@ static bool nidtodigest(int nid, int *algo) {
|
|||
static bool digesttonid(int algo, int *nid) {
|
||||
int i;
|
||||
|
||||
for(i = 0; i < sizeof digesttable / sizeof *digesttable; i++) {
|
||||
for(i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) {
|
||||
if(algo == digesttable[i].algo) {
|
||||
*nid = digesttable[i].nid;
|
||||
return true;
|
||||
|
|
@ -81,10 +81,11 @@ static bool digest_open(digest_t *digest, int algo, int maclength) {
|
|||
|
||||
unsigned int len = gcry_md_get_algo_dlen(algo);
|
||||
|
||||
if(maclength > len || maclength < 0)
|
||||
if(maclength > len || maclength < 0) {
|
||||
digest->maclength = len;
|
||||
else
|
||||
} else {
|
||||
digest->maclength = maclength;
|
||||
}
|
||||
|
||||
digest->algo = algo;
|
||||
digest->hmac = NULL;
|
||||
|
|
@ -119,16 +120,21 @@ bool digest_open_sha1(digest_t *digest, int maclength) {
|
|||
}
|
||||
|
||||
void digest_close(digest_t *digest) {
|
||||
if(digest->hmac)
|
||||
if(digest->hmac) {
|
||||
gcry_md_close(digest->hmac);
|
||||
}
|
||||
|
||||
digest->hmac = NULL;
|
||||
}
|
||||
|
||||
bool digest_set_key(digest_t *digest, const void *key, size_t len) {
|
||||
if(!digest->hmac)
|
||||
if(!digest->hmac) {
|
||||
gcry_md_open(&digest->hmac, digest->algo, GCRY_MD_FLAG_HMAC);
|
||||
if(!digest->hmac)
|
||||
}
|
||||
|
||||
if(!digest->hmac) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !gcry_md_setkey(digest->hmac, key, len);
|
||||
}
|
||||
|
|
@ -141,8 +147,11 @@ bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *out
|
|||
gcry_md_reset(digest->hmac);
|
||||
gcry_md_write(digest->hmac, indata, inlen);
|
||||
tmpdata = gcry_md_read(digest->hmac, digest->algo);
|
||||
if(!tmpdata)
|
||||
|
||||
if(!tmpdata) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(outdata, tmpdata, digest->maclength);
|
||||
} else {
|
||||
char tmpdata[len];
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
#ifndef TINC_GCRYPT_DIGEST_H
|
||||
#define TINC_GCRYPT_DIGEST_H
|
||||
|
||||
/*
|
||||
digest.h -- header file digest.c
|
||||
Copyright (C) 2007-2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
|
@ -17,9 +20,6 @@
|
|||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef __TINC_DIGEST_H__
|
||||
#define __TINC_DIGEST_H__
|
||||
|
||||
#include <gcrypt.h>
|
||||
|
||||
#define DIGEST_MAX_SIZE 64
|
||||
|
|
|
|||
|
|
@ -23,8 +23,9 @@
|
|||
#include "../ed25519/sha512.h"
|
||||
|
||||
static void memxor(char *buf, char c, size_t len) {
|
||||
for(size_t i = 0; i < len; i++)
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
buf[i] ^= c;
|
||||
}
|
||||
}
|
||||
|
||||
static const size_t mdlen = 64;
|
||||
|
|
@ -38,30 +39,39 @@ static bool hmac_sha512(const char *key, size_t keylen, const char *msg, size_t
|
|||
memcpy(tmp, key, keylen);
|
||||
memset(tmp + keylen, 0, blklen - keylen);
|
||||
} else {
|
||||
if(sha512(key, keylen, tmp) != 0)
|
||||
if(sha512(key, keylen, tmp) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(tmp + mdlen, 0, blklen - mdlen);
|
||||
}
|
||||
|
||||
if(sha512_init(&md) != 0)
|
||||
if(sha512_init(&md) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ipad
|
||||
memxor(tmp, 0x36, blklen);
|
||||
if(sha512_update(&md, tmp, blklen) != 0)
|
||||
|
||||
if(sha512_update(&md, tmp, blklen) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// message
|
||||
if(sha512_update(&md, msg, msglen) != 0)
|
||||
if(sha512_update(&md, msg, msglen) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(sha512_final(&md, tmp + blklen) != 0)
|
||||
if(sha512_final(&md, tmp + blklen) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// opad
|
||||
memxor(tmp, 0x36 ^ 0x5c, blklen);
|
||||
if(sha512(tmp, sizeof tmp, out) != 0)
|
||||
|
||||
if(sha512(tmp, sizeof(tmp), out) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -84,18 +94,23 @@ bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char
|
|||
|
||||
while(outlen > 0) {
|
||||
/* Inner HMAC */
|
||||
if(!hmac_sha512(secret, secretlen, data, sizeof data, data))
|
||||
if(!hmac_sha512(secret, secretlen, data, sizeof(data), data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Outer HMAC */
|
||||
if(outlen >= mdlen) {
|
||||
if(!hmac_sha512(secret, secretlen, data, sizeof data, out))
|
||||
if(!hmac_sha512(secret, secretlen, data, sizeof(data), out)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
out += mdlen;
|
||||
outlen -= mdlen;
|
||||
} else {
|
||||
if(!hmac_sha512(secret, secretlen, data, sizeof data, hash))
|
||||
if(!hmac_sha512(secret, secretlen, data, sizeof(data), hash)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(out, hash, outlen);
|
||||
out += outlen;
|
||||
outlen = 0;
|
||||
|
|
|
|||
141
src/gcrypt/rsa.c
141
src/gcrypt/rsa.c
|
|
@ -27,28 +27,28 @@
|
|||
// Base64 decoding table
|
||||
|
||||
static const uint8_t b64d[128] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
|
||||
0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
|
||||
0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
|
||||
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
|
||||
0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
|
||||
0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
||||
0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
|
||||
0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
|
||||
0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
|
||||
0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
|
||||
0x31, 0x32, 0x33, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
|
||||
0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
|
||||
0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
|
||||
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
|
||||
0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
|
||||
0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
||||
0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
|
||||
0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
|
||||
0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
|
||||
0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
|
||||
0x31, 0x32, 0x33, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff
|
||||
};
|
||||
|
||||
// PEM encoding/decoding functions
|
||||
|
|
@ -61,12 +61,15 @@ static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size,
|
|||
size_t i, j = 0;
|
||||
|
||||
while(!feof(fp)) {
|
||||
if(!fgets(line, sizeof line, fp))
|
||||
if(!fgets(line, sizeof(line), fp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!decode && !strncmp(line, "-----BEGIN ", 11)) {
|
||||
if(!strncmp(line + 11, header, strlen(header)))
|
||||
if(!strncmp(line + 11, header, strlen(header))) {
|
||||
decode = true;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -74,14 +77,18 @@ static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size,
|
|||
break;
|
||||
}
|
||||
|
||||
if(!decode)
|
||||
if(!decode) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for(i = 0; line[i] >= ' '; i++) {
|
||||
if((signed char)line[i] < 0 || b64d[(int)line[i]] == 0xff)
|
||||
if((signed char)line[i] < 0 || b64d[(int)line[i]] == 0xff) {
|
||||
break;
|
||||
}
|
||||
|
||||
word |= b64d[(int)line[i]] << shift;
|
||||
shift -= 6;
|
||||
|
||||
if(shift <= 2) {
|
||||
if(j > size) {
|
||||
errno = ENOMEM;
|
||||
|
|
@ -95,8 +102,10 @@ static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size,
|
|||
}
|
||||
}
|
||||
|
||||
if(outsize)
|
||||
if(outsize) {
|
||||
*outsize = j;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -104,20 +113,25 @@ static bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size,
|
|||
// BER decoding functions
|
||||
|
||||
static int ber_read_id(unsigned char **p, size_t *buflen) {
|
||||
if(*buflen <= 0)
|
||||
if(*buflen <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((**p & 0x1f) == 0x1f) {
|
||||
int id = 0;
|
||||
bool more;
|
||||
|
||||
while(*buflen > 0) {
|
||||
id <<= 7;
|
||||
id |= **p & 0x7f;
|
||||
more = *(*p)++ & 0x80;
|
||||
(*buflen)--;
|
||||
if(!more)
|
||||
|
||||
if(!more) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return id;
|
||||
} else {
|
||||
(*buflen)--;
|
||||
|
|
@ -126,15 +140,18 @@ static int ber_read_id(unsigned char **p, size_t *buflen) {
|
|||
}
|
||||
|
||||
static size_t ber_read_len(unsigned char **p, size_t *buflen) {
|
||||
if(*buflen <= 0)
|
||||
if(*buflen <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(**p & 0x80) {
|
||||
size_t result = 0;
|
||||
int len = *(*p)++ & 0x7f;
|
||||
(*buflen)--;
|
||||
if(len > *buflen)
|
||||
|
||||
if(len > *buflen) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while(len--) {
|
||||
result <<= 8;
|
||||
|
|
@ -155,8 +172,10 @@ static bool ber_read_sequence(unsigned char **p, size_t *buflen, size_t *result)
|
|||
size_t len = ber_read_len(p, buflen);
|
||||
|
||||
if(tag == 0x10) {
|
||||
if(result)
|
||||
if(result) {
|
||||
*result = len;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
|
@ -168,11 +187,13 @@ static bool ber_read_mpi(unsigned char **p, size_t *buflen, gcry_mpi_t *mpi) {
|
|||
size_t len = ber_read_len(p, buflen);
|
||||
gcry_error_t err = 0;
|
||||
|
||||
if(tag != 0x02 || len > *buflen)
|
||||
if(tag != 0x02 || len > *buflen) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(mpi)
|
||||
if(mpi) {
|
||||
err = gcry_mpi_scan(mpi, GCRYMPI_FMT_USG, *p, len, NULL);
|
||||
}
|
||||
|
||||
*p += len;
|
||||
*buflen -= len;
|
||||
|
|
@ -184,7 +205,7 @@ bool rsa_set_hex_public_key(rsa_t *rsa, char *n, char *e) {
|
|||
gcry_error_t err = 0;
|
||||
|
||||
err = gcry_mpi_scan(&rsa->n, GCRYMPI_FMT_HEX, n, 0, NULL)
|
||||
?: gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL);
|
||||
? : gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL);
|
||||
|
||||
if(err) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading RSA public key: %s", gcry_strerror(errno));
|
||||
|
|
@ -198,8 +219,8 @@ bool rsa_set_hex_private_key(rsa_t *rsa, char *n, char *e, char *d) {
|
|||
gcry_error_t err = 0;
|
||||
|
||||
err = gcry_mpi_scan(&rsa->n, GCRYMPI_FMT_HEX, n, 0, NULL)
|
||||
?: gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL)
|
||||
?: gcry_mpi_scan(&rsa->d, GCRYMPI_FMT_HEX, d, 0, NULL);
|
||||
? : gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL)
|
||||
? : gcry_mpi_scan(&rsa->d, GCRYMPI_FMT_HEX, d, 0, NULL);
|
||||
|
||||
if(err) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading RSA public key: %s", gcry_strerror(errno));
|
||||
|
|
@ -215,15 +236,15 @@ bool rsa_read_pem_public_key(rsa_t *rsa, FILE *fp) {
|
|||
uint8_t derbuf[8096], *derp = derbuf;
|
||||
size_t derlen;
|
||||
|
||||
if(!pem_decode(fp, "RSA PUBLIC KEY", derbuf, sizeof derbuf, &derlen)) {
|
||||
if(!pem_decode(fp, "RSA PUBLIC KEY", derbuf, sizeof(derbuf), &derlen)) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA public key: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!ber_read_sequence(&derp, &derlen, NULL)
|
||||
|| !ber_read_mpi(&derp, &derlen, &rsa->n)
|
||||
|| !ber_read_mpi(&derp, &derlen, &rsa->e)
|
||||
|| derlen) {
|
||||
|| !ber_read_mpi(&derp, &derlen, &rsa->n)
|
||||
|| !ber_read_mpi(&derp, &derlen, &rsa->e)
|
||||
|| derlen) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while decoding RSA public key");
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -235,22 +256,22 @@ bool rsa_read_pem_private_key(rsa_t *rsa, FILE *fp) {
|
|||
uint8_t derbuf[8096], *derp = derbuf;
|
||||
size_t derlen;
|
||||
|
||||
if(!pem_decode(fp, "RSA PRIVATE KEY", derbuf, sizeof derbuf, &derlen)) {
|
||||
if(!pem_decode(fp, "RSA PRIVATE KEY", derbuf, sizeof(derbuf), &derlen)) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA private key: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!ber_read_sequence(&derp, &derlen, NULL)
|
||||
|| !ber_read_mpi(&derp, &derlen, NULL)
|
||||
|| !ber_read_mpi(&derp, &derlen, &rsa->n)
|
||||
|| !ber_read_mpi(&derp, &derlen, &rsa->e)
|
||||
|| !ber_read_mpi(&derp, &derlen, &rsa->d)
|
||||
|| !ber_read_mpi(&derp, &derlen, NULL) // p
|
||||
|| !ber_read_mpi(&derp, &derlen, NULL) // q
|
||||
|| !ber_read_mpi(&derp, &derlen, NULL)
|
||||
|| !ber_read_mpi(&derp, &derlen, NULL)
|
||||
|| !ber_read_mpi(&derp, &derlen, NULL) // u
|
||||
|| derlen) {
|
||||
|| !ber_read_mpi(&derp, &derlen, NULL)
|
||||
|| !ber_read_mpi(&derp, &derlen, &rsa->n)
|
||||
|| !ber_read_mpi(&derp, &derlen, &rsa->e)
|
||||
|| !ber_read_mpi(&derp, &derlen, &rsa->d)
|
||||
|| !ber_read_mpi(&derp, &derlen, NULL) // p
|
||||
|| !ber_read_mpi(&derp, &derlen, NULL) // q
|
||||
|| !ber_read_mpi(&derp, &derlen, NULL)
|
||||
|| !ber_read_mpi(&derp, &derlen, NULL)
|
||||
|| !ber_read_mpi(&derp, &derlen, NULL) // u
|
||||
|| derlen) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while decoding RSA private key");
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -277,10 +298,12 @@ bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) {
|
|||
gcry_mpi_powm(outmpi, inmpi, rsa->e, rsa->n);
|
||||
|
||||
int pad = len - (gcry_mpi_get_nbits(outmpi) + 7) / 8;
|
||||
while(pad--)
|
||||
*(char *)out++ = 0;
|
||||
|
||||
check(gcry_mpi_print(GCRYMPI_FMT_USG, out,len, NULL, outmpi));
|
||||
while(pad--) {
|
||||
*(char *)out++ = 0;
|
||||
}
|
||||
|
||||
check(gcry_mpi_print(GCRYMPI_FMT_USG, out, len, NULL, outmpi));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -293,10 +316,12 @@ bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) {
|
|||
gcry_mpi_powm(outmpi, inmpi, rsa->d, rsa->n);
|
||||
|
||||
int pad = len - (gcry_mpi_get_nbits(outmpi) + 7) / 8;
|
||||
while(pad--)
|
||||
*(char *)out++ = 0;
|
||||
|
||||
check(gcry_mpi_print(GCRYMPI_FMT_USG, out,len, NULL, outmpi));
|
||||
while(pad--) {
|
||||
*(char *)out++ = 0;
|
||||
}
|
||||
|
||||
check(gcry_mpi_print(GCRYMPI_FMT_USG, out, len, NULL, outmpi));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,14 +44,16 @@ static bool pem_encode(FILE *fp, const char *header, uint8_t *buf, size_t size)
|
|||
word = buf[i] << 16 | buf[i + 1] << 8 | buf[i + 2];
|
||||
} else {
|
||||
word = buf[i] << 16;
|
||||
if(i == size - 2)
|
||||
|
||||
if(i == size - 2) {
|
||||
word |= buf[i + 1] << 8;
|
||||
}
|
||||
}
|
||||
|
||||
line[j++] = b64e[(word >> 18) ];
|
||||
line[j++] = b64e[(word >> 12) & 0x3f];
|
||||
line[j++] = b64e[(word >> 6) & 0x3f];
|
||||
line[j++] = b64e[(word ) & 0x3f];
|
||||
line[j++] = b64e[(word) & 0x3f];
|
||||
|
||||
if(j >= 64) {
|
||||
line[j++] = '\n';
|
||||
|
|
@ -62,8 +64,10 @@ static bool pem_encode(FILE *fp, const char *header, uint8_t *buf, size_t size)
|
|||
}
|
||||
|
||||
if(size % 3 > 0) {
|
||||
if(size % 3 > 1)
|
||||
if(size % 3 > 1) {
|
||||
line[j++] = '=';
|
||||
}
|
||||
|
||||
line[j++] = '=';
|
||||
}
|
||||
|
||||
|
|
@ -82,19 +86,24 @@ static bool pem_encode(FILE *fp, const char *header, uint8_t *buf, size_t size)
|
|||
// BER encoding functions
|
||||
|
||||
static bool ber_write_id(uint8_t **p, size_t *buflen, int id) {
|
||||
if(*buflen <= 0)
|
||||
if(*buflen <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(id >= 0x1f) {
|
||||
while(id) {
|
||||
if(*buflen <= 0)
|
||||
if(*buflen <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
(*buflen)--;
|
||||
**p = id & 0x7f;
|
||||
id >>= 7;
|
||||
if(id)
|
||||
|
||||
if(id) {
|
||||
**p |= 0x80;
|
||||
}
|
||||
|
||||
(*p)++;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -107,14 +116,18 @@ static bool ber_write_id(uint8_t **p, size_t *buflen, int id) {
|
|||
|
||||
static bool ber_write_len(uint8_t **p, size_t *buflen, size_t len) {
|
||||
do {
|
||||
if(*buflen <= 0)
|
||||
if(*buflen <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
(*buflen)--;
|
||||
**p = len & 0x7f;
|
||||
len >>= 7;
|
||||
if(len)
|
||||
|
||||
if(len) {
|
||||
**p |= 0x80;
|
||||
}
|
||||
|
||||
(*p)++;
|
||||
} while(len);
|
||||
|
||||
|
|
@ -122,8 +135,9 @@ static bool ber_write_len(uint8_t **p, size_t *buflen, size_t len) {
|
|||
}
|
||||
|
||||
static bool ber_write_sequence(uint8_t **p, size_t *buflen, uint8_t *seqbuf, size_t seqlen) {
|
||||
if(!ber_write_id(p, buflen, 0x10) || !ber_write_len(p, buflen, seqlen) || *buflen < seqlen)
|
||||
if(!ber_write_id(p, buflen, 0x10) || !ber_write_len(p, buflen, seqlen) || *buflen < seqlen) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(*p, seqbuf, seqlen);
|
||||
*p += seqlen;
|
||||
|
|
@ -134,15 +148,18 @@ static bool ber_write_sequence(uint8_t **p, size_t *buflen, uint8_t *seqbuf, siz
|
|||
|
||||
static bool ber_write_mpi(uint8_t **p, size_t *buflen, gcry_mpi_t mpi) {
|
||||
uint8_t tmpbuf[1024];
|
||||
size_t tmplen = sizeof tmpbuf;
|
||||
size_t tmplen = sizeof(tmpbuf);
|
||||
gcry_error_t err;
|
||||
|
||||
err = gcry_mpi_aprint(GCRYMPI_FMT_USG, &tmpbuf, &tmplen, mpi);
|
||||
if(err)
|
||||
return false;
|
||||
|
||||
if(!ber_write_id(p, buflen, 0x02) || !ber_write_len(p, buflen, tmplen) || *buflen < tmplen)
|
||||
if(err) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!ber_write_id(p, buflen, 0x02) || !ber_write_len(p, buflen, tmplen) || *buflen < tmplen) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(*p, tmpbuf, tmplen);
|
||||
*p += tmplen;
|
||||
|
|
@ -158,12 +175,12 @@ bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) {
|
|||
uint8_t derbuf2[8096];
|
||||
uint8_t *derp1 = derbuf1;
|
||||
uint8_t *derp2 = derbuf2;
|
||||
size_t derlen1 = sizeof derbuf1;
|
||||
size_t derlen2 = sizeof derbuf2;
|
||||
size_t derlen1 = sizeof(derbuf1);
|
||||
size_t derlen2 = sizeof(derbuf2);
|
||||
|
||||
if(!ber_write_mpi(&derp1, &derlen1, &rsa->n)
|
||||
|| !ber_write_mpi(&derp1, &derlen1, &rsa->e)
|
||||
|| !ber_write_sequence(&derp2, &derlen2, derbuf1, derlen1)) {
|
||||
|| !ber_write_mpi(&derp1, &derlen1, &rsa->e)
|
||||
|| !ber_write_sequence(&derp2, &derlen2, derbuf1, derlen1)) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while encoding RSA public key");
|
||||
return false;
|
||||
}
|
||||
|
|
@ -181,28 +198,30 @@ bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) {
|
|||
uint8_t derbuf2[8096];
|
||||
uint8_t *derp1 = derbuf1;
|
||||
uint8_t *derp2 = derbuf2;
|
||||
size_t derlen1 = sizeof derbuf1;
|
||||
size_t derlen2 = sizeof derbuf2;
|
||||
size_t derlen1 = sizeof(derbuf1);
|
||||
size_t derlen2 = sizeof(derbuf2);
|
||||
|
||||
if(!ber_write_mpi(&derp1, &derlen1, &bits)
|
||||
|| ber_write_mpi(&derp1, &derlen1, &rsa->n) // modulus
|
||||
|| ber_write_mpi(&derp1, &derlen1, &rsa->e) // public exponent
|
||||
|| ber_write_mpi(&derp1, &derlen1, &rsa->d) // private exponent
|
||||
|| ber_write_mpi(&derp1, &derlen1, &p)
|
||||
|| ber_write_mpi(&derp1, &derlen1, &q)
|
||||
|| ber_write_mpi(&derp1, &derlen1, &exp1)
|
||||
|| ber_write_mpi(&derp1, &derlen1, &exp2)
|
||||
|| ber_write_mpi(&derp1, &derlen1, &coeff))
|
||||
|| ber_write_mpi(&derp1, &derlen1, &rsa->n) // modulus
|
||||
|| ber_write_mpi(&derp1, &derlen1, &rsa->e) // public exponent
|
||||
|| ber_write_mpi(&derp1, &derlen1, &rsa->d) // private exponent
|
||||
|| ber_write_mpi(&derp1, &derlen1, &p)
|
||||
|| ber_write_mpi(&derp1, &derlen1, &q)
|
||||
|| ber_write_mpi(&derp1, &derlen1, &exp1)
|
||||
|| ber_write_mpi(&derp1, &derlen1, &exp2)
|
||||
|| ber_write_mpi(&derp1, &derlen1, &coeff)) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Error while encoding RSA private key");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!pem_encode(fp, "RSA PRIVATE KEY", derbuf2, derlen2)) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Unable to write RSA private key: %s", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
if(!pem_encode(fp, "RSA PRIVATE KEY", derbuf2, derlen2)) {
|
||||
logger(DEBUG_ALWAYS, LOG_ERR, "Unable to write RSA private key: %s", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue