summaryrefslogtreecommitdiff
path: root/docs/api/chapters/new-crypto.sgml
diff options
context:
space:
mode:
Diffstat (limited to 'docs/api/chapters/new-crypto.sgml')
-rw-r--r--docs/api/chapters/new-crypto.sgml487
1 files changed, 487 insertions, 0 deletions
diff --git a/docs/api/chapters/new-crypto.sgml b/docs/api/chapters/new-crypto.sgml
new file mode 100644
index 00000000..52191417
--- /dev/null
+++ b/docs/api/chapters/new-crypto.sgml
@@ -0,0 +1,487 @@
+<chapter id="xmlsec-notes-new-crypto">
+ <title>Adding support for new cryptographic library.</title>
+ <sect1 id="xmlsec-notes-new-crypto-overview">
+ <title>Overview.</title>
+ <para>XML Security Library can support practicaly any cryptographic
+ library. Currently, it has "out-of-the-box" support for OpenSSL,
+ MSCrypto, NSS, GnuTLS and GCrypt. If your favorite library is not supported yet then
+ you can write necessary code yourself. If you and your company
+ (university, ...) are willing to share the results of your work I would
+ be happy to add support for new libraries to the main XML Security
+ Library distribution.</para>
+ <para>
+ The XML Security Library
+ <link linkend="xmlsec-notes-structure">separates</link>
+ the cryptographic library (engine)
+ specific code in an "xmlsec-&lt;crypto&gt;" library (where "&lt;crypto&gt;" is
+ "openssl", "mscrypt", "gnutls", "gcrypt", "nss", etc.) which includes following items:
+ <itemizedlist>
+ <listitem><para>
+ xmlSecCryptoApp* functions.
+ </para></listitem>
+ <listitem><para>
+ Cryptographic transforms and keys data implementation.
+ </para></listitem>
+ <listitem><para>
+ Keys store support (X509, PGP, etc.).
+ </para></listitem>
+ </itemizedlist>
+ In this chapter, we will discuss
+ a task of creating "xmlsec-mycrypto" library that provides support
+ for your favorite "MyCrypto" cryptographic library.
+ </para>
+ </sect1>
+ <sect1 id="xmlsec-notes-new-crypto-skeleton">
+ <title>Creating a framework from the skeleton.</title>
+ <para>
+ The XML Security Library contains a "skeleton" for creating new
+ "xmlsec-&lt;crypto&gt;" libraries. In order to create "xmlsec-mycrypto"
+ library framework, do the following (this example assumes that you
+ are using *nix system, adjust the commands if you are using something else):
+ <itemizedlist>
+ <listitem><para>
+ Copy src/skeleton and include/xmlsec/skeleton folders to src/mycrypto and
+ include/xmlsec/mycrypto folders and remove CVS folders from the result:
+ <example>
+ <title>Coping skeleton folders.</title>
+ <programlisting><![CDATA[
+cd src
+cp -r skeleton mycrypto
+cd mycrypto
+rm -rf CVS
+cd ../..
+cd include/xmlsec
+cp -r skeleton mycrypto
+cd mycrypto
+rm -rf CVS
+cd ../../..
+ ]]></programlisting>
+ </example>
+ </para></listitem>
+ <listitem><para>
+ Replace "skeleton" with "mycrypto" in the copied files (note that there
+ are different possible cases here):
+ <example>
+ <title>Replacing "skeleton" with "mycrypto".</title>
+ <programlisting><![CDATA[
+for i in `ls include/xmlsec/mycrypto/* src/mycrypto/*`; do
+ echo Processing $i ..;
+ sed 's/skeleton/mycrypto/g' $i | \
+ sed 's/SKELETON/MYCRYPTO/g' | \
+ sed 's/Skeleton/MyCrypto/g' > $i.tmp;
+ mv $i.tmp $i;
+done
+ ]]></programlisting>
+ </example>
+ </para></listitem>
+ <listitem><para>
+ Add "xmlsec-mycrypto" library to the "include/xmlsec/crypto.h" file:
+ <example>
+ <title>Modifying include/xmlsec/crypto.h file.</title>
+ <programlisting><![CDATA[
+...
+#ifdef XMLSEC_CRYPTO_MYCRYPTO
+#include <xmlsec/mycrypto/app.h>
+#include <xmlsec/mycrypto/crypto.h>
+#include <xmlsec/mycrypto/symbols.h>
+#else /* XMLSEC_CRYPTO_MYCRYPTO */
+...
+#endif /* XMLSEC_CRYPTO_MYCRYPTO */
+...
+ ]]></programlisting>
+ </example>
+ </para></listitem>
+ <listitem><para>
+ Add "xmlsec-crypto" library to the configure.in file (for *nix systems;
+ for Windows you need to modify win32/confgure.js and win32/Makefile.msvc
+ files, see win32/README.txt for details):
+ <example>
+ <title>Modifying configure.in file.</title>
+ <programlisting><![CDATA[
+dnl ==========================================================================
+dnl See if we can find MyCrypto
+dnl ==========================================================================
+XMLSEC_MYCRYPTO_DEFINES=""
+MYCRYPTO_CONFIG="mycrypto-config" # TODO
+XMLSEC_NO_MYCRYPTO="1"
+MYCRYPTO_MIN_VERSION="0.0.0" # TODO
+MYCRYPTO_VERSION=""
+MYCRYPTO_PREFIX=""
+MYCRYPTO_CFLAGS=""
+MYCRYPTO_LIBS=""
+MYCRYPTO_LDADDS=""
+AC_MSG_CHECKING(for mycrypto libraries >= $MYCRYPTO_MIN_VERSION)
+AC_ARG_WITH(mycrypto, [ --with-mycrypto=[PFX] mycrypto location])
+if test "$with_mycrypto" = "no" ; then
+ XMLSEC_CRYPTO_DISABLED_LIST="$XMLSEC_CRYPTO_DISABLED_LIST mycrypto"
+ AC_MSG_RESULT(no)
+else
+ if test "$with_mycrypto" != "" ; then
+ MYCRYPTO_PREFIX=$with_mycrypto
+ MYCRYPTO_CONFIG=$MYCRYPTO_PREFIX/bin/$MYCRYPTO_CONFIG
+ fi
+ if ! $MYCRYPTO_CONFIG --version > /dev/null 2>&1 ; then
+ if test "$with_mycrypto" != "" ; then
+ AC_MSG_ERROR(Unable to find mycrypto at '$with_mycrypto')
+ fi
+ else
+ vers=`$MYCRYPTO_CONFIG --version | awk -F. '{ printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'`
+ minvers=`echo $MYCRYPTO_MIN_VERSION | awk -F. '{ printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'`
+ if test "$vers" -ge "$minvers" ; then
+ MYCRYPTO_LIBS="`$MYCRYPTO_CONFIG --libs`"
+ MYCRYPTO_CFLAGS="`$MYCRYPTO_CONFIG --cflags`"
+ MYCRYPTO_VERSION="`$MYCRYPTO_CONFIG --version`"
+ XMLSEC_NO_MYCRYPTO="0"
+ else
+ AC_MSG_ERROR(You need at least mycrypto $MYCRYPTO_MIN_VERSION for this version of $PACKAGE)
+ fi
+ fi
+
+ dnl update crypt libraries list
+ if test "z$XMLSEC_NO_MYCRYPTO" = "z0" ; then
+ dnl first crypto library is default one
+ if test "z$XMLSEC_CRYPTO" = "z" ; then
+ XMLSEC_CRYPTO="mycrypto"
+ XMLSEC_CRYPTO_LIB="xmlsec1-mycrypto"
+ XMLSEC_CRYPTO_CFLAGS="$MYCRYPTO_CFLAGS -DXMLSEC_CRYPTO_MYCRYPTO=1"
+ XMLSEC_CRYPTO_LIBS="$MYCRYPTO_LIBS"
+ XMLSEC_CRYPTO_LDADDS="$MYCRYPTO_LDADDS"
+ fi
+ XMLSEC_CRYPTO_LIST="$XMLSEC_CRYPTO_LIST mycrypto"
+ AC_MSG_RESULT(yes ('$MYCRYPTO_VERSION'))
+ else
+ XMLSEC_CRYPTO_DISABLED_LIST="$XMLSEC_CRYPTO_DISABLED_LIST mycrypto"
+ AC_MSG_RESULT(no)
+ fi
+fi
+AC_SUBST(XMLSEC_NO_MYCRYPTO)
+AC_SUBST(MYCRYPTO_MIN_VERSION)
+AC_SUBST(MYCRYPTO_VERSION)
+AC_SUBST(MYCRYPTO_CONFIG)
+AC_SUBST(MYCRYPTO_PREFIX)
+AC_SUBST(MYCRYPTO_CFLAGS)
+AC_SUBST(MYCRYPTO_LIBS)
+AC_SUBST(MYCRYPTO_LDADDS)
+AC_SUBST(XMLSEC_MYCRYPTO_DEFINES)
+
+...
+AC_OUTPUT([
+...
+include/xmlsec/mycrypto/Makefile
+src/mycrypto/Makefile
+...
+])
+ ]]></programlisting>
+ </example>
+ </para></listitem>
+ <listitem><para>Modify "xmlsec.spec.in" file to create "xmlsec-mycrypto"
+ RPM (if necessary).
+ </para></listitem>
+ </itemizedlist>
+
+ By now you should be able to sucessfuly compile XML Security Library
+ with MyCrypto library (we disable all other libraries to make sure
+ that xmlsec command line utility is linked against xmlsec-mycrypto
+ library):
+ <example>
+ <title>Compiling the results.</title>
+ <programlisting><![CDATA[
+./autogen.sh --without-openssl --without-nss --without-gnutls --without-gcrypt \
+ --with-mycrypto=$HOME --disable-tmpl-tests
+make
+ ]]></programlisting>
+ </example>
+ </para>
+ </sect1>
+ <sect1 id="xmlsec-notes-new-crypto-functions">
+ <title>xmlSecCryptoApp* functions.</title>
+ <para>
+ The XML Security Library allows application to load multiple
+ "xmlsec-&lt;crypto&gt; libraries. To prevent symbol conflicts,
+ all "xmlsec-mycrypto" library names MUST start with "xmlSecMyCrypto".
+ However, in some applications (for example, the xmlsec command line
+ utility) that can use any crypto library, would prefer to
+ use a generic function names where possible.
+ The "include/xmlsec/crypto.h" and "include/xmlsec/mycrypto/symbols.h"
+ include files do the magic by mapping "xmlSecMyCrypto*" to
+ "xmlSecCrypto*" names using "XMLSEC_CRYPTO_*" defines.
+ </para>
+ <para>
+ In order to build xmlsec command line utility, the
+ "xmlsec-&lt;crypto&gt;" library must implement several functions.
+ The stubs for all these functions are provided in the "skeleton"
+ we've created. While these functions are not required to be
+ implemented by "xmlsec-&lt;crypto&gt;" library, you should consider
+ doing so (if possible) to simplify testing (thru xmlsec command line
+ utility) and application development.
+ </para>
+ <para>
+ In adition to xmlSecCryptoApp* functions, the xmlsec-&lt;crypto&gt;
+ library MUST implement following xmlSecCrypto* functions:
+ <table>
+ <title>xmlSecCrypto* functions.</title>
+ <tgroup cols="2"><tbody>
+ <row><entry>xmlSecCryptoInit()</entry>
+ <entry>Initializes xmlsec-&lt;crypto&gt; library: registers cryptographic
+ transforms implemented by the library, keys, etc.
+ Please note, that the application might want to intialize
+ the cryprographic library by itself. The default cryprographic
+ library initialization (for example, used by xmlsec utility)
+ is implemented in xmlSecCryptoAppInit() function.
+ </entry></row>
+ <row><entry>xmlSecCryptoShutdown()</entry>
+ <entry>Shuts down xmlsec-&lt;crypto&gt; library.
+ Please note, that the application might want to shutdown
+ the cryprographic library by itself. The default cryprographic
+ library shutdown (for example, used by xmlsec utility)
+ is implemented in xmlSecCryptoAppShutdown() function.
+ </entry></row>
+ <row><entry>xmlSecCryptoKeysMngrInit()</entry>
+ <entry>Adds keys stores implemented by the xmlsec-&lt;crypto&gt; library
+ to the keys manager object.
+ </entry></row>
+ </tbody></tgroup></table>
+ </para>
+ </sect1>
+ <sect1 id="xmlsec-notes-new-crypto-klasses">
+ <title>Klasses and objects.</title>
+ <para>The XML Security Library is written in C but it uses some OOP techniques:
+ the objects in the library have "klasses" and there is "klasses" inheritance.
+ (see <link linkend="xmlsec-signature-klasses">signature</link> and
+ <link linkend="xmlsec-encryption-klasses">encryption</link> klasses
+ diagrams). The "klass" is different from C++ "class" (btw, this is
+ one of the reasons why it is spelled differently). The idea of "klasses"
+ used in XML Security Library are close to one in the GLIB/GTK/GNOME
+ and many other C projects. If you ever seen an OOP code written in C
+ you should find everything familiar.
+ </para>
+ <para>XML Security Library "klass" includes three main parts:
+ <itemizedlist>
+ <listitem><para>"Klass" declaration structure that defines "klass" interfaces
+ and global constant data (for example, the human-readable name of
+ the "klass").
+ <example>
+ <title>Base transform "klass" and its child XPath transform "klass" structure.</title>
+ <programlisting><![CDATA[
+struct _xmlSecTransformKlass {
+ /* data */
+ size_t klassSize;
+ size_t objSize;
+ const xmlChar* name;
+ const xmlChar* href;
+ xmlSecTransformUsage usage;
+
+ /* methods */
+ xmlSecTransformInitializeMethod initialize;
+ xmlSecTransformFinalizeMethod finalize;
+
+ xmlSecTransformNodeReadMethod readNode;
+ xmlSecTransformNodeWriteMethod writeNode;
+
+ ...
+};
+
+...
+
+static xmlSecTransformKlass xmlSecTransformXPathKlass = {
+ /* klass/object sizes */
+ sizeof(xmlSecTransformKlass), /* size_t klassSize */
+ xmlSecXPathTransformSize, /* size_t objSize */
+
+ xmlSecNameXPath, /* const xmlChar* name; */
+ xmlSecXPathNs, /* const xmlChar* href; */
+ xmlSecTransformUsageDSigTransform, /* xmlSecTransformUsage usage; */
+
+ xmlSecTransformXPathInitialize, /* xmlSecTransformInitializeMethod initialize; */
+ xmlSecTransformXPathFinalize, /* xmlSecTransformFinalizeMethod finalize; */
+ xmlSecTransformXPathNodeRead, /* xmlSecTransformNodeReadMethod readNode; */
+ NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
+
+ ...
+};
+ ]]></programlisting>
+ </example>
+ </para></listitem>
+
+ <listitem><para>"Klass" id which is simply a pointer to the "klass"
+ declaration strucutre. "Klass" id is used to bind "klass" objects
+ to the "klass" declaration and to pass "klass" strucutre to functions.
+ <example>
+ <title>Base transform "klass" id declaration and its child XPath transform "klass" id implementation.</title>
+ <programlisting><![CDATA[
+typedef const struct _xmlSecTransformKlass xmlSecTransformKlass, *xmlSecTransformId;
+
+...
+
+#define xmlSecTransformXPathId xmlSecTransformXPathGetKlass()
+
+...
+
+xmlSecTransformId
+xmlSecTransformXPathGetKlass(void) {
+ return(&xmlSecTransformXPathKlass);
+}
+ ]]></programlisting>
+ </example>
+ </para></listitem>
+
+ <listitem><para>"Klass" object structure that contains object specific
+ data. The child object specific data are placed after the parent "klass"
+ object data.
+ <example>
+ <title>Base transform object strucutre and its child XPath transform object.</title>
+ <programlisting><![CDATA[
+struct _xmlSecTransform {
+ xmlSecTransformId id;
+ xmlSecTransformOperation operation;
+ xmlSecTransformStatus status;
+ xmlNodePtr hereNode;
+
+ /* transforms chain */
+ xmlSecTransformPtr next;
+ xmlSecTransformPtr prev;
+
+ ...
+};
+
+...
+
+/******************************************************************************
+ *
+ * XPath/XPointer transforms
+ *
+ * xmlSecPtrList with XPath expressions is located after xmlSecTransform structure
+ *
+ *****************************************************************************/
+#define xmlSecXPathTransformSize \
+ (sizeof(xmlSecTransform) + sizeof(xmlSecPtrList))
+#define xmlSecXPathTransformGetDataList(transform) \
+ ((xmlSecTransformCheckSize((transform), xmlSecXPathTransformSize)) ? \
+ (xmlSecPtrListPtr)(((unsigned char*)(transform)) + sizeof(xmlSecTransform)) : \
+ (xmlSecPtrListPtr)NULL)
+ ]]></programlisting>
+ </example>
+ </para></listitem>
+ </itemizedlist>
+ </para>
+ </sect1>
+ <sect1 id="xmlsec-notes-new-crypto-transforms">
+ <title>Cryptographic transforms.</title>
+ <para>The cryptographic transforms (digests, signatures and encryption)
+ implementation is the main goal of "xmlsec-&lt;crypto&gt;" library.
+ Most of the cryptographic <link linkend="xmlsec-notes-transforms">transforms</link>
+ use default <structfield>pushBin</structfield> and <structfield>popBin</structfield>
+ methods and provide custom <link linkend="xmlSecTransformExecuteMethod">execute</link> method.
+ The binary transform <link linkend="xmlSecTransformExecuteMethod">execute</link> method
+ processes data from the input buffer
+ <structfield>inBuf</structfield> and pushes results to
+ <structfield>outBuf</structfield>. The transform should try to
+ consume and remove data from <structfield>inBuf</structfield> buffer
+ as soon as the data became available. However, it might happen
+ that current data size in the input buffer is not enough (for example,
+ RSA-PKCS1 algorithm requires that all the data are available in
+ one buffer). In this case, transform might keep the data in the
+ input buffer till the next call to
+ <link linkend="xmlSecTransformExecuteMethod">execute</link>
+ method. The "last" parameter of the
+ <link linkend="xmlSecTransformExecuteMethod">execute</link>
+ indicates that transform MUST process all the data in the input buffer
+ and return as much as possible in the output buffer. The
+ <link linkend="xmlSecTransformExecuteMethod">execute</link> method
+ might be called multiple times with non-zero "last" parameter until
+ the transforms returns nothing
+ in the output buffer. In addition, the transform implementation is
+ responsible for managing the transform <structfield>status</structfield>
+ variable.
+ <table>
+ <title>Typical transform status managing.</title>
+ <tgroup cols="2"><tbody>
+ <row><entry>xmlSecTransformStatusNone</entry>
+ <entry>Transform initializes itself (for example, cipher transform
+ generates or reads IV) and sets <structfield>status</structfield>
+ variable to xmlSecTransformStatusWorking.</entry></row>
+ <row><entry>xmlSecTransformStatusWorking</entry>
+ <entry>Transform process the next (if "last" parameter is zero) or
+ last block of data (if "last" parameter is non-zero).
+ When transform returns all the data, it sets the
+ <structfield>status</structfield> variable to
+ xmlSecTransformStatusFinished.</entry></row>
+ <row><entry>xmlSecTransformStatusFinished</entry>
+ <entry>Transform returns no data to indicate that it finished
+ processing.</entry></row>
+ </tbody></tgroup></table>
+ </para>
+ <para>In adition to <link linkend="xmlSecTransformExecuteMethod">execute</link>
+ methods, signature, hmac or digest transforms
+ MUST implement <link linkend="xmlSecTransformVerifyMethod">verify</link> method.
+ The <link linkend="xmlSecTransformVerifyMethod">verify</link> method is called
+ after transform execution is finished. The
+ <link linkend="xmlSecTransformVerifyMethod">verify</link> method implementation
+ must set the "status" member to <link linkend="xmlSecTransformStatusOk">xmlSecTransformStatusOk</link>
+ if signature, hmac or digest is successfuly verified or to
+ <link linkend="xmlSecTransformStatusFail">xmlSecTransformStatusFail</link>
+ otherwise.
+ </para>
+ <para>The transforms that require a key (signature or encryption
+ transforms, for example) MUST imlpement
+ <link linkend="xmlSecTransformSetKeyRequirementsMethod">setKeyReq</link>
+ (prepares the <link linkend="xmlSecKeyReq">key requirements</link>
+ for key search) and
+ <link linkend="xmlSecTransformSetKeyMethod">setKey</link>
+ (sets the key in the transform) methods.
+ </para>
+ </sect1>
+ <sect1 id="xmlsec-notes-new-crypto-keys">
+ <title>Keys data and keys data stores.</title>
+ <para>
+ There are two key data types: key value data (for example, AES, DES, DSA,
+ HMAC or RSA key data) and others (for example, key name, X509 or PGP data).
+ The key data implementation should implement at least one of
+ <link linkend="xmlSecKeyDataXmlReadMethod">xmlRead</link>
+ or <link linkend="xmlSecKeyDataBinReadMethod">binRead</link> methods.
+ </para>
+ <para>TODO</para>
+ </sect1>
+ <sect1 id="xmlsec-notes-new-crypto-simple-keys-mngr">
+ <title>Default keys manager.</title>
+ <para>Any "xmlsec-&lt;crypto&gt;" library implementation must provide
+ a default keys store. The XML Security Library has a built-in flat
+ list based <link linkend="xmlSecSimpleKeysStoreId">simple keys
+ store</link> which could be used if cryptographic library does not
+ have one itself.
+ </para>
+ </sect1>
+ <sect1 id="xmlsec-notes-new-crypto-sharing-results">
+ <title>Sharing the results.</title>
+ <para>If you implemented support for new cryptographic library
+ (or extended an existing one) and both you and your company/university/...
+ are willing to share the code I would be glad to add your work
+ to XML Security Library. Many people will thank you for this
+ and will use your library. Of course, you'll get all the credits
+ for your work.
+ </para>
+ <para>The best way to submit your enchancements is to provide a diff
+ with the current CVS version. In order to do this,
+ <itemizedlist>
+ <listitem><para>Checkout the sources from <ulink URL="http://developer.gnome.org/tools/cvs.html">GNOME CVS</ulink>
+ (module name is "xmlsec").
+ </para></listitem>
+ <listitem><para>Add all the new files with "cvs add" command (this will not
+ create files in CVS but mark them as "added" localy). You'll not be able
+ to create new folders without a valid GNOME CVS account, let me know
+ what you need and I'll be happy to help.
+ </para></listitem>
+ <listitem><para>Get a diff of all existing and new files using
+ "cvs -z3 diff -u -N" command.
+ </para></listitem>
+ <listitem><para>Send the resulting diff file to the xmlsec mailing list
+ with some information about yourself so I can update the authors
+ and coping information.
+ </para></listitem>
+ </itemizedlist>
+ I will try to review and check in your patch as soon as possible.
+ </para>
+ </sect1>
+</chapter>
+
+