1 /* $Id$
2 *
3 * Lasso - A free implementation of the Liberty Alliance specifications.
4 *
5 * Copyright (C) 2004-2007 Entr'ouvert
6 * http://lasso.entrouvert.org
7 *
8 * Authors: See AUTHORS file in top-level directory.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #ifndef __LASSO_XML_PRIVATE_H__
25 #define __LASSO_XML_PRIVATE_H__
26
27 #ifdef __cplusplus
28 extern "C" {
29 #endif /* __cplusplus */
30
31 #include "xml.h"
32 #include "xml_enc.h"
33 #include <xmlsec/crypto.h>
34 #include <xmlsec/xmlenc.h>
35 #include "saml-2.0/saml2_encrypted_element.h"
36 #include "../utils.h"
37
38 typedef enum {
39 SNIPPET_NODE,
40 SNIPPET_CONTENT,
41 SNIPPET_TEXT_CHILD,
42 SNIPPET_UNUSED1,
43 SNIPPET_ATTRIBUTE,
44 SNIPPET_NODE_IN_CHILD,
45 SNIPPET_LIST_NODES,
46 SNIPPET_LIST_CONTENT,
47 SNIPPET_EXTENSION,
48 SNIPPET_SIGNATURE,
49 SNIPPET_LIST_XMLNODES,
50 SNIPPET_XMLNODE,
51 SNIPPET_COLLECT_NAMESPACES,
52 SNIPPET_JUMP_OFFSET_SIGN = 1 << 19,
53 SNIPPET_JUMP_OFFSET_SHIFT = 15,
54 SNIPPET_JUMP_OFFSET_MASK = 0x0f << SNIPPET_JUMP_OFFSET_SHIFT,
55 SNIPPET_JUMP_1 = 1 << SNIPPET_JUMP_OFFSET_SHIFT,
56 SNIPPET_JUMP_2 = 2 << SNIPPET_JUMP_OFFSET_SHIFT,
57 SNIPPET_JUMP_3 = 3 << SNIPPET_JUMP_OFFSET_SHIFT,
58 SNIPPET_JUMP_4 = 4 << SNIPPET_JUMP_OFFSET_SHIFT,
59 SNIPPET_JUMP_5 = 5 << SNIPPET_JUMP_OFFSET_SHIFT,
60 SNIPPET_JUMP_6 = 6 << SNIPPET_JUMP_OFFSET_SHIFT,
61 SNIPPET_JUMP_7 = 7 << SNIPPET_JUMP_OFFSET_SHIFT,
62 SNIPPET_BACK_1 = 1 << SNIPPET_JUMP_OFFSET_SHIFT | SNIPPET_JUMP_OFFSET_SIGN,
63 SNIPPET_BACK_2 = 2 << SNIPPET_JUMP_OFFSET_SHIFT | SNIPPET_JUMP_OFFSET_SIGN,
64 SNIPPET_BACK_3 = 3 << SNIPPET_JUMP_OFFSET_SHIFT | SNIPPET_JUMP_OFFSET_SIGN,
65 SNIPPET_BACK_4 = 4 << SNIPPET_JUMP_OFFSET_SHIFT | SNIPPET_JUMP_OFFSET_SIGN,
66 SNIPPET_BACK_5 = 5 << SNIPPET_JUMP_OFFSET_SHIFT | SNIPPET_JUMP_OFFSET_SIGN,
67 SNIPPET_BACK_6 = 6 << SNIPPET_JUMP_OFFSET_SHIFT | SNIPPET_JUMP_OFFSET_SIGN,
68 SNIPPET_BACK_7 = 7 << SNIPPET_JUMP_OFFSET_SHIFT | SNIPPET_JUMP_OFFSET_SIGN,
69 /* transformers for content transformation */
70 SNIPPET_STRING = 1 << 0, /* default, can be omitted */
71 SNIPPET_BOOLEAN = 1 << 20,
72 SNIPPET_INTEGER = 1 << 21,
73 SNIPPET_LASSO_DUMP = 1 << 22,
74 SNIPPET_OPTIONAL = 1 << 23, /* optional, ignored if 0 */
75 SNIPPET_OPTIONAL_NEG = 1 << 24, /* optional, ignored if -1 */
76 SNIPPET_ANY = 1 << 25, /* ##any node */
77 SNIPPET_ALLOW_TEXT = 1 << 26, /* allow text childs in list of nodes */
78 SNIPPET_KEEP_XMLNODE = 1 << 27, /* force keep xmlNode */
79 SNIPPET_PRIVATE = 1 << 28, /* means that the offset is relative to a private extension */
80 SNIPPET_MANDATORY = 1 << 29, /* means that the element cardinality is at least 1 */
81 SNIPPET_JUMP_ON_MATCH = 1 << 30,
82 SNIPPET_JUMP_ON_MISS = 1 << 31,
83 SNIPPET_JUMP = SNIPPET_JUMP_ON_MISS | SNIPPET_JUMP_ON_MATCH,
84
85 } SnippetType;
86
87 #define SNIPPET_JUMP_OFFSET(type) ((type & SNIPPET_JUMP_OFFSET_SIGN) ? \
88 (-(type & SNIPPET_JUMP_OFFSET_MASK) >> SNIPPET_JUMP_OFFSET_SHIFT) \
89 : ((type & SNIPPET_JUMP_OFFSET_MASK) >> SNIPPET_JUMP_OFFSET_SHIFT))
90
91 typedef enum {
92 NO_OPTION = 0,
93 NO_SINGLE_REFERENCE = 1 /* SAML signature should contain a single reference,
94 * but WS-Security signatures can contain many */,
95 EMPTY_URI = 2,
96 } SignatureVerificationOption;
97
98 struct XmlSnippet {
99 char *name; /* name of the node or attribute to match */
100 SnippetType type; /* type of node to deserialize */
101 guint offset; /* offset of the storage field relative to the public or private object (if
102 using SNIPPET_PRIVATE). If 0, means that no storage must be done, it will
103 be handled by the init_from_xml virtual method. */
104 char *class_name; /* Force a certain LassoNode class for deserializing a node, usually
105 useless. */
106 char *ns_name; /* if the namespace is different from the one of the parent node, specify it
107 there */
108 char *ns_uri;
109 };
110
111 /**
112 * LassoSignatureContext:
113 * @signature_method: the method for signing (RSA, DSA, HMAC)
114 * @signature_key: a key for the signature
115 *
116 * Information needed to make a signature
117 */
118 typedef struct _LassoSignatureContext {
119 LassoSignatureMethod signature_method;
120 xmlSecKey *signature_key;
121 } LassoSignatureContext;
122
123 #define LASSO_SIGNATURE_CONTEXT_NONE ((LassoSignatureContext){LASSO_SIGNATURE_TYPE_NONE, NULL})
124
125 #define lasso_assign_signature_context(to, from) \
126 do { \
127 LassoSignatureContext *__to = &(to); \
128 LassoSignatureContext __from = (from); \
129 __to->signature_method = __from.signature_method; \
130 lasso_assign_sec_key(__to->signature_key, __from.signature_key); \
131 } while(0)
132
133 #define lasso_assign_new_signature_context(to, from) \
134 do { \
135 LassoSignatureContext *__to = &(to); \
136 LassoSignatureContext __from = (from); \
137 __to->signature_method = __from.signature_method; \
138 lasso_assign_new_sec_key(__to->signature_key, __from.signature_key); \
139 } while(0)
140
141 static inline gboolean
lasso_validate_signature_context(LassoSignatureContext context)142 lasso_validate_signature_context(LassoSignatureContext context) {
143 return lasso_validate_signature_method(context.signature_method)
144 && context.signature_key != NULL;
145 }
146
147 /**
148 * This inline method replace normal use of G_STRUCT_MEMBER_P/G_STRUCT_MEMBER, in order to add an
149 * indirection through the private structure attached to a GObject instance if needed */
150 inline static void *
snippet_struct_member(void * base,GType type,struct XmlSnippet * snippet)151 snippet_struct_member(void *base, GType type, struct XmlSnippet *snippet)
152 {
153 if (snippet->type & SNIPPET_PRIVATE) {
154 if (! G_IS_OBJECT(base))
155 return NULL;
156 GObject *object = (GObject*)base;
157 base = g_type_instance_get_private((GTypeInstance*)object,
158 type);
159 }
160 return G_STRUCT_MEMBER_P(base, snippet->offset);
161 }
162
163 #define SNIPPET_STRUCT_MEMBER(type, base, gtype, snippet) \
164 (*(type*)snippet_struct_member(base, gtype, snippet))
165
166 #define SNIPPET_STRUCT_MEMBER_P(base, gtype, snippet) \
167 snippet_struct_member(base, gtype, snippet)
168
169 struct QuerySnippet {
170 char *path;
171 char *field_name;
172 };
173
174 struct _LassoNodeClassData
175 {
176 struct XmlSnippet *snippets;
177 struct QuerySnippet *query_snippets;
178 char *node_name;
179 xmlNs *ns;
180 char *id_attribute_name;
181 int id_attribute_offset;
182 int sign_type_offset;
183 int sign_method_offset;
184 int private_key_file_offset;
185 int certificate_file_offset;
186 gboolean keep_xmlnode;
187 gboolean xsi_sub_type;
188 };
189
190 void lasso_node_class_set_nodename(LassoNodeClass *klass, char *name);
191 void lasso_node_class_set_ns(LassoNodeClass *klass, char *href, char *prefix);
192 void lasso_node_class_add_snippets(LassoNodeClass *klass, struct XmlSnippet *snippets);
193 void lasso_node_class_add_query_snippets(LassoNodeClass *klass, struct QuerySnippet *snippets);
194
195 gchar* lasso_node_build_query_from_snippets(LassoNode *node);
196 gboolean lasso_node_init_from_query_fields(LassoNode *node, char **query_fields);
197 gboolean lasso_node_init_from_saml2_query_fields(LassoNode *node,
198 char **query_fields, char **relay_state);
199 LassoMessageFormat lasso_node_init_from_message_with_format(LassoNode *node, const char *message, LassoMessageFormat constraint, xmlDoc **doc_out, xmlNode **root_out);
200
201 typedef enum {
202 LASSO_PEM_FILE_TYPE_UNKNOWN,
203 LASSO_PEM_FILE_TYPE_PUB_KEY,
204 LASSO_PEM_FILE_TYPE_PRIVATE_KEY,
205 LASSO_PEM_FILE_TYPE_CERT
206 } LassoPemFileType;
207
208 void lasso_build_random_sequence(char *buffer, unsigned int size);
209 char* lasso_build_unique_id(unsigned int size);
210 char* lasso_get_current_time(void);
211 char* lasso_time_to_iso_8601_gmt(time_t now);
212 time_t lasso_iso_8601_gmt_to_time_t(const char *xsdtime);
213 LassoPemFileType lasso_get_pem_file_type(const char *file);
214
215 xmlSecKeyPtr lasso_get_public_key_from_pem_file(const char *file);
216 xmlSecKeyPtr lasso_get_public_key_from_pem_cert_file(const char *file);
217 xmlSecKeysMngr* lasso_load_certs_from_pem_certs_chain_file (const char *file);
218
219 char* lasso_query_sign(char *query, LassoSignatureContext signature_context);
220
221 int lasso_query_verify_signature(const char *query, const xmlSecKey *public_key);
222
223 int lasso_saml2_query_verify_signature(const char *query, const xmlSecKey *sender_public_key);
224
225 char* lasso_sha1(const char *str);
226
227 char* lasso_sha256(const char *str);
228
229 char* lasso_sha384(const char *str);
230
231 char* lasso_sha512(const char *str);
232
233 xmlChar** lasso_urlencoded_to_strings(const char *str);
234
235 int lasso_sign_node(xmlNode *xmlnode, LassoSignatureContext context, const char *id_attr_name, const char *id_value);
236
237 int lasso_verify_signature(xmlNode *signed_node, xmlDoc *doc, const char *id_attr_name,
238 xmlSecKeysMngr *keys_manager, xmlSecKey *public_key,
239 SignatureVerificationOption signature_verification_option,
240 GList **uri_references);
241 void xmlCleanNs(xmlNode *root_node);
242
243 void xml_insure_namespace(xmlNode *xmlnode, xmlNs *ns, gboolean force,
244 gchar *ns_href, gchar *ns_prefix);
245
246 gchar* lasso_node_build_deflated_query(LassoNode *node);
247
248 gchar* lasso_node_build_query(LassoNode *node);
249
250 gboolean lasso_node_init_from_deflated_query_part(LassoNode *node, char *deflate_string);
251
252 xmlNode* lasso_node_get_xmlnode_for_any_type(LassoNode *node, xmlNode *cur);
253
254 LassoSaml2EncryptedElement* lasso_node_encrypt(LassoNode *lasso_node,
255 xmlSecKey *encryption_public_key, LassoEncryptionSymKeyType encryption_sym_key_type, const char *recipient);
256
257 int lasso_node_decrypt_xmlnode(xmlNode* encrypted_element, GList *encrypted_key,
258 xmlSecKey *encryption_private_key, LassoNode **output);
259
260 void lasso_node_remove_signature(LassoNode *node);
261
262 char* lasso_concat_url_query(const char *url, const char *query);
263
264 xmlDocPtr lasso_xml_parse_memory(const char *buffer, int size);
265
266 xmlNode* lasso_xml_get_soap_content(xmlNode *root);
267
268 xmlNodePtr lasso_xml_next_element_node(xmlNodePtr node);
269
270 const xmlChar* lasso_xml_get_node_ns_href(const xmlNodePtr node);
271
272 gboolean lasso_xml_is_element_node(const xmlNodePtr node,
273 const xmlChar *name, const xmlChar *ns);
274
275 gboolean lasso_xml_is_soap(xmlNode *root);
276
277 xmlNodePtr lasso_xml_soap11_get_header(xmlNodePtr envelope_node);
278
279 xmlNodePtr lasso_xml_soap11_get_body(xmlNodePtr envelope_node);
280
281 gboolean lasso_eval_xpath_expression(xmlXPathContextPtr xpath_ctx, const char *expression,
282 xmlXPathObjectPtr *xpath_object_ptr, int *xpath_error_code);
283
284 #define IF_SAML2(profile) \
285 if (lasso_provider_get_protocol_conformance(LASSO_PROVIDER(profile->server)) == \
286 LASSO_PROTOCOL_SAML_2_0)
287
288 char * lasso_get_relaystate_from_query(const char *query);
289 char * lasso_url_add_parameters(char *url, gboolean free, ...);
290 xmlChar * lasso_xmlURIEscapeStr(const xmlChar *from, const xmlChar *list);
291 xmlSecKey* lasso_xmlsec_load_private_key_from_buffer(const char *buffer, size_t length, const char *password, LassoSignatureMethod signature_method, const char *certificate);
292 xmlSecKey* lasso_xmlsec_load_private_key(const char *filename_or_buffer, const char *password,
293 LassoSignatureMethod signature_method, const char *certificate);
294 xmlDocPtr lasso_xml_parse_file(const char *filepath);
295 xmlDocPtr lasso_xml_parse_memory_with_error(const char *buffer, int size, xmlError *error);
296 xmlSecKeyPtr lasso_xmlsec_load_key_info(xmlNode *key_descriptor);
297 char* lasso_xmlnode_to_string(xmlNode *node, gboolean format, int level);
298 gboolean lasso_string_to_xsd_integer(const char *str, long int *integer);
299 void lasso_set_string_from_prop(char **str, xmlNode *node, xmlChar *name, xmlChar *ns);
300
301 void lasso_node_add_custom_namespace(LassoNode *node, const char *prefix, const char *href);
302
303 int lasso_node_set_signature(LassoNode *node, LassoSignatureContext context);
304
305 LassoSignatureContext lasso_node_get_signature(LassoNode *node);
306
307 void lasso_node_set_encryption(LassoNode *node, xmlSecKey *encryption_public_key,
308 LassoEncryptionSymKeyType encryption_sym_key_type);
309
310 void lasso_node_get_encryption(LassoNode *node, xmlSecKey **encryption_public_key,
311 LassoEncryptionSymKeyType *encryption_sym_key_type);
312 gboolean lasso_base64_decode(const char *from, char **buffer, int *buffer_len);
313
314 xmlSecKeyPtr
315 lasso_create_hmac_key(const xmlSecByte * buf, xmlSecSize size);
316
317 lasso_error_t
318 lasso_get_hmac_key(const xmlSecKey *key, void **buffer, size_t *size);
319
320 LassoSignatureContext lasso_make_signature_context_from_buffer(const void *buffer, size_t length,
321 const char *password, LassoSignatureMethod signature_method,
322 const char *certificate);
323
324 LassoSignatureContext lasso_make_signature_context_from_path_or_string(char *filename_or_buffer,
325 const char *password, LassoSignatureMethod signature_method,
326 const char *certificate);
327
328 xmlNs * get_or_define_ns(xmlNode *xmlnode, const xmlChar *ns_uri, const xmlChar
329 *advised_prefix);
330
331 void set_qname_attribute(xmlNode *node,
332 const xmlChar *attribute_ns_prefix,
333 const xmlChar *attribute_ns_href,
334 const xmlChar *attribute_name,
335 const xmlChar *prefix,
336 const xmlChar *href,
337 const xmlChar *name);
338
339
340 void set_xsi_type(xmlNode *node,
341 const xmlChar *type_ns_prefix,
342 const xmlChar *type_ns_href,
343 const xmlChar *type_name);
344
345 void lasso_xmlnode_add_saml2_signature_template(xmlNode *node, LassoSignatureContext context,
346 const char *id);
347
348 gchar* lasso_xmlnode_build_deflated_query(xmlNode *xmlnode);
349
350 xmlTextReader *lasso_xmltextreader_from_message(const char *message, char **to_free);
351
352 #ifdef __cplusplus
353 }
354 #endif /* __cplusplus */
355
356 #endif /* __LASSO_XML_PRIVATE_H__ */
357