1 /*
2  * Copyright 2019 Daniel Silverstone <dsilvers@netsurf-browser.org>
3  *
4  * This file is part of NetSurf, http://www.netsurf-browser.org/
5  *
6  * NetSurf is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * NetSurf 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.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 /**
20  * \file
21  *
22  * SSL related types and values
23  */
24 
25 #ifndef NETSURF_SSL_CERTS_H_
26 #define NETSURF_SSL_CERTS_H_
27 
28 struct nsurl;
29 
30 /**
31  * ssl certificate error status
32  *
33  * Do not reorder / remove entries because these may be persisted to the disk
34  * cache as simple ints.
35  */
36 typedef enum {
37 	SSL_CERT_ERR_OK,	/**< Nothing wrong with this certificate */
38 	SSL_CERT_ERR_UNKNOWN,	/**< Unknown error */
39 	SSL_CERT_ERR_BAD_ISSUER, /**< Bad issuer */
40 	SSL_CERT_ERR_BAD_SIG,	/**< Bad signature on this certificate */
41 	SSL_CERT_ERR_TOO_YOUNG,	/**< This certificate is not yet valid */
42 	SSL_CERT_ERR_TOO_OLD,	/**< This certificate is no longer valid */
43 	SSL_CERT_ERR_SELF_SIGNED, /**< This certificate (or the chain) is self signed */
44 	SSL_CERT_ERR_CHAIN_SELF_SIGNED, /**< This certificate chain is self signed */
45 	SSL_CERT_ERR_REVOKED,	/**< This certificate has been revoked */
46 	SSL_CERT_ERR_HOSTNAME_MISMATCH, /**< This certificate host did not match the server */
47 	SSL_CERT_ERR_CERT_MISSING, /**< This certificate was missing from the chain, its data is useless */
48 } ssl_cert_err;
49 
50 /** Always the max known ssl certificate error type */
51 #define SSL_CERT_ERR_MAX_KNOWN SSL_CERT_ERR_HOSTNAME_MISMATCH
52 
53 /** maximum number of X509 certificates in chain for TLS connection */
54 #define MAX_CERT_DEPTH 10
55 
56 /**
57  * X509 certificate chain
58  */
59 struct cert_chain {
60 	/**
61 	 * the number of certificates in the chain
62 	 * */
63 	size_t depth;
64 	struct {
65 		/**
66 		 * Whatever is wrong with this certificate
67 		 */
68 		ssl_cert_err err;
69 
70 		/**
71 		 * data in Distinguished Encoding Rules (DER) format
72 		 */
73 		uint8_t *der;
74 
75 		/**
76 		 * DER length
77 		 */
78 		size_t der_length;
79 	} certs[MAX_CERT_DEPTH];
80 };
81 
82 /**
83  * create new certificate chain
84  *
85  * \param dpth the depth to set in the new chain.
86  * \param chain_out A pointer to recive the new chain.
87  * \return NSERROR_OK on success or NSERROR_NOMEM on memory exhaustion
88  */
89 nserror cert_chain_alloc(size_t depth, struct cert_chain **chain_out);
90 
91 /**
92  * duplicate a certificate chain into an existing chain
93  *
94  * \param src The certificate chain to copy from
95  * \param dst The chain to overwrite with a copy of src
96  * \return NSERROR_OK on success or NSERROR_NOMEM on memory exhaustion
97  *
98  * NOTE: if this returns NSERROR_NOMEM then the destination chain will have
99  * some amount of content and should be cleaned up with cert_chain_free.
100  */
101 nserror cert_chain_dup_into(const struct cert_chain *src, struct cert_chain *dst);
102 
103 /**
104  * duplicate a certificate chain
105  *
106  * \param src The certificate chain to copy from
107  * \param dst_out A pointer to recive the duplicated chain
108  * \return NSERROR_OK on success or NSERROR_NOMEM on memory exhaustion
109  */
110 nserror cert_chain_dup(const struct cert_chain *src, struct cert_chain **dst_out);
111 
112 /**
113  * create a certificate chain from a fetch query string
114  *
115  * \param url The url to convert the query from
116  * \param dst_out A pointer to recive the duplicated chain
117  * \return NSERROR_OK on success or NSERROR_NOMEM on memory exhaustion
118  */
119 nserror cert_chain_from_query(struct nsurl *url, struct cert_chain **chain_out);
120 
121 /**
122  * create a fetch query string from a certificate chain
123  *
124  *
125  * \return NSERROR_OK on success or NSERROR_NOMEM on memory exhaustion
126  */
127 nserror cert_chain_to_query(struct cert_chain *chain, struct nsurl **url_out);
128 
129 /**
130  * free a certificate chain
131  *
132  * \param chain The certificate chain to free
133  * \return NSERROR_OK on success
134  */
135 nserror cert_chain_free(struct cert_chain *chain);
136 
137 /**
138  * total number of data bytes in a chain
139  *
140  * \param chain The chain to size
141  * \return the number of bytes used by the chain
142  */
143 size_t cert_chain_size(const struct cert_chain *chain);
144 
145 #endif /* NETSURF_SSL_CERTS_H_ */
146