[xmlsec] the ws security templates

Alexandre Kalendarev akalend at mail.ru
Tue Jan 16 22:56:05 PST 2007


Hi All,

In the attachment You can to find the some functions for create ws:Security nodes. I will to supplement this list. So, in the near future I'll the add the parsing ws:Security nodes functions.


I will very glad, if my code will helpful for You and Aleksey could be like to include as part libxmlsec.


Alexandre.
-------------- next part --------------

/**
 * Creating signature and encryption templates.
 *
 * This is free software; see Copyright file in the source
 * distribution for preciese wording.
 *
 * Copyright (C) 2002-2003 Aleksey Sanin <aleksey at aleksey.com>
 *           (C) 2006 Alexandre Kalendarev <akalend at mail.ru>
 */

 /*************************************************************************
 *
 * Global Namespaces
 *
 ************************************************************************/
const xmlChar xmlSecWsNs[] 			= "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";

 
/*************************************************************************
 *
 *  WS Security Nodes
 *
 ************************************************************************/
const xmlChar xmlSecNodeWsSecurity []				= "Security";
const xmlChar xmlSecNodeSecurityTokenReference[] 	= "SecurityTokenReference";
const xmlChar xmlSecNodeBinarySecurityToken[]	 	=  "BinarySecurityToken";
const xmlChar  xmlSecNodeUserNameSecurityToken[]	 = "UsernameToken";
 const xmlChar  xmlSecNodeUserNameToken[] 			="UsernameToken";
 const xmlChar  xmlSecNodeUserName[] 				="UserName";
 const xmlChar  xmlSecNodePassword[] 				="Password";
/*************************************************************************
 *
 *  WS Security Attributes
 *
 ************************************************************************/
const xmlChar xmlSecAttrValueType[]			= "ValueType";
const xmlChar xmlSecAttrEncodingType[]		= "EncodingType";

const xmlChar xmlSecWsBase64Binary[]		= "wsse:Base64Binary";
const xmlChar xmlSecWsHexBinary[]			= "wsse:HexBinary";

const xmlChar xmlSecWsX509v3[]				= "wsse:X509v3";
const xmlChar xmlSecWsKerberosv5TGT[]		= "wsse:Kerberosv5TGT";
const xmlChar xmlSecWsKerberosv5ST[]		= "wsse:Kerberosv5ST";

const xmlChar xmlSecWsPasswordText[]		= "PasswordText";
const xmlChar xmlSecWsPasswordDigest[]		= "PasswordDigest";

xmlNsPtr xmlSecSetNs(xmlNodePtr encNode, xmlChar *nsPrefix, const xmlChar* nsUrl ){
	xmlNsPtr ns;

	if(nsPrefix == NULL)
		ns = xmlNewNs(encNode, nsUrl, NULL);
	else
		ns = xmlNewNs(encNode, nsUrl, nsPrefix );

    if(ns == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlNewNs",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    "ns=%s, prefix=%s",
		    xmlSecErrorsSafeString(nsUrl),
			xmlSecErrorsSafeString(nsPrefix));
	}
	xmlSetNs(encNode,ns);
	return (ns);
	}


/**************************************************************************
 *
 * <enc:EncryptedData/> node
 *
 **************************************************************************/
/**
 * xmlSecTmplEncDataCreate:
 * @doc: 		the pointer to signature document or NULL; in the later
 *			case, application must later call @xmlSetTreeDoc to ensure
 *			that all the children nodes have correct pointer to XML document.
 * @encMethodId:	the encryption method (may be NULL).
 * @id: 		the Id attribute (optional).
 * @type: 		the Type attribute (optional)
 * @mimeType: 		the MimeType attribute (optional)
 * @encoding: 		the Encoding attribute (optional)
 * @namespace		the namespace prefix
 *
 * Creates new <enc:EncryptedData /> node for encryption template.
 *
 * Returns the pointer newly created  <enc:EncryptedData/> node or NULL
 * if an error occurs.
 */
xmlNode*	xmlSecTmplEncDataCreateNs(xmlDocPtr doc, xmlSecTransformId encMethodId,
			    const xmlChar *id, const xmlChar *type,
			    const xmlChar *mimeType, const xmlChar *encoding, const xmlChar *namespace ) {
    xmlNodePtr encNode;
    xmlNsPtr ns;

    encNode = xmlNewDocNode(doc, NULL, xmlSecNodeEncryptedData, NULL);

    if(encNode == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlNewDocNode",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString(xmlSecNodeEncryptedData));
//	fprintf(stderr, "xmlNewDocNode error \n");
	return(NULL);
    }

	if ( namespace == NULL )
    	ns = xmlNewNs(encNode, xmlSecEncNs, NULL);
	else
		ns = xmlNewNs(encNode, xmlSecEncNs, namespace);

    if(ns == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlNewNs",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    "ns=%s",
		    xmlSecErrorsSafeString(xmlSecEncNs));

//	fprintf(stderr, "xmlNewNs error \n");
	return(NULL);
    }
    xmlSetNs(encNode, ns);

    if(id != NULL) {
	xmlSetProp(encNode, xmlSecAttrId, id);
    }

	if(type != NULL) {
	xmlSetProp(encNode, xmlSecAttrType, type);
    }

	if(mimeType != NULL) {
	xmlSetProp(encNode, xmlSecAttrMimeType, mimeType);
    }
    if(encoding != NULL) {
	xmlSetProp(encNode, xmlSecAttrEncoding, encoding);
    }

    if(xmlSecTmplPrepareEncDataNs(encNode, encMethodId, ns) < 0) {
	//fprintf(stderr, "xmlFreeNode encNode\n");
	xmlFreeNode(encNode);
	return(NULL);
    }

	return(encNode);
}

