X-Git-Url: https://tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fed25519%2Fecdsa.c;h=4bd71556ee9efa06006e9b7e62260382f9c47dc6;hb=7b55200887d05c29abb8cea31aa914e03b806e9a;hp=1da27977560518afd6c519ac7edfa76a1074d545;hpb=2f01744f82be542894fe2ceecbfb9ead93c9ffa5;p=tinc diff --git a/src/ed25519/ecdsa.c b/src/ed25519/ecdsa.c index 1da27977..4bd71556 100644 --- a/src/ed25519/ecdsa.c +++ b/src/ed25519/ecdsa.c @@ -21,7 +21,7 @@ #include "ed25519.h" -#define __TINC_ECDSA_INTERNAL__ +#define TINC_ECDSA_INTERNAL typedef struct { uint8_t private[64]; uint8_t public[32]; @@ -38,12 +38,13 @@ ecdsa_t *ecdsa_set_base64_public_key(const char *p) { int len = strlen(p); if(len != 43) { - logger(DEBUG_ALWAYS, LOG_ERR, "Invalid size %s for public key!", len); + logger(DEBUG_ALWAYS, LOG_ERR, "Invalid size %d for public key!", len); return 0; } - ecdsa_t *ecdsa = xzalloc(sizeof *ecdsa); + ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa)); len = b64decode(p, ecdsa->public, len); + if(len != 32) { logger(DEBUG_ALWAYS, LOG_ERR, "Invalid format of public key! len = %d", len); free(ecdsa); @@ -55,30 +56,95 @@ ecdsa_t *ecdsa_set_base64_public_key(const char *p) { char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) { char *base64 = xmalloc(44); - b64encode(ecdsa->public, base64, sizeof ecdsa->public); + b64encode(ecdsa->public, base64, sizeof(ecdsa->public)); return base64; } // Read PEM ECDSA keys +static bool read_pem(FILE *fp, const char *type, void *vbuf, size_t size) { + char line[1024]; + bool data = false; + size_t typelen = strlen(type); + char *buf = vbuf; + + while(fgets(line, sizeof(line), fp)) { + if(!data) { + if(strncmp(line, "-----BEGIN ", 11)) { + continue; + } + + if(strncmp(line + 11, type, typelen)) { + continue; + } + + data = true; + continue; + } + + if(!strncmp(line, "-----END ", 9)) { + break; + } + + size_t linelen = strcspn(line, "\r\n"); + size_t len = b64decode(line, line, linelen); + + if(!len) { + logger(DEBUG_ALWAYS, LOG_ERR, "Invalid base64 data in PEM file\n"); + errno = EINVAL; + return false; + } + + if(len > size) { + logger(DEBUG_ALWAYS, LOG_ERR, "Too much base64 data in PEM file\n"); + errno = EINVAL; + return false; + } + + memcpy(buf, line, len); + buf += len; + size -= len; + } + + if(size) { + if(data) { + errno = EINVAL; + logger(DEBUG_ALWAYS, LOG_ERR, "Too little base64 data in PEM file\n"); + } else { + errno = ENOENT; + } + + return false; + } + + return true; +} + ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) { - ecdsa_t *ecdsa = xzalloc(sizeof *ecdsa); - if(fread(ecdsa->public, sizeof ecdsa->public, 1, fp) == 1) + ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa)); + + if(read_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof(ecdsa->public))) { return ecdsa; + } + free(ecdsa); return 0; } ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) { - ecdsa_t *ecdsa = xmalloc(sizeof *ecdsa); - if(fread(ecdsa, sizeof *ecdsa, 1, fp) == 1) + ecdsa_t *ecdsa = xmalloc(sizeof(*ecdsa)); + + if(read_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof(*ecdsa))) { return ecdsa; + } + free(ecdsa); return 0; } size_t ecdsa_size(ecdsa_t *ecdsa) { + (void)ecdsa; return 64; }