DKIM: move ed25519_privkey_pem_to_pubkey_raw_b64 to src/util/ and add usage notes...
[exim.git] / src / util / src / ed25519_privkey_pem_to_pubkey_raw_b64.c
CommitLineData
286b9d5f
JH
1
2#include <sys/types.h>
3#include <sys/stat.h>
4#include <fcntl.h>
5
6#include <stdarg.h>
7#include <stddef.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11#include <unistd.h>
12
13/* Unix includes */
14
15typedef unsigned char uschar;
16
17#define CS (char *)
18#define US (unsigned char *)
19
20#define FALSE 0
21#define TRUE 1
22
23
24
25#ifdef HAVE_GNUTLS
26
27
28#include <gnutls/gnutls.h>
29#include <gnutls/abstract.h>
30#include <gnutls/x509.h>
31
32#if GNUTLS_VERSION_NUMBER >= 0x030600
33# define SIGN_HAVE_ED25519
34#endif
35
36
37
38static uschar *enc64table =
39 US"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
40
41uschar *
42b64encode(uschar *clear, int len)
43{
44uschar *code = malloc(4*((len+2)/3) + 2);
45uschar *p = code;
46
47while (len-- >0)
48 {
49 int x, y;
50
51 x = *clear++;
52 *p++ = enc64table[(x >> 2) & 63];
53
54 if (len-- <= 0)
55 {
56 *p++ = enc64table[(x << 4) & 63];
57 *p++ = '=';
58 *p++ = '=';
59 break;
60 }
61
62 y = *clear++;
63 *p++ = enc64table[((x << 4) | ((y >> 4) & 15)) & 63];
64
65 if (len-- <= 0)
66 {
67 *p++ = enc64table[(y << 2) & 63];
68 *p++ = '=';
69 break;
70 }
71
72 x = *clear++;
73 *p++ = enc64table[((y << 2) | ((x >> 6) & 3)) & 63];
74
75 *p++ = enc64table[x & 63];
76 }
77
78*p = 0;
79
80return code;
81}
82
83/*************************************************
84* Main Program *
85*************************************************/
86
87
88int
89main(int argc, char **argv)
90{
91uschar * pemfile = argv[1];
92int fd;
93uschar buf[1024];
94int len, rc;
95gnutls_privkey_t privkey;
96gnutls_datum_t k;
97gnutls_pubkey_t pubkey;
98uschar * b64;
99
100#ifdef SIGN_HAVE_ED25519
101if ((fd = open(CS pemfile, O_RDONLY)) < 0)
102 exit(1);
103
104if ((len = read(fd, buf, sizeof(buf)-1)) < 0)
105 exit(2);
106
107k.data = buf;
108k.size = len;
109
110if ( (rc = gnutls_privkey_init(&privkey))
111 || (rc = gnutls_privkey_import_x509_raw(privkey, &k, GNUTLS_X509_FMT_PEM, NULL, GNUTLS_PKCS_PLAIN))
112 || (rc = gnutls_pubkey_init(&pubkey))
113 || (rc = gnutls_pubkey_import_privkey(pubkey, privkey, GNUTLS_KEY_DIGITAL_SIGNATURE, 0))
114 || (rc = gnutls_pubkey_export_ecc_raw2(pubkey, NULL, &k, NULL, GNUTLS_EXPORT_FLAG_NO_LZ))
115 )
116 fprintf(stderr, "%s\n", gnutls_strerror(rc));
117
118b64 = b64encode(k.data, k.size);
119
120printf("%s\n", b64);
121exit(0);
122
123#else
124fprintf(stderr, "No support for ed25519 signing in GnuTLS (version %s)\n", gnutls_check_version(NULL));
125exit(3);
126#endif
127}
128
129#endif
130
131#ifdef HAVE_OPENSSL
132int
133main(int argc, char **argv)
134{
135fprintf(stderr, "No support for ed25519 signing in OpenSSL\n");
136exit(3);
137}
138
139#endif