X-Git-Url: https://tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fed25519%2Fecdsa.c;h=f8aafe460b128868f9f63dd36c0ad47b0ebeead4;hb=cffcaf966b65a61943a00120f1ec5c868c917c1f;hp=4515131a0cd1c9c56648d5fd7e6dd622618a827f;hpb=27acb5d04792f2da70e937543de9110e16aae21c;p=tinc diff --git a/src/ed25519/ecdsa.c b/src/ed25519/ecdsa.c index 4515131a..f8aafe46 100644 --- a/src/ed25519/ecdsa.c +++ b/src/ed25519/ecdsa.c @@ -62,9 +62,59 @@ char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) { // Read PEM ECDSA keys +static bool read_pem(FILE *fp, const char *type, void *buf, size_t size) { + char line[1024]; + bool data = false; + size_t typelen = strlen(type); + + 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) + if(read_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof ecdsa->public)) return ecdsa; free(ecdsa); return 0; @@ -72,7 +122,7 @@ ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) { ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) { ecdsa_t *ecdsa = xmalloc(sizeof *ecdsa); - if(fread(ecdsa, sizeof *ecdsa, 1, fp) == 1) + if(read_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof *ecdsa)) return ecdsa; free(ecdsa); return 0;