]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libstrongswan/crypto/proposal/proposal_keywords.c
Update copyright headers after acquisition by secunet
[thirdparty/strongswan.git] / src / libstrongswan / crypto / proposal / proposal_keywords.c
1 /*
2 * Copyright (C) 2012 Tobias Brunner
3 *
4 * Copyright (C) secunet Security Networks AG
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 /*
18 * Copyright (c) 2012 Nanoteq Pty Ltd
19 *
20 * Permission is hereby granted, free of charge, to any person obtaining a copy
21 * of this software and associated documentation files (the "Software"), to deal
22 * in the Software without restriction, including without limitation the rights
23 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
24 * copies of the Software, and to permit persons to whom the Software is
25 * furnished to do so, subject to the following conditions:
26 *
27 * The above copyright notice and this permission notice shall be included in
28 * all copies or substantial portions of the Software.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
33 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
35 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
36 * THE SOFTWARE.
37 */
38
39 #include "proposal_keywords.h"
40 #include "proposal_keywords_static.h"
41
42 #include <collections/linked_list.h>
43 #include <threading/rwlock.h>
44
45 typedef struct private_proposal_keywords_t private_proposal_keywords_t;
46
47 struct private_proposal_keywords_t {
48
49 /**
50 * public interface
51 */
52 proposal_keywords_t public;
53
54 /**
55 * registered tokens, as proposal_token_t
56 */
57 linked_list_t * tokens;
58
59 /**
60 * registered algname parsers, as proposal_algname_parser_t
61 */
62 linked_list_t *parsers;
63
64 /**
65 * rwlock to lock access to modules
66 */
67 rwlock_t *lock;
68 };
69
70 /**
71 * Find the token object for the algorithm specified.
72 */
73 static const proposal_token_t* find_token(private_proposal_keywords_t *this,
74 const char *str)
75 {
76 proposal_token_t *token, *found = NULL;
77 enumerator_t *enumerator;
78
79 this->lock->read_lock(this->lock);
80 enumerator = this->tokens->create_enumerator(this->tokens);
81 while (enumerator->enumerate(enumerator, &token))
82 {
83 if (streq(token->name, str))
84 {
85 found = token;
86 break;
87 }
88 }
89 enumerator->destroy(enumerator);
90 this->lock->unlock(this->lock);
91 return found;
92 }
93
94 /**
95 * Parse the given algorithm into a token with user defined parser functions.
96 */
97 static const proposal_token_t* parse_token(private_proposal_keywords_t *this,
98 const char *str)
99 {
100 proposal_algname_parser_t parser;
101 enumerator_t *enumerator;
102 proposal_token_t *found = NULL;
103
104 this->lock->read_lock(this->lock);
105 enumerator = this->parsers->create_enumerator(this->parsers);
106 while (enumerator->enumerate(enumerator, &parser))
107 {
108 found = parser(str);
109 if (found)
110 {
111 break;
112 }
113 }
114 enumerator->destroy(enumerator);
115 this->lock->unlock(this->lock);
116 return found;
117 }
118
119 METHOD(proposal_keywords_t, get_token, const proposal_token_t*,
120 private_proposal_keywords_t *this, const char *str)
121 {
122 const proposal_token_t *token;
123
124 token = proposal_get_token_static(str, strlen(str));
125 if (!token)
126 {
127 token = find_token(this, str);
128 }
129 if (!token)
130 {
131 token = parse_token(this, str);
132 }
133 return token;
134 }
135
136 METHOD(proposal_keywords_t, register_token, void,
137 private_proposal_keywords_t *this, const char *name, transform_type_t type,
138 uint16_t algorithm, uint16_t keysize)
139 {
140 proposal_token_t *token;
141
142 INIT(token,
143 .name = strdup(name),
144 .type = type,
145 .algorithm = algorithm,
146 .keysize = keysize,
147 );
148
149 this->lock->write_lock(this->lock);
150 this->tokens->insert_first(this->tokens, token);
151 this->lock->unlock(this->lock);
152 }
153
154 METHOD(proposal_keywords_t, register_algname_parser, void,
155 private_proposal_keywords_t *this, proposal_algname_parser_t parser)
156 {
157 this->lock->write_lock(this->lock);
158 this->parsers->insert_first(this->parsers, parser);
159 this->lock->unlock(this->lock);
160 }
161
162 METHOD(proposal_keywords_t, destroy, void,
163 private_proposal_keywords_t *this)
164 {
165 proposal_token_t *token;
166
167 while (this->tokens->remove_first(this->tokens, (void**)&token) == SUCCESS)
168 {
169 free(token->name);
170 free(token);
171 }
172 this->tokens->destroy(this->tokens);
173 this->parsers->destroy(this->parsers);
174 this->lock->destroy(this->lock);
175 free(this);
176 }
177
178 /*
179 * Described in header.
180 */
181 proposal_keywords_t *proposal_keywords_create()
182 {
183 private_proposal_keywords_t *this;
184
185 INIT(this,
186 .public = {
187 .get_token = _get_token,
188 .register_token = _register_token,
189 .register_algname_parser = _register_algname_parser,
190 .destroy = _destroy,
191 },
192 .tokens = linked_list_create(),
193 .parsers = linked_list_create(),
194 .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
195 );
196
197 return &this->public;
198 }