int xmlSecTmplPrepareEncDataNs(xmlNodePtr parentNode, xmlSecTransformId encMethodId, xmlNsPtr ns) {//xmlChar *nsName
    xmlNodePtr cur;

    xmlSecAssert2(parentNode != NULL, -1);
    xmlSecAssert2((encMethodId == NULL) || (encMethodId->href != NULL), -1);

    /* add EncryptionMethod node if requested */
    if(encMethodId != NULL) {
	cur = xmlSecAddChild(parentNode, xmlSecNodeEncryptionMethod, NULL);
	if(cur == NULL) {
	    xmlSecError(XMLSEC_ERRORS_HERE,
			NULL,
			"xmlSecAddChild",
			XMLSEC_ERRORS_R_XMLSEC_FAILED,
			"node=%s",
			xmlSecErrorsSafeString(xmlSecNodeEncryptionMethod));
	    return(-1);
	}
	xmlSetNs(cur, ns );

	if(xmlSetProp(cur, xmlSecAttrAlgorithm, encMethodId->href) == NULL) {
	    xmlSecError(XMLSEC_ERRORS_HERE,
		        NULL,
			"xmlSetProp",
		        XMLSEC_ERRORS_R_XML_FAILED,
			"name=%s,value=%s",
		        xmlSecErrorsSafeString(xmlSecAttrAlgorithm),
			xmlSecErrorsSafeString(encMethodId->href));
	    return(-1);
	}
    }

    /* and CipherData node */
    cur = xmlSecAddChild(parentNode, xmlSecNodeCipherData, NULL);
    if(cur == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlSecAddChild",
		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString(xmlSecNodeCipherData));
	return(-1);
    }
    xmlSetNs(cur, ns );

    return(0);
}

/**
 * xmlSecTmplEncDataEnsureCipherValue:
 * @encNode: 		the pointer to <enc:EncryptedData/> node.
 * @ns			the pointer to the namespace
 *
 * Adds <enc:CipherValue/> to the <enc:EncryptedData/> node @encNode.
 * Returns the pointer to newly created <enc:CipherValue/> node or
 * NULL if an error occurs.
 */
xmlNodePtr
xmlSecTmplEncDataEnsureCipherValueNs(xmlNodePtr encNode, xmlNsPtr ns) {
    xmlNodePtr cipherDataNode;
    xmlNodePtr res, tmp;

	xmlSecAssert2(encNode != NULL, NULL);

    cipherDataNode = xmlSecFindChild(encNode, xmlSecNodeCipherData, xmlSecEncNs);
    if(cipherDataNode == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    xmlSecErrorsSafeString(xmlSecNodeCipherData),
		    XMLSEC_ERRORS_R_NODE_NOT_FOUND,
		    XMLSEC_ERRORS_NO_MESSAGE);
	return(NULL);
    }
    /* check that we don;t have CipherReference node */
    tmp = xmlSecFindChild(cipherDataNode, xmlSecNodeCipherReference, xmlSecEncNs);
    if(tmp != NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    xmlSecErrorsSafeString(xmlSecNodeCipherReference),
		    XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
		    XMLSEC_ERRORS_NO_MESSAGE);
	return(NULL);
    }

    res = xmlSecFindChild(cipherDataNode, xmlSecNodeCipherValue, xmlSecEncNs);
    if(res == NULL) {
		res = xmlSecAddChild(cipherDataNode, xmlSecNodeCipherValue, NULL);
		if(res == NULL) {
			xmlSecError(XMLSEC_ERRORS_HERE,
				NULL,
				"xmlSecAddChild",
				XMLSEC_ERRORS_R_XMLSEC_FAILED,
				"node=%s",
				xmlSecErrorsSafeString(xmlSecNodeCipherValue));
		return(NULL);
		}
		xmlSetNs(res,ns);
	    //xmlSecSetNs(res, nsName, xmlSecEncNs);
    }

    return(res);
}

/**
 * xmlSecTmplEncDataEnsureKeyInfo:
 * @encNode: 		the pointer to <enc:EncryptedData/> node.
 * @id:			the Id attrbibute (optional).
 * @nsPrefix		the prefix of the namespace
 *
 * Adds <dsig:KeyInfo/> to the  <enc:EncryptedData/> node @encNode.
 *
 * Returns the pointer to newly created <dsig:KeyInfo/> node or
 * NULL if an error occurs.
 */
