Implement a PEM-like format for Ed25519 keys.

We don't require compatibility with any other software, but we do want Ed25519 keys to work
the same as RSA keys for now.
This commit is contained in:
Guus Sliepen 2014-05-18 20:49:35 +02:00
parent f0e7e6b03e
commit 666718998e
3 changed files with 64 additions and 5 deletions

View file

@ -62,9 +62,52 @@ 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");
return false;
}
if(len > size) {
logger(DEBUG_ALWAYS, LOG_ERR, "Too much base64 data in PEM file\n");
return false;
}
memcpy(buf, line, len);
buf += len;
size -= len;
}
if(size) {
logger(DEBUG_ALWAYS, LOG_ERR, "Too little base64 data in PEM file\n");
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 +115,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;

View file

@ -46,10 +46,26 @@ ecdsa_t *ecdsa_generate(void) {
// Write PEM ECDSA keys
static bool write_pem(FILE *fp, const char *type, void *buf, size_t size) {
fprintf(fp, "-----BEGIN %s-----\n", type);
char base64[65];
while(size) {
size_t todo = size > 48 ? 48 : size;
b64encode(buf, base64, todo);
fprintf(fp, "%s\n", base64);
buf += todo;
size -= todo;
}
fprintf(fp, "-----END %s-----\n", type);
return !ferror(fp);
}
bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) {
return fwrite(ecdsa->public, sizeof ecdsa->public, 1, fp) == 1;
return write_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof ecdsa->public);
}
bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) {
return fwrite(ecdsa, sizeof *ecdsa, 1, fp) == 1;
return write_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof *ecdsa);
}

View file

@ -246,7 +246,7 @@ static void disable_old_keys(const char *filename, const char *what) {
while(fgets(buf, sizeof buf, r)) {
if(!block && !strncmp(buf, "-----BEGIN ", 11)) {
if((strstr(buf, " RSA ") && strstr(what, "RSA"))) {
if((strstr(buf, " ED25519 ") && strstr(what, "Ed25519")) || (strstr(buf, " RSA ") && strstr(what, "RSA"))) {
disabled = true;
block = true;
}