summaryrefslogtreecommitdiff
path: root/xs_openssl.h
diff options
context:
space:
mode:
Diffstat (limited to 'xs_openssl.h')
-rw-r--r--xs_openssl.h159
1 files changed, 159 insertions, 0 deletions
diff --git a/xs_openssl.h b/xs_openssl.h
new file mode 100644
index 0000000..a6a17b1
--- /dev/null
+++ b/xs_openssl.h
@@ -0,0 +1,159 @@
1/* copyright (c) 2022 grunfink - MIT license */
2
3#ifndef _XS_OPENSSL_H
4
5#define _XS_OPENSSL_H
6
7d_char *xs_md5_hex(const void *input, int size);
8d_char *xs_sha1_hex(const void *input, int size);
9d_char *xs_sha256_hex(const void *input, int size);
10d_char *xs_rsa_genkey(int bits);
11d_char *xs_rsa_sign(char *secret, char *mem, int size);
12int xs_rsa_verify(char *pubkey, char *mem, int size, char *b64sig);
13
14
15#ifdef XS_IMPLEMENTATION
16
17#include "openssl/md5.h"
18#include "openssl/sha.h"
19#include "openssl/rsa.h"
20#include "openssl/pem.h"
21
22d_char *xs_md5_hex(const void *input, int size)
23{
24 unsigned char md5[16];
25 MD5_CTX ctx;
26
27 MD5_Init(&ctx);
28 MD5_Update(&ctx, input, size);
29 MD5_Final(md5, &ctx);
30
31 return xs_hex_enc((char *)md5, sizeof(md5));
32}
33
34
35d_char *xs_sha1_hex(const void *input, int size)
36{
37 unsigned char sha1[20];
38 SHA_CTX ctx;
39
40 SHA1_Init(&ctx);
41 SHA1_Update(&ctx, input, size);
42 SHA1_Final(sha1, &ctx);
43
44 return xs_hex_enc((char *)sha1, sizeof(sha1));
45}
46
47
48d_char *xs_sha256_hex(const void *input, int size)
49{
50 unsigned char sha256[32];
51 SHA256_CTX ctx;
52
53 SHA256_Init(&ctx);
54 SHA256_Update(&ctx, input, size);
55 SHA256_Final(sha256, &ctx);
56
57 return xs_hex_enc((char *)sha256, sizeof(sha256));
58}
59
60
61d_char *xs_rsa_genkey(int bits)
62/* generates an RSA keypair */
63{
64 BIGNUM *bne;
65 RSA *rsa;
66 d_char *keypair = NULL;
67
68 if ((bne = BN_new()) != NULL) {
69 if (BN_set_word(bne, RSA_F4) == 1) {
70 if ((rsa = RSA_new()) != NULL) {
71 if (RSA_generate_key_ex(rsa, bits, bne, NULL) == 1) {
72 BIO *bs = BIO_new(BIO_s_mem());
73 BIO *bp = BIO_new(BIO_s_mem());
74 BUF_MEM *sptr;
75 BUF_MEM *pptr;
76
77 PEM_write_bio_RSAPrivateKey(bs, rsa, NULL, NULL, 0, 0, NULL);
78 BIO_get_mem_ptr(bs, &sptr);
79
80 PEM_write_bio_RSA_PUBKEY(bp, rsa);
81 BIO_get_mem_ptr(bp, &pptr);
82
83 keypair = xs_dict_new();
84
85 keypair = xs_dict_append(keypair, "secret", sptr->data);
86 keypair = xs_dict_append(keypair, "public", pptr->data);
87
88 BIO_free(bs);
89 BIO_free(bp);
90 }
91 }
92 }
93 }
94
95 return keypair;
96}
97
98
99d_char *xs_rsa_sign(char *secret, char *mem, int size)
100/* signs a memory block (secret is in PEM format) */
101{
102 d_char *signature = NULL;
103 BIO *b;
104 RSA *rsa;
105 unsigned char *sig;
106 unsigned int sig_len;
107
108 /* un-PEM the key */
109 b = BIO_new_mem_buf(secret, strlen(secret));
110 rsa = PEM_read_bio_RSAPrivateKey(b, NULL, NULL, NULL);
111
112 /* alloc space */
113 sig = malloc(RSA_size(rsa));
114
115 if (RSA_sign(NID_sha256, (unsigned char *)mem, size, sig, &sig_len, rsa) == 1)
116 signature = xs_base64_enc((char *)sig, sig_len);
117
118 BIO_free(b);
119 RSA_free(rsa);
120 free(sig);
121
122 return signature;
123}
124
125
126int xs_rsa_verify(char *pubkey, char *mem, int size, char *b64sig)
127/* verifies a base64 block, returns non-zero on ok */
128{
129 int r = 0;
130 BIO *b;
131 RSA *rsa;
132
133 /* un-PEM the key */
134 b = BIO_new_mem_buf(pubkey, strlen(pubkey));
135 rsa = PEM_read_bio_RSA_PUBKEY(b, NULL, NULL, NULL);
136
137 if (rsa != NULL) {
138 d_char *sig = NULL;
139 int s_size;
140
141 /* de-base64 */
142 sig = xs_base64_dec(b64sig, &s_size);
143
144 if (sig != NULL)
145 r = RSA_verify(NID_sha256, (unsigned char *)mem, size,
146 (unsigned char *)sig, s_size, rsa);
147
148 free(sig);
149 }
150
151 BIO_free(b);
152 RSA_free(rsa);
153
154 return r;
155}
156
157#endif /* XS_IMPLEMENTATION */
158
159#endif /* _XS_OPENSSL_H */