Git init
[external/xmlsec1.git] / docs / api / chapters / using-x509-certs.sgml
1 <chapter id="xmlsec-notes-x509">
2     <title>Using X509 Certificates.</title>
3     <sect1 id="xmlsec-notes-x509-overview">
4         <title>Overview.</title>
5         <para>X509 certificate is one of many possible keys data object that can be
6         associated with a key. Application may read and write X509 data
7         from/to XML file. The X509 certificates management policies significantly
8         vary from one crypto library to another. The examples in this chapter
9         were tested with OpenSSL and they might be broken if anither crypto
10         engine is used. Check API reference documentation for more specific 
11         information about your crypto engine.
12         </para>
13     </sect1>
14     
15     <sect1 id="xmlsec-notes-sign-x509" >
16         <title>Signing data with X509 certificate.</title>
17         <para>To sign a file using X509 certificate, 
18         an application need to associate the certificate (or certificates) 
19         with the private key using one of the following functions:
20         <itemizedlist>
21             <listitem><para>
22             <link linkend="xmlSecOpenSSLAppKeyCertLoad">xmlSecOpenSSLAppKeyCertLoad</link> - loads
23             certificate from a file and adds to the key;
24             </para></listitem>
25
26             <listitem><para>
27             <link linkend="xmlSecOpenSSLAppPkcs12Load">xmlSecOpenSSLAppPkcs12Load</link> -
28             loads private key and all the certificates associated with it from a PKCS12 file;
29             </para></listitem>
30
31             <listitem><para>
32             <link linkend="xmlSecKeyAdoptData">xmlSecKeyAdoptData</link> - low level
33             function to add key data (including X509 key data) to the key.
34             </para></listitem>
35         </itemizedlist>     
36         <example>
37             <title>Loading private key and X509 certificate.</title>
38             <programlisting><![CDATA[
39     /* load private key, assuming that there is not password */
40     key = xmlSecCryptoAppKeyLoad(key_file, xmlSecKeyDataFormatPem, NULL, NULL, NULL);
41     if(key == NULL) {
42         fprintf(stderr,"Error: failed to load private pem key from \"%s\"\n", key_file);
43         goto done;
44     }
45     
46     /* load certificate and add to the key */
47     if(xmlSecCryptoAppKeyCertLoad(key, cert_file, xmlSecKeyDataFormatPem) < 0) {
48         fprintf(stderr,"Error: failed to load pem certificate \"%s\"\n", cert_file);
49         goto done;
50     }
51             ]]></programlisting>
52             <simpara><link linkend="xmlsec-example-sign3">Full program listing</link></simpara>
53         </example>
54         </para>
55         <para>Next step is to prepare signature template with &lt;dsig:X509Data/&gt;
56         child of the &lt;dsig:KeyInfo/&gt; element. When XML Security Library finds
57         this node in the template, it automaticaly creates &lt;dsig:X509Certificate/&gt; 
58         children of the &lt;dsig:X509Data/&gt; element and writes to result XML document
59         all the certificates associated with the signature key. 
60         <example>
61             <title>Dynamicaly creating a signature template for signing document using X509 certificate.</title>
62             <programlisting><![CDATA[
63     /* create signature template for RSA-SHA1 enveloped signature */
64     signNode = xmlSecTmplSignatureCreate(doc, xmlSecTransformExclC14NId,
65                                          xmlSecTransformRsaSha1Id, NULL);
66     if(signNode == NULL) {
67         fprintf(stderr, "Error: failed to create signature template\n");
68         goto done;              
69     }
70
71     /* add <dsig:Signature/> node to the doc */
72     xmlAddChild(xmlDocGetRootElement(doc), signNode);
73     
74     /* add reference */
75     refNode = xmlSecTmplSignatureAddReference(signNode, xmlSecTransformSha1Id,
76                                         NULL, NULL, NULL);
77     if(refNode == NULL) {
78         fprintf(stderr, "Error: failed to add reference to signature template\n");
79         goto done;              
80     }
81
82     /* add enveloped transform */
83     if(xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformEnvelopedId) == NULL) {
84         fprintf(stderr, "Error: failed to add enveloped transform to reference\n");
85         goto done;              
86     }
87     
88     /* add <dsig:KeyInfo/> and <dsig:X509Data/> */
89     keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(signNode, NULL);
90     if(keyInfoNode == NULL) {
91         fprintf(stderr, "Error: failed to add key info\n");
92         goto done;              
93     }
94     
95     if(xmlSecTmplKeyInfoAddX509Data(keyInfoNode) == NULL) {
96         fprintf(stderr, "Error: failed to add X509Data node\n");
97         goto done;              
98     }
99             ]]></programlisting>
100             <simpara><link linkend="xmlsec-example-sign3">Full program listing</link></simpara>
101         </example>
102         </para>
103     </sect1>
104
105     <sect1 id="xmlsec-notes-verify-x509" >
106         <title>Verifing document signed with X509 certificates.</title>
107         <para>
108         If the document is signed with an X509 certificate then the signature
109         verification consist of two steps:
110         <itemizedlist>
111             <listitem><para>Creating and verifing X509 certificates chain.
112             </para></listitem>
113             <listitem><para>Verifing signature itself using key exrtacted from 
114             a certificate verified on previous step.
115             </para></listitem>
116         </itemizedlist>
117         Certificates chain is constructed from certificates in a way that
118         each certificate in the chain is signed with previous one:
119         <figure>
120             <title>Certificates chain.</title>
121             <programlisting>
122 Certificate A (signed with B) <- Certificate B (signed with C) <- ... <- Root Certificate (signed by itself)
123             </programlisting>
124         </figure>
125         At the end of the chain there is a &quot;Root Certificate&quot; which
126         is signed by itself. There is no way to verify the validity of the
127         root certificate and application have to &quot;trust&quot; it
128         (another name for root certificates is &quot;trusted&quot; certificates).
129         </para>
130         
131         <para>
132         Application can use <link linkend="xmlSecCryptoAppKeysMngrCertLoad">xmlSecCryptoAppKeysMngrCertLoad</link>
133         function to load both &quot;trusted&quot; and &quot;un-trusted&quot;
134         certificates. However, the selection of &quot;trusted&quot;
135         certificates is very sensitive process and this function might be
136         not implemented for some crypto engines. In this case, the 
137         &quot;trusted&quot; certificates list is loaded during initialization
138         or specified in crypto engine configuration files.
139         Check XML Security Library API reference for more details. 
140         <example>
141             <title>Loading trusted X509 certificate.</title>
142             <programlisting><![CDATA[
143 /**
144  * load_trusted_certs:
145  * @files:              the list of filenames.
146  * @files_size:         the number of filenames in #files.
147  *
148  * Creates simple keys manager and load trusted certificates from PEM #files.
149  * The caller is responsible for destroing returned keys manager using
150  * @xmlSecKeysMngrDestroy.
151  *
152  * Returns the pointer to newly created keys manager or NULL if an error
153  * occurs.
154  */
155 xmlSecKeysMngrPtr 
156 load_trusted_certs(char** files, int files_size) {
157     xmlSecKeysMngrPtr mngr;
158     int i;
159         
160     assert(files);
161     assert(files_size > 0);
162     
163     /* create and initialize keys manager, we use a simple list based
164      * keys manager, implement your own xmlSecKeysStore klass if you need
165      * something more sophisticated 
166      */
167     mngr = xmlSecKeysMngrCreate();
168     if(mngr == NULL) {
169         fprintf(stderr, "Error: failed to create keys manager.\n");
170         return(NULL);
171     }
172     if(xmlSecCryptoAppDefaultKeysMngrInit(mngr) < 0) {
173         fprintf(stderr, "Error: failed to initialize keys manager.\n");
174         xmlSecKeysMngrDestroy(mngr);
175         return(NULL);
176     }    
177     
178     for(i = 0; i < files_size; ++i) {
179         assert(files[i]);
180
181         /* load trusted cert */
182         if(xmlSecCryptoAppKeysMngrCertLoad(mngr, files[i], xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) {
183             fprintf(stderr,"Error: failed to load pem certificate from \"%s\"\n", files[i]);
184             xmlSecKeysMngrDestroy(mngr);
185             return(NULL);
186         }
187     }
188
189     return(mngr);
190 }
191             ]]></programlisting>
192             <simpara><link linkend="xmlsec-example-verify3">Full program listing</link></simpara>
193         </example>
194         </para>
195     </sect1>
196 </chapter>
197