summaryrefslogtreecommitdiffstats
path: root/lasso/xml/private.h
blob: f1b0e94b58eef79501b9264c4da96b8cb049b548 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
/* $Id$
 *
 * Lasso - A free implementation of the Liberty Alliance specifications.
 *
 * Copyright (C) 2004-2007 Entr'ouvert
 * http://lasso.entrouvert.org
 *
 * Authors: See AUTHORS file in top-level directory.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __LASSO_XML_PRIVATE_H__
#define __LASSO_XML_PRIVATE_H__

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

#include "xml.h"
#include "xml_enc.h"
#include <xmlsec/crypto.h>
#include <xmlsec/xmlenc.h>
#include "saml-2.0/saml2_encrypted_element.h"
#include "../utils.h"

typedef enum {
	SNIPPET_NODE,
	SNIPPET_CONTENT,
	SNIPPET_TEXT_CHILD,
	SNIPPET_UNUSED1,
	SNIPPET_ATTRIBUTE,
	SNIPPET_NODE_IN_CHILD,
	SNIPPET_LIST_NODES,
	SNIPPET_LIST_CONTENT,
	SNIPPET_EXTENSION,
	SNIPPET_SIGNATURE,
	SNIPPET_LIST_XMLNODES,
	SNIPPET_XMLNODE,
	SNIPPET_COLLECT_NAMESPACES,
	SNIPPET_JUMP_OFFSET_SIGN = 1 << 19,
	SNIPPET_JUMP_OFFSET_SHIFT = 15,
	SNIPPET_JUMP_OFFSET_MASK = 0x0f << SNIPPET_JUMP_OFFSET_SHIFT,
	SNIPPET_JUMP_1 = 1 << SNIPPET_JUMP_OFFSET_SHIFT,
	SNIPPET_JUMP_2 = 2 << SNIPPET_JUMP_OFFSET_SHIFT,
	SNIPPET_JUMP_3 = 3 << SNIPPET_JUMP_OFFSET_SHIFT,
	SNIPPET_JUMP_4 = 4 << SNIPPET_JUMP_OFFSET_SHIFT,
	SNIPPET_JUMP_5 = 5 << SNIPPET_JUMP_OFFSET_SHIFT,
	SNIPPET_JUMP_6 = 6 << SNIPPET_JUMP_OFFSET_SHIFT,
	SNIPPET_JUMP_7 = 7 << SNIPPET_JUMP_OFFSET_SHIFT,
	SNIPPET_BACK_1 = 1 << SNIPPET_JUMP_OFFSET_SHIFT | SNIPPET_JUMP_OFFSET_SIGN,
	SNIPPET_BACK_2 = 2 << SNIPPET_JUMP_OFFSET_SHIFT | SNIPPET_JUMP_OFFSET_SIGN,
	SNIPPET_BACK_3 = 3 << SNIPPET_JUMP_OFFSET_SHIFT | SNIPPET_JUMP_OFFSET_SIGN,
	SNIPPET_BACK_4 = 4 << SNIPPET_JUMP_OFFSET_SHIFT | SNIPPET_JUMP_OFFSET_SIGN,
	SNIPPET_BACK_5 = 5 << SNIPPET_JUMP_OFFSET_SHIFT | SNIPPET_JUMP_OFFSET_SIGN,
	SNIPPET_BACK_6 = 6 << SNIPPET_JUMP_OFFSET_SHIFT | SNIPPET_JUMP_OFFSET_SIGN,
	SNIPPET_BACK_7 = 7 << SNIPPET_JUMP_OFFSET_SHIFT | SNIPPET_JUMP_OFFSET_SIGN,
	/* transformers for content transformation */
	SNIPPET_STRING  = 1 << 0, /* default, can be omitted */
	SNIPPET_BOOLEAN = 1 << 20,
	SNIPPET_INTEGER = 1 << 21,
	SNIPPET_LASSO_DUMP = 1 << 22,
	SNIPPET_OPTIONAL = 1 << 23, /* optional, ignored if 0 */
	SNIPPET_OPTIONAL_NEG = 1 << 24, /* optional, ignored if -1 */
	SNIPPET_ANY = 1 << 25, /* ##any node */
	SNIPPET_ALLOW_TEXT = 1 << 26, /* allow text childs in list of nodes */
	SNIPPET_KEEP_XMLNODE = 1 << 27, /* force keep xmlNode */
	SNIPPET_PRIVATE = 1 << 28, /* means that the offset is relative to a private extension */
	SNIPPET_MANDATORY = 1 << 29, /* means that the element cardinality is at least 1 */
	SNIPPET_JUMP_ON_MATCH = 1 << 30,
	SNIPPET_JUMP_ON_MISS = 1 << 31,
	SNIPPET_JUMP = SNIPPET_JUMP_ON_MISS | SNIPPET_JUMP_ON_MATCH,

} SnippetType;

