Commit | Line | Data |
---|---|---|
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 | ||
15 | typedef 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 | ||
38 | static uschar *enc64table = | |
39 | US"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
40 | ||
41 | uschar * | |
42 | b64encode(uschar *clear, int len) | |
43 | { | |
44 | uschar *code = malloc(4*((len+2)/3) + 2); | |
45 | uschar *p = code; | |
46 | ||
47 | while (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 | ||
80 | return code; | |
81 | } | |
82 | ||
83 | /************************************************* | |
84 | * Main Program * | |
85 | *************************************************/ | |
86 | ||
87 | ||
88 | int | |
89 | main(int argc, char **argv) | |
90 | { | |
91 | uschar * pemfile = argv[1]; | |
92 | int fd; | |
93 | uschar buf[1024]; | |
94 | int len, rc; | |
95 | gnutls_privkey_t privkey; | |
96 | gnutls_datum_t k; | |
97 | gnutls_pubkey_t pubkey; | |
98 | uschar * b64; | |
99 | ||
100 | #ifdef SIGN_HAVE_ED25519 | |
101 | if ((fd = open(CS pemfile, O_RDONLY)) < 0) | |
102 | exit(1); | |
103 | ||
104 | if ((len = read(fd, buf, sizeof(buf)-1)) < 0) | |
105 | exit(2); | |
106 | ||
107 | k.data = buf; | |
108 | k.size = len; | |
109 | ||
110 | if ( (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 | ||
118 | b64 = b64encode(k.data, k.size); | |
119 | ||
120 | printf("%s\n", b64); | |
121 | exit(0); | |
122 | ||
123 | #else | |
124 | fprintf(stderr, "No support for ed25519 signing in GnuTLS (version %s)\n", gnutls_check_version(NULL)); | |
125 | exit(3); | |
126 | #endif | |
127 | } | |
128 | ||
129 | #endif | |
130 | ||
131 | #ifdef HAVE_OPENSSL | |
132 | int | |
133 | main(int argc, char **argv) | |
134 | { | |
135 | fprintf(stderr, "No support for ed25519 signing in OpenSSL\n"); | |
136 | exit(3); | |
137 | } | |
138 | ||
139 | #endif |