xmlNodePtr
xmlSecTmplEncDataEnsureKeyInfoNs(xmlNodePtr encNode, const xmlChar* id, xmlChar* nsPrefix) {
//xmlSecTmplEncDataEnsureKeyInfoNs(xmlNodePtr encNode, const xmlChar* id, xmlNsPtr ns) {    
	xmlNodePtr res, cur;
    
	xmlSecAssert2(encNode != NULL, NULL);

    res = xmlSecFindChild(encNode, xmlSecNodeKeyInfo, xmlSecDSigNs);
    if(res == NULL) {
	xmlNodePtr cipherDataNode;

    cipherDataNode = xmlSecFindChild(encNode, xmlSecNodeCipherData, xmlSecEncNs);
	if(cipherDataNode == NULL) {
	    xmlSecError(XMLSEC_ERRORS_HERE,
		        NULL,
			xmlSecErrorsSafeString(xmlSecNodeCipherData),
		        XMLSEC_ERRORS_R_NODE_NOT_FOUND,
			XMLSEC_ERRORS_NO_MESSAGE);
	    return(NULL);
	}
	
	// res = xmlSecAddPrevSibling(cipherDataNode, xmlSecNodeKeyInfo, xmlSecEncNs);
	cur = xmlNewNode(NULL, xmlSecNodeKeyInfo);
    if(cur == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlNewNode",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    XMLSEC_ERRORS_NO_MESSAGE);
	return(NULL);
    }

	res = xmlAddPrevSibling(cipherDataNode, cur);	
	if(res == NULL) {
	    xmlSecError(XMLSEC_ERRORS_HERE,
		        NULL,
			"xmlSecAddPrevSibling",
			XMLSEC_ERRORS_R_XMLSEC_FAILED,
			"node=%s",
			xmlSecErrorsSafeString(xmlSecNodeKeyInfo));
	    return(NULL);
	}
	
	xmlSecSetNs(res, nsPrefix, xmlSecDSigNs);    
	

	}	
    if(id != NULL) {
	xmlSetProp(res, xmlSecAttrId, id);
    }
	return(res);
}


/**
 * xmlSecTmplKeyInfoAddEncryptedKey:
 * @keyInfoNode: 	the pointer to <dsig:KeyInfo/> node.
 * @encMethodId:	the encryption method (optional).
 * @id: 		the Id attribute (optional).
 * @type: 		the Type attribute (optional).
 * @recipient: 		the Recipient attribute (optional).
 * @ns			the pointer to the namespace
 *
 * Adds <enc:EncryptedKey/> node with given attributes to
 * the <dsig:KeyInfo/> node @keyInfoNode.
 *
 * Returns the pointer to the newly created <enc:EncryptedKey/> node or
 * NULL if an error occurs.
 */
xmlNodePtr
xmlSecTmplKeyInfoAddEncryptedKeyNs(xmlNodePtr keyInfoNode, xmlSecTransformId encMethodId,
			 const xmlChar* id, const xmlChar* type, const xmlChar* recipient, xmlNsPtr ns) {//xmlChar *nsName
    xmlNodePtr encKeyNode;

	xmlSecAssert2(keyInfoNode != NULL, NULL);

    /* we allow multiple encrypted key elements */
    encKeyNode = xmlSecAddChild(keyInfoNode, xmlSecNodeEncryptedKey, xmlSecEncNs);
    if(encKeyNode == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlSecAddChild",
		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString(xmlSecNodeEncryptedKey));
	return(NULL);
    }
	//ns = xmlSecSetNs(encKeyNode, nsName, xmlSecEncNs);
	xmlSetNs(encKeyNode,ns);


    if(id != NULL) {
	xmlSetProp(encKeyNode, xmlSecAttrId, id);
    }
    if(type != NULL) {
	xmlSetProp(encKeyNode, xmlSecAttrType, type);
    }
    if(recipient != NULL) {
	xmlSetProp(encKeyNode, xmlSecAttrRecipient, recipient);
    }

    if(xmlSecTmplPrepareEncDataNs(encKeyNode, encMethodId, ns) < 0) {
//		fprintf(stderr, "encKeyNode xmlUnlinkNode \n");
		xmlUnlinkNode(encKeyNode);
		xmlFreeNode(encKeyNode);
	return(NULL);
    }

    return(encKeyNode);
}

/**************************************************************************
 *
 * <dsig:KeyInfo/> node
 *
 **************************************************************************/

/**
 * xmlSecTmplKeyInfoAddKeyNameNs:
 * @keyInfoNode: 	the pointer to <dsig:KeyInfo/> node.
 * @name:		the key name (optional).
 * @ns			the pointer to the namespace
 *
 * Adds <dsig:KeyName/> node to the <dsig:KeyInfo/> node @keyInfoNode.
 *
 * Returns the pointer to the newly created <dsig:KeyName/> node or
 * NULL if an error occurs.
 */
xmlNodePtr
xmlSecTmplKeyInfoAddKeyNameNs(xmlNodePtr keyInfoNode, const xmlChar* name, xmlNsPtr ns) {
    xmlNodePtr res;

    xmlSecAssert2(keyInfoNode != NULL, NULL);

    res = xmlSecAddChild(keyInfoNode, xmlSecNodeKeyName, NULL);
    if(res == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlSecAddChild",
		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString(xmlSecNodeKeyName));
	return(NULL);
    }
	xmlSetNs(res, ns);
	
    if(name != NULL) {
	xmlNodeSetContent(res, name);
    }
    return(res);
}