#define SNIPPET_JUMP_OFFSET(type) ((type & SNIPPET_JUMP_OFFSET_SIGN) ? \
		                      (-(type & SNIPPET_JUMP_OFFSET_MASK) >> SNIPPET_JUMP_OFFSET_SHIFT) \
		                    : ((type & SNIPPET_JUMP_OFFSET_MASK) >> SNIPPET_JUMP_OFFSET_SHIFT))

typedef enum {
	NO_OPTION = 0,
	NO_SINGLE_REFERENCE = 1 /* SAML signature should contain a single reference,
				  * but WS-Security signatures can contain many */,
	EMPTY_URI = 2,
} SignatureVerificationOption;

struct XmlSnippet {
	char *name; /* name of the node or attribute to match */
	SnippetType type; /* type of node to deserialize */
	guint offset; /* offset of the storage field relative to the public or private object (if
			 using SNIPPET_PRIVATE). If 0, means that no storage must be done, it will
			 be handled by the init_from_xml virtual method. */
	char *class_name; /* Force a certain LassoNode class for deserializing a node, usually
			     useless. */
	char *ns_name; /* if the namespace is different from the one of the parent node, specify it
			  there */
	char *ns_uri;
};

/**
 * LassoSignatureContext:
 * @signature_method: the method for signing (RSA, DSA, HMAC)
 * @signature_key: a key for the signature
 *
 * Information needed to make a signature
 */
typedef struct _LassoSignatureContext {
	LassoSignatureMethod signature_method;
	xmlSecKey *signature_key;
} LassoSignatureContext;

#define LASSO_SIGNATURE_CONTEXT_NONE ((LassoSignatureContext){LASSO_SIGNATURE_TYPE_NONE, NULL})

#define lasso_assign_signature_context(to, from) \
	do { \
		LassoSignatureContext *__to = &(to); \
		LassoSignatureContext __from = (from); \
		__to->signature_method = __from.signature_method; \
		lasso_assign_sec_key(__to->signature_key, __from.signature_key); \
	} while(0)

#define lasso_assign_new_signature_context(to, from) \
	do { \
		LassoSignatureContext *__to = &(to); \
		LassoSignatureContext __from = (from); \
		__to->signature_method = __from.signature_method; \
		lasso_assign_new_sec_key(__to->signature_key, __from.signature_key); \
	} while(0)

static inline gboolean
lasso_validate_signature_context(LassoSignatureContext context) {
	return lasso_validate_signature_method(context.signature_method)
		&& context.signature_key != NULL;
}

/**
 * This inline method replace normal use of G_STRUCT_MEMBER_P/G_STRUCT_MEMBER, in order to add an
 * indirection through the private structure attached to a GObject instance if needed */
inline static void *
snippet_struct_member(void *base, GType type, struct XmlSnippet *snippet)
{
	if (snippet->type & SNIPPET_PRIVATE) {
		if (! G_IS_OBJECT(base))
			return NULL;
		GObject *object = (GObject*)base;
		base = g_type_instance_get_private((GTypeInstance*)object,
				type);
	}
	return G_STRUCT_MEMBER_P(base, snippet->offset);
}

