// 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;
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;
// 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);
}
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;
}