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:
parent
f0e7e6b03e
commit
666718998e
3 changed files with 64 additions and 5 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue