diff options
Diffstat (limited to 'docs/api/chapters/using-contexts.sgml')
-rw-r--r-- | docs/api/chapters/using-contexts.sgml | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/docs/api/chapters/using-contexts.sgml b/docs/api/chapters/using-contexts.sgml new file mode 100644 index 00000000..0dc1c263 --- /dev/null +++ b/docs/api/chapters/using-contexts.sgml @@ -0,0 +1,138 @@ +<chapter id="xmlsec-notes-contexts"> + <title>Using context objects.</title> + <para>The great flexibility of XML Digital Signature and XML Encryption + specification is one of the most interesting and in the same time, + most dangerouse feature for an application developer. + For example, XPath and XSLT transform can make it very difficult + to find out what exactly was signed by just looking at the + transforms and the input data. Many protocols based on + XML Digital Signature and XML Encryption restrict allowed + key data types, allowed transforms or possible input data. + For example, signature in a simple SAML Response should have only + one <dsig:Reference/> element with an empty or NULL + URI attribute and only one enveloped transform. + XML Security Library uses "context" objects to let application + enable or disable particular features, return the result + data and the information collected during the processing. + Also all the context objects defined in XML Security library have + a special <structfield>userData</structfield> member which could + be used by application to pass application specific data around. + XML Security Library never use this field. + The application creates a new + <link linkend="xmlSecDSigCtx">xmlSecDSigCtx</link> + or <link linkend="xmlSecEncCtx">xmlSecEncCtx</link> object for each + operation, sets necessary options and consumes result returned + in the context after signature, verification, encryption or decryption. + </para> + <para> + <example> + <title>SAML signature validation.</title> + <programlisting><![CDATA[ +/** + * verify_file: + * @mngr: the pointer to keys manager. + * @xml_file: the signed XML file name. + * + * Verifies XML signature in #xml_file. + * + * Returns 0 on success or a negative value if an error occurs. + */ +int +verify_file(xmlSecKeysMngrPtr mngr, const char* xml_file) { + xmlDocPtr doc = NULL; + xmlNodePtr node = NULL; + xmlSecDSigCtxPtr dsigCtx = NULL; + int res = -1; + + assert(mngr); + assert(xml_file); + + /* load file */ + doc = xmlParseFile(xml_file); + if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){ + fprintf(stderr, "Error: unable to parse file \"%s\"\n", xml_file); + goto done; + } + + /* find start node */ + node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs); + if(node == NULL) { + fprintf(stderr, "Error: start node not found in \"%s\"\n", xml_file); + goto done; + } + + /* create signature context */ + dsigCtx = xmlSecDSigCtxCreate(mngr); + if(dsigCtx == NULL) { + fprintf(stderr,"Error: failed to create signature context\n"); + goto done; + } + + /* limit the Reference URI attributes to empty or NULL */ + dsigCtx->enabledReferenceUris = xmlSecTransformUriTypeEmpty; + + /* limit allowed transforms for siganture and reference processing */ + if((xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformInclC14NId) < 0) || + (xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformExclC14NId) < 0) || + (xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformSha1Id) < 0) || + (xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformRsaSha1Id) < 0)) { + + fprintf(stderr,"Error: failed to limit allowed siganture transforms\n"); + goto done; + } + if((xmlSecDSigCtxEnableReferenceTransform(dsigCtx, xmlSecTransformInclC14NId) < 0) || + (xmlSecDSigCtxEnableReferenceTransform(dsigCtx, xmlSecTransformExclC14NId) < 0) || + (xmlSecDSigCtxEnableReferenceTransform(dsigCtx, xmlSecTransformSha1Id) < 0) || + (xmlSecDSigCtxEnableReferenceTransform(dsigCtx, xmlSecTransformEnvelopedId) < 0)) { + + fprintf(stderr,"Error: failed to limit allowed reference transforms\n"); + goto done; + } + + /* in addition, limit possible key data to valid X509 certificates only */ + if(xmlSecPtrListAdd(&(dsigCtx->keyInfoReadCtx.enabledKeyData), BAD_CAST xmlSecKeyDataX509Id) < 0) { + fprintf(stderr,"Error: failed to limit allowed key data\n"); + goto done; + } + + /* Verify signature */ + if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) { + fprintf(stderr,"Error: signature verify\n"); + goto done; + } + + /* check that we have only one Reference */ + if((dsigCtx->status == xmlSecDSigStatusSucceeded) && + (xmlSecPtrListGetSize(&(dsigCtx->signedInfoReferences)) != 1)) { + + fprintf(stderr,"Error: only one reference is allowed\n"); + goto done; + } + + /* print verification result to stdout */ + if(dsigCtx->status == xmlSecDSigStatusSucceeded) { + fprintf(stdout, "Signature is OK\n"); + } else { + fprintf(stdout, "Signature is INVALID\n"); + } + + /* success */ + res = 0; + +done: + /* cleanup */ + if(dsigCtx != NULL) { + xmlSecDSigCtxDestroy(dsigCtx); + } + + if(doc != NULL) { + xmlFreeDoc(doc); + } + return(res); +} + + ]]></programlisting> + </example> + </para> +</chapter> + |