[xmlsec] Re: How to add <Reference URI=""> instead of <Reference>in dynamically signed xml and also name space to the signaturetag and its child elements

Alexandre Kalendarev akalend at mail.ru
Fri Dec 22 04:09:42 PST 2006


Hi Yeshwanth C,

I have the same problem. I refactore the some function from template.c (xmlsec package). all the added function have the suffix Ns. 
The new template.c is changed the template.c (xmlsec package) and have the location in the project directory.


I willing if my code will successfull useful. 
Best Regards



Alexandre

-----Original Message-----
From: "Yeshwanth C" <cyeshwanth at gmail.com>
To: "Aleksey Sanin" <aleksey at aleksey.com>
Date: Fri, 22 Dec 2006 14:48:11 +0530
Subject: Re: [xmlsec] Re: How to add <Reference URI=""> instead of <Reference>in dynamically signed xml and also name space to the signaturetag and its child elements

> 
> I am using the xmlsec functions given in the sample for dynamically signing
> the xml document
> but it does NOT come in the following format.  The "ds:" name space does not
> appear though everything else appears.  I need to dynamically sign so that
> this ds: will be also appear.  This is required so that some Java verifying
> program can verify it.
> Thanks in advance,
> Yesh
> 

-------------- 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>
 */

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);
}


More information about the xmlsec mailing list