/**************************************************************************
 *
 * <dsig:Signature/> node
 *
 **************************************************************************/
/**
 * xmlSecTmplSignatureCreate:
 * @doc: 		the pointer to signature document or NULL; in the
 *			second case, application must later call @xmlSetTreeDoc
 *			to ensure that all the children nodes have correct
 *			pointer to XML document.
 * @c14nMethodId: 	the signature canonicalization method.
 * @signMethodId: 	the signature  method.
 * @id: 		the node id (may be NULL).
 * @namespace		the namespace prefix
 *
 * Creates new <dsig:Signature/> node with the mandatory <dsig:SignedInfo/>,
 * <dsig:CanonicalizationMethod/>, <dsig:SignatureMethod/> and
 * <dsig:SignatureValue/> children and sub-children.
 * The application is responsible for inserting the returned node
 * in the XML document.
 *
 * Returns the pointer to newly created <dsig:Signature/> node or NULL if an
 * error occurs.
 */
xmlNodePtr
xmlSecTmplSignatureCreateNs(xmlDocPtr doc, xmlSecTransformId c14nMethodId,
		      xmlSecTransformId signMethodId, const xmlChar *id, xmlChar* nsPrefix) {
    xmlNodePtr signNode;
    xmlNodePtr signedInfoNode;
    xmlNodePtr cur;
    xmlNsPtr ns;

    xmlSecAssert2(c14nMethodId != NULL, NULL);
    xmlSecAssert2(c14nMethodId->href != NULL, NULL);
    xmlSecAssert2(signMethodId != NULL, NULL);
    xmlSecAssert2(signMethodId->href != NULL, NULL);

    /* create Signature node itself */
    signNode = xmlNewDocNode(doc, NULL, xmlSecNodeSignature, NULL);
    if(signNode == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlNewDocNode",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString(xmlSecNodeSignature));
	return(NULL);
    }

    ns = xmlSecSetNs(signNode, nsPrefix, xmlSecDSigNs );

    if(id != NULL) {
	xmlSetProp(signNode, BAD_CAST "Id", id);
    }

    /* add SignedInfo node */
    signedInfoNode = xmlSecAddChild(signNode, xmlSecNodeSignedInfo, NULL);
    if(signedInfoNode == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlSecAddChild",
		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString(xmlSecNodeSignedInfo));
	xmlFreeNode(signNode);
	return(NULL);
    }
	xmlSetNs( signedInfoNode, ns);

    /* add SignatureValue node */
    cur = xmlSecAddChild(signNode, xmlSecNodeSignatureValue, NULL);
    if(cur == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlSecAddChild",
		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString(xmlSecNodeSignatureValue));
	xmlFreeNode(signNode);
	return(NULL);
    }
	xmlSetNs( cur, ns);

    /* add CanonicaizationMethod node to SignedInfo */
    cur = xmlSecAddChild(signedInfoNode, xmlSecNodeCanonicalizationMethod, NULL);
    if(cur == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlSecAddChild",
		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString(xmlSecNodeCanonicalizationMethod));
	xmlFreeNode(signNode);
	return(NULL);
    }
	xmlSetNs( cur, ns);

    if(xmlSetProp(cur, xmlSecAttrAlgorithm, c14nMethodId->href) == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlSetProp",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    "name=%s,value=%s",
		    xmlSecErrorsSafeString(xmlSecAttrAlgorithm),
		    xmlSecErrorsSafeString(c14nMethodId->href));
	xmlFreeNode(signNode);
	return(NULL);
    }

    /* add SignatureMethod node to SignedInfo */
    cur = xmlSecAddChild(signedInfoNode, xmlSecNodeSignatureMethod, NULL);
    if(cur == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlSecAddChild",
		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString(xmlSecNodeSignatureMethod));
	xmlFreeNode(signNode);
	return(NULL);
    }
	xmlSetNs( cur, ns);

    if(xmlSetProp(cur, xmlSecAttrAlgorithm, signMethodId->href) == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlSetProp",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    "name=%s,value=%s",
		    xmlSecErrorsSafeString(xmlSecAttrAlgorithm),
		    xmlSecErrorsSafeString(signMethodId->href));
	xmlFreeNode(signNode);
	return(NULL);
    }

    return(signNode);
}