#define SNIPPET_STRUCT_MEMBER(type, base, gtype, snippet) \
	(*(type*)snippet_struct_member(base, gtype, snippet))

#define SNIPPET_STRUCT_MEMBER_P(base, gtype, snippet) \
	snippet_struct_member(base, gtype, snippet)

struct QuerySnippet {
	char *path;
	char *field_name;
};

struct _LassoNodeClassData
{
	struct XmlSnippet *snippets;
	struct QuerySnippet *query_snippets;
	char *node_name;
	xmlNs *ns;
	char *id_attribute_name;
	int id_attribute_offset;
	int sign_type_offset;
	int sign_method_offset;
	int private_key_file_offset;
	int certificate_file_offset;
	gboolean keep_xmlnode;
	gboolean xsi_sub_type;
};

void lasso_node_class_set_nodename(LassoNodeClass *klass, char *name);
void lasso_node_class_set_ns(LassoNodeClass *klass, char *href, char *prefix);
void lasso_node_class_add_snippets(LassoNodeClass *klass, struct XmlSnippet *snippets);
void lasso_node_class_add_query_snippets(LassoNodeClass *klass, struct QuerySnippet *snippets);

gchar* lasso_node_build_query_from_snippets(LassoNode *node);
gboolean lasso_node_init_from_query_fields(LassoNode *node, char **query_fields);
gboolean lasso_node_init_from_saml2_query_fields(LassoNode *node,
		char **query_fields, char **relay_state);
LassoMessageFormat lasso_node_init_from_message_with_format(LassoNode *node, const char *message, LassoMessageFormat constraint, xmlDoc **doc_out, xmlNode **root_out);

typedef enum {
	LASSO_PEM_FILE_TYPE_UNKNOWN,
	LASSO_PEM_FILE_TYPE_PUB_KEY,
	LASSO_PEM_FILE_TYPE_PRIVATE_KEY,
	LASSO_PEM_FILE_TYPE_CERT
} LassoPemFileType;

void  lasso_build_random_sequence(char *buffer, unsigned int size);
char* lasso_build_unique_id(unsigned int size);
char* lasso_get_current_time(void);
char* lasso_time_to_iso_8601_gmt(time_t now);
time_t lasso_iso_8601_gmt_to_time_t(const char *xsdtime);
LassoPemFileType lasso_get_pem_file_type(const char *file);

xmlSecKeyPtr lasso_get_public_key_from_pem_file(const char *file);
xmlSecKeyPtr lasso_get_public_key_from_pem_cert_file(const char *file);
xmlSecKeysMngr* lasso_load_certs_from_pem_certs_chain_file (const char *file);

char* lasso_query_sign(char *query, LassoSignatureContext signature_context);

int lasso_query_verify_signature(const char *query, const xmlSecKey *public_key);

int lasso_saml2_query_verify_signature(const char *query, const xmlSecKey *sender_public_key);

char* lasso_sha1(const char *str);

char** urlencoded_to_strings(const char *str);

int lasso_sign_node(xmlNode *xmlnode, LassoSignatureContext context, const char *id_attr_name, const char *id_value);

int lasso_verify_signature(xmlNode *signed_node, xmlDoc *doc, const char *id_attr_name,
		xmlSecKeysMngr *keys_manager, xmlSecKey *public_key,
		SignatureVerificationOption signature_verification_option,
		GList **uri_references);
void xmlCleanNs(xmlNode *root_node);

void xml_insure_namespace(xmlNode *xmlnode, xmlNs *ns, gboolean force,
		gchar *ns_href, gchar *ns_prefix);

gchar* lasso_node_build_deflated_query(LassoNode *node);

gchar* lasso_node_build_query(LassoNode *node);

gboolean lasso_node_init_from_deflated_query_part(LassoNode *node, char *deflate_string);

xmlNode* lasso_node_get_xmlnode_for_any_type(LassoNode *node, xmlNode *cur);

LassoSaml2EncryptedElement* lasso_node_encrypt(LassoNode *lasso_node,
	xmlSecKey *encryption_public_key, LassoEncryptionSymKeyType encryption_sym_key_type, const char *recipient);

