blob: 32dc5a2fe1edf0c232f36e543a8f4565ce2841d9 [file] [log] [blame]
James Kuszmaul4a42b182021-01-17 11:32:46 -08001#include "parameters.h"
2#include "../dtls_fingerprint/fingerprint.h"
3#include <rawrtc/certificate.h>
4#include <rawrtc/dtls_parameters.h>
5#include <rawrtc/dtls_transport.h>
6#include <re.h>
7
8/*
9 * Destructor for an existing DTLS parameter's fingerprints instance.
10 */
11static void rawrtc_dtls_parameters_fingerprints_destroy(void* arg) {
12 struct rawrtc_dtls_fingerprints* const fingerprints = arg;
13 size_t i;
14
15 // Un-reference each item
16 for (i = 0; i < fingerprints->n_fingerprints; ++i) {
17 mem_deref(fingerprints->fingerprints[i]);
18 }
19}
20
21/*
22 * Destructor for an existing DTLS parameters instance.
23 */
24static void rawrtc_dtls_parameters_destroy(void* arg) {
25 struct rawrtc_dtls_parameters* const parameters = arg;
26
27 // Un-reference
28 mem_deref(parameters->fingerprints);
29}
30
31/*
32 * Common code to allocate a DTLS parameters instance.
33 */
34static enum rawrtc_code rawrtc_dtls_parameters_allocate(
35 struct rawrtc_dtls_parameters** const parametersp, // de-referenced
36 enum rawrtc_dtls_role const role,
37 size_t const n_fingerprints) {
38 enum rawrtc_code error = RAWRTC_CODE_SUCCESS;
39 struct rawrtc_dtls_parameters* parameters;
40 size_t fingerprints_size;
41
42 // Allocate parameters
43 parameters = mem_zalloc(sizeof(*parameters), rawrtc_dtls_parameters_destroy);
44 if (!parameters) {
45 return RAWRTC_CODE_NO_MEMORY;
46 }
47
48 // Set role
49 parameters->role = role;
50
51 // Allocate fingerprints array & set length immediately
52 fingerprints_size = sizeof(*parameters) * n_fingerprints;
53 parameters->fingerprints = mem_zalloc(
54 sizeof(*parameters) + fingerprints_size, rawrtc_dtls_parameters_fingerprints_destroy);
55 if (!parameters->fingerprints) {
56 error = RAWRTC_CODE_NO_MEMORY;
57 goto out;
58 }
59 parameters->fingerprints->n_fingerprints = n_fingerprints;
60
61out:
62 if (error) {
63 mem_deref(parameters);
64 } else {
65 // Set pointer
66 *parametersp = parameters;
67 }
68 return error;
69}
70
71/*
72 * Create a new DTLS parameters instance.
73 * `*parametersp` must be unreferenced.
74 */
75enum rawrtc_code rawrtc_dtls_parameters_create(
76 struct rawrtc_dtls_parameters** const parametersp, // de-referenced
77 enum rawrtc_dtls_role const role,
78 struct rawrtc_dtls_fingerprint* const fingerprints[], // referenced (each item)
79 size_t const n_fingerprints) {
80 struct rawrtc_dtls_parameters* parameters;
81 enum rawrtc_code error;
82 size_t i;
83
84 // Check arguments
85 if (!parametersp || !fingerprints || n_fingerprints < 1) {
86 return RAWRTC_CODE_INVALID_ARGUMENT;
87 }
88
89 // Create parameters
90 error = rawrtc_dtls_parameters_allocate(&parameters, role, n_fingerprints);
91 if (error) {
92 goto out;
93 }
94
95 // Reference and set each fingerprint
96 for (i = 0; i < n_fingerprints; ++i) {
97 // Null?
98 if (!fingerprints[i]) {
99 error = RAWRTC_CODE_INVALID_ARGUMENT;
100 goto out;
101 }
102
103 // Check algorithm
104 if (fingerprints[i]->algorithm == RAWRTC_CERTIFICATE_SIGN_ALGORITHM_NONE) {
105 error = RAWRTC_CODE_INVALID_ARGUMENT;
106 goto out;
107 }
108
109 // Reference and set fingerprint
110 parameters->fingerprints->fingerprints[i] = mem_ref(fingerprints[i]);
111 }
112
113out:
114 if (error) {
115 mem_deref(parameters);
116 } else {
117 // Set pointer
118 *parametersp = parameters;
119 }
120 return error;
121}
122
123/*
124 * Create parameters from the internal vars of a DTLS transport
125 * instance.
126 */
127enum rawrtc_code rawrtc_dtls_parameters_create_internal(
128 struct rawrtc_dtls_parameters** const parametersp, // de-referenced
129 enum rawrtc_dtls_role const role,
130 struct list* const fingerprints) {
131 size_t n_fingerprints;
132 struct rawrtc_dtls_parameters* parameters;
133 enum rawrtc_code error;
134 struct le* le;
135 size_t i;
136
137 // Check arguments
138 if (!parametersp || !fingerprints) {
139 return RAWRTC_CODE_INVALID_ARGUMENT;
140 }
141
142 // Get fingerprints length
143 n_fingerprints = list_count(fingerprints);
144
145 // Create parameters
146 error = rawrtc_dtls_parameters_allocate(&parameters, role, n_fingerprints);
147 if (error) {
148 goto out;
149 }
150
151 // Reference and set each fingerprint
152 for (le = list_head(fingerprints), i = 0; le != NULL; le = le->next, ++i) {
153 struct rawrtc_dtls_fingerprint* const fingerprint = le->data;
154
155 // Check algorithm
156 if (fingerprint->algorithm == RAWRTC_CERTIFICATE_SIGN_ALGORITHM_NONE) {
157 error = RAWRTC_CODE_INVALID_ARGUMENT;
158 goto out;
159 }
160
161 // Reference and set fingerprint
162 parameters->fingerprints->fingerprints[i] = mem_ref(fingerprint);
163 }
164
165out:
166 if (error) {
167 mem_deref(parameters);
168 } else {
169 // Set pointer
170 *parametersp = parameters;
171 }
172 return error;
173}