xmlNodePtr
xmlSecTmplAddReferenceNs(xmlNodePtr parentNode, xmlSecTransformId digestMethodId,
		    const xmlChar *id, const xmlChar *uri, const xmlChar *type, xmlNsPtr ns) {
    xmlNodePtr res;
    xmlNodePtr cur;

    xmlSecAssert2(parentNode != NULL, NULL);
    xmlSecAssert2(digestMethodId != NULL, NULL);
    xmlSecAssert2(digestMethodId->href != NULL, NULL);

    /* add Reference node */
    res = xmlSecAddChild(parentNode, xmlSecNodeReference, NULL);
    if(res == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlSecAddChild",
		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString(xmlSecNodeReference));
	return(NULL);
    }

    xmlSetNs(res,ns);

	/* set Reference node attributes */
    if(id != NULL) {
	xmlSetProp(res, xmlSecAttrId, id);
    }
    if(type != NULL) {
	xmlSetProp(res, xmlSecAttrType, type);
    }
    if(uri != NULL) {
	xmlSetProp(res, xmlSecAttrURI, uri);
    }

    /* add DigestMethod node and set algorithm */
    cur = xmlSecAddChild(res, xmlSecNodeDigestMethod, NULL);
    if(cur == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlSecAddChild",
		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString(xmlSecNodeDigestMethod));
	xmlUnlinkNode(res);
	xmlFreeNode(res);
	return(NULL);
    }
    xmlSetNs(cur,ns);

	if(xmlSetProp(cur, xmlSecAttrAlgorithm, digestMethodId->href) == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlSetProp",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    "name=%s,value=%s",
		    xmlSecErrorsSafeString(xmlSecAttrAlgorithm),
		    xmlSecErrorsSafeString(digestMethodId->href));
	xmlUnlinkNode(res);
	xmlFreeNode(res);
	return(NULL);
    }

    /* add DigestValue node */
    cur = xmlSecAddChild(res, xmlSecNodeDigestValue, NULL);
    if(cur == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlSecAddChild",
		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString(xmlSecNodeDigestValue));
	xmlUnlinkNode(res);
	xmlFreeNode(res);
	return(NULL);
    }
    xmlSetNs(cur,ns);
    return(res);
}


/**
 * xmlSecTmplSignatureAddReference:
 * @signNode: 		the pointer to <dsig:Signature/> node.
 * @digestMethodId:	the reference digest method.
 * @id: 		the node id (may be NULL).
 * @uri: 		the reference node uri (may be NULL).
 * @type: 		the reference node type (may be NULL).
 * @ns			the pointer to the namespace
 *
 * Adds <dsig:Reference/> node with given URI (@uri), Id (@id) and
 * Type (@type) attributes and the required children <dsig:DigestMethod/> and
 * <dsig:DigestValue/> to the <dsig:SignedInfo/> child of @signNode.
 *
 * Returns the pointer to newly created <dsig:Reference/> node or NULL
 * if an error occurs.
*/
xmlNodePtr
xmlSecTmplSignatureAddReferenceNs(xmlNodePtr signNode, xmlSecTransformId digestMethodId,
		    const xmlChar *id, const xmlChar *uri, const xmlChar *type, xmlNsPtr ns) {
    xmlNodePtr signedInfoNode;

    xmlSecAssert2(signNode != NULL, NULL);
    xmlSecAssert2(digestMethodId != NULL, NULL);
    xmlSecAssert2(digestMethodId->href != NULL, NULL);

    signedInfoNode = xmlSecFindChild(signNode, xmlSecNodeSignedInfo, xmlSecDSigNs);
    if(signedInfoNode == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    xmlSecErrorsSafeString(xmlSecNodeSignedInfo),
		    XMLSEC_ERRORS_R_NODE_NOT_FOUND,
		    XMLSEC_ERRORS_NO_MESSAGE);
	return(NULL);
    }

    return(xmlSecTmplAddReferenceNs(signedInfoNode, digestMethodId, id, uri, type, ns));
}


/**
 * xmlSecTmplReferenceAddTransform:
 * @referenceNode: 		the pointer to <dsig:Reference/> node.
 * @transformId: 		the transform method id.
 * @ns			the pointer to the namespace
 *
 * Adds <dsig:Transform/> node to the <dsig:Reference/> node @referenceNode.
 *
 * Returns the pointer to newly created <dsig:Transform/> node or NULL if an
 * error occurs.
 */
xmlNodePtr
xmlSecTmplReferenceAddTransformNs(xmlNodePtr referenceNode, xmlSecTransformId transformId, xmlNsPtr ns) {
    xmlNodePtr transformsNode;
    xmlNodePtr res;

    xmlSecAssert2(referenceNode != NULL, NULL);
    xmlSecAssert2(transformId != NULL, NULL);
    xmlSecAssert2(transformId->href != NULL, NULL);

    /* do we need to create Transforms node first */
    transformsNode = xmlSecFindChild(referenceNode, xmlSecNodeTransforms, xmlSecDSigNs);
    if(transformsNode == NULL) {
	xmlNodePtr tmp;

	tmp = xmlSecGetNextElementNode(referenceNode->children);
	if(tmp == NULL) {
			transformsNode = xmlSecAddChild(referenceNode, xmlSecNodeTransforms, NULL);
		} else {
			transformsNode = xmlSecAddPrevSibling(tmp, xmlSecNodeTransforms, NULL);
		}
		if(transformsNode == NULL) {
			xmlSecError(XMLSEC_ERRORS_HERE,
				NULL,
				"xmlSecAddChild or xmlSecAddPrevSibling",
				XMLSEC_ERRORS_R_XMLSEC_FAILED,
				"node=%s",
				xmlSecErrorsSafeString(xmlSecNodeTransforms));
			return(NULL);
		}
		xmlSetNs(transformsNode,ns);
	}

    res = xmlSecAddChild(transformsNode, xmlSecNodeTransform, NULL);
    if(res == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlSecAddChild",
		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString(xmlSecNodeTransform));
	return(NULL);
    }
	xmlSetNs(res,ns);

    if(xmlSetProp(res, xmlSecAttrAlgorithm, transformId->href) == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlSetProp",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    "name=%s,value=%s",
		    xmlSecErrorsSafeString(xmlSecAttrAlgorithm),
		    xmlSecErrorsSafeString(transformId->href));
	xmlUnlinkNode(res);
	xmlFreeNode(res);
	return(NULL);
    }

    return(res);
}


