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.
/** * 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 <[EMAIL PROTECTED]> * (C) 2006 Alexandre Kalendarev <[EMAIL PROTECTED]> */ /************************************************************************* * * 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); }
_______________________________________________ xmlsec mailing list xmlsec@aleksey.com http://www.aleksey.com/mailman/listinfo/xmlsec