Hi all, Rob>Also if you make sure that your template code is good, you should Rob>probably submit the patches to him as well (that code really doesnt Rob>belong in the PHP extension but rather within the xmlsec lib itself).
I and Rob Richardson make patch for template.c. The new php_xmlsec extention (beta-version) use the new version of template.c. Thanks. Alexandre
Index: include/xmlsec/soap.h =================================================================== --- include/xmlsec/soap.h (revision 974) +++ include/xmlsec/soap.h (working copy) @@ -27,6 +27,8 @@ * **********************************************************************/ XMLSEC_EXPORT xmlNodePtr xmlSecSoap11CreateEnvelope (xmlDocPtr doc); +XMLSEC_EXPORT xmlNodePtr xmlSecSoap11CreateEnvelopeNsPref (xmlDocPtr doc, + const xmlChar* nsName); XMLSEC_EXPORT xmlNodePtr xmlSecSoap11EnsureHeader (xmlNodePtr envNode); XMLSEC_EXPORT xmlNodePtr xmlSecSoap11AddBodyEntry (xmlNodePtr envNode, xmlNodePtr entryNode); Index: include/xmlsec/templates.h =================================================================== --- include/xmlsec/templates.h (revision 974) +++ include/xmlsec/templates.h (working copy) @@ -41,6 +41,12 @@ const xmlChar *id, const xmlChar *uri, const xmlChar *type); +XMLSEC_EXPORT xmlNodePtr xmlSecTmplSignatureAddReferenceNs (xmlNodePtr signNode, + xmlSecTransformId digestMethodId, + const xmlChar *id, + const xmlChar *uri, + const xmlChar *type, + xmlNsPtr ns); XMLSEC_EXPORT xmlNodePtr xmlSecTmplSignatureAddObject (xmlNodePtr signNode, const xmlChar *id, const xmlChar *mimeType, @@ -50,6 +56,9 @@ XMLSEC_EXPORT xmlNodePtr xmlSecTmplReferenceAddTransform (xmlNodePtr referenceNode, xmlSecTransformId transformId); +XMLSEC_EXPORT xmlNodePtr xmlSecTmplReferenceAddTransformNs (xmlNodePtr referenceNode, + xmlSecTransformId transformId, + xmlNsPtr ns); XMLSEC_EXPORT xmlNodePtr xmlSecTmplObjectAddSignProperties (xmlNodePtr objectNode, const xmlChar *id, const xmlChar *target); @@ -72,6 +81,13 @@ const xmlChar *type, const xmlChar *mimeType, const xmlChar *encoding); +XMLSEC_EXPORT xmlNodePtr xmlSecTmplEncDataCreateNsPref (xmlDocPtr doc, + xmlSecTransformId encMethodId, + const xmlChar *id, + const xmlChar *type, + const xmlChar *mimeType, + const xmlChar *encoding, + const xmlChar *nsPrefix); XMLSEC_EXPORT xmlNodePtr xmlSecTmplEncDataEnsureKeyInfo (xmlNodePtr encNode, const xmlChar *id); XMLSEC_EXPORT xmlNodePtr xmlSecTmplEncDataEnsureEncProperties (xmlNodePtr encNode, @@ -115,6 +131,12 @@ const xmlChar *id, const xmlChar *type, const xmlChar *recipient); +XMLSEC_EXPORT xmlNodePtr xmlSecTmplKeyInfoAddEncryptedKeyNs (xmlNodePtr keyInfoNode, + xmlSecTransformId encMethodId, + const xmlChar *id, + const xmlChar *type, + const xmlChar *recipient, + xmlNsPtr ns); /*********************************************************************** * Index: src/soap.c =================================================================== --- src/soap.c (revision 974) +++ src/soap.c (working copy) @@ -52,6 +52,35 @@ */ xmlNodePtr xmlSecSoap11CreateEnvelope(xmlDocPtr doc) { + return xmlSecSoap11CreateEnvelopeNsPref(doc, NULL); +} + +/** + * xmlSecSoap11CreateEnvelopeNsPref: + * @doc: the parent doc (might be NULL). + * @nsPrefix: the namespace prefix for the soap envelope (e.g. "soap"), or NULL + * + * 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/): + * + * <xs:element name="Envelope" type="tns:Envelope"/> + * <xs:complexType name="Envelope"> + * <xs:sequence> + * <xs:element ref="tns:Header" minOccurs="0"/> + * <xs:element ref="tns:Body" minOccurs="1"/> + * <xs:any namespace="##other" minOccurs="0" + * maxOccurs="unbounded" processContents="lax"/> + * </xs:sequence> + * <xs:anyAttribute namespace="##other" processContents="lax"/> + * </xs:complexType> + * + * Returns pointer to newly created <soap:Envelope> node or NULL + * if an error occurs. + */ +xmlNodePtr +xmlSecSoap11CreateEnvelopeNsPref(xmlDocPtr doc, const xmlChar* nsName) { xmlNodePtr envNode; xmlNodePtr bodyNode; xmlNsPtr ns; @@ -67,8 +96,7 @@ xmlSecErrorsSafeString(xmlSecNodeEnvelope)); return(NULL); } - - ns = xmlNewNs(envNode, xmlSecSoap11Ns, NULL) ; + ns = xmlNewNs(envNode, xmlSecSoap11Ns, nsName); if(ns == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, Index: src/templates.c =================================================================== --- src/templates.c (revision 974) +++ src/templates.c (working copy) @@ -29,8 +29,16 @@ const xmlChar *id, const xmlChar *uri, const xmlChar *type); +static xmlNodePtr xmlSecTmplAddReferenceNs (xmlNodePtr parentNode, + xmlSecTransformId digestMethodId, + const xmlChar *id, + const xmlChar *uri, + const xmlChar *type, + xmlNsPtr ns); static int xmlSecTmplPrepareEncData (xmlNodePtr parentNode, xmlSecTransformId encMethodId); +static int xmlSecTmplPrepareEncDataNs (xmlNodePtr parentNode, + xmlSecTransformId encMethodId, xmlNsPtr ns); static int xmlSecTmplNodeWriteNsList (xmlNodePtr parentNode, const xmlChar** namespaces); /************************************************************************** @@ -272,6 +280,29 @@ xmlNodePtr xmlSecTmplSignatureAddReference(xmlNodePtr signNode, xmlSecTransformId digestMethodId, const xmlChar *id, const xmlChar *uri, const xmlChar *type) { + return xmlSecTmplSignatureAddReferenceNs(signNode, digestMethodId, + id, uri, type, NULL); +} + +/** + * xmlSecTmplSignatureAddReferenceNs: + * @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 signature namespace (may be NULL). + * + * 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); @@ -288,21 +319,32 @@ return(NULL); } - return(xmlSecTmplAddReference(signedInfoNode, digestMethodId, id, uri, type)); + return(xmlSecTmplAddReferenceNs(signedInfoNode, digestMethodId, id, uri, type, ns)); } static xmlNodePtr xmlSecTmplAddReference(xmlNodePtr parentNode, xmlSecTransformId digestMethodId, - const xmlChar *id, const xmlChar *uri, const xmlChar *type) { + const xmlChar *id, const xmlChar *uri, const xmlChar *type) { + return xmlSecTmplAddReferenceNs(parentNode, digestMethodId, + id, uri, type, NULL); +} + +static xmlNodePtr +xmlSecTmplAddReferenceNs(xmlNodePtr parentNode, xmlSecTransformId digestMethodId, + const xmlChar *id, const xmlChar *uri, const xmlChar *type, xmlNsPtr ns) { xmlNodePtr res; xmlNodePtr cur; - + const xmlChar *nsuri = NULL; + xmlSecAssert2(parentNode != NULL, NULL); xmlSecAssert2(digestMethodId != NULL, NULL); xmlSecAssert2(digestMethodId->href != NULL, NULL); /* add Reference node */ - res = xmlSecAddChild(parentNode, xmlSecNodeReference, xmlSecDSigNs); + if (ns == NULL) { + nsuri = xmlSecDSigNs; + } + res = xmlSecAddChild(parentNode, xmlSecNodeReference, nsuri); if(res == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, @@ -312,6 +354,9 @@ xmlSecErrorsSafeString(xmlSecNodeReference)); return(NULL); } + if (ns != NULL) { + xmlSetNs(res,ns); + } /* set Reference node attributes */ if(id != NULL) { @@ -325,7 +370,7 @@ } /* add DigestMethod node and set algorithm */ - cur = xmlSecAddChild(res, xmlSecNodeDigestMethod, xmlSecDSigNs); + cur = xmlSecAddChild(res, xmlSecNodeDigestMethod, nsuri); if(cur == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, @@ -337,6 +382,10 @@ xmlFreeNode(res); return(NULL); } + if (ns != NULL) { + xmlSetNs(cur,ns); + } + if(xmlSetProp(cur, xmlSecAttrAlgorithm, digestMethodId->href) == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, @@ -351,7 +400,7 @@ } /* add DigestValue node */ - cur = xmlSecAddChild(res, xmlSecNodeDigestValue, xmlSecDSigNs); + cur = xmlSecAddChild(res, xmlSecNodeDigestValue, nsuri); if(cur == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, @@ -363,7 +412,10 @@ xmlFreeNode(res); return(NULL); } - + if (ns != NULL) { + xmlSetNs(cur,ns); + } + return(res); } @@ -472,6 +524,22 @@ */ xmlNodePtr xmlSecTmplReferenceAddTransform(xmlNodePtr referenceNode, xmlSecTransformId transformId) { + return xmlSecTmplReferenceAddTransformNs(referenceNode, transformId, NULL); +} + +/** + * xmlSecTmplReferenceAddTransformNs: + * @referenceNode: the pointer to <dsig:Reference/> node. + * @transformId: the transform method id. + * @ns: the pointer to the dsig namespace (may be NULL). + * + * 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; @@ -482,47 +550,55 @@ /* 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, xmlSecDSigNs); + xmlNodePtr tmp = xmlSecGetNextElementNode(referenceNode->children); + if(tmp == NULL) { + transformsNode = xmlSecAddChild(referenceNode, xmlSecNodeTransforms, xmlSecDSigNs); + } else { + transformsNode = xmlSecAddPrevSibling(tmp, xmlSecNodeTransforms, xmlSecDSigNs); + } + if(transformsNode == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecAddChild or xmlSecAddPrevSibling", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeTransforms)); + return(NULL); + } + if (ns != NULL) { + xmlSetNs(transformsNode,ns); + } + } + + if (ns == NULL) { + res = xmlSecAddChild(transformsNode, xmlSecNodeTransform, xmlSecDSigNs); } else { - transformsNode = xmlSecAddPrevSibling(tmp, xmlSecNodeTransforms, xmlSecDSigNs); - } - if(transformsNode == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecAddChild or xmlSecAddPrevSibling", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "node=%s", - xmlSecErrorsSafeString(xmlSecNodeTransforms)); - return(NULL); + res = xmlSecAddChild(transformsNode, xmlSecNodeTransform, NULL); } - } - - res = xmlSecAddChild(transformsNode, xmlSecNodeTransform, xmlSecDSigNs); if(res == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecAddChild", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "node=%s", - xmlSecErrorsSafeString(xmlSecNodeTransform)); - return(NULL); + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecAddChild", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeTransform)); + return(NULL); } + if (ns != 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); + 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); @@ -642,6 +718,31 @@ xmlSecTmplEncDataCreate(xmlDocPtr doc, xmlSecTransformId encMethodId, const xmlChar *id, const xmlChar *type, const xmlChar *mimeType, const xmlChar *encoding) { + return xmlSecTmplEncDataCreateNsPref(doc, encMethodId, id, type, + mimeType, encoding, NULL); +} + +/** + * xmlSecTmplEncDataCreateNsPref: + * @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) + * @nsPrefix: the namespace prefix for the signature element (e.g. "enc"), or NULL + * + * Creates new <enc:EncryptedData /> node for encryption template. + * + * Returns the pointer newly created <enc:EncryptedData/> node or NULL + * if an error occurs. + */ +xmlNodePtr +xmlSecTmplEncDataCreateNsPref(xmlDocPtr doc, xmlSecTransformId encMethodId, + const xmlChar *id, const xmlChar *type, + const xmlChar *mimeType, const xmlChar *encoding, const xmlChar *nsPrefix) { xmlNodePtr encNode; xmlNsPtr ns; @@ -655,16 +756,20 @@ xmlSecErrorsSafeString(xmlSecNodeEncryptedData)); return(NULL); } - - ns = xmlNewNs(encNode, xmlSecEncNs, NULL); + + if (nsPrefix == NULL) + ns = xmlNewNs(encNode, xmlSecEncNs, NULL); + else + ns = xmlNewNs(encNode, xmlSecEncNs, nsPrefix); + if(ns == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlNewNs", - XMLSEC_ERRORS_R_XML_FAILED, - "ns=%s", - xmlSecErrorsSafeString(xmlSecEncNs)); - return(NULL); + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlNewNs", + XMLSEC_ERRORS_R_XML_FAILED, + "ns=%s", + xmlSecErrorsSafeString(xmlSecEncNs)); + return(NULL); } xmlSetNs(encNode, ns); @@ -688,52 +793,69 @@ return(encNode); } -static int -xmlSecTmplPrepareEncData(xmlNodePtr parentNode, xmlSecTransformId encMethodId) { +static int +xmlSecTmplPrepareEncDataNs(xmlNodePtr parentNode, xmlSecTransformId encMethodId, xmlNsPtr ns) { xmlNodePtr cur; - + const xmlChar *nsuri=NULL; + xmlSecAssert2(parentNode != NULL, -1); xmlSecAssert2((encMethodId == NULL) || (encMethodId->href != NULL), -1); - + + if (ns == NULL) { + nsuri = xmlSecEncNs; + } + /* add EncryptionMethod node if requested */ if(encMethodId != NULL) { - cur = xmlSecAddChild(parentNode, xmlSecNodeEncryptionMethod, xmlSecEncNs); - if(cur == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecAddChild", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "node=%s", - xmlSecErrorsSafeString(xmlSecNodeEncryptionMethod)); - return(-1); - } - 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); - } + cur = xmlSecAddChild(parentNode, xmlSecNodeEncryptionMethod, nsuri); + if(cur == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecAddChild", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeEncryptionMethod)); + return(-1); + } + if (ns != NULL) { + 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, xmlSecEncNs); + cur = xmlSecAddChild(parentNode, xmlSecNodeCipherData, nsuri); + if(cur == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecAddChild", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "node=%s", - xmlSecErrorsSafeString(xmlSecNodeCipherData)); - return(-1); + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecAddChild", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "node=%s", + xmlSecErrorsSafeString(xmlSecNodeCipherData)); + return(-1); } - + if (ns != NULL) { + xmlSetNs(cur, ns); + } + return(0); } +static int +xmlSecTmplPrepareEncData(xmlNodePtr parentNode, xmlSecTransformId encMethodId) { + return xmlSecTmplPrepareEncDataNs(parentNode, encMethodId, NULL); +} /** * xmlSecTmplEncDataEnsureKeyInfo: @@ -1401,12 +1523,38 @@ xmlNodePtr xmlSecTmplKeyInfoAddEncryptedKey(xmlNodePtr keyInfoNode, xmlSecTransformId encMethodId, const xmlChar* id, const xmlChar* type, const xmlChar* recipient) { + return xmlSecTmplKeyInfoAddEncryptedKeyNs(keyInfoNode, encMethodId, + id, type, recipient, NULL); +} + +/** + * xmlSecTmplKeyInfoAddEncryptedKeyNs: + * @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 specific enc namespace (optional). + * + * 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) { xmlNodePtr encKeyNode; xmlSecAssert2(keyInfoNode != NULL, NULL); /* we allow multiple encrypted key elements */ - encKeyNode = xmlSecAddChild(keyInfoNode, xmlSecNodeEncryptedKey, xmlSecEncNs); + if (ns != NULL) { + encKeyNode = xmlSecAddChild(keyInfoNode, xmlSecNodeEncryptedKey, xmlSecEncNs); + } else { + encKeyNode = xmlSecAddChild(keyInfoNode, xmlSecNodeEncryptedKey, NULL); + } if(encKeyNode == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, @@ -1416,6 +1564,9 @@ xmlSecErrorsSafeString(xmlSecNodeEncryptedKey)); return(NULL); } + if (ns != NULL) { + xmlSetNs(encKeyNode,ns); + } if(id != NULL) { xmlSetProp(encKeyNode, xmlSecAttrId, id);
_______________________________________________ xmlsec mailing list xmlsec@aleksey.com http://www.aleksey.com/mailman/listinfo/xmlsec