/**
 * xmlSecTmplSignatureEnsureKeyInfo:
 * @signNode: 		the  pointer to <dsig:Signature/> node.
 * @id: 		the node id (may be NULL).
 * @ns			the pointer to the namespace
 *
 * Adds (if necessary) <dsig:KeyInfo/> node to the <dsig:Signature/>
 * node @signNode.
 *
 * Returns the pointer to newly created <dsig:KeyInfo/> node or NULL if an
 * error occurs.
 */
xmlNodePtr
xmlSecTmplSignatureEnsureKeyInfoNs(xmlNodePtr signNode, const xmlChar *id, xmlNsPtr ns) {
    xmlNodePtr res;

    xmlSecAssert2(signNode != NULL, NULL);

    res = xmlSecFindChild(signNode, xmlSecNodeKeyInfo, xmlSecDSigNs);
    if(res == NULL) {
	xmlNodePtr signValueNode;

    signValueNode = xmlSecFindChild(signNode, xmlSecNodeSignatureValue, xmlSecDSigNs);
	if(signValueNode == NULL) {
	    xmlSecError(XMLSEC_ERRORS_HERE,
		        NULL,
			xmlSecErrorsSafeString(xmlSecNodeSignatureValue),
		        XMLSEC_ERRORS_R_NODE_NOT_FOUND,
			XMLSEC_ERRORS_NO_MESSAGE);
	    return(NULL);
	}
	res = xmlSecAddNextSibling(signValueNode, xmlSecNodeKeyInfo, NULL);
	if(res == NULL) {
	    xmlSecError(XMLSEC_ERRORS_HERE,
		        NULL,
			"xmlSecAddNextSibling",
			XMLSEC_ERRORS_R_XMLSEC_FAILED,
			"node=%s",
			xmlSecErrorsSafeString(xmlSecNodeKeyInfo));
	    return(NULL);
	}
    xmlSetNs(res,ns);
	}
    if(id != NULL) {
	xmlSetProp(res, xmlSecAttrId, id);
    }
	return(res);
}

/***********************************************************************
 *
 * <dsig:X509Data> node
 *
 **********************************************************************/ 

/**
 * xmlSecTmplKeyInfoAddX509DataNs:
 * @keyInfoNode: 	the pointer to <dsig:KeyInfo/> node.
 * @ns			the pointer to the namespace
 *
 * Adds <dsig:X509Data/> node to the <dsig:KeyInfo/> node @keyInfoNode.
 *
 * Returns the pointer to the newly created <dsig:X509Data/> node or
 * NULL if an error occurs.
 */
xmlNodePtr
xmlSecTmplKeyInfoAddX509DataNs(xmlNodePtr keyInfoNode,  xmlNsPtr ns) {
    xmlNodePtr res;

    xmlSecAssert2(keyInfoNode != NULL, NULL);
        
    res = xmlSecAddChild(keyInfoNode, xmlSecNodeX509Data, NULL); 
    if(res == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlSecAddChild",
		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString(xmlSecNodeX509Data));
	return(NULL);	
    }
    
    xmlSetNs(res,ns);
    return(res);
}

 
/**
 * xmlSecTmplX509DataAddCertificateNs:
 * @x509DataNode: 	the pointer to <dsig:X509Data/> node.
 * @ns				the pointer to the namespace
 * 
 * Adds <dsig:X509Certificate/> node to the given <dsig:X509Data/> node.
 *
 * Returns the pointer to the newly created <dsig:X509Certificate/> node or
 * NULL if an error occurs.
 */

xmlNodePtr 
xmlSecTmplX509DataAddCertificateNs(xmlNodePtr x509DataNode, xmlNsPtr ns) {
    xmlNodePtr cur;

    xmlSecAssert2(x509DataNode != NULL, NULL);

    cur = xmlSecFindChild(x509DataNode, xmlSecNodeX509Certificate, xmlSecDSigNs);
    if(cur != NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    xmlSecErrorsSafeString(xmlSecNodeX509Certificate),
		    XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
		    XMLSEC_ERRORS_NO_MESSAGE);
	return(NULL);
    }
    
    cur = xmlSecAddChild(x509DataNode, xmlSecNodeX509Certificate, NULL);
    if(cur == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlSecAddChild",
		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
		    "node=%s", 
		    xmlSecErrorsSafeString(xmlSecNodeX509Certificate));
	return(NULL);
    }    
    xmlSetNs( cur, ns);
    return (cur);
}

/***********************************************************************
 *
 * SOAP 
 *
 **********************************************************************/
