[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