Mstdlib-1.24.0
m_tls_certs.h
1/* The MIT License (MIT)
2 *
3 * Copyright (c) 2017 Monetra Technologies, LLC.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 */
23
24#ifndef __M_TLS_CERTS__
25#define __M_TLS_CERTS__
26
27/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
28
29#include <mstdlib/base/m_defs.h>
30#include <mstdlib/base/m_types.h>
31
32/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
33
34__BEGIN_DECLS
35
36/*! \addtogroup m_tls_certs TLS Certificates
37 * \ingroup m_tls
38 *
39 * Basic TLS certificate functionality. This is primary used
40 * to aid in generating self signed certificates programmatically.
41 *
42 * \warning
43 * These functions are experimental and unstable. They should not
44 * be used in production at this time.
45 *
46 * Example generating a CA, server certificate and signing the
47 * certificate with the CA.
48 *
49 * \code{.c}
50 * #include <mstdlib/mstdlib.h>
51 * #include <mstdlib/mstdlib_tls.h>
52 *
53 * #define VALID_SEC (5*365*24*60*60)
54 *
55 * int main(int argc, char **argv)
56 * {
57 * char *CA_privkey;
58 * M_tls_x509_t *CA_x509;
59 * char *CA_crt;
60 * char *Server_privkey;
61 * M_tls_x509_t *Server_x509;
62 * M_tls_x509_t *Server_csr_x509;
63 * char *Server_crt;
64 * char *Server_csr;
65 *
66 * // Generate our certificate authority.
67 * CA_privkey = M_tls_rsa_generate_key(2048);
68 * CA_x509 = M_tls_x509_new(CA_privkey);
69 * M_tls_x509_txt_add(CA_x509, M_TLS_X509_TXT_COMMONNAME, "MY CA", M_FALSE);
70 * M_tls_x509_txt_add(CA_x509, M_TLS_X509_TXT_ORGANIZATION, "MY ORG", M_FALSE);
71 * M_tls_x509_txt_SAN_add(CA_x509, M_TLS_X509_SAN_TYPE_DNS, "ca.myorg.local", M_FALSE);
72 * CA_crt = M_tls_x509_selfsign(CA_x509, VALID_SEC);
73 *
74 * // Generate the server x509
75 * Server_privkey = M_tls_rsa_generate_key(2048);
76 * Server_x509 = M_tls_x509_new(Server_privkey);
77 * M_tls_x509_txt_add(Server_x509, M_TLS_X509_TXT_COMMONNAME, "MY Server", M_FALSE);
78 * M_tls_x509_txt_add(Server_x509, M_TLS_X509_TXT_ORGANIZATION, "MY ORG", M_FALSE);
79 * M_tls_x509_txt_SAN_add(Server_x509, M_TLS_X509_SAN_TYPE_DNS, "server.myorg.local", M_FALSE);
80 *
81 * // Generate a server CSR from the server x509.
82 * // Sign the CSR creating a server certificate.
83 * Server_csr = M_tls_x509_write_csr(Server_x509);
84 * Server_csr_x509 = M_tls_x509_read_csr(Server_csr);
85 * Server_crt = M_tls_x509_sign(Server_csr_x509, CA_crt, CA_privkey, VALID_SEC);
86 *
87 * M_printf("CA Priv Key:\n%s\n", CA_privkey);
88 * M_printf("CA CRT:\n%s\n", CA_crt);
89 * M_printf("Server Priv Key:\n%s\n", Server_privkey);
90 * M_printf("Server CSR:\n%s\n", Server_csr);
91 * M_printf("Server CRT:\n%s\n", Server_crt);
92 *
93 * M_free(Server_csr);
94 * M_free(Server_crt);
95 * M_free(Server_privkey);
96 * M_free(CA_crt);
97 * M_free(CA_privkey);
98 * M_tls_x509_destroy(CA_x509);
99 * M_tls_x509_destroy(Server_csr_x509);
100 * M_tls_x509_destroy(Server_x509);
101 * }
102 * \endcode
103 * @{
104 */
105
106struct M_tls_x509;
107typedef struct M_tls_x509 M_tls_x509_t;
108
109
110/*! X509 certificate text attributes. */
111typedef enum {
112 M_TLS_X509_TXT_COMMONNAME = 1, /*!< (CN) Name of certificate. */
113 M_TLS_X509_TXT_ORGANIZATION = 2, /*!< (O) Organization owning certificate. */
114 M_TLS_X509_TXT_COUNTRY = 3, /*!< (C) County where the organization is located. */
115 M_TLS_X509_TXT_STATE = 4, /*!< (S) State or providence where the organization is located. */
116 M_TLS_X509_TXT_ORGANIZATIONALUNIT = 5, /*!< (OU) Group within the organization owning the certificate. */
117 M_TLS_X509_TXT_LOCALITY = 6 /*!< (L) State, township, county, etc. where the organizational unit
118 is located. */
120
121
122/*! Certificate hash algorithm. */
123typedef enum {
124 M_TLS_X509_SIG_ALG_SHA1 = 1, /*!< SHA 1. */
125 M_TLS_X509_SIG_ALG_SHA256 = 2 /*!< SHA 256. */
127
128
129/*! Type of subject alternative name. */
131 M_TLS_X509_SAN_TYPE_DNS = 1, /*!< Name is a host name that can be retrieved by DNS. */
132 M_TLS_X509_SAN_TYPE_IP = 2 /*!< Name is an ip address. */
135
136
137/*! Generate an RSA private key
138 *
139 * \param[in] bits Bit size of the key.
140 *
141 * \return Buffer containing private key
142 */
143M_API char *M_tls_rsa_generate_key(size_t bits);
144
145/*! Create a new x509 certificate.
146 *
147 * \param[in] rsa_privkey RSA private key.
148 *
149 * \return X509 certificate.
150 *
151 * \see M_tls_rsa_generate_key
152 */
153M_API M_tls_x509_t *M_tls_x509_new(const char *rsa_privkey);
154
155
156/*! Destroy an x509 certificate.
157 *
158 * \param[in] x509 Certificate.
159 */
161
162
163/*! Add a text entry to the certificate of the requested type.
164 *
165 * \param[in] x509 Certificate.
166 * \param[in] type Type of attribute.
167 * \param[in] text Text to put in attribute.
168 * \param[in] append M_TRUE to append. M_FALSE to replace if the attribute already exists.
169 *
170 * \return M_TRUE on success, otherwise M_FALSE on error.
171 */
172M_API M_bool M_tls_x509_txt_add(M_tls_x509_t *x509, M_tls_x509_txt_t type, const char *text, M_bool append);
173
174
175/*! Add subject alternative name to a certificate.
176 *
177 * \param[in] x509 Certificate.
178 * \param[in] type Type of attribute.
179 * \param[in] text Text to put in attribute.
180 * \param[in] append M_TRUE to append. M_FALSE to replace if the attribute already exists.
181 *
182 * \return M_TRUE on success, otherwise M_FALSE on error.
183 */
184M_API M_bool M_tls_x509_txt_SAN_add(M_tls_x509_t *x509, M_tls_x509_san_type_t type, const char *text, M_bool append);
185
186
187/*! Generate a CSR from an x509 certificate.
188 *
189 * \param[in] x509 Certificate.
190 *
191 * \return String on success, otherwise NULL on error.
192 */
194
195
196/*! Read a CSR request.
197 *
198 * \param[in] csr CSR requested.
199 *
200 * \return x509 certificate on success, otherwise NULL on error.
201 */
202M_API M_tls_x509_t *M_tls_x509_read_csr(const char *csr);
203
204
205/*! Read a PEM-encoded certificate.
206 *
207 * \param[in] crt Certificate.
208 *
209 * \return x509 certificate on success, otherwise NULL on error.
210 */
211M_API M_tls_x509_t *M_tls_x509_read_crt(const char *crt);
212
213
214/*! Self-sign the certificate.
215 *
216 * Signs using SHA 256 algorithm.
217 *
218 * \param[in] x509 Certificate.
219 * \param[in] valid_secs The validity period for the certificate in seconds.
220 *
221 * \return Buffer containing x509 certificate.
222 */
223M_API char *M_tls_x509_selfsign(M_tls_x509_t *x509, M_uint64 valid_secs);
224
225
226/*! Sign the certificate
227 *
228 * Signs using SHA 256 algorithm.
229 *
230 * \param[in] x509 Certificate.
231 * \param[in] cacert CA certificate to use for signing.
232 * \param[in] caprivkey CA certificate private key.
233 * \param[in] valid_secs The validity period for the certificate in seconds.
234 *
235 * \return Buffer containing signed x509 certificate.
236 */
237M_API char *M_tls_x509_sign(M_tls_x509_t *x509, const char *cacert, const char *caprivkey, M_uint64 valid_secs);
238
239
240/*! Get the start time (not before) of a certificate.
241 *
242 * \param[in] x509 Certificate.
243 *
244 * \return Time.
245 */
247
248
249/*! Get the end time (not after) of a certificate.
250 *
251 * \param[in] x509 Certificate.
252 *
253 * \return Time.
254 */
256
257
258/*! Get the subject name of a certificate.
259 *
260 * \param[in] x509 Certificate.
261 *
262 * \return String.
263 */
265
266
267/*! Get the issuer name of a certificate.
268 *
269 * \param[in] x509 Certificate.
270 *
271 * \return String.
272 */
274
275/*! Retrieves the signature/digest of the x509 certificate.
276 *
277 * Useful for matching clients to certificates
278 *
279 * \param[in] x509 Certificate.
280 * \param[in] alg Algorithm to use for signature calculation.
281 *
282 * \return String.
283 */
285
286
287/*! Generate DH parameters.
288 *
289 * Could take a very long time, should probably occur
290 * in its own thread to not block program execution.
291 *
292 * \param[in] bits Bit size of the parameters.
293 * \param[out] out_len Length of the output.
294 *
295 * \return dhparams.
296 */
297M_API unsigned char *M_tls_dhparam_generate(size_t bits, size_t *out_len);
298
299/*! @} */
300
301__END_DECLS
302
303#endif
M_int64 M_time_t
Definition: m_time.h:161
M_tls_x509_t * M_tls_x509_read_crt(const char *crt)
unsigned char * M_tls_dhparam_generate(size_t bits, size_t *out_len)
enum M_tls_x509_san_type M_tls_x509_san_type_t
Definition: m_tls_certs.h:134
M_tls_x509_txt_t
Definition: m_tls_certs.h:111
struct M_tls_x509 M_tls_x509_t
Definition: m_tls_certs.h:107
M_bool M_tls_x509_txt_SAN_add(M_tls_x509_t *x509, M_tls_x509_san_type_t type, const char *text, M_bool append)
char * M_tls_x509_signature(M_tls_x509_t *x509, M_tls_x509_sig_alg_t alg)
M_tls_x509_t * M_tls_x509_new(const char *rsa_privkey)
M_tls_x509_t * M_tls_x509_read_csr(const char *csr)
char * M_tls_rsa_generate_key(size_t bits)
char * M_tls_x509_selfsign(M_tls_x509_t *x509, M_uint64 valid_secs)
M_tls_x509_san_type
Definition: m_tls_certs.h:130
M_time_t M_tls_x509_time_end(M_tls_x509_t *x509)
M_bool M_tls_x509_txt_add(M_tls_x509_t *x509, M_tls_x509_txt_t type, const char *text, M_bool append)
char * M_tls_x509_subject_name(M_tls_x509_t *x509)
char * M_tls_x509_sign(M_tls_x509_t *x509, const char *cacert, const char *caprivkey, M_uint64 valid_secs)
void M_tls_x509_destroy(M_tls_x509_t *x509)
M_tls_x509_sig_alg_t
Definition: m_tls_certs.h:123
char * M_tls_x509_issuer_name(M_tls_x509_t *x509)
char * M_tls_x509_write_csr(M_tls_x509_t *x509)
M_time_t M_tls_x509_time_start(M_tls_x509_t *x509)
@ M_TLS_X509_TXT_ORGANIZATION
Definition: m_tls_certs.h:113
@ M_TLS_X509_TXT_LOCALITY
Definition: m_tls_certs.h:117
@ M_TLS_X509_TXT_ORGANIZATIONALUNIT
Definition: m_tls_certs.h:116
@ M_TLS_X509_TXT_COMMONNAME
Definition: m_tls_certs.h:112
@ M_TLS_X509_TXT_COUNTRY
Definition: m_tls_certs.h:114
@ M_TLS_X509_TXT_STATE
Definition: m_tls_certs.h:115
@ M_TLS_X509_SAN_TYPE_DNS
Definition: m_tls_certs.h:131
@ M_TLS_X509_SAN_TYPE_IP
Definition: m_tls_certs.h:132
@ M_TLS_X509_SIG_ALG_SHA256
Definition: m_tls_certs.h:125
@ M_TLS_X509_SIG_ALG_SHA1
Definition: m_tls_certs.h:124