2 ecdsa.c -- ECDSA key handling
3 Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "../system.h"
24 #define __TINC_ECDSA_INTERNAL__
30 #include "../logger.h"
33 #include "../xalloc.h"
35 // Get and set ECDSA keys
37 ecdsa_t
*ecdsa_set_base64_public_key(const char *p
) {
41 logger(DEBUG_ALWAYS
, LOG_ERR
, "Invalid size %d for public key!", len
);
45 ecdsa_t
*ecdsa
= xzalloc(sizeof *ecdsa
);
46 len
= b64decode(p
, ecdsa
->public, len
);
48 logger(DEBUG_ALWAYS
, LOG_ERR
, "Invalid format of public key! len = %d", len
);
56 char *ecdsa_get_base64_public_key(ecdsa_t
*ecdsa
) {
57 char *base64
= xmalloc(44);
58 b64encode(ecdsa
->public, base64
, sizeof ecdsa
->public);
63 // Read PEM ECDSA keys
65 static bool read_pem(FILE *fp
, const char *type
, void *buf
, size_t size
) {
68 size_t typelen
= strlen(type
);
70 while(fgets(line
, sizeof line
, fp
)) {
72 if(strncmp(line
, "-----BEGIN ", 11))
74 if(strncmp(line
+ 11, type
, typelen
))
80 if(!strncmp(line
, "-----END ", 9))
83 size_t linelen
= strcspn(line
, "\r\n");
84 size_t len
= b64decode(line
, line
, linelen
);
86 logger(DEBUG_ALWAYS
, LOG_ERR
, "Invalid base64 data in PEM file\n");
91 logger(DEBUG_ALWAYS
, LOG_ERR
, "Too much base64 data in PEM file\n");
95 memcpy(buf
, line
, len
);
101 logger(DEBUG_ALWAYS
, LOG_ERR
, "Too little base64 data in PEM file\n");
108 ecdsa_t
*ecdsa_read_pem_public_key(FILE *fp
) {
109 ecdsa_t
*ecdsa
= xzalloc(sizeof *ecdsa
);
110 if(read_pem(fp
, "ED25519 PUBLIC KEY", ecdsa
->public, sizeof ecdsa
->public))
116 ecdsa_t
*ecdsa_read_pem_private_key(FILE *fp
) {
117 ecdsa_t
*ecdsa
= xmalloc(sizeof *ecdsa
);
118 if(read_pem(fp
, "ED25519 PRIVATE KEY", ecdsa
->private, sizeof *ecdsa
))
124 size_t ecdsa_size(ecdsa_t
*ecdsa
) {
128 // TODO: standardise output format?
130 bool ecdsa_sign(ecdsa_t
*ecdsa
, const void *in
, size_t len
, void *sig
) {
131 ed25519_sign(sig
, in
, len
, ecdsa
->public, ecdsa
->private);
135 bool ecdsa_verify(ecdsa_t
*ecdsa
, const void *in
, size_t len
, const void *sig
) {
136 return ed25519_verify(sig
, in
, len
, ecdsa
->public);
139 bool ecdsa_active(ecdsa_t
*ecdsa
) {
143 void ecdsa_free(ecdsa_t
*ecdsa
) {