int lasso_node_decrypt_xmlnode(xmlNode* encrypted_element, GList *encrypted_key,
		xmlSecKey *encryption_private_key, LassoNode **output);

void lasso_node_remove_signature(LassoNode *node);

char* lasso_concat_url_query(const char *url, const char *query);

xmlDocPtr lasso_xml_parse_memory(const char *buffer, int size);

xmlNode* lasso_xml_get_soap_content(xmlNode *root);

gboolean lasso_xml_is_soap(xmlNode *root);

gboolean lasso_eval_xpath_expression(xmlXPathContextPtr xpath_ctx, const char *expression,
		xmlXPathObjectPtr *xpath_object_ptr, int *xpath_error_code);

#define IF_SAML2(profile) \
	if (lasso_provider_get_protocol_conformance(LASSO_PROVIDER(profile->server)) == \
			LASSO_PROTOCOL_SAML_2_0)

char * lasso_get_relaystate_from_query(const char *query);
char * lasso_url_add_parameters(char *url, gboolean free, ...);
xmlSecKey* lasso_xmlsec_load_private_key_from_buffer(const char *buffer, size_t length, const char *password, LassoSignatureMethod signature_method, const char *certificate);
xmlSecKey* lasso_xmlsec_load_private_key(const char *filename_or_buffer, const char *password,
		LassoSignatureMethod signature_method, const char *certificate);
xmlDocPtr lasso_xml_parse_file(const char *filepath);
xmlDocPtr lasso_xml_parse_memory_with_error(const char *buffer, int size, xmlError *error);
xmlSecKeyPtr lasso_xmlsec_load_key_info(xmlNode *key_descriptor);
char* lasso_xmlnode_to_string(xmlNode *node, gboolean format, int level);
gboolean lasso_string_to_xsd_integer(const char *str, long int *integer);
void lasso_set_string_from_prop(char **str, xmlNode *node, xmlChar *name, xmlChar *ns);

void lasso_node_add_custom_namespace(LassoNode *node, const char *prefix, const char *href);

int lasso_node_set_signature(LassoNode *node, LassoSignatureContext context);

LassoSignatureContext lasso_node_get_signature(LassoNode *node);

void lasso_node_set_encryption(LassoNode *node, xmlSecKey *encryption_public_key,
		LassoEncryptionSymKeyType encryption_sym_key_type);

void lasso_node_get_encryption(LassoNode *node, xmlSecKey **encryption_public_key,
		LassoEncryptionSymKeyType *encryption_sym_key_type);
gboolean lasso_base64_decode(const char *from, char **buffer, int *buffer_len);

xmlSecKeyPtr
lasso_create_hmac_key(const xmlSecByte * buf, xmlSecSize size);

lasso_error_t
lasso_get_hmac_key(const xmlSecKey *key, void **buffer, size_t *size);

LassoSignatureContext lasso_make_signature_context_from_buffer(const void *buffer, size_t length,
		const char *password, LassoSignatureMethod signature_method,
		const char *certificate);

LassoSignatureContext lasso_make_signature_context_from_path_or_string(char *filename_or_buffer,
		const char *password, LassoSignatureMethod signature_method,
		const char *certificate);

xmlNs * get_or_define_ns(xmlNode *xmlnode, const xmlChar *ns_uri, const xmlChar
		*advised_prefix);

void set_qname_attribute(xmlNode *node,
		const xmlChar *attribute_ns_prefix,
		const xmlChar *attribute_ns_href,
		const xmlChar *attribute_name,
		const xmlChar *prefix,
		const xmlChar *href,
		const xmlChar *name);


void set_xsi_type(xmlNode *node,
		const xmlChar *type_ns_prefix,
		const xmlChar *type_ns_href,
		const xmlChar *type_name);

void lasso_xmlnode_add_saml2_signature_template(xmlNode *node, LassoSignatureContext context,
		const char *id);

gchar* lasso_xmlnode_build_deflated_query(xmlNode *xmlnode);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __LASSO_XML_PRIVATE_H__ */