/**
* xmlSecSoap12CreateEnvelopeNs:
* @doc:        	the parent doc (might be NULL).
 * @nsName	the namespace
* 
* Creates a new SOAP Envelope node. Caller is responsible for 
* adding the returned node to the XML document.
*
* XML Schema (http://schemas.xmlsoap.org/soap/envelope/):
*
*   <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
*     <Body/>
*   </Envelope>
* Returns pointer to newly created <soap:Envelope> node or NULL
* if an error occurs.
*/
xmlNodePtr 
xmlSecSoap11CreateEnvelopeNs(xmlDocPtr doc, char* nsName ) {
    xmlNodePtr envNode;
    xmlNodePtr bodyNode;
    xmlNodePtr hdrNode;
    xmlNsPtr ns;
    
    
    /* create Envelope node */
    envNode = xmlNewDocNode(doc, NULL, xmlSecNodeEnvelope, NULL);
    if(envNode == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlNewDocNode",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString(xmlSecNodeEnvelope));
	return(NULL);	            
    }
    
    ns = xmlNewNs(envNode, xmlSecSoap12Ns, nsName) ;
    if(ns == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlNewNs",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    "ns=%s",
		    xmlSecErrorsSafeString(xmlSecSoap11Ns));
	xmlFreeNode(envNode);
	return(NULL);	        	
    }
    xmlSetNs(envNode, ns);
    
    /* add required Body node */    
    bodyNode = xmlSecAddChild(envNode, xmlSecNodeBody, NULL);
    if(bodyNode == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlSecAddChild",
		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString(xmlSecNodeBody));
	xmlFreeNode(envNode);
	return(NULL);	        	
    }
    xmlSetNs(bodyNode, ns);
    
     /* finally add Header node before body */
    hdrNode = xmlSecAddPrevSibling(bodyNode, xmlSecNodeHeader, NULL);
    if(hdrNode == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
                    "xmlSecAddPrevSibling",
		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
		    XMLSEC_ERRORS_NO_MESSAGE);
        return(NULL);
    }
    xmlSetNs(hdrNode, ns);

    
    return(envNode);
}

/***********************************************************************
 *
 * WS Security 1.1
 *
 **********************************************************************/
/**
* xmlSecWsCreate:
* @doc:        	the parent doc (might be NULL).
* @nsName	the prefix of namespace WS Security (wsse)
* @mustUnderstand the S11 attribute mustUnderstand = "1"
* @pS11Ns	the namespace pointer to S11 namespace
* 
* Creates a new Security node
*
* Returns pointer to newly created <wsse:Security> node or NULL
* if an error occurs.
* if  @mustUnderstand = 1 create the attribute mustUnderstand and  value =1
* the namespace of mustUnderstand attribute is SOAP ENVELOPE namespace
*/
xmlNodePtr 
xmlSecWsCreate(xmlDocPtr doc, char* nsName ,int mustUnderstand , xmlNsPtr pS11Ns ) {
    xmlNodePtr cur;
    xmlNsPtr ns;
    
    cur = xmlNewDocNode(doc, NULL, xmlSecNodeWsSecurity, NULL);
    if( cur == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlNewDocNode",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString( xmlSecNodeWsSecurity ));
	return(NULL);	            
    }
 
    ns = xmlNewNs( cur,  xmlSecWsNs, nsName) ;
    if(ns == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlNewNs",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    "ns=%s",
		    xmlSecErrorsSafeString( xmlSecWsNs));
	xmlFreeNode( cur);
	return(NULL);	        	
    }
    xmlSetNs(cur, ns);
    
    if ( mustUnderstand ==1 ){
       xmlSetNsProp (cur,  pS11Ns,"mustUnderstand","1");
    }   
    
    return(cur);    
}


/**
* xmlSecWsAddSecurityTokenReference:
* @doc:        		the parent doc (might be NULL).
* @keyInfoNode	the pointer to <dsig:KeyInfo> node.
* @uri			the value of URI attribute of <wsse:Reference /> node, may be null
* @ns			the pointer of the  WS Security namespace (wsse)
* 
* Creates a new <wsse:SecurityTokenReference><wsse:Reference /></wsse:SecurityTokenReference>   nodes
*
* Returns pointer to newly created <wsse:SecurityTokenReference> node or NULL
* if an error occurs.
*/
xmlNodePtr 
xmlSecWsAddSecurityTokenReference(xmlDocPtr doc,  xmlNodePtr  keyInfoNode , char* uri ,  xmlNsPtr ns ) {
    xmlNodePtr cur;
    xmlNodePtr referenceNode;
    
    cur = xmlSecAddChild(keyInfoNode, xmlSecNodeSecurityTokenReference, NULL);
    if( cur == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlNewDocNode",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString( xmlSecNodeSecurityTokenReference ));
	return(NULL);	            
    }    
    xmlSetNs( cur, ns);
    
    referenceNode = xmlSecAddChild(cur, xmlSecNodeReference, NULL);    
    if( referenceNode == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlNewDocNode",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString( xmlSecNodeReference  ));
	return(NULL);	            
    }
    xmlSetNs( referenceNode, ns);
    
	if(uri != NULL) 
		xmlSetProp(referenceNode, xmlSecAttrURI, uri );
   
    return(cur);	            
    
}

