summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Dauvergne <bdauvergne@entrouvert.com>2008-08-01 14:07:57 +0000
committerBenjamin Dauvergne <bdauvergne@entrouvert.com>2008-08-01 14:07:57 +0000
commitda8bef4d6965db0d6f4a1ca26eefce644d1ff7a6 (patch)
treeffdb529cf8822d1bdd09ef76f2c2b5dc4162b5d0
parent52483330ff0526f13097f462c7be77eefcda8645 (diff)
downloadlasso-da8bef4d6965db0d6f4a1ca26eefce644d1ff7a6.tar.gz
lasso-da8bef4d6965db0d6f4a1ca26eefce644d1ff7a6.tar.xz
lasso-da8bef4d6965db0d6f4a1ca26eefce644d1ff7a6.zip
- lasso_wsf_profile_add_credential_signature:
* add documentation * reformat * add comments on the work flow * fix memleak - suppress lasso_wsf_profile_get_public_key_from_credential
-rw-r--r--lasso/id-wsf/wsf_profile.c249
1 files changed, 98 insertions, 151 deletions
diff --git a/lasso/id-wsf/wsf_profile.c b/lasso/id-wsf/wsf_profile.c
index 6040a1c0..a8cc93f5 100644
--- a/lasso/id-wsf/wsf_profile.c
+++ b/lasso/id-wsf/wsf_profile.c
@@ -478,18 +478,40 @@ exit:
return ret;
}
+/**
+ * lasso_wsf_profile_add_credential_signature:
+ * @profile: a #LassoWsfProfile
+ * @doc: an #xmlDoc containging the credential node
+ * @credential: an #xmlNode representing the credentials
+ * @sign_method: the signature method to use in signing the credentials, can be
+ * LASSO_SIGNATURE_METHOD_RSA_SHA1 or LASSO_SIGNATURE_METHOD_DSA_SHA1.
+ *
+ * Add an XMLSEC signature to a credential node.
+ *
+ * Returns: 0 if the signature was added,
+ * %LASSO_DS_ERROR_SIGNATURE_TEMPLATE_NOT_FOUND if not signature template is
+ * present in the credential node, %LASSO_DS_ERROR_PRIVATE_KEY_LOAD_FAILED if
+ * we cannot load our private key, %LASSO_DS_ERROR_CERTIFICATE_LOAD_FAILED if
+ * we cannot load our certificate and %LASSO_DS_ERROR_SIGNATURE_FAILED if the
+ * signing failed.
+ */
static gint
lasso_wsf_profile_add_credential_signature(LassoWsfProfile *profile,
- xmlDoc *doc, xmlNode *credential, LassoSignatureMethod sign_method)
+ xmlDoc *doc, xmlNode *credential,
+ LassoSignatureMethod sign_method)
{
- xmlNode *signature = NULL, *sign_tmpl, *reference, *key_info;
- char *uri;
-
+ xmlNode *signature = NULL, *sign_tmpl = NULL,
+ *reference = NULL, *key_info = NULL;
+ char *uri = NULL;
xmlAttr *id_attr;
+ xmlSecDSigCtx *dsigCtx = NULL;
+ gint ret = 0;
+ gchar *assertionID = NULL;
+ gboolean with_x509 = FALSE;
- xmlSecDSigCtx *dsigCtx;
-
- /* Add signature template */
+ with_x509 = profile->server->certificate != NULL &&
+ profile->server->certificate[0] != 0;
+ /* 1. Add signature template */
if (sign_method == LASSO_SIGNATURE_METHOD_RSA_SHA1) {
signature = xmlSecTmplSignatureCreate(NULL,
xmlSecTransformExclC14NId,
@@ -499,170 +521,95 @@ lasso_wsf_profile_add_credential_signature(LassoWsfProfile *profile,
xmlSecTransformExclC14NId,
xmlSecTransformDsaSha1Id, NULL);
}
-
- xmlAddChild(credential, signature);
-
- /* Credential reference */
- uri = g_strdup_printf("#%s", xmlGetProp(credential, (xmlChar *) "AssertionID"));
- reference = xmlSecTmplSignatureAddReference(signature, xmlSecTransformSha1Id,
- NULL, (xmlChar*)uri, NULL);
+ if (signature == NULL) {
+ ret = LASSO_DS_ERROR_SIGNATURE_TMPL_CREATION_FAILED;
+ goto exit;
+ } else {
+ if (xmlAddChild(credential, signature) !=
+ signature) {
+ ret = LASSO_DS_ERROR_SIGNATURE_TMPL_CREATION_FAILED;
+ goto exit;
+ }
+ }
+ /* 2. Find and create reference */
+ id_attr = xmlHasProp(credential, (xmlChar *)"AssertionID");
+ if (id_attr == NULL) {
+ ret = LASSO_WSF_PROFILE_ERROR_MISSING_ASSERTION_ID;
+ goto exit;
+ }
+ assertionID = xmlGetProp(credential, (xmlChar *) "AssertionID");
+ uri = g_strdup_printf("#%s", assertionID);
+ reference = xmlSecTmplSignatureAddReference(signature,
+ xmlSecTransformSha1Id, NULL, (xmlChar*)uri, NULL);
+ g_release_string(uri);
xmlSecTmplReferenceAddTransform(reference, xmlSecTransformEnvelopedId);
xmlSecTmplReferenceAddTransform(reference, xmlSecTransformExclC14NId);
- id_attr = xmlHasProp(credential, (xmlChar *)"AssertionID");
- xmlAddID(NULL, doc, xmlGetProp(credential, (xmlChar *) "AssertionID"), id_attr);
+ xmlAddID(NULL, doc, assertionID, id_attr);
+ xmlFree(assertionID);
- /* FIXME: X509 authentication needs X509 signature type */
- if (profile->server->certificate != NULL && profile->server->certificate[0] != 0) {
+ /* 3. Add X509 info if server possess a certificate. XXX: Why ? */
+ if (with_x509)
+ {
key_info = xmlSecTmplSignatureEnsureKeyInfo(signature, NULL);
xmlSecTmplKeyInfoAddX509Data(key_info);
}
- /* Sign SOAP message */
- sign_tmpl = xmlSecFindNode(credential, xmlSecNodeSignature, xmlSecDSigNs);
- if (sign_tmpl == NULL)
- return LASSO_DS_ERROR_SIGNATURE_TEMPLATE_NOT_FOUND;
-
+ /* 4. Create signature context and load a key in it */
dsigCtx = xmlSecDSigCtxCreate(NULL);
dsigCtx->signKey = xmlSecCryptoAppKeyLoad(profile->server->private_key,
xmlSecKeyDataFormatPem, NULL, NULL, NULL);
if (dsigCtx->signKey == NULL) {
- xmlSecDSigCtxDestroy(dsigCtx);
- return LASSO_DS_ERROR_PRIVATE_KEY_LOAD_FAILED;
+ ret = LASSO_DS_ERROR_PRIVATE_KEY_LOAD_FAILED;
+ goto exit;
}
- if (profile->server->certificate != NULL && profile->server->certificate[0] != 0) {
- if (xmlSecCryptoAppKeyCertLoad(dsigCtx->signKey, profile->server->certificate,
+ /* 5. Complete the key with a certificate as needed, but don't break
+ * on it. */
+ if (with_x509) {
+ /* Dont stop if we cannot load the certificate, just
+ * remove the KeyInfo node */
+ if (xmlSecCryptoAppKeyCertLoad(dsigCtx->signKey,
+ profile->server->certificate,
xmlSecKeyDataFormatPem) < 0) {
- xmlSecDSigCtxDestroy(dsigCtx);
- return LASSO_DS_ERROR_CERTIFICATE_LOAD_FAILED;
+ message(G_LOG_LEVEL_WARNING, "Could not load the certificate %s", profile->server->certificate);
+ ret = LASSO_DS_ERROR_CERTIFICATE_LOAD_FAILED;
+ g_unlink_and_release_node(key_info);
}
}
- if (xmlSecDSigCtxSign(dsigCtx, sign_tmpl) < 0) {
- xmlSecDSigCtxDestroy(dsigCtx);
- return LASSO_DS_ERROR_SIGNATURE_FAILED;
- }
- xmlSecDSigCtxDestroy(dsigCtx);
-
- return 0;
-}
-
-static xmlSecKey*
-lasso_wsf_profile_get_public_key_from_credential(LassoWsfProfile *profile, xmlNode *credential)
-{
- xmlNode *authentication_statement, *subject, *subject_confirmation, *key_info;
- xmlSecKeyPtr public_key;
- xmlSecKeyInfoCtx *ctx;
-
- /* get AuthenticationStatement element */
- authentication_statement = credential->children;
- while (authentication_statement) {
- if (authentication_statement->type == XML_ELEMENT_NODE &&
- strcmp((char*)authentication_statement->name,
- "AuthenticationStatement") == 0)
- break;
- authentication_statement = authentication_statement->next;
- }
- if (authentication_statement == NULL) {
- return NULL;
- }
-
- /* get Subject element */
- subject = authentication_statement->children;
- while (subject) {
- if (subject->type == XML_ELEMENT_NODE &&
- strcmp((char*)subject->name, "Subject") == 0)
- break;
- subject = subject->next;
- }
- if (subject == NULL) {
- return NULL;
- }
-
- /* get SubjectConfirmation */
- subject_confirmation = subject->children;
- while (subject_confirmation) {
- if (subject_confirmation->type == XML_ELEMENT_NODE &&
- strcmp((char*)subject_confirmation->name, "SubjectConfirmation") == 0)
- break;
- subject_confirmation = subject_confirmation->next;
- }
- if (subject_confirmation == NULL) {
- return NULL;
- }
-
- /* get KeyInfo */
- key_info = subject_confirmation->children;
- while (key_info) {
- if (key_info->type == XML_ELEMENT_NODE &&
- strcmp((char*)key_info->name, "KeyInfo") == 0)
- break;
- key_info = key_info->next;
- }
- if (!key_info)
- return NULL;
-
- ctx = xmlSecKeyInfoCtxCreate(NULL);
- xmlSecKeyInfoCtxInitialize(ctx, NULL);
-
- ctx->mode = xmlSecKeyInfoModeRead;
- ctx->keyReq.keyType = xmlSecKeyDataTypePublic;
-
- public_key = xmlSecKeyCreate();
-
- /* FIXME: get xml sec key from key_info instead of a rebuilt local node */
- /* xmlSecKeyInfoNodeRead(key_info, public_key, ctx); */
-
- {
- xmlDoc *doc;
- xmlChar *modulus_value, *exponent_value;
- xmlNode *rsa_key_value, *xmlnode, *modulus, *exponent;
-
- xmlnode = key_info->children;
- while (xmlnode) {
- if (strcmp((char*)xmlnode->name, "KeyValue") == 0) {
- break;
- }
- xmlnode = xmlnode->next;
- }
- rsa_key_value = xmlnode->children;
- while (rsa_key_value) {
- if (strcmp((char*)rsa_key_value->name, "RsaKeyValue") == 0) {
- break;
- }
- rsa_key_value = rsa_key_value->next;
- }
- xmlnode = rsa_key_value->children;
- while (xmlnode) {
- if (strcmp((char*)xmlnode->name, "Modulus") == 0) {
- modulus_value = xmlNodeGetContent(xmlnode);
- } else if (strcmp((char*)xmlnode->name, "Exponent") == 0) {
- exponent_value = xmlNodeGetContent(xmlnode);
- }
- xmlnode = xmlnode->next;
- }
-
- doc = xmlSecCreateTree((xmlChar*)"KeyInfo",
- (xmlChar*)"http://www.w3.org/2000/09/xmldsig#");
- key_info = xmlDocGetRootElement(doc);
-
- xmlnode = xmlSecAddChild(key_info, (xmlChar*)"KeyValue",
- (xmlChar*)"http://www.w3.org/2000/09/xmldsig#");
- xmlnode = xmlSecAddChild(xmlnode, (xmlChar*)"RSAKeyValue",
- (xmlChar*)"http://www.w3.org/2000/09/xmldsig#");
- modulus = xmlSecAddChild(xmlnode, (xmlChar*)"Modulus",
- (xmlChar*)"http://www.w3.org/2000/09/xmldsig#");
- xmlNodeSetContent(modulus, modulus_value);
-
- exponent = xmlSecAddChild(xmlnode, (xmlChar*)"Exponent",
- (xmlChar*)"http://www.w3.org/2000/09/xmldsig#");
- xmlNodeSetContent(exponent, exponent_value);
+ /* 6. Sign */
+ if (xmlSecDSigCtxSign(dsigCtx, signature) < 0) {
+ ret = LASSO_DS_ERROR_SIGNATURE_FAILED;
+ goto exit;
}
+ signature = NULL; // Steal the reference
+exit:
+ /* Destroy the signature when error exit */
+ g_unlink_and_release_node(signature);
+ /* Clean dsigCtx */
+ if (dsigCtx)
+ xmlSecDSigCtxDestroy(dsigCtx);
- xmlSecKeyInfoNodeRead(key_info, public_key, ctx);
-
- return public_key;
+ return ret;
}
+/**
+ * lasso_wsf_profile_verify_saml_authentication:
+ * @profile: a #LassoWsfProfile pointer
+ * @doc: an #xmlDoc pointer
+ *
+ * Verify the the signature on the assertion given in the wsse:Security header with
+ * respect to the provider set as Issuer of this Assertion.
+ *
+ * Returns: 0 if saml authentication is valid,
+ * %LASSO_PROFILE_ERROR_MISSING_ISSUER if credential contains no Issuer
+ * attribute, %LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND if the Issuer provider is
+ * unknown from #LassoServer, %LASSO_DS_ERROR_CA_CERT_CHAIN_LOAD_FAILED if we
+ * cannot load the given CA chcert chain,
+ * %LASSO_DS_ERROR_PUBLIC_KEY_LOAD_FAILED if we cannot the public key of the
+ * provider, %LASSO_DS_ERROR_SIGNATURE_VERIFICATION_FAILED if the signature
+ * verification failed, and %LASSO_DS_ERROR_INVALID_SIGNATURE if the signature
+ * is invalid.
+ */
static gint
lasso_wsf_profile_verify_saml_authentication(LassoWsfProfile *profile, xmlDoc *doc)
{