/**
* xmlSecWsAddBinarySecurityToken:
* @doc:        		the parent doc (might be NULL).
* @parentNode	the pointer to parent node.
* @valueType 		the enum ( value of attribute ValueType  )
* @id			the ID attribute of the node
* @ns			the pointer of the  WS Security namespace (wsse)
* 
* Create a new <wsse:BinarySecurityToken/> node
*
* Returns pointer to newly created <wsse:BinarySecurityToken> node or NULL
* if an error occurs.
*/
xmlNodePtr 
xmlSecWsAddBinarySecurityToken(xmlDocPtr doc,  xmlNodePtr  parentNode , char* id ,  xmlNsPtr ns ) {
    xmlNodePtr cur;
    xmlNodePtr referenceNode;
    xmlChar strNs ;
    
    cur = xmlSecAddChild( parentNode, xmlSecNodeBinarySecurityToken, NULL);
    if( cur == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlNewDocNode",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString( xmlSecNodeBinarySecurityToken));
	return(NULL);	            
    }    
    xmlSetNs( cur, ns);
    
   xmlSetProp(cur, xmlSecAttrEncodingType,  xmlSecWsBase64Binary );
    
    xmlSetProp(cur, xmlSecAttrValueType, xmlSecWsX509v3 );
    
   if(id != NULL) 
	xmlSetProp(cur, xmlSecAttrId, id );
		
   //if (  strNs =! NULL )        xmlFree( strNs );
	
    return(cur);	            
    
}


/**
* xmlSecWsAddUserNameToken 
* @doc:        		the parent doc (might be NULL).
* @parentNode	the pointer to parent node.
* @id			the ID attribute of the node
* @ns			the pointer of the  WS Security namespace (wsse)
* 
* Create a new <wsse:UserNameToken/> node
*
* Returns pointer to newly created <wsse:UserNameToken> node or NULL
* if an error occurs.
*/
xmlNodePtr 
xmlSecWsAddUserNameToken (xmlDocPtr doc,  xmlNodePtr  parentNode , char* id ,  xmlNsPtr ns ) {
    xmlNodePtr cur;    
    xmlChar strNs ;
    
    cur = xmlSecAddChild( parentNode, xmlSecNodeUserNameToken, NULL);
    if( cur == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlNewDocNode",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString( xmlSecNodeUserNameToken));
	return(NULL);	            
    }    
    xmlSetNs( cur, ns);
       
   if(id != NULL) 
	xmlSetProp(cur, xmlSecAttrId, id );

return(cur);	          
}

/**
* xmlSecWsAddUserName
* @doc:        		the parent doc (might be NULL).
* @parentNode	the pointer to parent node.
* @UserName	the content of the node
* @ns			the pointer of the  WS Security namespace (wsse)
* 
* Create a new <wsse:UserName/> node
*
* Returns pointer to newly created <wsse:UserName> node or NULL
* if an error occurs.
*/
xmlNodePtr 
xmlSecWsAddUserName (xmlDocPtr doc,  xmlNodePtr  parentNode , char* userName,  xmlNsPtr ns ) {
    xmlNodePtr cur;    
    xmlChar strNs ;
    
    cur = xmlSecAddChild( parentNode, xmlSecNodeUserName, NULL);
    if( cur == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlNewDocNode",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString( xmlSecNodeUserName));
	return(NULL);	            
    }    
    xmlSetNs( cur, ns);

   xmlNodeSetContent ( cur, userName );       

return(cur);	            	
    
}


/**
* xmlSecWsAddPassword
* @doc:        		the parent doc (might be NULL).
* @parentNode	the pointer to parent node.
* @password		the content of the node
* @type			the value of the Type attribute 
* @ns			the pointer of the  WS Security namespace (wsse)
* 
* Create a new <wsse:Passwoord/> node
*
* Returns pointer to newly created <wsse:UserName> node or NULL
* if an error occurs.
*/
xmlNodePtr 
xmlSecWsAddPassword (xmlDocPtr doc,  xmlNodePtr  parentNode , char* password	,  char* type,  xmlNsPtr ns ) {
    xmlNodePtr cur;    
    xmlChar strNs ;
    
    cur = xmlSecAddChild( parentNode, xmlSecNodePassword, NULL);
    if( cur == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlNewDocNode",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    "node=%s",
		    xmlSecErrorsSafeString( xmlSecNodePassword));
	return(NULL);	            
    }    
    xmlSetNs( cur, ns);

   xmlNodeSetContent ( cur, password );       
   if ( type != NULL){
		if (  xmlStrcmp (( xmlChar*)  type, xmlSecWsPasswordDigest) ==0  )
				xmlSetProp(cur, xmlSecAttrType, xmlSecWsPasswordDigest);
		else if (  xmlStrcmp (( xmlChar*)  type, xmlSecWsPasswordText)  ==0 )
				xmlSetProp(cur, xmlSecAttrType, xmlSecWsPasswordText);
		else {
			xmlSecError(XMLSEC_ERRORS_HERE,
				NULL,
				"xmlAddAttribute",
				XMLSEC_ERRORS_R_XML_FAILED,
				"node=%s attribute value=%s",
				xmlSecErrorsSafeString( xmlSecNodePassword),
				xmlSecErrorsSafeString( type));
		return(NULL);	            
		}
	}
	else 
		xmlSetProp(cur, xmlSecAttrType, xmlSecWsPasswordText);
return(cur);	            	
    
}



More information about the xmlsec mailing list