summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorMatěj Cepl <mcepl@cepl.eu>2017-04-20 16:48:07 +0200
committerMatěj Cepl <mcepl@cepl.eu>2017-09-20 20:52:13 +0200
commitc0b300a5e4532b549f18b5526604219d717e2582 (patch)
treef5ac18c4cbc4b61c6f256f5a925168a7acff4080 /doc
parent5b1beb4b943ab7866162c4f8d0a19a779c0e2d1b (diff)
downloadm2crypto-c0b300a5e4532b549f18b5526604219d717e2582.tar.gz
Incorporate existing HTML files into Sphinx documents.
Diffstat (limited to 'doc')
-rw-r--r--doc/ZServerSSL-HOWTO.html271
-rw-r--r--doc/ZServerSSL-HOWTO.rst237
-rw-r--r--doc/howto.ca.html891
-rw-r--r--doc/howto.ca.rst368
-rw-r--r--doc/howto.smime.html1573
-rw-r--r--doc/howto.smime.rst776
-rw-r--r--doc/howto.ssl.html206
-rw-r--r--doc/howto.ssl.rst129
-rw-r--r--doc/index.rst17
9 files changed, 1522 insertions, 2946 deletions
diff --git a/doc/ZServerSSL-HOWTO.html b/doc/ZServerSSL-HOWTO.html
deleted file mode 100644
index 827cd0e..0000000
--- a/doc/ZServerSSL-HOWTO.html
+++ /dev/null
@@ -1,271 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-<base href="http://localhost:9080/home/m2/zserverssl-011-howto/" />
-
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="generator" content="Docutils 0.2.8: http://docutils.sourceforge.net/" />
-<title>ZServerSSL HOWTO</title>
-<meta name="author" content="Ng Pheng Siong" />
-<meta name="date" content="2003-06-22" />
-<link rel="stylesheet" href="default.css" type="text/css" />
-</head>
-<body>
-<div class="document" id="zserverssl-howto">
-<h1 class="title">ZServerSSL HOWTO</h1>
-<table class="docinfo" frame="void" rules="none">
-<col class="docinfo-name" />
-<col class="docinfo-content" />
-<tbody valign="top">
-<tr><th class="docinfo-name">Author:</th>
-<td>Ng Pheng Siong</td></tr>
-<tr class="field"><th class="docinfo-name">Id:</th><td class="field-body">ZServerSSL-HOWTO,v 1.1 2003/06/22 17:40:13 ngps Exp</td>
-</tr>
-<tr><th class="docinfo-name">Date:</th>
-<td>2003-06-22</td></tr>
-<tr class="field"><th class="docinfo-name">Web-Site:</th><td class="field-body"><a class="reference" href="http://chandlerproject.org/Projects/MeTooCrypto">http://chandlerproject.org/Projects/MeTooCrypto</a></td>
-</tr>
-</tbody>
-</table>
-<div class="contents topic" id="contents">
-<p class="topic-title"><a name="contents">Contents</a></p>
-<ul class="simple">
-<li><a class="reference" href="#introduction" id="id2" name="id2">Introduction</a></li>
-<li><a class="reference" href="#preparation" id="id3" name="id3">Preparation</a></li>
-<li><a class="reference" href="#installation" id="id4" name="id4">Installation</a></li>
-<li><a class="reference" href="#testing" id="id5" name="id5">Testing</a><ul>
-<li><a class="reference" href="#https" id="id6" name="id6">HTTPS</a></li>
-<li><a class="reference" href="#webdav-over-https" id="id7" name="id7">WebDAV-over-HTTPS</a></li>
-<li><a class="reference" href="#webdav-source-over-https" id="id8" name="id8">WebDAV-Source-over-HTTPS</a></li>
-<li><a class="reference" href="#python-with-m2crypto" id="id9" name="id9">Python with M2Crypto</a><ul>
-<li><a class="reference" href="#id1" id="id10" name="id10">HTTPS</a></li>
-<li><a class="reference" href="#xmlrpc-over-https" id="id11" name="id11">XMLRPC-over-HTTPS</a></li>
-</ul>
-</li>
-</ul>
-</li>
-<li><a class="reference" href="#conclusion" id="id12" name="id12">Conclusion</a></li>
-</ul>
-</div>
-<div class="section" id="introduction">
-<h1><a class="toc-backref" href="#id2" name="introduction">Introduction</a></h1>
-<p>ZServerSSL adds to Zope's ZServer the following:</p>
-<ul class="simple">
-<li>HTTPS server</li>
-<li>WebDAV-source-over-HTTPS server</li>
-</ul>
-<p>With the HTTPS server, ZServerSSL also provides WebDAV-over-HTTPS
-and XMLRPC-over-HTTPS access to Zope.</p>
-<p>These instructions apply to both Un*x and Windows installations of
-Zope 2.6.1. To avoid cluttering the presentation, Windows pathnames
-are shown in Un*x fashion.</p>
-</div>
-<div class="section" id="preparation">
-<h1><a class="toc-backref" href="#id3" name="preparation">Preparation</a></h1>
-<ol class="arabic simple">
-<li>Download M2Crypto 0.11, contained in the file <tt class="literal"><span class="pre">m2crypto-0.11.zip</span></tt>.</li>
-<li>Unpack <tt class="literal"><span class="pre">m2crypto-0.11.zip</span></tt>. This will create a directory
-<tt class="literal"><span class="pre">m2crypto-0.11</span></tt>. Henceforth, we refer to this directory as <tt class="literal"><span class="pre">$M2</span></tt>.</li>
-<li>Install M2Crypto per the instructions in <tt class="literal"><span class="pre">$M2/INSTALL</span></tt>.</li>
-</ol>
-<p>The ZServerSSL distribution is in <tt class="literal"><span class="pre">$M2/demo/Zope</span></tt>. We shall refer to
-this directory as <tt class="literal"><span class="pre">$ZSSL</span></tt>.</p>
-</div>
-<div class="section" id="installation">
-<h1><a class="toc-backref" href="#id4" name="installation">Installation</a></h1>
-<p>Below, we refer to your Zope top-level directory as <tt class="literal"><span class="pre">$ZOPE</span></tt>.</p>
-<ol class="arabic">
-<li><p class="first">Copy <tt class="literal"><span class="pre">$ZSSL/z2s.py</span></tt> into <tt class="literal"><span class="pre">$ZOPE</span></tt>.</p>
-</li>
-<li><p class="first">Depending on your operating system, modify <tt class="literal"><span class="pre">$ZOPE/start</span></tt> or
-<tt class="literal"><span class="pre">$ZOPE/start.bat</span></tt> to invoke <tt class="literal"><span class="pre">$ZOPE/z2s.py</span></tt>, instead of
-<tt class="literal"><span class="pre">$ZOPE/z2.py</span></tt>. The files <tt class="literal"><span class="pre">$ZSSL/starts</span></tt> and
-<tt class="literal"><span class="pre">$ZSSL/starts.bat</span></tt> serve as examples.</p>
-</li>
-<li><p class="first">Copy <tt class="literal"><span class="pre">$ZSSL/dh1024.pem</span></tt> into <tt class="literal"><span class="pre">$ZOPE</span></tt>. This file contains
-Diffie-Hellman parameters for use by the SSL protocol.</p>
-</li>
-<li><p class="first">Copy <tt class="literal"><span class="pre">$ZSSL/randpool.dat</span></tt> into <tt class="literal"><span class="pre">$ZOPE</span></tt>. This file contains seed
-material for the OpenSSL PRNG. Alternatively, create
-<tt class="literal"><span class="pre">$ZOPE/randpool.dat</span></tt> thusly:</p>
-<pre class="literal-block">
-$ dd if=/dev/urandom of=randpool.dat bs=1024 count=1
-</pre>
-</li>
-<li><p class="first">Copy <tt class="literal"><span class="pre">$ZSSL/ca.pem</span></tt> to <tt class="literal"><span class="pre">$ZOPE</span></tt>. This file contains an example
-Certification Authority (CA) certificate. For information on
-operating your own CA, see
-<a class="reference" href="http://svn.osafoundation.org/m2crypto/trunk/doc/howto.ca.html">howto.ca.html</a> or one of numerous
-similar documents available on the web.</p>
-</li>
-<li><p class="first">Copy <tt class="literal"><span class="pre">$ZSSL/server.pem</span></tt> to <tt class="literal"><span class="pre">$ZOPE</span></tt>. This file contains an RSA
-key pair and its X.509v3 certificate issued by the above CA. You
-may also create your own key/certificate bundle.</p>
-</li>
-<li><p class="first">Copy <tt class="literal"><span class="pre">$ZSSL/ZServer/HTTPS_Server.py</span></tt> to <tt class="literal"><span class="pre">$ZOPE/ZServer</span></tt>.</p>
-</li>
-<li><p class="first">Copy <tt class="literal"><span class="pre">$ZSSL/ZServer/__init__.py</span></tt> to <tt class="literal"><span class="pre">$ZOPE/ZServer</span></tt>. This
-overwrites the existing <tt class="literal"><span class="pre">$ZOPE/ZServer/__init__.py</span></tt>. Alternatively,
-apply the following patch to <tt class="literal"><span class="pre">$ZOPE/ZServer/__init__.py</span></tt>:</p>
-<pre class="literal-block">
---- __init__.py.org Sat Jun 21 23:20:41 2003
-+++ __init__.py Tue Jan 7 23:30:53 2003
-&#64;&#64; -84,6 +84,7 &#64;&#64;
- import asyncore
- from medusa import resolver, logger
- from HTTPServer import zhttp_server, zhttp_handler
-+from HTTPS_Server import zhttps_server, zhttps_handler
- from PCGIServer import PCGIServer
- from FCGIServer import FCGIServer
- from FTPServer import FTPServer
-</pre>
-</li>
-<li><p class="first">Copy <tt class="literal"><span class="pre">$ZSSL/ZServer/medusa/https_server.py</span></tt> to
-<tt class="literal"><span class="pre">$ZOPE/ZServer/medusa</span></tt>.</p>
-</li>
-<li><p class="first">Stop Zope, if it is running.</p>
-</li>
-<li><p class="first">Start Zope with ZServerSSL thusly:</p>
-<pre class="literal-block">
-./starts -X -f 9021 -w 9080 -W 9081 -y 9443 -Y 9444
-</pre>
-<p>This starts the following:</p>
-<ul class="simple">
-<li>an FTP server on port 9021</li>
-<li>a HTTP server on port 9080</li>
-<li>a WebDAV-source server on port 9081</li>
-<li>a HTTPS server on port 9443</li>
-<li>a WebDAV-source-over-HTTPS server on port 9444</li>
-</ul>
-</li>
-</ol>
-</div>
-<div class="section" id="testing">
-<h1><a class="toc-backref" href="#id5" name="testing">Testing</a></h1>
-<p>Below, we assume your Zope server is running on <tt class="literal"><span class="pre">localhost</span></tt>.</p>
-<div class="section" id="https">
-<h2><a class="toc-backref" href="#id6" name="https">HTTPS</a></h2>
-<p>This testing is done with Mozilla 1.1 on FreeBSD.</p>
-<ol class="arabic simple">
-<li>With a browser, connect to <a class="reference" href="https://localhost:9443/">https://localhost:9443/</a>. Browse
-around. Check out your browser's HTTPS informational screens.</li>
-<li>Connect to <a class="reference" href="https://localhost:9443/manage">https://localhost:9443/manage</a>. Verify that you can
-access Zope's management functionality.</li>
-</ol>
-</div>
-<div class="section" id="webdav-over-https">
-<h2><a class="toc-backref" href="#id7" name="webdav-over-https">WebDAV-over-HTTPS</a></h2>
-<p>This testing is done with Cadaver 0.21.0 on FreeBSD.</p>
-<pre class="literal-block">
-$ cadaver https://localhost:9443/
-WARNING: Untrusted server certificate presented:
-Issued to: M2Crypto, SG
-Issued by: M2Crypto, SG
-Do you wish to accept the certificate? (y/n) y
-dav:/&gt; ls
-Listing collection `/': succeeded.
-Coll: Channels 0 Jun 19 00:04
-Coll: Control_Panel 0 Jun 6 00:13
-Coll: Examples 0 Jun 6 00:12
-Coll: catalog 0 Jun 12 11:53
-Coll: ngps 0 Jun 16 15:34
-Coll: portal 0 Jun 21 15:21
-Coll: skunk 0 Jun 18 21:18
-Coll: temp_folder 0 Jun 22 17:57
-Coll: zope 0 Jun 20 15:27
- acl_users 0 Dec 30 1998
- browser_id_manager 0 Jun 6 00:12
- default.css 3037 Jun 21 16:38
- error_log 0 Jun 6 00:12
- index_html 313 Jun 12 13:36
- portal0 0 Jun 21 15:21
- session_data_manager 0 Jun 6 00:12
- standard_error_message 1365 Jan 21 2001
- standard_html_footer 50 Jun 12 12:30
- standard_html_header 80 Jan 21 2001
- standard_template.pt 282 Jun 6 00:12
- zsyncer 0 Jun 17 15:28
-dav:/&gt; quit
-Connection to `localhost' closed.
-$
-</pre>
-</div>
-<div class="section" id="webdav-source-over-https">
-<h2><a class="toc-backref" href="#id8" name="webdav-source-over-https">WebDAV-Source-over-HTTPS</a></h2>
-<p>This testing is done with Mozilla 1.1 on FreeBSD.</p>
-<ol class="arabic simple">
-<li>Open the Mozilla Composer window.</li>
-<li>Click &quot;File&quot;, &quot;Open Web Location&quot;. A dialog box appears.</li>
-<li>Enter <tt class="literal"><span class="pre">https://localhost:9444/index_html</span></tt> for the URL.</li>
-<li>Select &quot;Open in new Composer window.&quot;</li>
-<li>Click &quot;Open&quot;. A new Composer window will open with <tt class="literal"><span class="pre">index_html</span></tt>
-loaded.</li>
-</ol>
-</div>
-<div class="section" id="python-with-m2crypto">
-<h2><a class="toc-backref" href="#id9" name="python-with-m2crypto">Python with M2Crypto</a></h2>
-<p>This testing is done with M2Crypto 0.11 and Python 2.2.2 on FreeBSD.</p>
-<div class="section" id="id1">
-<h3><a class="toc-backref" href="#id10" name="id1">HTTPS</a></h3>
-<pre class="doctest-block">
-&gt;&gt;&gt; from M2Crypto import Rand, SSL, m2urllib
-&gt;&gt;&gt; url = m2urllib.FancyURLopener()
-&gt;&gt;&gt; url.addheader('Connection', 'close')
-&gt;&gt;&gt; u = url.open('https://127.0.0.1:9443/')
-send: 'GET / HTTP/1.1\r\nHost: 127.0.0.1:9443\r\nAccept-Encoding: identity\r\nUser-agent: Python-urllib/1.15\r\nConnection: close\r\n\r\n'
-reply: 'HTTP/1.1 200 OK\r\n'
-header: Server: ZServerSSL/0.11
-header: Date: Sun, 22 Jun 2003 13:42:34 GMT
-header: Connection: close
-header: Content-Type: text/html
-header: Etag:
-header: Content-Length: 535
-&gt;&gt;&gt; while 1:
-... data = u.read()
-... if not data: break
-... print(data)
-...
-</pre>
-<pre class="literal-block">
-&lt;html&gt;&lt;head&gt;
-&lt;base href=&quot;https://127.0.0.1:9443/&quot; /&gt;
-&lt;title&gt;Zope&lt;/title&gt;&lt;/head&gt;&lt;body bgcolor=&quot;#FFFFFF&quot;&gt;
-
-&lt;h1&gt;NgPS Desktop Portal&lt;/h1&gt;
-
-&amp;nbsp;&amp;nbsp;So many hacks.&lt;br&gt;
-&amp;nbsp;&amp;nbsp;So little time.&lt;br&gt;
-
-&lt;h2&gt;Link Farm&lt;/h2&gt;
-&lt;ul&gt;
-&lt;li&gt;&lt;a href=&quot;http://localhost:8080/portal&quot;&gt;Portal&lt;/a&gt;&lt;/li&gt;
-&lt;li&gt;&lt;a href=&quot;http://localhost/&quot;&gt;Local Apache Home Page&lt;/a&gt;&lt;/li&gt;
-&lt;/ul&gt;
-
-&lt;hr&gt;&lt;a href=&quot;http://www.zope.org/Credits&quot; target=&quot;_top&quot;&gt;&lt;img src=&quot;https://127.0.0.1:9443/p_/ZopeButton&quot; width=&quot;115&quot; height=&quot;50&quot; border=&quot;0&quot; alt=&quot;Powered by Zope&quot; /&gt;&lt;/a&gt;&lt;/body&gt;&lt;/html&gt;
-</pre>
-<pre class="doctest-block">
-&gt;&gt;&gt; u.close()
-&gt;&gt;&gt;
-</pre>
-</div>
-<div class="section" id="xmlrpc-over-https">
-<h3><a class="toc-backref" href="#id11" name="xmlrpc-over-https">XMLRPC-over-HTTPS</a></h3>
-<pre class="doctest-block">
-&gt;&gt;&gt; from M2Crypto.m2xmlrpclib import Server, SSL_Transport
-&gt;&gt;&gt; zs = Server('https://127.0.0.1:9443/', SSL_Transport())
-&gt;&gt;&gt; print(zs.propertyMap())
-[{'type': 'string', 'id': 'title', 'mode': 'w'}]
-&gt;&gt;&gt;
-</pre>
-</div>
-</div>
-</div>
-<div class="section" id="conclusion">
-<h1><a class="toc-backref" href="#id12" name="conclusion">Conclusion</a></h1>
-<p>Well, it works! ;-)</p>
-</div>
-</div>
-</body>
-</html>
diff --git a/doc/ZServerSSL-HOWTO.rst b/doc/ZServerSSL-HOWTO.rst
new file mode 100644
index 0000000..d09426d
--- /dev/null
+++ b/doc/ZServerSSL-HOWTO.rst
@@ -0,0 +1,237 @@
+.. _zserverssl-howto:
+
+ZServerSSL-HOWTO
+################
+
+:author: Pheng Siong Ng <ngps@post1.com>
+:copyright: © 2000, 2001 by Ng Pheng Siong.
+:date: 2003-06-22
+
+.. contents::
+ :backlinks: entry
+
+.. sectnum::
+ :suffix: .
+
+Introduction
+============
+
+ZServerSSL adds to Zope's ZServer the following:
+
+- HTTPS server
+- WebDAV-source-over-HTTPS server
+
+With the HTTPS server, ZServerSSL also provides WebDAV-over-HTTPS and
+XMLRPC-over-HTTPS access to Zope.
+
+These instructions apply to both Un\*x and Windows installations of Zope
+2.6.1. To avoid cluttering the presentation, Windows pathnames are shown
+in Un\*x fashion.
+
+Preparation
+===========
+
+#. Download M2Crypto 0.11, contained in the file ``m2crypto-0.11.zip``.
+#. Unpack ``m2crypto-0.11.zip``. This will create a directory
+ ``m2crypto-0.11``. Henceforth, we refer to this directory as ``$M2``.
+#. Install M2Crypto per the instructions in ``$M2/INSTALL``.
+
+The ZServerSSL distribution is in ``$M2/demo/Zope``. We shall refer to
+this directory as ``$ZSSL``.
+
+Installation
+============
+
+Below, we refer to your Zope top-level directory as ``$ZOPE``.
+
+#. Copy ``$ZSSL/z2s.py`` into ``$ZOPE``.
+
+#. Depending on your operating system, modify ``$ZOPE/start`` or
+ ``$ZOPE/start.bat`` to invoke ``$ZOPE/z2s.py``, instead of
+ ``$ZOPE/z2.py``. The files ``$ZSSL/starts`` and ``$ZSSL/starts.bat``
+ serve as examples.
+
+#. Copy ``$ZSSL/dh1024.pem`` into ``$ZOPE``. This file contains
+ Diffie-Hellman parameters for use by the SSL protocol.
+
+#. Copy ``$ZSSL/randpool.dat`` into ``$ZOPE``. This file contains seed
+ material for the OpenSSL PRNG. Alternatively, create
+ ``$ZOPE/randpool.dat`` thusly::
+
+ $ dd if=/dev/urandom of=randpool.dat bs=1024 count=1
+
+#. Copy ``$ZSSL/ca.pem`` to ``$ZOPE``. This file contains an
+ example Certification Authority (CA) certificate. For
+ information on operating your own CA, see :ref:`howto-ca` or
+ one of numerous similar documents available on the web.
+
+#. Copy ``$ZSSL/server.pem`` to ``$ZOPE``. This file contains an RSA key
+ pair and its X.509v3 certificate issued by the above CA. You may also
+ create your own key/certificate bundle.
+
+#. Copy ``$ZSSL/ZServer/HTTPS_Server.py`` to ``$ZOPE/ZServer``.
+
+#. Copy ``$ZSSL/ZServer/__init__.py`` to ``$ZOPE/ZServer``. This
+ overwrites the existing ``$ZOPE/ZServer/__init__.py``. Alternatively,
+ apply the following patch to ``$ZOPE/ZServer/__init__.py``::
+
+ --- __init__.py.org Sat Jun 21 23:20:41 2003
+ +++ __init__.py Tue Jan 7 23:30:53 2003
+ @@ -84,6 +84,7 @@
+ import asyncore
+ from medusa import resolver, logger
+ from HTTPServer import zhttp_server, zhttp_handler
+ +from HTTPS_Server import zhttps_server, zhttps_handler
+ from PCGIServer import PCGIServer
+ from FCGIServer import FCGIServer
+ from FTPServer import FTPServer
+
+#. Copy ``$ZSSL/ZServer/medusa/https_server.py`` to
+ ``$ZOPE/ZServer/medusa``.
+
+#. Stop Zope, if it is running.
+
+#. Start Zope with ZServerSSL thusly::
+
+ ./starts -X -f 9021 -w 9080 -W 9081 -y 9443 -Y 9444
+
+ This starts the following:
+
+ - an FTP server on port 9021
+ - a HTTP server on port 9080
+ - a WebDAV-source server on port 9081
+ - a HTTPS server on port 9443
+ - a WebDAV-source-over-HTTPS server on port 9444
+
+Testing
+=======
+
+Below, we assume your Zope server is running on ``localhost``.
+
+HTTPS
+=====
+
+This testing is done with Mozilla 1.1 on FreeBSD.
+
+#. With a browser, connect to https://localhost:9443/. Browse around.
+ Check out your browser's HTTPS informational screens.
+#. Connect to https://localhost:9443/manage. Verify that you can access
+ Zope's management functionality.
+
+WebDAV-over-HTTPS
+=================
+
+This testing is done with Cadaver 0.21.0 on FreeBSD.::
+
+ $ cadaver https://localhost:9443/
+ WARNING: Untrusted server certificate presented:
+ Issued to: M2Crypto, SG
+ Issued by: M2Crypto, SG
+ Do you wish to accept the certificate? (y/n) y
+ dav:/> ls
+ Listing collection `/': succeeded.
+ Coll: Channels 0 Jun 19 00:04
+ Coll: Control_Panel 0 Jun 6 00:13
+ Coll: Examples 0 Jun 6 00:12
+ Coll: catalog 0 Jun 12 11:53
+ Coll: ngps 0 Jun 16 15:34
+ Coll: portal 0 Jun 21 15:21
+ Coll: skunk 0 Jun 18 21:18
+ Coll: temp_folder 0 Jun 22 17:57
+ Coll: zope 0 Jun 20 15:27
+ acl_users 0 Dec 30 1998
+ browser_id_manager 0 Jun 6 00:12
+ default.css 3037 Jun 21 16:38
+ error_log 0 Jun 6 00:12
+ index_html 313 Jun 12 13:36
+ portal0 0 Jun 21 15:21
+ session_data_manager 0 Jun 6 00:12
+ standard_error_message 1365 Jan 21 2001
+ standard_html_footer 50 Jun 12 12:30
+ standard_html_header 80 Jan 21 2001
+ standard_template.pt 282 Jun 6 00:12
+ zsyncer 0 Jun 17 15:28
+ dav:/> quit
+ Connection to `localhost' closed.
+ $
+
+
+WebDAV-Source-over-HTTPS
+========================
+
+This testing is done with Mozilla 1.1 on FreeBSD.
+
+#. Open the Mozilla Composer window.
+#. Click "File", "Open Web Location". A dialog box appears.
+#. Enter ``https://localhost:9444/index_html`` for the URL.
+#. Select "Open in new Composer window."
+#. Click "Open". A new Composer window will open with ``index_html``
+ loaded.
+
+Python with M2Crypto
+====================
+
+This testing is done with M2Crypto 0.11 and Python 2.2.2 on FreeBSD.
+
+HTTPS
+=====
+
+::
+
+ >>> from M2Crypto import Rand, SSL, m2urllib
+ >>> url = m2urllib.FancyURLopener()
+ >>> url.addheader('Connection', 'close')
+ >>> u = url.open('https://127.0.0.1:9443/')
+ send: 'GET / HTTP/1.1\r\nHost: 127.0.0.1:9443\r\nAccept-Encoding: identity\r\nUser-agent: Python-urllib/1.15\r\nConnection: close\r\n\r\n'
+ reply: 'HTTP/1.1 200 OK\r\n'
+ header: Server: ZServerSSL/0.11
+ header: Date: Sun, 22 Jun 2003 13:42:34 GMT
+ header: Connection: close
+ header: Content-Type: text/html
+ header: Etag:
+ header: Content-Length: 535
+ >>> while 1:
+ ... data = u.read()
+ ... if not data: break
+ ... print(data)
+ ...
+
+::
+
+ <html><head>
+ <base href="https://127.0.0.1:9443/" />
+ <title>Zope</title></head><body bgcolor="#FFFFFF">
+
+ <h1>NgPS Desktop Portal</h1>
+
+ &nbsp;&nbsp;So many hacks.<br>
+ &nbsp;&nbsp;So little time.<br>
+
+ <h2>Link Farm</h2>
+ <ul>
+ <li><a href="http://localhost:8080/portal">Portal</a></li>
+ <li><a href="http://localhost/">Local Apache Home Page</a></li>
+ </ul>
+
+ <hr><a href="http://www.zope.org/Credits" target="_top"><img src="https://127.0.0.1:9443/p_/ZopeButton" width="115" height="50" border="0" alt="Powered by Zope" /></a></body></html>
+
+::
+
+ >>> u.close()
+ >>>
+
+XMLRPC-over-HTTPS
+=================
+
+::
+
+ >>> from M2Crypto.m2xmlrpclib import Server, SSL_Transport
+ >>> zs = Server('https://127.0.0.1:9443/', SSL_Transport())
+ >>> print(zs.propertyMap())
+ [{'type': 'string', 'id': 'title', 'mode': 'w'}]
+ >>>
+
+Conclusion
+==========
+
+Well, it works! ;-)
diff --git a/doc/howto.ca.html b/doc/howto.ca.html
deleted file mode 100644
index f33d7e5..0000000
--- a/doc/howto.ca.html
+++ /dev/null
@@ -1,891 +0,0 @@
-<HTML
-><HEAD
-><TITLE
->HOWTO: Creating your own CA with OpenSSL</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.64
-"></HEAD
-><BODY
-CLASS="ARTICLE"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="ARTICLE"
-><DIV
-CLASS="TITLEPAGE"
-><H1
-CLASS="TITLE"
-><A
-NAME="AEN2"
->HOWTO: Creating your own CA with OpenSSL</A
-></H1
-><H3
-CLASS="AUTHOR"
-><A
-NAME="AEN4"
->Pheng Siong Ng</A
-></H3
-><DIV
-CLASS="AFFILIATION"
-><DIV
-CLASS="ADDRESS"
-><P
-CLASS="ADDRESS"
->ngps@post1.com</P
-></DIV
-></DIV
-><P
-CLASS="COPYRIGHT"
->Copyright &copy; 2000, 2001 by Ng Pheng Siong.</P
-><DIV
-CLASS="REVHISTORY"
-><TABLE
-WIDTH="100%"
-BORDER="0"
-><TR
-><TH
-ALIGN="LEFT"
-VALIGN="TOP"
-COLSPAN="3"
-><B
->Revision History</B
-></TH
-></TR
-><TR
-><TD
-ALIGN="LEFT"
->Revision $Revision: 1.1 $</TD
-><TD
-ALIGN="LEFT"
->$Date: 2003/06/22 16:41:18 $</TD
-><TD
-ALIGN="LEFT"
-></TD
-></TR
-><TR
-><TD
-ALIGN="LEFT"
-COLSPAN="3"
-></TD
-></TR
-></TABLE
-></DIV
-><HR></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="INTRODUCTION"
->Introduction</A
-></H1
-><P
->This is a HOWTO on creating your own <I
-CLASS="EMPHASIS"
->certification
- authority</I
-> (<I
-CLASS="EMPHASIS"
->CA</I
->) with OpenSSL.
- </P
-><P
->I last created a CA about a year ago, when I began work on <A
-HREF="http://chandlerproject.org/Projects/MeTooCrypto"
-TARGET="_top"
->M2Crypto</A
-> and needed
- certificates for the SSL bits. I accepted the tools' default settings
- then, e.g., certificate validity of 365 days; this meant that my
- certificates, including my CA's certificate, have now expired.
- </P
-><P
->Since I am using these certificates for M2Crypto's demonstration
- programs (and I have forgotten the passphrase to the CA's private key),
- I decided to discard the old CA and start afresh. I also decided to
- document the process, hence this HOWTO.
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="PROCEDURE"
->The Procedure</A
-></H1
-><P
->I use <TT
-CLASS="FILENAME"
->CA.pl</TT
->, a Perl program written by
- Steve Hanson and bundled with OpenSSL.
- </P
-><P
->The following are the steps to create a CA:
- </P
-><DIV
-CLASS="PROCEDURE"
-><OL
-TYPE="1"
-><LI
-><P
->Choose a directory to do your CA work. All commands are executed
- within this directory. Let's call the directory <TT
-CLASS="FILENAME"
->demo</TT
->.
- </P
-></LI
-><LI
-><P
->Copy <TT
-CLASS="FILENAME"
->CA.pl</TT
-> and <TT
-CLASS="FILENAME"
->openssl.cnf</TT
->
- into <TT
-CLASS="FILENAME"
->demo</TT
->.
- </P
-></LI
-><LI
-><P
->Apply the following patch to <TT
-CLASS="FILENAME"
->CA.pl</TT
->, which
- allows it to generate a CA certificate with a validity period of 1095 days,
- i.e., 3 years:
- </P
-><PRE
-CLASS="PROGRAMLISTING"
-> --- CA.pl.org Sat Mar 31 12:40:13 2001
- +++ CA.pl Sat Mar 31 12:41:15 2001
- @@ -97,7 +97,7 @@
- } else {
- print "Making CA certificate ...\n";
- system ("$REQ -new -x509 -keyout " .
- - "${CATOP}/private/$CAKEY -out ${CATOP}/$CACERT $DAYS");
- + "${CATOP}/private/$CAKEY -out ${CATOP}/$CACERT -days 1095");
- $RET=$?;
- }
- }
- </PRE
-></LI
-><LI
-><P
->Create a new CA like this:
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->./CA.pl -newca
- </B
-></TT
->
- A certificate filename (or enter to create) <TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->&lt;enter&gt;</I
-></TT
-></B
-></TT
->
-
- Making CA certificate ...
- Using configuration from openssl.cnf
- Generating a 1024 bit RSA private key
- ............++++++
- ......................++++++
- writing new private key to './demoCA/private/cakey.pem'
- Enter PEM pass phrase: <TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->&lt;secret passphrase here&gt;</I
-></TT
-></B
-></TT
->
- Verifying password - Enter PEM pass phrase: <TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->&lt;secret passphrase again&gt;</I
-></TT
-></B
-></TT
->
- -----
- You are about to be asked to enter information that will be incorporated
- into your certificate request.
- What you are about to enter is what is called a Distinguished Name or a DN.
- There are quite a few fields but you can leave some blank
- For some fields there will be a default value,
- If you enter '.', the field will be left blank.
- -----
- Country Name (2 letter code) [AU]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->SG</I
-></TT
-></B
-></TT
->
- State or Province Name (full name) [Some-State]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->
- Locality Name (eg, city) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->.
- Organization Name (eg, company) [Internet Widgits Pty Ltd]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->DemoCA</I
-></TT
-></B
-></TT
->
- Organizational Unit Name (eg, section) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->
- Common Name (eg, YOUR name) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->DemoCA Certificate Master</I
-></TT
-></B
-></TT
->
- Email Address []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->certmaster@democa.dom</I
-></TT
-></B
-></TT
->
- </PRE
-><P
->This creates a new CA in the directory <TT
-CLASS="FILENAME"
->demoCA</TT
->.
- The CA's self-signed certificate is in
- <TT
-CLASS="FILENAME"
->demoCA/cacert.pem</TT
-> and its RSA key pair is in
- <TT
-CLASS="FILENAME"
->demoCA/private/cakey.pem</TT
->.
- </P
-><P
-><TT
-CLASS="FILENAME"
->demoCA/private/cakey.pem</TT
-> looks like this:
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->cat demoCA/private/cakey.pem
- </B
-></TT
->
- -----BEGIN RSA PRIVATE KEY-----
- Proc-Type: 4,ENCRYPTED
- DEK-Info: DES-EDE3-CBC,19973A9DBBB601BA
-
- eOq9WFScNiI4/UWEUaSnGTKpJv2JYuMD3HwQox2Q3Cd4zGqVjJ6gF3exa5126cKf
- X/bMVnwbPpuFZPiAIvaLyCjT6pYeXTBbSzs7/GQnvEOv+nYnDUFWi0Qm92qLk0uy
- pFi/M1aWheN3vir2ZlAw+DW0bOOZhj8tC7Co7lMYb0YE271b6/YRPZCwQ3GXAHUJ
- +aMYxlUDrK45aCUa/1CZDzTgk7h9cDgx2QJSIvYMYytCfI3zsuZMJS8/4OXLL0bI
- lKmAc1dwB3DqGJt5XK4WJesiNfdxeCNEgAcYtEAgYZTPIApU+kTgTCIxJl2nMW7j
- ax+Q1z7g+4MpgG20WD633D4z4dTlDdz+dnLi0rvuvxiwt+dUhrqiML1tyi+Z6EBH
- jU4/cLBWev3rYfrlp4x8J9mDte0YKOk3t0wQOHqRetTsIfdtjnFp/Hu3qDmTCWjD
- z/g7PPoO/bg/B877J9WBPbL/1hXXFYo88M+2aGlPOgDcFdiOqbLb2DCscohMbbVr
- A4mgiy2kwWfIE73qiyV7yyG8FlRvr1iib+jbT3LTGf743utYAAs7HNGuOUObhoyt
- jYvBD7ACn35P5YX7KTqvqErwdijxYCaNBCnvmRtmYSaNw9Kv1UJTxc5Vx7YLwIPk
- E9KyBgKI7vPOjWBZ27+zOvNycmv1ciNtpALAw4bWtXnhCDVTHaVDy34OkheMzNCg
- 2cjcBFzOkMIjcI03KbTQXOFIQGlsTWXGzkNf/zBQ+KksT1MCj+zBXSCvlDASMckg
- kef21pGgUqPF14gKGfWX3sV4bjc1vbrRwq6zlG3nMuYqR5MtJJY9eQ==
- -----END RSA PRIVATE KEY-----
- </PRE
-></LI
-><LI
-><P
->Next, generate a certificate request.
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->./CA.pl -newreq
- </B
-></TT
->
- Using configuration from openssl.cnf
- Generating a 1024 bit RSA private key
- ..........++++++
- ..............++++++
- writing new private key to 'newreq.pem'
- Enter PEM pass phrase: <TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->&lt;another secret passphrase here&gt;</I
-></TT
-></B
-></TT
->
- Verifying password - Enter PEM pass phrase: <TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->&lt;another secret passphrase again&gt;</I
-></TT
-></B
-></TT
->
- -----
- You are about to be asked to enter information that will be incorporated
- into your certificate request.
- What you are about to enter is what is called a Distinguished Name or a DN.
- There are quite a few fields but you can leave some blank
- For some fields there will be a default value,
- If you enter '.', the field will be left blank.
- -----
- Country Name (2 letter code) [AU]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->SG</I
-></TT
-></B
-></TT
->
- State or Province Name (full name) [Some-State]:.<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->
- Locality Name (eg, city) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->
- Organization Name (eg, company) [Internet Widgits Pty Ltd]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->M2Crypto</I
-></TT
-></B
-></TT
->
- Organizational Unit Name (eg, section) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->
- Common Name (eg, YOUR name) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->localhost</I
-></TT
-></B
-></TT
->
- Email Address []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->admin@server.example.dom</I
-></TT
-></B
-></TT
->
-
- Please enter the following 'extra' attributes
- to be sent with your certificate request
- A challenge password []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->&lt;enter&gt;</I
-></TT
-></B
-></TT
->
- An optional company name []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->&lt;enter&gt;</I
-></TT
-></B
-></TT
->
- Request (and private key) is in newreq.pem
- </PRE
-><P
->The certificate request and private key in <TT
-CLASS="FILENAME"
->newreq.pem</TT
-> looks like this:
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->cat newreq.pem
- </B
-></TT
->
- -----BEGIN RSA PRIVATE KEY-----
- Proc-Type: 4,ENCRYPTED
- DEK-Info: DES-EDE3-CBC,41B2874DF3D02DD4
-
- mg611EoVkLEooSTv+qTM0Ddmm/M1jE/Jy5RD/sc3LSMhuGu9xc26OgsTJmkQuIAh
- J/B4lAw8G59VTG6DykeEtrG0rUBx4bggc7PKbFuiN423YjJODWcHvVgnPOzXMQt+
- lY4tPl5+217MRHyx2NsWGrpkQNdu3GeSPOVMl3jeQiaXupONbwQ7rj42+X/VtAJP
- W4D1NNwu8aGCPyShsEXHc/fI1WDpphYWke97pOjIZVQESFZOPty5HjIYZux4U+td
- W81xODtq2ecJXc8fn2Wpa9y5VD1LT7oJksOuL1+Z04OVaeUe4x0swM17HlBm2kVt
- fe/C/L6kN27MwZhE331VjtTjSGl4/gknqQDbLOtqT06f3OISsDJETm2itllyhgzv
- C6Fi3N03rGFmKectijC+tws5k+P+HRG6sai33usk8xPokJqA+HYSWPz1XVlpRmv4
- kdjQOdST7ovU62mOTgf3ARcduPPwuzTfxOlYONe5NioO1APVHBrInQwcpLkpOTQR
- vI4roIN+b75/nihUWGUJn/nbbBa2Yl0N5Gs1Tyiy9Z+CcRT2TfWKBBFlEUIFl7Mb
- J9fTV3DI+k+akbR4il1NkQ8EcSmCr3WpA0I9n0EHI7ZVpVaHxc0sqaPFl8YGdFHq
- 1Qk53C/w6+qPpDzT3yKFmG2LZytAAM1czvb6RbNRJJP2ZrpBwn/h99sUTo/yPfxY
- nueYmFJDm0uVNtG0icXGNUfSfnjKNTtHPAgyKGetRIC3kgJz/bo2w7EI6iEjBAzK
- l5TRm4x6ZJxwuXXMiJCehMMd8TC8ybwWO4AO19B3ebFFeTVsUgxSGA==
- -----END RSA PRIVATE KEY-----
- -----BEGIN CERTIFICATE REQUEST-----
- MIIBnTCCAQYCAQAwXTELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIw
- EAYDVQQDEwlsb2NhbGhvc3QxJzAlBgkqhkiG9w0BCQEWGGFkbWluQHNlcnZlci5l
- eGFtcGxlLmRvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAr1nYY1Qrll1r
- uB/FqlCRrr5nvupdIN+3wF7q915tvEQoc74bnu6b8IbbGRMhzdzmvQ4SzFfVEAuM
- MuTHeybPq5th7YDrTNizKKxOBnqE2KYuX9X22A1Kh49soJJFg6kPb9MUgiZBiMlv
- tb7K3CHfgw5WagWnLl8Lb+ccvKZZl+8CAwEAAaAAMA0GCSqGSIb3DQEBBAUAA4GB
- AHpoRp5YS55CZpy+wdigQEwjL/wSluvo+WjtpvP0YoBMJu4VMKeZi405R7o8oEwi
- PdlrrliKNknFmHKIaCKTLRcU59ScA6ADEIWUzqmUzP5Cs6jrSRo3NKfg1bd09D1K
- 9rsQkRc9Urv9mRBIsredGnYECNeRaK5R1yzpOowninXC
- -----END CERTIFICATE REQUEST-----
- </PRE
-><P
->Decoding the certificate request gives the following:
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->openssl req -text -noout &#60; newreq.pem
- </B
-></TT
->
- Using configuration from /usr/local/pkg/openssl/openssl.cnf
- Certificate Request:
- Data:
- Version: 0 (0x0)
- Subject: C=SG, O=M2Crypto, CN=localhost/Email=admin@server.example.dom
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public Key: (1024 bit)
- Modulus (1024 bit):
- 00:af:59:d8:63:54:2b:96:5d:6b:b8:1f:c5:aa:50:
- 91:ae:be:67:be:ea:5d:20:df:b7:c0:5e:ea:f7:5e:
- 6d:bc:44:28:73:be:1b:9e:ee:9b:f0:86:db:19:13:
- 21:cd:dc:e6:bd:0e:12:cc:57:d5:10:0b:8c:32:e4:
- c7:7b:26:cf:ab:9b:61:ed:80:eb:4c:d8:b3:28:ac:
- 4e:06:7a:84:d8:a6:2e:5f:d5:f6:d8:0d:4a:87:8f:
- 6c:a0:92:45:83:a9:0f:6f:d3:14:82:26:41:88:c9:
- 6f:b5:be:ca:dc:21:df:83:0e:56:6a:05:a7:2e:5f:
- 0b:6f:e7:1c:bc:a6:59:97:ef
- Exponent: 65537 (0x10001)
- Attributes:
- a0:00
- Signature Algorithm: md5WithRSAEncryption
- 7a:68:46:9e:58:4b:9e:42:66:9c:be:c1:d8:a0:40:4c:23:2f:
- fc:12:96:eb:e8:f9:68:ed:a6:f3:f4:62:80:4c:26:ee:15:30:
- a7:99:8b:8d:39:47:ba:3c:a0:4c:22:3d:d9:6b:ae:58:8a:36:
- 49:c5:98:72:88:68:22:93:2d:17:14:e7:d4:9c:03:a0:03:10:
- 85:94:ce:a9:94:cc:fe:42:b3:a8:eb:49:1a:37:34:a7:e0:d5:
- b7:74:f4:3d:4a:f6:bb:10:91:17:3d:52:bb:fd:99:10:48:b2:
- b7:9d:1a:76:04:08:d7:91:68:ae:51:d7:2c:e9:3a:8c:27:8a:
- 75:c2
- </PRE
-></LI
-><LI
-><P
->Now, sign the certificate request:
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->./CA.pl -sign
- </B
-></TT
->
- Using configuration from openssl.cnf
- Enter PEM pass phrase: <TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->&lt;CA's passphrase&gt;</I
-></TT
-></B
-></TT
->
- Check that the request matches the signature
- Signature ok
- The Subjects Distinguished Name is as follows
- countryName :PRINTABLE:'SG'
- organizationName :PRINTABLE:'M2Crypto'
- commonName :PRINTABLE:'localhost'
- emailAddress :IA5STRING:'admin@server.example.dom'
- Certificate is to be certified until Mar 31 02:57:30 2002 GMT (365 days)
- Sign the certificate? [y/n]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->y</I
-></TT
-></B
-></TT
->
-
-
- 1 out of 1 certificate requests certified, commit? [y/n]<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->y</I
-></TT
-></B
-></TT
->
- Write out database with 1 new entries
- Data Base Updated
- Signed certificate is in newcert.pem
- </PRE
-><P
-><TT
-CLASS="FILENAME"
->newcert.pem</TT
-> looks like this:
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->cat newcert.pem
- </B
-></TT
->
- Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1 (0x1)
- Signature Algorithm: md5WithRSAEncryption
- Issuer: C=SG, O=DemoCA, CN=DemoCA Certificate Master/Email=certmaster@democa.dom
- Validity
- Not Before: Mar 31 02:57:30 2001 GMT
- Not After : Mar 31 02:57:30 2002 GMT
- Subject: C=SG, O=M2Crypto, CN=localhost/Email=admin@server.example.dom
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public Key: (1024 bit)
- Modulus (1024 bit):
- 00:af:59:d8:63:54:2b:96:5d:6b:b8:1f:c5:aa:50:
- 91:ae:be:67:be:ea:5d:20:df:b7:c0:5e:ea:f7:5e:
- 6d:bc:44:28:73:be:1b:9e:ee:9b:f0:86:db:19:13:
- 21:cd:dc:e6:bd:0e:12:cc:57:d5:10:0b:8c:32:e4:
- c7:7b:26:cf:ab:9b:61:ed:80:eb:4c:d8:b3:28:ac:
- 4e:06:7a:84:d8:a6:2e:5f:d5:f6:d8:0d:4a:87:8f:
- 6c:a0:92:45:83:a9:0f:6f:d3:14:82:26:41:88:c9:
- 6f:b5:be:ca:dc:21:df:83:0e:56:6a:05:a7:2e:5f:
- 0b:6f:e7:1c:bc:a6:59:97:ef
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints:
- Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1 (0x1)
- Signature Algorithm: md5WithRSAEncryption
- Issuer: C=SG, O=DemoCA, CN=DemoCA Certificate Master/Email=certmaster@democa.dom
- Validity
- Not Before: Mar 31 02:57:30 2001 GMT
- Not After : Mar 31 02:57:30 2002 GMT
- Subject: C=SG, O=M2Crypto, CN=localhost/Email=admin@server.example.dom
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public Key: (1024 bit)
- Modulus (1024 bit):
- 00:af:59:d8:63:54:2b:96:5d:6b:b8:1f:c5:aa:50:
- 91:ae:be:67:be:ea:5d:20:df:b7:c0:5e:ea:f7:5e:
- 6d:bc:44:28:73:be:1b:9e:ee:9b:f0:86:db:19:13:
- 21:cd:dc:e6:bd:0e:12:cc:57:d5:10:0b:8c:32:e4:
- c7:7b:26:cf:ab:9b:61:ed:80:eb:4c:d8:b3:28:ac:
- 4e:06:7a:84:d8:a6:2e:5f:d5:f6:d8:0d:4a:87:8f:
- 6c:a0:92:45:83:a9:0f:6f:d3:14:82:26:41:88:c9:
- 6f:b5:be:ca:dc:21:df:83:0e:56:6a:05:a7:2e:5f:
- 0b:6f:e7:1c:bc:a6:59:97:ef
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints:
- CA:FALSE
- Netscape Comment:
- OpenSSL Generated Certificate
- X509v3 Subject Key Identifier:
- B3:D6:89:88:2F:B1:15:40:EC:0A:C0:30:35:3A:B7:DA:72:73:1B:4D
- X509v3 Authority Key Identifier:
- keyid:F9:6A:A6:34:97:6B:BC:BB:5A:17:0D:19:FC:62:21:0B:00:B5:0E:29
- DirName:/C=SG/O=DemoCA/CN=DemoCA Certificate Master/Email=certmaster@democa.dom
- serial:00
-
- Signature Algorithm: md5WithRSAEncryption
- </PRE
-></LI
-><LI
-><P
->In certain situations, e.g., where your certificate and
- private key are to be used in an unattended SSL server, you may wish to
- not encrypt the private key, i.e., leave the key in the clear. This
- decision should be governed by your site's security policy and threat
- model, of course.
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->openssl rsa &#60; newkey.pem &#62; newkey2.pem
- </B
-></TT
->
- read RSA key
- Enter PEM pass phrase:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->&lt;secret passphrase here&gt;</I
-></TT
-></B
-></TT
->
- writing RSA key
- </PRE
-><P
-><TT
-CLASS="FILENAME"
->newkey2.pem</TT
-> looks like this:
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->cat newkey2.pem
- </B
-></TT
->
- -----BEGIN RSA PRIVATE KEY-----
- MIICXgIBAAKBgQCvWdhjVCuWXWu4H8WqUJGuvme+6l0g37fAXur3Xm28RChzvhue
- 7pvwhtsZEyHN3Oa9DhLMV9UQC4wy5Md7Js+rm2HtgOtM2LMorE4GeoTYpi5f1fbY
- DUqHj2ygkkWDqQ9v0xSCJkGIyW+1vsrcId+DDlZqBacuXwtv5xy8plmX7wIDAQAB
- AoGAbAkU8w3W1Qu15Hle1bJSL7GMReoreqeblOBmMAZz4by0l6sXZXJpjWXo86f/
- +dASMYTMPC4ZTYtv06N07AFbjL+kDfqDMTfzQkYMHp1LAq1Ihbq1rHWSBH5n3ekq
- KiY8JKpv8DR5Po1iKaXJFuDByGDENJwYbSRSpSK3P+vkWWECQQDkEUE/ZPqqqZkQ
- 2iWRPAsCbEID8SAraQl3DdCLYs/GgARfmmj4yUHEwkys9Jo1H8k4BdxugmaUwNi5
- YQ/CVzrXAkEAxNO80ArbGxPUmr11GHG/bGBYj1DUBkHZSc7dgxZdtUCLGNxQnNsg
- Iwq3n6j1sUzS3UW6abQ8bivYNOUcMKJAqQJBANQxFaLU4b/NQaODQ3aoBZpAfP9L
- 5eFdvbet+7zjt2r5CpikgkwOfAmDuXEltx/8LevY0CllW+nErx9zJgVrwUsCQQCu
- 76H5JiznPBDSF2FjgHWqVVdgyW4owY3mU739LHvNBLicN/RN9VPy0Suy8/CqzKT9
- lWPBXzf2k3FuUdNkRlFBAkEAmpXoybuiFR2S5Bma/ax96lVs0/VihhfC1zZP/X/F
- Br77+h9dIul+2DnyOl50zu0Sdzst1/7ay4JSDHyiBCMGSQ==
- -----END RSA PRIVATE KEY-----
- </PRE
-></LI
-></OL
-></DIV
-><P
->That's it! The certificate, <TT
-CLASS="FILENAME"
->newcert.pem</TT
->, and
- the private key - <TT
-CLASS="FILENAME"
->newkey.pem</TT
-> (encrypted) or
- <TT
-CLASS="FILENAME"
->newkey2.pem</TT
-> (unencrypted) - are now ready to be used.
- You may wish to rename the files to more intuitive names.
- </P
-><P
->You should also keep the CA's certificate <TT
-CLASS="FILENAME"
->demo/cacert.pem
- </TT
-> handy for use when developing and deploying SSL or S/MIME
- applications.
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="CONCLUSION"
->Conclusion</A
-></H1
-><P
->We've walked through the basic steps in the creation of a CA and
- certificates using the tools that come with OpenSSL. We did not cover more
- advanced topics such as constraining a certificate to be SSL-only or
- S/MIME-only.
- </P
-><P
->There exist several HOWTOs similar to this one on the net. This one
- is written specifically to facilitate discussions in my other HOWTOs
- on developing SSL and S/MIME applications in
- <A
-HREF="http://www.python.org"
-TARGET="_top"
->Python</A
-> using
- <A
-HREF="http://chandlerproject.org/Projects/MeTooCrypto"
-TARGET="_top"
->M2Crypto</A
->.
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="ID-KLUDGE"
-></A
-></H1
-><P
-> <TT
-CLASS="LITERAL"
->$Id:howto.ca.html 583 2007-10-01 19:23:12Z heikki $</TT
->
- </P
-></DIV
-></DIV
-></BODY
-></HTML
->
diff --git a/doc/howto.ca.rst b/doc/howto.ca.rst
new file mode 100644
index 0000000..3c6b460
--- /dev/null
+++ b/doc/howto.ca.rst
@@ -0,0 +1,368 @@
+.. _howto-ca:
+
+HOWTO: Creating your own CA with OpenSSL
+########################################
+
+:author: Pheng Siong Ng <ngps@post1.com>
+:copyright: © 2000, 2001 by Ng Pheng Siong.
+
+Introduction
+============
+
+This is a HOWTO on creating your own *certification authority* (*CA*)
+with OpenSSL.
+
+I last created a CA about a year ago, when I began work on
+`M2Crypto <https://gitlab.com/m2crypto/m2crypto/>`__ and needed
+certificates for the SSL bits. I accepted the tools' default
+settings then, e.g., certificate validity of 365 days; this meant
+that my certificates, including my CA's certificate, have now
+expired.
+
+Since I am using these certificates for M2Crypto's demonstration
+programs (and I have forgotten the passphrase to the CA's private
+key), I decided to discard the old CA and start afresh. I also
+decided to document the process, hence this HOWTO.
+
+The Procedure
+=============
+
+I use ``CA.pl``, a Perl program written by Steve Hanson and bundled with
+OpenSSL.
+
+The following are the steps to create a CA:
+
+1. Choose a directory to do your CA work. All commands are executed
+ within this directory. Let's call the directory ``demo``.
+
+2. Copy ``CA.pl`` and ``openssl.cnf`` into ``demo``.
+
+3. Apply the following patch to ``CA.pl``, which allows it to generate a
+ CA certificate with a validity period of 1095 days, i.e.,
+ 3 years::
+
+ --- CA.pl.org Sat Mar 31 12:40:13 2001
+ +++ CA.pl Sat Mar 31 12:41:15 2001
+ @@ -97,7 +97,7 @@
+ } else {
+ print "Making CA certificate ...\n";
+ system ("$REQ -new -x509 -keyout " .
+ - "${CATOP}/private/$CAKEY -out ${CATOP}/$CACERT $DAYS");
+ + "${CATOP}/private/$CAKEY -out ${CATOP}/$CACERT -days 1095");
+ $RET=$?;
+ }
+ }
+
+
+4. Create a new CA like this::
+
+ ./CA.pl -newca
+
+ A certificate filename (or enter to create) <enter>
+
+ Making CA certificate ...
+ Using configuration from openssl.cnf
+ Generating a 1024 bit RSA private key
+ ............++++++
+ ......................++++++
+ writing new private key to './demoCA/private/cakey.pem'
+ Enter PEM pass phrase: <secret passphrase here>
+ Verifying password - Enter PEM pass phrase: <secret passphrase again>
+ -----
+ You are about to be asked to enter information that will be incorporated
+ into your certificate request.
+ What you are about to enter is what is called a Distinguished Name or a DN.
+ There are quite a few fields but you can leave some blank
+ For some fields there will be a default value,
+ If you enter '.', the field will be left blank.
+ -----
+ Country Name (2 letter code) [AU]:SG
+ State or Province Name (full name) [Some-State]:.
+ Locality Name (eg, city) []:..
+ Organization Name (eg, company) [Internet Widgits Pty Ltd]:DemoCA
+ Organizational Unit Name (eg, section) []:.
+ Common Name (eg, YOUR name) []:DemoCA Certificate Master
+ Email Address []:certmaster@democa.dom
+
+ This creates a new CA in the directory ``demoCA``. The CA's
+ self-signed certificate is in ``demoCA/cacert.pem`` and its RSA key
+ pair is in ``demoCA/private/cakey.pem``.
+
+ ``demoCA/private/cakey.pem`` looks like this::
+
+ cat demoCA/private/cakey.pem
+
+ -----BEGIN RSA PRIVATE KEY-----
+ Proc-Type: 4,ENCRYPTED
+ DEK-Info: DES-EDE3-CBC,19973A9DBBB601BA
+
+ eOq9WFScNiI4/UWEUaSnGTKpJv2JYuMD3HwQox2Q3Cd4zGqVjJ6gF3exa5126cKf
+ X/bMVnwbPpuFZPiAIvaLyCjT6pYeXTBbSzs7/GQnvEOv+nYnDUFWi0Qm92qLk0uy
+ pFi/M1aWheN3vir2ZlAw+DW0bOOZhj8tC7Co7lMYb0YE271b6/YRPZCwQ3GXAHUJ
+ +aMYxlUDrK45aCUa/1CZDzTgk7h9cDgx2QJSIvYMYytCfI3zsuZMJS8/4OXLL0bI
+ lKmAc1dwB3DqGJt5XK4WJesiNfdxeCNEgAcYtEAgYZTPIApU+kTgTCIxJl2nMW7j
+ ax+Q1z7g+4MpgG20WD633D4z4dTlDdz+dnLi0rvuvxiwt+dUhrqiML1tyi+Z6EBH
+ jU4/cLBWev3rYfrlp4x8J9mDte0YKOk3t0wQOHqRetTsIfdtjnFp/Hu3qDmTCWjD
+ z/g7PPoO/bg/B877J9WBPbL/1hXXFYo88M+2aGlPOgDcFdiOqbLb2DCscohMbbVr
+ A4mgiy2kwWfIE73qiyV7yyG8FlRvr1iib+jbT3LTGf743utYAAs7HNGuOUObhoyt
+ jYvBD7ACn35P5YX7KTqvqErwdijxYCaNBCnvmRtmYSaNw9Kv1UJTxc5Vx7YLwIPk
+ E9KyBgKI7vPOjWBZ27+zOvNycmv1ciNtpALAw4bWtXnhCDVTHaVDy34OkheMzNCg
+ 2cjcBFzOkMIjcI03KbTQXOFIQGlsTWXGzkNf/zBQ+KksT1MCj+zBXSCvlDASMckg
+ kef21pGgUqPF14gKGfWX3sV4bjc1vbrRwq6zlG3nMuYqR5MtJJY9eQ==
+ -----END RSA PRIVATE KEY-----
+
+
+5. Next, generate a certificate request::
+
+ ./CA.pl -newreq
+
+ Using configuration from openssl.cnf
+ Generating a 1024 bit RSA private key
+ ..........++++++
+ ..............++++++
+ writing new private key to 'newreq.pem'
+ Enter PEM pass phrase: <another secret passphrase here>
+ Verifying password - Enter PEM pass phrase: <another secret passphrase again>
+ -----
+ You are about to be asked to enter information that will be incorporated
+ into your certificate request.
+ What you are about to enter is what is called a Distinguished Name or a DN.
+ There are quite a few fields but you can leave some blank
+ For some fields there will be a default value,
+ If you enter '.', the field will be left blank.
+ -----
+ Country Name (2 letter code) [AU]:SG
+ State or Province Name (full name) [Some-State]:..
+ Locality Name (eg, city) []:.
+ Organization Name (eg, company) [Internet Widgits Pty Ltd]:M2Crypto
+ Organizational Unit Name (eg, section) []:.
+ Common Name (eg, YOUR name) []:localhost
+ Email Address []:admin@server.example.dom
+
+ Please enter the following 'extra' attributes
+ to be sent with your certificate request
+ A challenge password []:<enter>
+ An optional company name []:<enter>
+ Request (and private key) is in newreq.pem
+
+\
+
+ The certificate request and private key in ``newreq.pem`` looks like
+ this::
+
+ cat newreq.pem
+
+ -----BEGIN RSA PRIVATE KEY-----
+ Proc-Type: 4,ENCRYPTED
+ DEK-Info: DES-EDE3-CBC,41B2874DF3D02DD4
+
+ mg611EoVkLEooSTv+qTM0Ddmm/M1jE/Jy5RD/sc3LSMhuGu9xc26OgsTJmkQuIAh
+ J/B4lAw8G59VTG6DykeEtrG0rUBx4bggc7PKbFuiN423YjJODWcHvVgnPOzXMQt+
+ lY4tPl5+217MRHyx2NsWGrpkQNdu3GeSPOVMl3jeQiaXupONbwQ7rj42+X/VtAJP
+ W4D1NNwu8aGCPyShsEXHc/fI1WDpphYWke97pOjIZVQESFZOPty5HjIYZux4U+td
+ W81xODtq2ecJXc8fn2Wpa9y5VD1LT7oJksOuL1+Z04OVaeUe4x0swM17HlBm2kVt
+ fe/C/L6kN27MwZhE331VjtTjSGl4/gknqQDbLOtqT06f3OISsDJETm2itllyhgzv
+ C6Fi3N03rGFmKectijC+tws5k+P+HRG6sai33usk8xPokJqA+HYSWPz1XVlpRmv4
+ kdjQOdST7ovU62mOTgf3ARcduPPwuzTfxOlYONe5NioO1APVHBrInQwcpLkpOTQR
+ vI4roIN+b75/nihUWGUJn/nbbBa2Yl0N5Gs1Tyiy9Z+CcRT2TfWKBBFlEUIFl7Mb
+ J9fTV3DI+k+akbR4il1NkQ8EcSmCr3WpA0I9n0EHI7ZVpVaHxc0sqaPFl8YGdFHq
+ 1Qk53C/w6+qPpDzT3yKFmG2LZytAAM1czvb6RbNRJJP2ZrpBwn/h99sUTo/yPfxY
+ nueYmFJDm0uVNtG0icXGNUfSfnjKNTtHPAgyKGetRIC3kgJz/bo2w7EI6iEjBAzK
+ l5TRm4x6ZJxwuXXMiJCehMMd8TC8ybwWO4AO19B3ebFFeTVsUgxSGA==
+ -----END RSA PRIVATE KEY-----
+ -----BEGIN CERTIFICATE REQUEST-----
+ MIIBnTCCAQYCAQAwXTELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIw
+ EAYDVQQDEwlsb2NhbGhvc3QxJzAlBgkqhkiG9w0BCQEWGGFkbWluQHNlcnZlci5l
+ eGFtcGxlLmRvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAr1nYY1Qrll1r
+ uB/FqlCRrr5nvupdIN+3wF7q915tvEQoc74bnu6b8IbbGRMhzdzmvQ4SzFfVEAuM
+ MuTHeybPq5th7YDrTNizKKxOBnqE2KYuX9X22A1Kh49soJJFg6kPb9MUgiZBiMlv
+ tb7K3CHfgw5WagWnLl8Lb+ccvKZZl+8CAwEAAaAAMA0GCSqGSIb3DQEBBAUAA4GB
+ AHpoRp5YS55CZpy+wdigQEwjL/wSluvo+WjtpvP0YoBMJu4VMKeZi405R7o8oEwi
+ PdlrrliKNknFmHKIaCKTLRcU59ScA6ADEIWUzqmUzP5Cs6jrSRo3NKfg1bd09D1K
+ 9rsQkRc9Urv9mRBIsredGnYECNeRaK5R1yzpOowninXC
+ -----END CERTIFICATE REQUEST-----
+
+\
+
+ Decoding the certificate request gives the following::
+
+ openssl req -text -noout < newreq.pem
+
+ Using configuration from /usr/local/pkg/openssl/openssl.cnf
+ Certificate Request:
+ Data:
+ Version: 0 (0x0)
+ Subject: C=SG, O=M2Crypto, CN=localhost/Email=admin@server.example.dom
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:af:59:d8:63:54:2b:96:5d:6b:b8:1f:c5:aa:50:
+ 91:ae:be:67:be:ea:5d:20:df:b7:c0:5e:ea:f7:5e:
+ 6d:bc:44:28:73:be:1b:9e:ee:9b:f0:86:db:19:13:
+ 21:cd:dc:e6:bd:0e:12:cc:57:d5:10:0b:8c:32:e4:
+ c7:7b:26:cf:ab:9b:61:ed:80:eb:4c:d8:b3:28:ac:
+ 4e:06:7a:84:d8:a6:2e:5f:d5:f6:d8:0d:4a:87:8f:
+ 6c:a0:92:45:83:a9:0f:6f:d3:14:82:26:41:88:c9:
+ 6f:b5:be:ca:dc:21:df:83:0e:56:6a:05:a7:2e:5f:
+ 0b:6f:e7:1c:bc:a6:59:97:ef
+ Exponent: 65537 (0x10001)
+ Attributes:
+ a0:00
+ Signature Algorithm: md5WithRSAEncryption
+ 7a:68:46:9e:58:4b:9e:42:66:9c:be:c1:d8:a0:40:4c:23:2f:
+ fc:12:96:eb:e8:f9:68:ed:a6:f3:f4:62:80:4c:26:ee:15:30:
+ a7:99:8b:8d:39:47:ba:3c:a0:4c:22:3d:d9:6b:ae:58:8a:36:
+ 49:c5:98:72:88:68:22:93:2d:17:14:e7:d4:9c:03:a0:03:10:
+ 85:94:ce:a9:94:cc:fe:42:b3:a8:eb:49:1a:37:34:a7:e0:d5:
+ b7:74:f4:3d:4a:f6:bb:10:91:17:3d:52:bb:fd:99:10:48:b2:
+ b7:9d:1a:76:04:08:d7:91:68:ae:51:d7:2c:e9:3a:8c:27:8a:
+ 75:c2
+
+6. Now, sign the certificate request::
+
+ ./CA.pl -sign
+
+ Using configuration from openssl.cnf
+ Enter PEM pass phrase: <CA's passphrase>
+ Check that the request matches the signature
+ Signature ok
+ The Subjects Distinguished Name is as follows
+ countryName :PRINTABLE:'SG'
+ organizationName :PRINTABLE:'M2Crypto'
+ commonName :PRINTABLE:'localhost'
+ emailAddress :IA5STRING:'admin@server.example.dom'
+ Certificate is to be certified until Mar 31 02:57:30 2002 GMT (365 days)
+ Sign the certificate? [y/n]:y
+
+
+ 1 out of 1 certificate requests certified, commit? [y/n]y
+ Write out database with 1 new entries
+ Data Base Updated
+ Signed certificate is in newcert.pem
+
+\
+
+ ``newcert.pem`` looks like this::
+
+ cat newcert.pem
+
+ Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: C=SG, O=DemoCA, CN=DemoCA Certificate Master/Email=certmaster@democa.dom
+ Validity
+ Not Before: Mar 31 02:57:30 2001 GMT
+ Not After : Mar 31 02:57:30 2002 GMT
+ Subject: C=SG, O=M2Crypto, CN=localhost/Email=admin@server.example.dom
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:af:59:d8:63:54:2b:96:5d:6b:b8:1f:c5:aa:50:
+ 91:ae:be:67:be:ea:5d:20:df:b7:c0:5e:ea:f7:5e:
+ 6d:bc:44:28:73:be:1b:9e:ee:9b:f0:86:db:19:13:
+ 21:cd:dc:e6:bd:0e:12:cc:57:d5:10:0b:8c:32:e4:
+ c7:7b:26:cf:ab:9b:61:ed:80:eb:4c:d8:b3:28:ac:
+ 4e:06:7a:84:d8:a6:2e:5f:d5:f6:d8:0d:4a:87:8f:
+ 6c:a0:92:45:83:a9:0f:6f:d3:14:82:26:41:88:c9:
+ 6f:b5:be:ca:dc:21:df:83:0e:56:6a:05:a7:2e:5f:
+ 0b:6f:e7:1c:bc:a6:59:97:ef
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: C=SG, O=DemoCA, CN=DemoCA Certificate Master/Email=certmaster@democa.dom
+ Validity
+ Not Before: Mar 31 02:57:30 2001 GMT
+ Not After : Mar 31 02:57:30 2002 GMT
+ Subject: C=SG, O=M2Crypto, CN=localhost/Email=admin@server.example.dom
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:af:59:d8:63:54:2b:96:5d:6b:b8:1f:c5:aa:50:
+ 91:ae:be:67:be:ea:5d:20:df:b7:c0:5e:ea:f7:5e:
+ 6d:bc:44:28:73:be:1b:9e:ee:9b:f0:86:db:19:13:
+ 21:cd:dc:e6:bd:0e:12:cc:57:d5:10:0b:8c:32:e4:
+ c7:7b:26:cf:ab:9b:61:ed:80:eb:4c:d8:b3:28:ac:
+ 4e:06:7a:84:d8:a6:2e:5f:d5:f6:d8:0d:4a:87:8f:
+ 6c:a0:92:45:83:a9:0f:6f:d3:14:82:26:41:88:c9:
+ 6f:b5:be:ca:dc:21:df:83:0e:56:6a:05:a7:2e:5f:
+ 0b:6f:e7:1c:bc:a6:59:97:ef
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ B3:D6:89:88:2F:B1:15:40:EC:0A:C0:30:35:3A:B7:DA:72:73:1B:4D
+ X509v3 Authority Key Identifier:
+ keyid:F9:6A:A6:34:97:6B:BC:BB:5A:17:0D:19:FC:62:21:0B:00:B5:0E:29
+ DirName:/C=SG/O=DemoCA/CN=DemoCA Certificate Master/Email=certmaster@democa.dom
+ serial:00
+
+ Signature Algorithm: md5WithRSAEncryption
+
+7. In certain situations, e.g., where your certificate and private key
+ are to be used in an unattended SSL server, you may wish to not
+ encrypt the private key, i.e., leave the key in the clear. This
+ decision should be governed by your site's security policy and threat
+ model, of course::
+
+ openssl rsa < newkey.pem > newkey2.pem
+
+ read RSA key
+ Enter PEM pass phrase:<secret passphrase here>
+ writing RSA key
+
+ ``newkey2.pem`` looks like this::
+
+ cat newkey2.pem
+
+ -----BEGIN RSA PRIVATE KEY-----
+ MIICXgIBAAKBgQCvWdhjVCuWXWu4H8WqUJGuvme+6l0g37fAXur3Xm28RChzvhue
+ 7pvwhtsZEyHN3Oa9DhLMV9UQC4wy5Md7Js+rm2HtgOtM2LMorE4GeoTYpi5f1fbY
+ DUqHj2ygkkWDqQ9v0xSCJkGIyW+1vsrcId+DDlZqBacuXwtv5xy8plmX7wIDAQAB
+ AoGAbAkU8w3W1Qu15Hle1bJSL7GMReoreqeblOBmMAZz4by0l6sXZXJpjWXo86f/
+ +dASMYTMPC4ZTYtv06N07AFbjL+kDfqDMTfzQkYMHp1LAq1Ihbq1rHWSBH5n3ekq
+ KiY8JKpv8DR5Po1iKaXJFuDByGDENJwYbSRSpSK3P+vkWWECQQDkEUE/ZPqqqZkQ
+ 2iWRPAsCbEID8SAraQl3DdCLYs/GgARfmmj4yUHEwkys9Jo1H8k4BdxugmaUwNi5
+ YQ/CVzrXAkEAxNO80ArbGxPUmr11GHG/bGBYj1DUBkHZSc7dgxZdtUCLGNxQnNsg
+ Iwq3n6j1sUzS3UW6abQ8bivYNOUcMKJAqQJBANQxFaLU4b/NQaODQ3aoBZpAfP9L
+ 5eFdvbet+7zjt2r5CpikgkwOfAmDuXEltx/8LevY0CllW+nErx9zJgVrwUsCQQCu
+ 76H5JiznPBDSF2FjgHWqVVdgyW4owY3mU739LHvNBLicN/RN9VPy0Suy8/CqzKT9
+ lWPBXzf2k3FuUdNkRlFBAkEAmpXoybuiFR2S5Bma/ax96lVs0/VihhfC1zZP/X/F
+ Br77+h9dIul+2DnyOl50zu0Sdzst1/7ay4JSDHyiBCMGSQ==
+ -----END RSA PRIVATE KEY-----
+
+
+That's it! The certificate, ``newcert.pem``, and the private key -
+``newkey.pem`` (encrypted) or ``newkey2.pem`` (unencrypted) - are now
+ready to be used. You may wish to rename the files to more intuitive
+names.
+
+You should also keep the CA's certificate ``demo/cacert.pem`` handy
+for use when developing and deploying SSL or S/MIME applications.
+
+Conclusion
+==========
+
+We've walked through the basic steps in the creation of a CA and
+certificates using the tools that come with OpenSSL. We did not cover
+more advanced topics such as constraining a certificate to be SSL-only
+or S/MIME-only.
+
+There exist several HOWTOs similar to this one on the net. This one is
+written specifically to facilitate discussions in my other HOWTOs on
+developing SSL and S/MIME applications in
+`Python <http://www.python.org>`__ using
+`M2Crypto <https://gitlab.com/m2crypto/m2crypto/>`__.
+
diff --git a/doc/howto.smime.html b/doc/howto.smime.html
deleted file mode 100644
index 00c5346..0000000
--- a/doc/howto.smime.html
+++ /dev/null
@@ -1,1573 +0,0 @@
-<HTML
-><HEAD
-><TITLE
->HOWTO: Programming S/MIME in Python with M2Crypto</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.64
-"></HEAD
-><BODY
-CLASS="ARTICLE"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="ARTICLE"
-><DIV
-CLASS="TITLEPAGE"
-><H1
-CLASS="TITLE"
-><A
-NAME="AEN2"
->HOWTO: Programming S/MIME in Python with M2Crypto</A
-></H1
-><H3
-CLASS="AUTHOR"
-><A
-NAME="AEN4"
->Pheng Siong Ng</A
-></H3
-><DIV
-CLASS="AFFILIATION"
-><DIV
-CLASS="ADDRESS"
-><P
-CLASS="ADDRESS"
->ngps@post1.com</P
-></DIV
-></DIV
-><P
-CLASS="COPYRIGHT"
->Copyright &copy; 2000, 2001 by Ng Pheng Siong.</P
-><DIV
-CLASS="REVHISTORY"
-><TABLE
-WIDTH="100%"
-BORDER="0"
-><TR
-><TH
-ALIGN="LEFT"
-VALIGN="TOP"
-COLSPAN="3"
-><B
->Revision History</B
-></TH
-></TR
-><TR
-><TD
-ALIGN="LEFT"
->Revision $Id$</TD
-><TD
-ALIGN="LEFT"
-></TD
-><TD
-ALIGN="LEFT"
-></TD
-></TR
-><TR
-><TD
-ALIGN="LEFT"
-COLSPAN="3"
-></TD
-></TR
-></TABLE
-></DIV
-><HR></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="INTRODUCTION"
->Introduction</A
-></H1
-><P
-><A
-HREF="http://chandlerproject.org/Projects/MeTooCrypto"
-TARGET="_top"
->M2Crypto</A
->
- is a <A
-HREF="http://www.python.org"
-TARGET="_top"
->Python</A
->
- interface to <A
-HREF="http://www.openssl.org"
-TARGET="_top"
->OpenSSL</A
->. It makes
- available to the Python programmer SSL functionality to implement clients
- and servers, S/MIME v2, RSA, DSA, DH, symmetric ciphers, message digests and
- HMACs.
- </P
-><P
->This document demonstrates programming S/MIME with M2Crypto.
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="SMIME"
->S/MIME</A
-></H1
-><P
->S/MIME - Secure Multipurpose Internet Mail Extensions
- [<SPAN
-CLASS="CITATION"
->RFC 2311, RFC 2312</SPAN
->] - provides a
- consistent way to send and receive secure MIME data. Based on the popular
- Internet MIME standard, S/MIME provides the following cryptographic security
- services for electronic messaging applications -
- <I
-CLASS="EMPHASIS"
->authentication</I
->, <I
-CLASS="EMPHASIS"
->message integrity </I
->
- and <I
-CLASS="EMPHASIS"
->non-repudiation of origin </I
-> (using <I
-CLASS="EMPHASIS"
->digital
- signatures</I
->), and <I
-CLASS="EMPHASIS"
->privacy </I
-> and <I
-CLASS="EMPHASIS"
->data
- security</I
-> (using <I
-CLASS="EMPHASIS"
->encryption</I
->).
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="KEYS-AND-CERTIFICATES"
->Keys and Certificates</A
-></H1
-><P
->To create an S/MIME-signed message, you need an RSA key pair
- (this consists of a public key and a private key) and an X.509
- certificate of said public key.
- </P
-><P
->To create an S/MIME-encrypted message, you need an X.509
- certificate for each recipient.
- </P
-><P
->To create an S/MIME-signed <I
-CLASS="EMPHASIS"
->and</I
-> -encrypted
- message, first create a signed message, then encrypt the signed
- message with the recipients' certificates.
- </P
-><P
->You may generate key pairs and obtain certificates by using a
- commercial <I
-CLASS="EMPHASIS"
->certification authority</I
-> service.
- </P
-><P
->You can also do so using freely-available software. For many
- purposes, e.g., automated S/MIME messaging by system administration
- processes, this approach is cheap and effective.
- </P
-><P
->We now work through using OpenSSL to generate key pairs and
- certificates. This assumes you have OpenSSL installed properly on your
- system.
- </P
-><P
->First, we generate an X.509 certificate to be used for signing:
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->openssl req -newkey rsa:1024 -nodes -x509 -days 365 -out signer.pem
- </B
-></TT
->
- Using configuration from /usr/local/pkg/openssl/openssl.cnf
- Generating a 1024 bit RSA private key
- ..++++++
- ....................++++++
- writing new private key to 'privkey.pem'
- -----
- You are about to be asked to enter information that will be incorporated
- into your certificate request.
- What you are about to enter is what is called a Distinguished Name or a DN.
- There are quite a few fields but you can leave some blank
- For some fields there will be a default value,
- If you enter '.', the field will be left blank.
- -----
- Country Name (2 letter code) [AU]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->SG</I
-></TT
-></B
-></TT
->
- State or Province Name (full name) [Some-State]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->
- Locality Name (eg, city) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->
- Organization Name (eg, company) [Internet Widgits Pty Ltd]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->M2Crypto</I
-></TT
-></B
-></TT
->
- Organizational Unit Name (eg, section) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->
- Common Name (eg, YOUR name) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->S/MIME Sender</I
-></TT
-></B
-></TT
->
- Email Address []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->sender@example.dom</I
-></TT
-></B
-></TT
->
- </PRE
-><P
->This generates a 1024-bit RSA key pair, unencrypted, into
- <TT
-CLASS="FILENAME"
->privkey.pem</TT
->; it also generates a self-signed X.509
- certificate for the public key into <TT
-CLASS="FILENAME"
->signer.pem</TT
->. The
- certificate is valid for 365 days, i.e., a year.
- </P
-><P
->Let's rename <TT
-CLASS="FILENAME"
->privkey.pem</TT
-> so that we know it is
- a companion of <TT
-CLASS="FILENAME"
->signer.pem</TT
->'s:
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->mv privkey.pem signer_key.pem</B
-></TT
->
- </PRE
-><P
->To verify the content of <TT
-CLASS="FILENAME"
->signer.pem</TT
->, execute the
- following:
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->openssl x509 -noout -text -in signer.pem
- </B
-></TT
->
- Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 0 (0x0)
- Signature Algorithm: md5WithRSAEncryption
- Issuer: C=SG, O=M2Crypto, CN=S/MIME Sender/Email=sender@example.dom
- Validity
- Not Before: Mar 24 12:56:16 2001 GMT
- Not After : Mar 24 12:56:16 2002 GMT
- Subject: C=SG, O=M2Crypto, CN=S/MIME Sender/Email=sender@example.dom
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public Key: (1024 bit)
- Modulus (1024 bit):
- 00:a9:d6:e2:b5:11:3b:ae:3c:e2:17:31:70:e1:6e:
- 01:f4:19:6d:bd:2a:42:36:2b:37:34:e2:83:1d:0d:
- 11:2e:b4:99:44:db:10:67:be:97:5f:5b:1a:26:33:
- 46:23:2f:95:04:7a:35:da:9d:f9:26:88:39:9e:17:
- cd:3e:eb:a8:19:8d:a8:2a:f1:43:da:55:a9:2e:2c:
- 65:ed:04:71:42:ce:73:53:b8:ea:7e:c7:f0:23:c6:
- 63:c5:5e:68:96:64:a7:b4:2a:94:26:76:eb:79:ea:
- e3:4e:aa:82:09:4f:44:87:4a:12:62:b5:d7:1f:ca:
- f2:ce:d5:ba:7e:1f:48:fd:b9
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Subject Key Identifier:
- 29:FB:38:B6:BF:E2:40:BB:FF:D5:71:D7:D5:C4:F0:83:1A:2B:C7:99
- X509v3 Authority Key Identifier:
- keyid:29:FB:38:B6:BF:E2:40:BB:FF:D5:71:D7:D5:C4:F0:83:1A:2B:C7:99
- DirName:/C=SG/O=M2Crypto/CN=S/MIME Sender/Email=sender@example.dom
- serial:00
-
- X509v3 Basic Constraints:
- CA:TRUE
- Signature Algorithm: md5WithRSAEncryption
- 68:c8:6b:1b:fa:7c:9a:39:35:76:18:15:c9:fd:89:97:62:db:
- 7a:b0:2d:13:dd:97:e8:1b:7a:9f:22:27:83:24:9d:2e:56:ec:
- 97:89:3c:ef:16:55:80:5a:18:7c:22:d0:f6:bb:e3:a4:e8:59:
- 30:ff:99:5a:93:3e:ea:bc:ee:7f:8d:d6:7d:37:8c:ac:3d:74:
- 80:ce:7a:99:ba:27:b9:2a:a3:71:fa:a5:25:ba:47:17:df:07:
- 56:96:36:fd:60:b9:6c:96:06:e8:e3:7b:9f:4b:6a:95:71:a8:
- 34:fc:fc:b5:88:8b:c4:3f:1e:24:f6:52:47:b2:7d:44:67:d9:
- 83:e8
- </PRE
-><P
->Next, we generate a self-signed X.509 certificate for the
- recipient. Note that <TT
-CLASS="FILENAME"
->privkey.pem</TT
-> will be
- recreated.
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->openssl req -newkey rsa:1024 -nodes -x509 -days 365 -out recipient.pem
- </B
-></TT
->
- Using configuration from /usr/local/pkg/openssl/openssl.cnf
- Generating a 1024 bit RSA private key
- .....................................++++++
- .................++++++
- writing new private key to 'privkey.pem'
- -----
- You are about to be asked to enter information that will be incorporated
- into your certificate request.
- What you are about to enter is what is called a Distinguished Name or a DN.
- There are quite a few fields but you can leave some blank
- For some fields there will be a default value,
- If you enter '.', the field will be left blank.
- -----
- Country Name (2 letter code) [AU]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->SG</I
-></TT
-></B
-></TT
->
- State or Province Name (full name) [Some-State]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->
- Locality Name (eg, city) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->
- Organization Name (eg, company) [Internet Widgits Pty Ltd]:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->M2Crypto</I
-></TT
-></B
-></TT
->
- Organizational Unit Name (eg, section) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->.</I
-></TT
-></B
-></TT
->
- Common Name (eg, YOUR name) []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->S/MIME Recipient</I
-></TT
-></B
-></TT
->
- Email Address []:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->recipient@example.dom</I
-></TT
-></B
-></TT
->
- </PRE
-><P
->Again, rename <TT
-CLASS="FILENAME"
->privkey.pem</TT
->:
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->mv privkey.pem recipient_key.pem</B
-></TT
->
- </PRE
-><P
->In the examples to follow, S/MIME Sender,
- <TT
-CLASS="EMAIL"
->&#60;<A
-HREF="mailto:sender@example.dom"
->sender@example.dom</A
->&#62;</TT
->, shall be the sender of S/MIME messages,
- while S/MIME Recipient, <TT
-CLASS="EMAIL"
->&#60;<A
-HREF="mailto:recipient@example.dom"
->recipient@example.dom</A
->&#62;</TT
->, shall be the
- recipient of S/MIME messages.
- </P
-><P
->Armed with the key pairs and certificates, we are now ready to begin
- programming S/MIME in Python.
- </P
-><DIV
-CLASS="NOTE"
-><BLOCKQUOTE
-CLASS="NOTE"
-><P
-><B
->Note: </B
->The private keys generated above are
- <I
-CLASS="EMPHASIS"
->not passphrase-protected</I
->, i.e., they are
- <I
-CLASS="EMPHASIS"
->in the clear</I
->. Anyone who has access to such a key can
- generate S/MIME-signed messages with it, and decrypt S/MIME messages
- encrypted to it's corresponding public key.
- </P
-><P
->We may passphrase-protect the keys, if we so choose. M2Crypto will
- prompt the user for the passphrase when such a key is being loaded.
- </P
-></BLOCKQUOTE
-></DIV
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="M2CRYPTO-SMIME"
->M2Crypto.SMIME</A
-></H1
-><P
->The Python programmer accesses M2Crypto's S/MIME functionality
- through class <TT
-CLASS="CLASSNAME"
->SMIME</TT
-> in the module
- <TT
-CLASS="CLASSNAME"
->M2Crypto.SMIME</TT
->. Typically, an <TT
-CLASS="CLASSNAME"
->SMIME</TT
->
- object is instantiated; the object is then set up for the intended
- operation: sign, encrypt, decrypt or verify; finally, the operation is invoked on
- the object.
- </P
-><P
-><TT
-CLASS="CLASSNAME"
->M2Crypto.SMIME</TT
-> makes extensive use of
- <TT
-CLASS="CLASSNAME"
->M2Crypto.BIO</TT
->: <TT
-CLASS="CLASSNAME"
->M2Crypto.BIO</TT
->
- is a Python abstraction of the <TT
-CLASS="CLASSNAME"
->BIO</TT
-> abstraction in
- OpenSSL. A commonly used <TT
-CLASS="CLASSNAME"
->BIO</TT
-> abstraction in M2Crypto is
- <TT
-CLASS="CLASSNAME"
->M2Crypto.BIO.MemoryBuffer</TT
->, which implements a
- memory-based file-like object, similar to Python's own
- <TT
-CLASS="CLASSNAME"
->StringIO</TT
->.
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="SIGN"
->Sign</A
-></H1
-><P
->The following code demonstrates how to generate an S/MIME-signed
- message. <TT
-CLASS="FILENAME"
->randpool.dat</TT
-> contains random data which is
- used to seed OpenSSL's pseudo-random number generator via M2Crypto.
- </P
-><PRE
-CLASS="PROGRAMLISTING"
-> from M2Crypto import BIO, Rand, SMIME
-
- def makebuf(text):
- return BIO.MemoryBuffer(text)
-
- # Make a MemoryBuffer of the message.
- buf = makebuf('a sign of our times')
-
- # Seed the PRNG.
- Rand.load_file('randpool.dat', -1)
-
- # Instantiate an SMIME object; set it up; sign the buffer.
- s = SMIME.SMIME()
- s.load_key('signer_key.pem', 'signer.pem')
- p7 = s.sign(buf, SMIME.PKCS7_DETACHED)
- </PRE
-><P
-><TT
-CLASS="VARNAME"
->p7</TT
-> now contains a <I
-CLASS="EMPHASIS"
->PKCS #7 signature
- blob</I
-> wrapped in an <TT
-CLASS="CLASSNAME"
->M2Crypto.SMIME.PKCS7</TT
->
- object. Note that <TT
-CLASS="VARNAME"
->buf</TT
-> has been consumed by
- <TT
-CLASS="FUNCTION"
->sign()</TT
-> and has to be recreated if it is to be used
- again.
- </P
-><P
->We may now send the signed message via SMTP. In these examples, we
- shall not do so; instead, we'll render the S/MIME output in
- mail-friendly format, and pretend that our messages are sent and
- received correctly.
- </P
-><PRE
-CLASS="PROGRAMLISTING"
-> # Recreate buf.
- buf = makebuf('a sign of our times')
-
- # Output p7 in mail-friendly format.
- out = BIO.MemoryBuffer()
- out.write('From: sender@example.dom\n')
- out.write('To: recipient@example.dom\n')
- out.write('Subject: M2Crypto S/MIME testing\n')
- s.write(out, p7, buf)
-
- print(out.read())
-
- # Save the PRNG's state.
- Rand.save_file('randpool.dat')
- </PRE
-><P
->Here's the output:
- </P
-><PRE
-CLASS="SCREEN"
-> From: sender@example.dom
- To: recipient@example.dom
- Subject: M2Crypto S/MIME testing
- MIME-Version: 1.0
- Content-Type: multipart/signed ; protocol="application/x-pkcs7-signature" ; micalg=sha1 ; boundary="----3C93156FC7B4EBF49FE9C7DB7F503087"
-
- This is an S/MIME signed message
-
- ------3C93156FC7B4EBF49FE9C7DB7F503087
- a sign of our times
- ------3C93156FC7B4EBF49FE9C7DB7F503087
- Content-Type: application/x-pkcs7-signature; name="smime.p7s"
- Content-Transfer-Encoding: base64
- Content-Disposition: attachment; filename="smime.p7s"
-
- MIIE8AYJKoZIhvcNAQcCoIIE4TCCBN0CAQExCzAJBgUrDgMCGgUAMCIGCSqGSIb3
- DQEHAaAVBBNhIHNpZ24gb2Ygb3VyIHRpbWVzoIIC5zCCAuMwggJMoAMCAQICAQAw
- DQYJKoZIhvcNAQEEBQAwWzELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRv
- MRYwFAYDVQQDEw1TL01JTUUgU2VuZGVyMSEwHwYJKoZIhvcNAQkBFhJzZW5kZXJA
- ZXhhbXBsZS5kb20wHhcNMDEwMzMxMTE0MDMzWhcNMDIwMzMxMTE0MDMzWjBbMQsw
- CQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlwdG8xFjAUBgNVBAMTDVMvTUlNRSBT
- ZW5kZXIxITAfBgkqhkiG9w0BCQEWEnNlbmRlckBleGFtcGxlLmRvbTCBnzANBgkq
- hkiG9w0BAQEFAAOBjQAwgYkCgYEA5c5Tj1CHTSOxa1q2q0FYiwMWYHptJpJcvtZm
- UwrgU5sHrA8OnCM0cDXEj0KPf3cfNjHffB8HWMzI4UEgNmFXQNsxoGZ+iqwxLlNj
- y9Mh7eFW/Bjq5hNXbouSlQ0rWBRkoxV64y+t6lQehb32WfYXQbKFxFJSXzSxOx3R
- 8YhSPd0CAwEAAaOBtjCBszAdBgNVHQ4EFgQUXOyolL1t4jaBwZFRM7MS8nBLzUow
- gYMGA1UdIwR8MHqAFFzsqJS9beI2gcGRUTOzEvJwS81KoV+kXTBbMQswCQYDVQQG
- EwJTRzERMA8GA1UEChMITTJDcnlwdG8xFjAUBgNVBAMTDVMvTUlNRSBTZW5kZXIx
- ITAfBgkqhkiG9w0BCQEWEnNlbmRlckBleGFtcGxlLmRvbYIBADAMBgNVHRMEBTAD
- AQH/MA0GCSqGSIb3DQEBBAUAA4GBAHo3DrCHR86fSTVAvfiXdSswWqKtCEhUHRdC
- TLFGl4hDk2GyZxaFuqZwiURz/H7nMicymI2wkz8H/wyHFg8G3BIehURpj2v/ZWXY
- eovbgS7EZALVVkDj4hNl/IIHWd6Gtv1UODf7URbxtl3hQ9/eTWITrefT1heuPnar
- 8czydsOLMYIBujCCAbYCAQEwYDBbMQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJD
- cnlwdG8xFjAUBgNVBAMTDVMvTUlNRSBTZW5kZXIxITAfBgkqhkiG9w0BCQEWEnNl
- bmRlckBleGFtcGxlLmRvbQIBADAJBgUrDgMCGgUAoIGxMBgGCSqGSIb3DQEJAzEL
- BgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTAxMDMzMTExNDUwMlowIwYJKoZI
- hvcNAQkEMRYEFOoeRUd8ExIYXfQq8BTFuKWrSP3iMFIGCSqGSIb3DQEJDzFFMEMw
- CgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFAMAcGBSsO
- AwIHMA0GCCqGSIb3DQMCAgEoMA0GCSqGSIb3DQEBAQUABIGAQpU8hFUtLCF6hO2t
- ec9EYJ/Imqqiiw+BxWxkUUVT81Vbjwdn9JST6+sztM5JRP2ZW+b4txEjZriYC8f3
- kv95YMTGbIsuWkJ93GrbvqoJ/CxO23r9WWRnZEm/1EZN9ZmlrYqzBTxnNRmP3Dhj
- cW8kzZwH+2/2zz2G7x1HxRWH95A=
-
- ------3C93156FC7B4EBF49FE9C7DB7F503087--
- </PRE
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="VERIFY"
->Verify</A
-></H1
-><P
->Assume the above output has been saved into <TT
-CLASS="FILENAME"
->sign.p7</TT
->.
- Let's now verify the signature:
- </P
-><PRE
-CLASS="PROGRAMLISTING"
-> from M2Crypto import SMIME, X509
-
- # Instantiate an SMIME object.
- s = SMIME.SMIME()
-
- # Load the signer's cert.
- x509 = X509.load_cert('signer.pem')
- sk = X509.X509_Stack()
- sk.push(x509)
- s.set_x509_stack(sk)
-
- # Load the signer's CA cert. In this case, because the signer's
- # cert is self-signed, it is the signer's cert itself.
- st = X509.X509_Store()
- st.load_info('signer.pem')
- s.set_x509_store(st)
-
- # Load the data, verify it.
- p7, data = SMIME.smime_load_pkcs7('sign.p7')
- v = s.verify(p7, data)
- print(v)
- print(data)
- print(data.read())
- </PRE
-><P
->Here's the output of the above program:
- </P
-><PRE
-CLASS="SCREEN"
-> a sign of our times
- &lt;M2Crypto.BIO.BIO instance at 0x822012c&gt;
- a sign of our times
- </PRE
-><P
->Suppose, instead of loading <TT
-CLASS="FILENAME"
->signer.pem</TT
-> above,
- we load <TT
-CLASS="FILENAME"
->recipient.pem</TT
->. That is, we do a global
- substitution of <TT
-CLASS="LITERAL"
->recipient.pem</TT
-> for
- <TT
-CLASS="LITERAL"
->signer.pem</TT
-> in the above program. Here's the modified
- program's output:
- </P
-><PRE
-CLASS="SCREEN"
-> Traceback (most recent call last):
- File "./verify.py", line 22, in ?
- v = s.verify(p7)
- File "/usr/local/home/ngps/prog/m2/M2Crypto/SMIME.py", line 205, in verify
- raise SMIME_Error, Err.get_error()
- M2Crypto.SMIME.SMIME_Error: 312:error:21075075:PKCS7 routines:PKCS7_verify:certificate verify error:pk7_smime.c:213:Verify error:self signed certificate
- </PRE
-><P
->As displayed, the error is generated by line 213 of OpenSSL's
- <TT
-CLASS="FILENAME"
->pk7_smime.c</TT
-> (as of OpenSSL 0.9.6); if you are a
- C programmer, you may wish to look up the C source to explore OpenSSL's
- S/MIME implementation and understand why the error message is worded thus.
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="ENCRYPT"
->Encrypt</A
-></H1
-><P
->We now demonstrate how to generate an S/MIME-encrypted message:
- </P
-><PRE
-CLASS="PROGRAMLISTING"
-> from M2Crypto import BIO, Rand, SMIME, X509
-
- def makebuf(text):
- return BIO.MemoryBuffer(text)
-
- # Make a MemoryBuffer of the message.
- buf = makebuf('a sign of our times')
-
- # Seed the PRNG.
- Rand.load_file('randpool.dat', -1)
-
- # Instantiate an SMIME object.
- s = SMIME.SMIME()
-
- # Load target cert to encrypt to.
- x509 = X509.load_cert('recipient.pem')
- sk = X509.X509_Stack()
- sk.push(x509)
- s.set_x509_stack(sk)
-
- # Set cipher: 3-key triple-DES in CBC mode.
- s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
-
- # Encrypt the buffer.
- p7 = s.encrypt(buf)
-
- # Output p7 in mail-friendly format.
- out = BIO.MemoryBuffer()
- out.write('From: sender@example.dom\n')
- out.write('To: recipient@example.dom\n')
- out.write('Subject: M2Crypto S/MIME testing\n')
- s.write(out, p7)
-
- print(out.read())
-
- # Save the PRNG's state.
- Rand.save_file('randpool.dat')
- </PRE
-><P
->Here's the output of the above program:
- </P
-><PRE
-CLASS="SCREEN"
-> From: sender@example.dom
- To: recipient@example.dom
- Subject: M2Crypto S/MIME testing
- MIME-Version: 1.0
- Content-Disposition: attachment; filename="smime.p7m"
- Content-Type: application/x-pkcs7-mime; name="smime.p7m"
- Content-Transfer-Encoding: base64
-
- MIIBVwYJKoZIhvcNAQcDoIIBSDCCAUQCAQAxggEAMIH9AgEAMGYwYTELMAkGA1UE
- BhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRkwFwYDVQQDExBTL01JTUUgUmVjaXBp
- ZW50MSQwIgYJKoZIhvcNAQkBFhVyZWNpcGllbnRAZXhhbXBsZS5kb20CAQAwDQYJ
- KoZIhvcNAQEBBQAEgYCBaXZ+qjpBEZwdP7gjfzfAtQitESyMwo3i+LBOw6sSDir6
- FlNDPCnkrTvqDX3Rt6X6vBtTCYOm+qiN7ujPkOU61cN7h8dvHR8YW9+0IPY80/W0
- lZ/HihSRgwTNd7LnxUUcPx8YV1id0dlmP0Hz+Lg+mHf6rqaR//JcYhX9vW4XvjA7
- BgkqhkiG9w0BBwEwFAYIKoZIhvcNAwcECMN+qya6ADywgBgHr9Jkhwn5Gsdu7BwX
- nIQfYTYcdL9I5Sk=
- </PRE
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="DECRYPT"
->Decrypt</A
-></H1
-><P
->Assume the above output has been saved into <TT
-CLASS="FILENAME"
->encrypt.p7</TT
->.
- Decrypt the message thusly:
- </P
-><PRE
-CLASS="PROGRAMLISTING"
-> from M2Crypto import BIO, SMIME, X509
-
- # Instantiate an SMIME object.
- s = SMIME.SMIME()
-
- # Load private key and cert.
- s.load_key('recipient_key.pem', 'recipient.pem')
-
- # Load the encrypted data.
- p7, data = SMIME.smime_load_pkcs7('encrypt.p7')
-
- # Decrypt p7.
- out = s.decrypt(p7)
-
- print(out)
- </PRE
-><P
->Here's the output:
- </P
-><PRE
-CLASS="SCREEN"
-> a sign of our times
- </PRE
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="SIGN-AND-ENCRYPT"
->Sign and Encrypt</A
-></H1
-><P
->Here's how to generate an S/MIME-signed/encrypted message:
- </P
-><PRE
-CLASS="PROGRAMLISTING"
-> from M2Crypto import BIO, Rand, SMIME, X509
-
- def makebuf(text):
- return BIO.MemoryBuffer(text)
-
- # Make a MemoryBuffer of the message.
- buf = makebuf('a sign of our times')
-
- # Seed the PRNG.
- Rand.load_file('randpool.dat', -1)
-
- # Instantiate an SMIME object.
- s = SMIME.SMIME()
-
- # Load signer's key and cert. Sign the buffer.
- s.load_key('signer_key.pem', 'signer.pem')
- p7 = s.sign(buf)
-
- # Load target cert to encrypt the signed message to.
- x509 = X509.load_cert('recipient.pem')
- sk = X509.X509_Stack()
- sk.push(x509)
- s.set_x509_stack(sk)
-
- # Set cipher: 3-key triple-DES in CBC mode.
- s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
-
- # Create a temporary buffer.
- tmp = BIO.MemoryBuffer()
-
- # Write the signed message into the temporary buffer.
- s.write(tmp, p7)
-
- # Encrypt the temporary buffer.
- p7 = s.encrypt(tmp)
-
- # Output p7 in mail-friendly format.
- out = BIO.MemoryBuffer()
- out.write('From: sender@example.dom\n')
- out.write('To: recipient@example.dom\n')
- out.write('Subject: M2Crypto S/MIME testing\n')
- s.write(out, p7)
-
- print(out.read())
-
- # Save the PRNG's state.
- Rand.save_file('randpool.dat')
- </PRE
-><P
->Here's the output of the above program:
- </P
-><PRE
-CLASS="SCREEN"
-> From: sender@example.dom
- To: recipient@example.dom
- Subject: M2Crypto S/MIME testing
- MIME-Version: 1.0
- Content-Disposition: attachment; filename="smime.p7m"
- Content-Type: application/x-pkcs7-mime; name="smime.p7m"
- Content-Transfer-Encoding: base64
-
- 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
- </PRE
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="DECRYPT-AND-VERIFY"
->Decrypt and Verify</A
-></H1
-><P
->Suppose the above output has been saved into
- <TT
-CLASS="FILENAME"
->se.p7</TT
->. The following demonstrates how to decrypt and
- verify it:
- </P
-><PRE
-CLASS="PROGRAMLISTING"
-> from M2Crypto import BIO, SMIME, X509
-
- # Instantiate an SMIME object.
- s = SMIME.SMIME()
-
- # Load private key and cert.
- s.load_key('recipient_key.pem', 'recipient.pem')
-
- # Load the signed/encrypted data.
- p7, data = SMIME.smime_load_pkcs7('se.p7')
-
- # After the above step, 'data' == None.
- # Decrypt p7. 'out' now contains a PKCS #7 signed blob.
- out = s.decrypt(p7)
-
- # Load the signer's cert.
- x509 = X509.load_cert('signer.pem')
- sk = X509.X509_Stack()
- sk.push(x509)
- s.set_x509_stack(sk)
-
- # Load the signer's CA cert. In this case, because the signer's
- # cert is self-signed, it is the signer's cert itself.
- st = X509.X509_Store()
- st.load_info('signer.pem')
- s.set_x509_store(st)
-
- # Recall 'out' contains a PKCS #7 blob.
- # Transform 'out'; verify the resulting PKCS #7 blob.
- p7_bio = BIO.MemoryBuffer(out)
- p7, data = SMIME.smime_load_pkcs7_bio(p7_bio)
- v = s.verify(p7)
-
- print(v)
- </PRE
-><P
->The output is as follows:
- </P
-><PRE
-CLASS="SCREEN"
-> a sign of our times
- </PRE
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="SMTP"
->Sending S/MIME messages via SMTP</A
-></H1
-><P
->In the above examples, we've assumed that our S/MIME messages
- are sent and received automagically. The following is a Python function that
- generates S/MIME-signed/encrypted messages and sends them via SMTP:
- </P
-><PRE
-CLASS="PROGRAMLISTING"
-> from M2Crypto import BIO, SMIME, X509
- import smtplib, string, sys
-
- def sendsmime(from_addr, to_addrs, subject, msg, from_key, from_cert=None, to_certs=None, smtpd='localhost'):
-
- msg_bio = BIO.MemoryBuffer(msg)
- sign = from_key
- encrypt = to_certs
-
- s = SMIME.SMIME()
- if sign:
- s.load_key(from_key, from_cert)
- if encrypt:
- p7 = s.sign(msg_bio, flags=SMIME.PKCS7_TEXT)
- else:
- p7 = s.sign(msg_bio, flags=SMIME.PKCS7_TEXT|SMIME.PKCS7_DETACHED)
- msg_bio = BIO.MemoryBuffer(msg) # Recreate coz sign() has consumed it.
-
- if encrypt:
- sk = X509.X509_Stack()
- for x in to_certs:
- sk.push(X509.load_cert(x))
- s.set_x509_stack(sk)
- s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
- tmp_bio = BIO.MemoryBuffer()
- if sign:
- s.write(tmp_bio, p7)
- else:
- tmp_bio.write(msg)
- p7 = s.encrypt(tmp_bio)
-
- out = BIO.MemoryBuffer()
- out.write('From: %s\r\n' % from_addr)
- out.write('To: %s\r\n' % string.join(to_addrs, ", "))
- out.write('Subject: %s\r\n' % subject)
- if encrypt:
- s.write(out, p7)
- else:
- if sign:
- s.write(out, p7, msg_bio, SMIME.PKCS7_TEXT)
- else:
- out.write('\r\n')
- out.write(msg)
- out.close()
-
- smtp = smtplib.SMTP()
- smtp.connect(smtpd)
- smtp.sendmail(from_addr, to_addrs, out.read())
- smtp.quit()
- </PRE
-><P
->This function sends plain, S/MIME-signed, S/MIME-encrypted,
- and S/MIME-signed/encrypted messages, depending on the parameters
- <TT
-CLASS="PARAMETER"
-><I
->from_key</I
-></TT
-> and <TT
-CLASS="PARAMETER"
-><I
->to_certs</I
-></TT
->. The
- function's output interoperates with Netscape Messenger.
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="VERIFYING-ORIGIN"
->Verifying origin of S/MIME messages</A
-></H1
-><P
->In our examples above that decrypt or verify messages, we skipped
- a step: verifying that the <TT
-CLASS="LITERAL"
->from</TT
-> address of the message
- matches the <TT
-CLASS="LITERAL"
->email address</TT
-> attribute in the sender's
- certificate.
- </P
-><P
->The premise of current X.509 certification practice is that the
- CA is supposed to verify your identity, and to issue a certificate with
- <TT
-CLASS="LITERAL"
->email address</TT
-> that matches your actual mail address.
- (Verisign's March 2001 failure in identity verification resulting in
- Microsoft certificates being issued to spoofers notwithstanding.)
- </P
-><P
->If you run your own CA, your certification practice is up to you, of
- course, and it would probably be part of your security policy.
- </P
-><P
->Whether your S/MIME messaging application needs to verify the
- <TT
-CLASS="LITERAL"
->from</TT
-> addresses of S/MIME messages depends on your
- security policy and your system's threat model, as always.
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="NETSCAPE-MESSENGER"
->Interoperating with Netscape Messenger</A
-></H1
-><P
->Suppose S/MIME Recipient uses Netscape Messenger. To enable Messenger
- to handle S/MIME messages from S/MIME Sender, S/MIME Recipient needs
- to configure Messenger with his private key and certificate, as well as S/MIME
- Sender's certificate.
- </P
-><DIV
-CLASS="NOTE"
-><BLOCKQUOTE
-CLASS="NOTE"
-><P
-><B
->Note: </B
->Configuring Messenger's POP or IMAP settings so that it retrieves
- mail correctly is beyond the scope of this HOWTO.
- </P
-></BLOCKQUOTE
-></DIV
-><P
->The following steps demonstrate how to import S/MIME Recipient's
- private key and certificate for Messenger:
- </P
-><DIV
-CLASS="PROCEDURE"
-><OL
-TYPE="1"
-><LI
-><P
->Transform S/MIME Recipient's private key and certificate into
- <I
-CLASS="EMPHASIS"
->PKCS #12</I
-> format.
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->openssl pkcs12 -export -in recipient.pem -inkey recipient_key.pem -name "S/MIME Recipient" -out recipient.p12
- </B
-></TT
->
- Enter Export Password:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->&lt;enter&gt;</I
-></TT
-></B
-></TT
->
- Verifying password - Enter Export Password:<TT
-CLASS="USERINPUT"
-><B
-><TT
-CLASS="REPLACEABLE"
-><I
->&lt;enter&gt;</I
-></TT
-></B
-></TT
->
- </PRE
-></LI
-><LI
-><P
->Start Messenger.
- </P
-></LI
-><LI
-><P
->Click on the (open) "lock" icon at the bottom left corner of
- Messenger's window. This brings up the "Security Info" dialog box.
- </P
-></LI
-><LI
-><P
->Click on "Yours" under "Certificates".
- </P
-></LI
-><LI
-><P
->Select "Import a certificate", then pick
- <TT
-CLASS="FILENAME"
->recipient.p12</TT
-> from the ensuing file selection dialog
- box.
- </P
-></LI
-></OL
-></DIV
-><P
->Next, you need to import <TT
-CLASS="FILENAME"
->signer.pem</TT
-> as a CA
- certificate, so that Messenger will mark messages signed by S/MIME Sender as
- "trusted":
- </P
-><DIV
-CLASS="PROCEDURE"
-><OL
-TYPE="1"
-><LI
-><P
->Create a DER encoding of <TT
-CLASS="FILENAME"
->signer.pem</TT
->.
- </P
-><PRE
-CLASS="SCREEN"
-> <TT
-CLASS="USERINPUT"
-><B
->openssl x509 -inform pem -outform der -in signer.pem -out signer.der
- </B
-></TT
->
- </PRE
-></LI
-><LI
-><P
->Install <TT
-CLASS="FILENAME"
->signer.der</TT
-> into Messenger as MIME type
- <TT
-CLASS="LITERAL"
->application/x-x509-ca-cert</TT
->. You do this by downloading
- <TT
-CLASS="FILENAME"
->signer.der</TT
-> via Navigator from a HTTP or HTTPS server,
- with the correct MIME type mapping. (You may use
- <TT
-CLASS="FILENAME"
->demo/ssl/https_srv.py</TT
->, bundled with M2Crypto, for
- this purpose.) Follow the series of dialog boxes to accept
- <TT
-CLASS="FILENAME"
->signer.der</TT
-> as a CA for certifying email users.
- </P
-></LI
-></OL
-></DIV
-><P
->S/MIME Recipient is now able to decrypt and read S/MIME Sender's
- messages with Messenger. Messenger will indicate that S/MIME Sender's
- messages are signed, encrypted, or encrypted <I
-CLASS="EMPHASIS"
->and</I
->
- signed, as the case may be, via the "stamp" icon on the message window's
- top right corner.
- </P
-><P
->Clicking on the "stamp" icon brings you to the Security Info dialog
- box. Messenger informs you that the message is, say, encrypted with
- 168-bit DES-EDE3-CBC and that it is digitally signed by the private key
- corresponding to the public key contained in the certificate
- <TT
-CLASS="FILENAME"
->signer.pem</TT
->.
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="MICROSOFT-OUTLOOK"
->Interoperating with Microsoft Outlook</A
-></H1
-><P
->I do not know how to do this, as I do not use Outlook. (Nor do I use
- Netscape Messenger, actually. I use Mutt, top dog of MUAs. ;-) Information on
- how to configure Outlook with keys and certificates so that it handles
- S/MIME mail is gratefully accepted.
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="ZSMIME"
->ZSmime</A
-></H1
-><P
->ZSmime is a <A
-HREF="http://www.zope.org"
-TARGET="_top"
->Zope</A
->
- <I
-CLASS="EMPHASIS"
->product</I
-> that enables Zope to generate
- S/MIME-signed/encrypted messages. ZSmime demonstrates how to invoke
- M2Crypto in a web application server extension.
- </P
-><P
->ZSmime has its own <A
-HREF="http://sandbox.rulemaker.net/ngps/zope/zsmime/howto.html"
-TARGET="_top"
->HOWTO</A
->
- explaining its usage. (That HOWTO has some overlap in content with
- this document.)
- </P
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="RESOURCES"
->Resources</A
-></H1
-><P
-></P
-><UL
-><LI
-STYLE="list-style-type: opencircle"
-><P
->IETF S/MIME Working Group -
- <A
-HREF="http://www.imc.org/ietf-smime"
-TARGET="_top"
-> http://www.imc.org/ietf-smime</A
->
- </P
-></LI
-><LI
-STYLE="list-style-type: opencircle"
-><P
->S/MIME and OpenPGP -
- <A
-HREF="http://www.imc.org/smime-pgpmime.html"
-TARGET="_top"
-> http://www.imc.org/smime-pgpmime.html</A
->
- </P
-></LI
-><LI
-STYLE="list-style-type: opencircle"
-><P
->S/MIME Freeware Library -
- <A
-HREF="http://www.getronicsgov.com/hot/sfl_home.htm"
-TARGET="_top"
-> http://www.getronicsgov.com/hot/sfl_home.htm</A
->
- </P
-></LI
-><LI
-STYLE="list-style-type: opencircle"
-><P
->Mozilla Network Security Services -
- <A
-HREF="http://www.mozilla.org/projects/security/pkg/nss"
-TARGET="_top"
-> http://www.mozilla.org/projects/security/pkg/nss</A
->
- </P
-></LI
-><LI
-STYLE="list-style-type: opencircle"
-><P
->S/MIME Cracking Screen Saver -
- <A
-HREF="http://www.counterpane.com/smime.html"
-TARGET="_top"
-> http://www.counterpane.com/smime.html</A
->
- </P
-></LI
-></UL
-></DIV
-><DIV
-CLASS="SECT1"
-><HR><H1
-CLASS="SECT1"
-><A
-NAME="ID-KLUDGE"
-></A
-></H1
-><P
-> <TT
-CLASS="LITERAL"
->$Id:howto.smime.html 583 2007-10-01 19:23:12Z heikki $</TT
->
- </P
-></DIV
-></DIV
-></BODY
-></HTML
->
diff --git a/doc/howto.smime.rst b/doc/howto.smime.rst
new file mode 100644
index 0000000..dfd7abf
--- /dev/null
+++ b/doc/howto.smime.rst
@@ -0,0 +1,776 @@
+.. _howto-smime:
+
+HOWTO: Programming S/MIME in Python with M2Crypto
+=================================================
+
+:author: Pheng Siong Ng <ngps@post1.com>
+:copyright: © 2000, 2001 by Ng Pheng Siong.
+
+Introduction
+============
+
+`M2Crypto <https://gitlab.com/m2crypto/m2crypto/>`__ is a
+`Python <http://www.python.org>`__ interface to
+`OpenSSL <http://www.openssl.org>`__. It makes available to the Python
+programmer SSL functionality to implement clients and servers, S/MIME
+v2, RSA, DSA, DH, symmetric ciphers, message digests and HMACs.
+
+This document demonstrates programming S/MIME with M2Crypto.
+
+S/MIME
+======
+
+S/MIME - Secure Multipurpose Internet Mail Extensions [RFC 2311, RFC
+2312] - provides a consistent way to send and receive secure MIME data.
+Based on the popular Internet MIME standard, S/MIME provides the
+following cryptographic security services for electronic messaging
+applications - *authentication*, *message integrity* and
+*non-repudiation of origin* (using *digital signatures*), and *privacy*
+and *data security* (using *encryption*).
+
+Keys and Certificates
+=====================
+
+To create an S/MIME-signed message, you need an RSA key pair (this
+consists of a public key and a private key) and an X.509 certificate of
+said public key.
+
+To create an S/MIME-encrypted message, you need an X.509 certificate for
+each recipient.
+
+To create an S/MIME-signed *and* -encrypted message, first create a
+signed message, then encrypt the signed message with the recipients'
+certificates.
+
+You may generate key pairs and obtain certificates by using a commercial
+*certification authority* service.
+
+You can also do so using freely-available software. For many purposes,
+e.g., automated S/MIME messaging by system administration processes,
+this approach is cheap and effective.
+
+We now work through using OpenSSL to generate key pairs and
+certificates. This assumes you have OpenSSL installed properly on your
+system.
+
+First, we generate an X.509 certificate to be used for signing::
+
+ openssl req -newkey rsa:1024 -nodes -x509 -days 365 -out signer.pem
+
+ Using configuration from /usr/local/pkg/openssl/openssl.cnf
+ Generating a 1024 bit RSA private key
+ ..++++++
+ ....................++++++
+ writing new private key to 'privkey.pem'
+ -----
+ You are about to be asked to enter information that will be incorporated
+ into your certificate request.
+ What you are about to enter is what is called a Distinguished Name or a DN.
+ There are quite a few fields but you can leave some blank
+ For some fields there will be a default value,
+ If you enter '.', the field will be left blank.
+ -----
+ Country Name (2 letter code) [AU]:SG
+ State or Province Name (full name) [Some-State]:.
+ Locality Name (eg, city) []:.
+ Organization Name (eg, company) [Internet Widgits Pty Ltd]:M2Crypto
+ Organizational Unit Name (eg, section) []:.
+ Common Name (eg, YOUR name) []:S/MIME Sender
+ Email Address []:sender@example.dom
+
+
+This generates a 1024-bit RSA key pair, unencrypted, into
+``privkey.pem``; it also generates a self-signed X.509 certificate for
+the public key into ``signer.pem``. The certificate is valid for 365
+days, i.e., a year.
+
+Let's rename ``privkey.pem`` so that we know it is a companion of
+``signer.pem``'s::
+
+ mv privkey.pem signer_key.pem
+
+To verify the content of ``signer.pem``, execute the following::
+
+ openssl x509 -noout -text -in signer.pem
+
+ Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 0 (0x0)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: C=SG, O=M2Crypto, CN=S/MIME Sender/Email=sender@example.dom
+ Validity
+ Not Before: Mar 24 12:56:16 2001 GMT
+ Not After : Mar 24 12:56:16 2002 GMT
+ Subject: C=SG, O=M2Crypto, CN=S/MIME Sender/Email=sender@example.dom
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:a9:d6:e2:b5:11:3b:ae:3c:e2:17:31:70:e1:6e:
+ 01:f4:19:6d:bd:2a:42:36:2b:37:34:e2:83:1d:0d:
+ 11:2e:b4:99:44:db:10:67:be:97:5f:5b:1a:26:33:
+ 46:23:2f:95:04:7a:35:da:9d:f9:26:88:39:9e:17:
+ cd:3e:eb:a8:19:8d:a8:2a:f1:43:da:55:a9:2e:2c:
+ 65:ed:04:71:42:ce:73:53:b8:ea:7e:c7:f0:23:c6:
+ 63:c5:5e:68:96:64:a7:b4:2a:94:26:76:eb:79:ea:
+ e3:4e:aa:82:09:4f:44:87:4a:12:62:b5:d7:1f:ca:
+ f2:ce:d5:ba:7e:1f:48:fd:b9
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 29:FB:38:B6:BF:E2:40:BB:FF:D5:71:D7:D5:C4:F0:83:1A:2B:C7:99
+ X509v3 Authority Key Identifier:
+ keyid:29:FB:38:B6:BF:E2:40:BB:FF:D5:71:D7:D5:C4:F0:83:1A:2B:C7:99
+ DirName:/C=SG/O=M2Crypto/CN=S/MIME Sender/Email=sender@example.dom
+ serial:00
+
+ X509v3 Basic Constraints:
+ CA:TRUE
+ Signature Algorithm: md5WithRSAEncryption
+ 68:c8:6b:1b:fa:7c:9a:39:35:76:18:15:c9:fd:89:97:62:db:
+ 7a:b0:2d:13:dd:97:e8:1b:7a:9f:22:27:83:24:9d:2e:56:ec:
+ 97:89:3c:ef:16:55:80:5a:18:7c:22:d0:f6:bb:e3:a4:e8:59:
+ 30:ff:99:5a:93:3e:ea:bc:ee:7f:8d:d6:7d:37:8c:ac:3d:74:
+ 80:ce:7a:99:ba:27:b9:2a:a3:71:fa:a5:25:ba:47:17:df:07:
+ 56:96:36:fd:60:b9:6c:96:06:e8:e3:7b:9f:4b:6a:95:71:a8:
+ 34:fc:fc:b5:88:8b:c4:3f:1e:24:f6:52:47:b2:7d:44:67:d9:
+ 83:e8
+
+Next, we generate a self-signed X.509 certificate for the recipient.
+Note that ``privkey.pem`` will be recreated::
+
+ openssl req -newkey rsa:1024 -nodes -x509 -days 365 -out recipient.pem
+
+ Using configuration from /usr/local/pkg/openssl/openssl.cnf
+ Generating a 1024 bit RSA private key
+ .....................................++++++
+ .................++++++
+ writing new private key to 'privkey.pem'
+ -----
+ You are about to be asked to enter information that will be incorporated
+ into your certificate request.
+ What you are about to enter is what is called a Distinguished Name or a DN.
+ There are quite a few fields but you can leave some blank
+ For some fields there will be a default value,
+ If you enter '.', the field will be left blank.
+ -----
+ Country Name (2 letter code) [AU]:SG
+ State or Province Name (full name) [Some-State]:.
+ Locality Name (eg, city) []:.
+ Organization Name (eg, company) [Internet Widgits Pty Ltd]:M2Crypto
+ Organizational Unit Name (eg, section) []:.
+ Common Name (eg, YOUR name) []:S/MIME Recipient
+ Email Address []:recipient@example.dom
+
+Again, rename ``privkey.pem``::
+
+ mv privkey.pem recipient_key.pem
+
+
+In the examples to follow, S/MIME Sender, ``<sender@example.dom>``,
+shall be the sender of S/MIME messages, while S/MIME Recipient,
+``<recipient@example.dom>``, shall be the recipient of S/MIME messages.
+
+Armed with the key pairs and certificates, we are now ready to begin
+programming S/MIME in Python.
+
+ **Note:** The private keys generated above are *not
+ passphrase-protected*, i.e., they are *in the clear*. Anyone who has
+ access to such a key can generate S/MIME-signed messages with it,
+ and decrypt S/MIME messages encrypted to it's corresponding public
+ key.
+
+ We may passphrase-protect the keys, if we so choose. M2Crypto will
+ prompt the user for the passphrase when such a key is being loaded.
+
+M2Crypto.SMIME
+==============
+
+The Python programmer accesses M2Crypto's S/MIME functionality through
+class ``SMIME`` in the module ``M2Crypto.SMIME``. Typically, an
+``SMIME`` object is instantiated; the object is then set up for the
+intended operation: sign, encrypt, decrypt or verify; finally, the
+operation is invoked on the object.
+
+``M2Crypto.SMIME`` makes extensive use of ``M2Crypto.BIO``:
+``M2Crypto.BIO`` is a Python abstraction of the ``BIO`` abstraction in
+OpenSSL. A commonly used ``BIO`` abstraction in M2Crypto is
+``M2Crypto.BIO.MemoryBuffer``, which implements a memory-based file-like
+object, similar to Python's own ``StringIO``.
+
+Sign
+====
+
+The following code demonstrates how to generate an S/MIME-signed
+message. ``randpool.dat`` contains random data which is used to seed
+OpenSSL's pseudo-random number generator via M2Crypto::
+
+ from M2Crypto import BIO, Rand, SMIME
+
+ def makebuf(text):
+ return BIO.MemoryBuffer(text)
+
+ # Make a MemoryBuffer of the message.
+ buf = makebuf('a sign of our times')
+
+ # Seed the PRNG.
+ Rand.load_file('randpool.dat', -1)
+
+ # Instantiate an SMIME object; set it up; sign the buffer.
+ s = SMIME.SMIME()
+ s.load_key('signer_key.pem', 'signer.pem')
+ p7 = s.sign(buf, SMIME.PKCS7_DETACHED)
+
+
+``p7`` now contains a *PKCS #7 signature blob* wrapped in an
+``M2Crypto.SMIME.PKCS7`` object. Note that ``buf`` has been consumed by
+``sign()`` and has to be recreated if it is to be used again.
+
+We may now send the signed message via SMTP. In these examples, we shall
+not do so; instead, we'll render the S/MIME output in mail-friendly
+format, and pretend that our messages are sent and received
+correctly::
+
+ # Recreate buf.
+ buf = makebuf('a sign of our times')
+
+ # Output p7 in mail-friendly format.
+ out = BIO.MemoryBuffer()
+ out.write('From: sender@example.dom\n')
+ out.write('To: recipient@example.dom\n')
+ out.write('Subject: M2Crypto S/MIME testing\n')
+ s.write(out, p7, buf)
+
+ print(out.read())
+
+ # Save the PRNG's state.
+ Rand.save_file('randpool.dat')
+
+Here's the output::
+
+ From: sender@example.dom
+ To: recipient@example.dom
+ Subject: M2Crypto S/MIME testing
+ MIME-Version: 1.0
+ Content-Type: multipart/signed ; protocol="application/x-pkcs7-signature" ; micalg=sha1 ; boundary="----3C93156FC7B4EBF49FE9C7DB7F503087"
+
+ This is an S/MIME signed message
+
+ ------3C93156FC7B4EBF49FE9C7DB7F503087
+ a sign of our times
+ ------3C93156FC7B4EBF49FE9C7DB7F503087
+ Content-Type: application/x-pkcs7-signature; name="smime.p7s"
+ Content-Transfer-Encoding: base64
+ Content-Disposition: attachment; filename="smime.p7s"
+
+ MIIE8AYJKoZIhvcNAQcCoIIE4TCCBN0CAQExCzAJBgUrDgMCGgUAMCIGCSqGSIb3
+ DQEHAaAVBBNhIHNpZ24gb2Ygb3VyIHRpbWVzoIIC5zCCAuMwggJMoAMCAQICAQAw
+ DQYJKoZIhvcNAQEEBQAwWzELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRv
+ MRYwFAYDVQQDEw1TL01JTUUgU2VuZGVyMSEwHwYJKoZIhvcNAQkBFhJzZW5kZXJA
+ ZXhhbXBsZS5kb20wHhcNMDEwMzMxMTE0MDMzWhcNMDIwMzMxMTE0MDMzWjBbMQsw
+ CQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlwdG8xFjAUBgNVBAMTDVMvTUlNRSBT
+ ZW5kZXIxITAfBgkqhkiG9w0BCQEWEnNlbmRlckBleGFtcGxlLmRvbTCBnzANBgkq
+ hkiG9w0BAQEFAAOBjQAwgYkCgYEA5c5Tj1CHTSOxa1q2q0FYiwMWYHptJpJcvtZm
+ UwrgU5sHrA8OnCM0cDXEj0KPf3cfNjHffB8HWMzI4UEgNmFXQNsxoGZ+iqwxLlNj
+ y9Mh7eFW/Bjq5hNXbouSlQ0rWBRkoxV64y+t6lQehb32WfYXQbKFxFJSXzSxOx3R
+ 8YhSPd0CAwEAAaOBtjCBszAdBgNVHQ4EFgQUXOyolL1t4jaBwZFRM7MS8nBLzUow
+ gYMGA1UdIwR8MHqAFFzsqJS9beI2gcGRUTOzEvJwS81KoV+kXTBbMQswCQYDVQQG
+ EwJTRzERMA8GA1UEChMITTJDcnlwdG8xFjAUBgNVBAMTDVMvTUlNRSBTZW5kZXIx
+ ITAfBgkqhkiG9w0BCQEWEnNlbmRlckBleGFtcGxlLmRvbYIBADAMBgNVHRMEBTAD
+ AQH/MA0GCSqGSIb3DQEBBAUAA4GBAHo3DrCHR86fSTVAvfiXdSswWqKtCEhUHRdC
+ TLFGl4hDk2GyZxaFuqZwiURz/H7nMicymI2wkz8H/wyHFg8G3BIehURpj2v/ZWXY
+ eovbgS7EZALVVkDj4hNl/IIHWd6Gtv1UODf7URbxtl3hQ9/eTWITrefT1heuPnar
+ 8czydsOLMYIBujCCAbYCAQEwYDBbMQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJD
+ cnlwdG8xFjAUBgNVBAMTDVMvTUlNRSBTZW5kZXIxITAfBgkqhkiG9w0BCQEWEnNl
+ bmRlckBleGFtcGxlLmRvbQIBADAJBgUrDgMCGgUAoIGxMBgGCSqGSIb3DQEJAzEL
+ BgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTAxMDMzMTExNDUwMlowIwYJKoZI
+ hvcNAQkEMRYEFOoeRUd8ExIYXfQq8BTFuKWrSP3iMFIGCSqGSIb3DQEJDzFFMEMw
+ CgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFAMAcGBSsO
+ AwIHMA0GCCqGSIb3DQMCAgEoMA0GCSqGSIb3DQEBAQUABIGAQpU8hFUtLCF6hO2t
+ ec9EYJ/Imqqiiw+BxWxkUUVT81Vbjwdn9JST6+sztM5JRP2ZW+b4txEjZriYC8f3
+ kv95YMTGbIsuWkJ93GrbvqoJ/CxO23r9WWRnZEm/1EZN9ZmlrYqzBTxnNRmP3Dhj
+ cW8kzZwH+2/2zz2G7x1HxRWH95A=
+
+ ------3C93156FC7B4EBF49FE9C7DB7F503087--
+
+
+Verify
+======
+
+Assume the above output has been saved into ``sign.p7``. Let's now
+verify the signature::
+
+ from M2Crypto import SMIME, X509
+
+ # Instantiate an SMIME object.
+ s = SMIME.SMIME()
+
+ # Load the signer's cert.
+ x509 = X509.load_cert('signer.pem')
+ sk = X509.X509_Stack()
+ sk.push(x509)
+ s.set_x509_stack(sk)
+
+ # Load the signer's CA cert. In this case, because the signer's
+ # cert is self-signed, it is the signer's cert itself.
+ st = X509.X509_Store()
+ st.load_info('signer.pem')
+ s.set_x509_store(st)
+
+ # Load the data, verify it.
+ p7, data = SMIME.smime_load_pkcs7('sign.p7')
+ v = s.verify(p7, data)
+ print(v)
+ print(data)
+ print(data.read())
+
+Here's the output of the above program::
+
+ a sign of our times
+ <M2Crypto.BIO.BIO instance at 0x822012c>
+ a sign of our times
+
+Suppose, instead of loading ``signer.pem`` above, we load
+``recipient.pem``. That is, we do a global substitution of
+``recipient.pem`` for ``signer.pem`` in the above program. Here's the
+modified program's output::
+
+ Traceback (most recent call last):
+ File "./verify.py", line 22, in ?
+ v = s.verify(p7)
+ File "/usr/local/home/ngps/prog/m2/M2Crypto/SMIME.py", line 205, in verify
+ raise SMIME_Error, Err.get_error()
+ M2Crypto.SMIME.SMIME_Error: 312:error:21075075:PKCS7 routines:PKCS7_verify:certificate verify error:pk7_smime.c:213:Verify error:self signed certificate
+
+
+As displayed, the error is generated by line 213 of OpenSSL's
+``pk7_smime.c`` (as of OpenSSL 0.9.6); if you are a C programmer, you
+may wish to look up the C source to explore OpenSSL's S/MIME
+implementation and understand why the error message is worded thus.
+
+Encrypt
+=======
+
+We now demonstrate how to generate an S/MIME-encrypted message::
+
+ from M2Crypto import BIO, Rand, SMIME, X509
+
+ def makebuf(text):
+ return BIO.MemoryBuffer(text)
+
+ # Make a MemoryBuffer of the message.
+ buf = makebuf('a sign of our times')
+
+ # Seed the PRNG.
+ Rand.load_file('randpool.dat', -1)
+
+ # Instantiate an SMIME object.
+ s = SMIME.SMIME()
+
+ # Load target cert to encrypt to.
+ x509 = X509.load_cert('recipient.pem')
+ sk = X509.X509_Stack()
+ sk.push(x509)
+ s.set_x509_stack(sk)
+
+ # Set cipher: 3-key triple-DES in CBC mode.
+ s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
+
+ # Encrypt the buffer.
+ p7 = s.encrypt(buf)
+
+ # Output p7 in mail-friendly format.
+ out = BIO.MemoryBuffer()
+ out.write('From: sender@example.dom\n')
+ out.write('To: recipient@example.dom\n')
+ out.write('Subject: M2Crypto S/MIME testing\n')
+ s.write(out, p7)
+
+ print(out.read())
+
+ # Save the PRNG's state.
+ Rand.save_file('randpool.dat')
+
+Here's the output of the above program::
+
+ From: sender@example.dom
+ To: recipient@example.dom
+ Subject: M2Crypto S/MIME testing
+ MIME-Version: 1.0
+ Content-Disposition: attachment; filename="smime.p7m"
+ Content-Type: application/x-pkcs7-mime; name="smime.p7m"
+ Content-Transfer-Encoding: base64
+
+ MIIBVwYJKoZIhvcNAQcDoIIBSDCCAUQCAQAxggEAMIH9AgEAMGYwYTELMAkGA1UE
+ BhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRkwFwYDVQQDExBTL01JTUUgUmVjaXBp
+ ZW50MSQwIgYJKoZIhvcNAQkBFhVyZWNpcGllbnRAZXhhbXBsZS5kb20CAQAwDQYJ
+ KoZIhvcNAQEBBQAEgYCBaXZ+qjpBEZwdP7gjfzfAtQitESyMwo3i+LBOw6sSDir6
+ FlNDPCnkrTvqDX3Rt6X6vBtTCYOm+qiN7ujPkOU61cN7h8dvHR8YW9+0IPY80/W0
+ lZ/HihSRgwTNd7LnxUUcPx8YV1id0dlmP0Hz+Lg+mHf6rqaR//JcYhX9vW4XvjA7
+ BgkqhkiG9w0BBwEwFAYIKoZIhvcNAwcECMN+qya6ADywgBgHr9Jkhwn5Gsdu7BwX
+ nIQfYTYcdL9I5Sk=
+
+
+Decrypt
+=======
+
+Assume the above output has been saved into ``encrypt.p7``. Decrypt the
+message thusly::
+
+ from M2Crypto import BIO, SMIME, X509
+
+ # Instantiate an SMIME object.
+ s = SMIME.SMIME()
+
+ # Load private key and cert.
+ s.load_key('recipient_key.pem', 'recipient.pem')
+
+ # Load the encrypted data.
+ p7, data = SMIME.smime_load_pkcs7('encrypt.p7')
+
+ # Decrypt p7.
+ out = s.decrypt(p7)
+
+ print(out)
+
+Here's the output::
+
+ a sign of our times
+
+
+Sign and Encrypt
+================
+
+Here's how to generate an S/MIME-signed/encrypted message::
+
+ from M2Crypto import BIO, Rand, SMIME, X509
+
+ def makebuf(text):
+ return BIO.MemoryBuffer(text)
+
+ # Make a MemoryBuffer of the message.
+ buf = makebuf('a sign of our times')
+
+ # Seed the PRNG.
+ Rand.load_file('randpool.dat', -1)
+
+ # Instantiate an SMIME object.
+ s = SMIME.SMIME()
+
+ # Load signer's key and cert. Sign the buffer.
+ s.load_key('signer_key.pem', 'signer.pem')
+ p7 = s.sign(buf)
+
+ # Load target cert to encrypt the signed message to.
+ x509 = X509.load_cert('recipient.pem')
+ sk = X509.X509_Stack()
+ sk.push(x509)
+ s.set_x509_stack(sk)
+
+ # Set cipher: 3-key triple-DES in CBC mode.
+ s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
+
+ # Create a temporary buffer.
+ tmp = BIO.MemoryBuffer()
+
+ # Write the signed message into the temporary buffer.
+ s.write(tmp, p7)
+
+ # Encrypt the temporary buffer.
+ p7 = s.encrypt(tmp)
+
+ # Output p7 in mail-friendly format.
+ out = BIO.MemoryBuffer()
+ out.write('From: sender@example.dom\n')
+ out.write('To: recipient@example.dom\n')
+ out.write('Subject: M2Crypto S/MIME testing\n')
+ s.write(out, p7)
+
+ print(out.read())
+
+ # Save the PRNG's state.
+ Rand.save_file('randpool.dat')
+
+Here's the output of the above program::
+
+ From: sender@example.dom
+ To: recipient@example.dom
+ Subject: M2Crypto S/MIME testing
+ MIME-Version: 1.0
+ Content-Disposition: attachment; filename="smime.p7m"
+ Content-Type: application/x-pkcs7-mime; name="smime.p7m"
+ Content-Transfer-Encoding: base64
+
+ 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
+
+
+Decrypt and Verify
+==================
+
+Suppose the above output has been saved into ``se.p7``. The following
+demonstrates how to decrypt and verify it::
+
+ from M2Crypto import BIO, SMIME, X509
+
+ # Instantiate an SMIME object.
+ s = SMIME.SMIME()
+
+ # Load private key and cert.
+ s.load_key('recipient_key.pem', 'recipient.pem')
+
+ # Load the signed/encrypted data.
+ p7, data = SMIME.smime_load_pkcs7('se.p7')
+
+ # After the above step, 'data' == None.
+ # Decrypt p7. 'out' now contains a PKCS #7 signed blob.
+ out = s.decrypt(p7)
+
+ # Load the signer's cert.
+ x509 = X509.load_cert('signer.pem')
+ sk = X509.X509_Stack()
+ sk.push(x509)
+ s.set_x509_stack(sk)
+
+ # Load the signer's CA cert. In this case, because the signer's
+ # cert is self-signed, it is the signer's cert itself.
+ st = X509.X509_Store()
+ st.load_info('signer.pem')
+ s.set_x509_store(st)
+
+ # Recall 'out' contains a PKCS #7 blob.
+ # Transform 'out'; verify the resulting PKCS #7 blob.
+ p7_bio = BIO.MemoryBuffer(out)
+ p7, data = SMIME.smime_load_pkcs7_bio(p7_bio)
+ v = s.verify(p7)
+
+ print(v)
+
+
+The output is as follows::
+
+ a sign of our times
+
+
+Sending S/MIME messages via SMTP
+================================
+
+In the above examples, we've assumed that our S/MIME messages are sent
+and received automagically. The following is a Python function that
+generates S/MIME-signed/encrypted messages and sends them via
+SMTP::
+
+ from M2Crypto import BIO, SMIME, X509
+ import smtplib, string, sys
+
+ def sendsmime(from_addr, to_addrs, subject, msg, from_key, from_cert=None, to_certs=None, smtpd='localhost'):
+
+ msg_bio = BIO.MemoryBuffer(msg)
+ sign = from_key
+ encrypt = to_certs
+
+ s = SMIME.SMIME()
+ if sign:
+ s.load_key(from_key, from_cert)
+ if encrypt:
+ p7 = s.sign(msg_bio, flags=SMIME.PKCS7_TEXT)
+ else:
+ p7 = s.sign(msg_bio, flags=SMIME.PKCS7_TEXT|SMIME.PKCS7_DETACHED)
+ msg_bio = BIO.MemoryBuffer(msg) # Recreate coz sign() has consumed it.
+
+ if encrypt:
+ sk = X509.X509_Stack()
+ for x in to_certs:
+ sk.push(X509.load_cert(x))
+ s.set_x509_stack(sk)
+ s.set_cipher(SMIME.Cipher('des_ede3_cbc'))
+ tmp_bio = BIO.MemoryBuffer()
+ if sign:
+ s.write(tmp_bio, p7)
+ else:
+ tmp_bio.write(msg)
+ p7 = s.encrypt(tmp_bio)
+
+ out = BIO.MemoryBuffer()
+ out.write('From: %s\r\n' % from_addr)
+ out.write('To: %s\r\n' % string.join(to_addrs, ", "))
+ out.write('Subject: %s\r\n' % subject)
+ if encrypt:
+ s.write(out, p7)
+ else:
+ if sign:
+ s.write(out, p7, msg_bio, SMIME.PKCS7_TEXT)
+ else:
+ out.write('\r\n')
+ out.write(msg)
+ out.close()
+
+ smtp = smtplib.SMTP()
+ smtp.connect(smtpd)
+ smtp.sendmail(from_addr, to_addrs, out.read())
+ smtp.quit()
+
+
+This function sends plain, S/MIME-signed, S/MIME-encrypted, and
+S/MIME-signed/encrypted messages, depending on the parameters
+``from_key`` and ``to_certs``. The function's output interoperates with
+Netscape Messenger.
+
+Verifying origin of S/MIME messages
+===================================
+
+In our examples above that decrypt or verify messages, we skipped a
+step: verifying that the ``from`` address of the message matches the
+``email address`` attribute in the sender's certificate.
+
+The premise of current X.509 certification practice is that the CA is
+supposed to verify your identity, and to issue a certificate with
+``email address`` that matches your actual mail address. (Verisign's
+March 2001 failure in identity verification resulting in Microsoft
+certificates being issued to spoofers notwithstanding.)
+
+If you run your own CA, your certification practice is up to you, of
+course, and it would probably be part of your security policy.
+
+Whether your S/MIME messaging application needs to verify the ``from``
+addresses of S/MIME messages depends on your security policy and your
+system's threat model, as always.
+
+Interoperating with Netscape Messenger
+======================================
+
+Suppose S/MIME Recipient uses Netscape Messenger. To enable Messenger to
+handle S/MIME messages from S/MIME Sender, S/MIME Recipient needs to
+configure Messenger with his private key and certificate, as well as
+S/MIME Sender's certificate.
+
+ **Note:** Configuring Messenger's POP or IMAP settings so that it
+ retrieves mail correctly is beyond the scope of this HOWTO.
+
+The following steps demonstrate how to import S/MIME Recipient's private
+key and certificate for Messenger:
+
+1. Transform S/MIME Recipient's private key and certificate into *PKCS
+ #12* format::
+
+ openssl pkcs12 -export -in recipient.pem -inkey recipient_key.pem \
+ -name "S/MIME Recipient" -out recipient.p12
+
+ Enter Export Password:<enter>
+ Verifying password - Enter Export Password:<enter>
+
+2. Start Messenger.
+
+3. Click on the (open) "lock" icon at the bottom left corner of
+ Messenger's window. This brings up the "Security Info" dialog box.
+
+4. Click on "Yours" under "Certificates".
+
+5. Select "Import a certificate", then pick ``recipient.p12`` from the
+ ensuing file selection dialog box.
+
+Next, you need to import ``signer.pem`` as a CA certificate, so that
+Messenger will mark messages signed by S/MIME Sender as "trusted":
+
+1. Create a DER encoding of ``signer.pem``::
+
+ openssl x509 -inform pem -outform der -in signer.pem -out signer.der
+
+2. Install ``signer.der`` into Messenger as MIME type
+ ``application/x-x509-ca-cert``. You do this by downloading
+ ``signer.der`` via Navigator from a HTTP or HTTPS server, with the
+ correct MIME type mapping. (You may use ``demo/ssl/https_srv.py``,
+ bundled with M2Crypto, for this purpose.) Follow the series of dialog
+ boxes to accept ``signer.der`` as a CA for certifying email users.
+
+S/MIME Recipient is now able to decrypt and read S/MIME Sender's
+messages with Messenger. Messenger will indicate that S/MIME Sender's
+messages are signed, encrypted, or encrypted *and* signed, as the case
+may be, via the "stamp" icon on the message window's top right corner.
+
+Clicking on the "stamp" icon brings you to the Security Info dialog box.
+Messenger informs you that the message is, say, encrypted with 168-bit
+DES-EDE3-CBC and that it is digitally signed by the private key
+corresponding to the public key contained in the certificate
+``signer.pem``.
+
+Interoperating with Microsoft Outlook
+=====================================
+
+I do not know how to do this, as I do not use Outlook. (Nor do I use
+Netscape Messenger, actually. I use Mutt, top dog of MUAs. ;-)
+Information on how to configure Outlook with keys and certificates so
+that it handles S/MIME mail is gratefully accepted.
+
+ZSmime
+======
+
+ZSmime is a `Zope <http://www.zope.org>`__ *product* that enables Zope
+to generate S/MIME-signed/encrypted messages. ZSmime demonstrates how to
+invoke M2Crypto in a web application server extension.
+
+ZSmime has its own
+`HOWTO <http://sandbox.rulemaker.net/ngps/zope/zsmime/howto.html>`__
+explaining its usage. (That HOWTO has some overlap in content with this
+document.)
+
+Resources
+=========
+
+- IETF S/MIME Working Group - http://www.imc.org/ietf-smime
+
+- S/MIME and OpenPGP - http://www.imc.org/smime-pgpmime.html
+
+- S/MIME Freeware Library -
+ http://www.getronicsgov.com/hot/sfl_home.htm
+
+- Mozilla Network Security Services -
+ http://www.mozilla.org/projects/security/pkg/nss
+
+- S/MIME Cracking Screen Saver - http://www.counterpane.com/smime.html
diff --git a/doc/howto.ssl.html b/doc/howto.ssl.html
deleted file mode 100644
index 340f264..0000000
--- a/doc/howto.ssl.html
+++ /dev/null
@@ -1,206 +0,0 @@
-<HTML
-><HEAD
-><TITLE
->HOWTO: Programming SSL in Python with M2Crypto</TITLE
->
-
-</HEAD>
-<BODY
-CLASS="ARTICLE"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
->
-
-<DIV
-CLASS="TITLEPAGE"
-><H1
-CLASS="TITLE"
-><A
-NAME="AEN2"
->HOWTO: Programming SSL in Python with M2Crypto</A
-></H1
->
-<P>
-Ng Pheng Siong (ngps@netmemetic.com) and Heikki Toivonen (heikki@osafoundation.org)
-</P
-><P
-CLASS="COPYRIGHT"
->Copyright &copy; 2001, 2002 by Ng Pheng Siong.</P
->
-<P
-CLASS="COPYRIGHT"
->Portions Copyright &copy; 2006 by Open Source Applications Foundation.</P
->
-</DIV>
-
-<DIV
-CLASS="SECT1"
-><H1
-CLASS="SECT1"
-><A
-NAME="INTRODUCTION"
->Introduction</A
-></H1
-><P
-><A
-HREF="http://chandlerproject.org/Projects/MeTooCrypto"
-TARGET="_top"
->M2Crypto</A
->
- is a <A
-HREF="http://www.python.org"
-TARGET="_top"
->Python</A
->
- interface to <A
-HREF="http://www.openssl.org"
-TARGET="_top"
->OpenSSL</A
->. It makes
- available to the Python programmer SSL functionality to implement clients
- and servers, S/MIME v2, RSA, DSA, DH, symmetric ciphers, message digests and
- HMACs.
- </P
-><P
->This document demonstrates programming HTTPS with M2Crypto.
- </P
-></DIV
->
-
-
-<DIV
-CLASS="SECT1"
-><H1
-CLASS="SECT1"
-><A
-NAME="history"
->A bit of history</A
-></H1
->
-
-<p> M2Crypto was created during the time of Python 1.5, which features
- a module httplib providing client-side HTTP functionality. M2Crypto sports
- a httpslib based on httplib.
- </p>
-
- <p>
- Beginning with version 2.0, Python's socket module provided
- (rudimentary) SSL support. Also in the same version, httplib was
- enhanced with class HTTPConnection, which is more sophisticated than
- the old class HTTP, and HTTPSConnection, which does HTTPS.
- </p>
-
- <p>
- Subsequently, M2Crypto.httpslib grew a compatible (but not identical)
- class HTTPSConnection.
- </p>
-
- <p>
- The primary interface difference between the two HTTPSConnection
- classes is that M2Crypto's version accepts an M2Crypto.SSL.Context
- instance as a parameter, whereas Python 2.x's SSL support does not
- permit Pythonic control of the SSL context.
- </p>
-
- <p> Within the implementations, Python's
- <tt>HTTPSConnection</tt> employs a
- <tt>FakeSocket</tt> object, which collects all input from
- the SSL connection before returning it to the application as a
- <tt>StringIO</tt> buffer, whereas M2Crypto's
- <tt>HTTPSConnection</tt> uses a buffering
- <tt>M2Crypto.BIO.IOBuffer</tt> object that works over the
- underlying M2Crypto.SSL.Connection directly. </p>
-
- <p>Since then M2Crypto has gained a Twisted wrapper that allows securing
- Twisted SSL connections with M2Crypto.</p>
-</DIV
->
-
-
-<DIV CLASS="SECT1" id="secure" name="secure">
-<H1 CLASS="SECT1">Secure SSL</H1>
-
-<p>It is recommended that you read the book Network Security with OpenSSL by John Viega, Matt Messier and Pravir Chandra,
-ISBN 059600270X.</p>
-
-<p>Using M2Crypto does not automatically make an SSL connection secure. There are various steps that need to be made
-before we can make that claim. Let's see how a simple client can establish a secure connection:</p>
-
-<pre>
-ctx = SSL.Context()
-ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, depth=9)
-if ctx.load_verify_locations('ca.pem') != 1: raise Exception('No CA certs')
-s = SSL.Connection(ctx)
-s.connect(server_address)
-# Normal protocol (for example HTTP) commands follow
-</pre>
-
-<p>The first line creates an SSL context. The defaults allow any SSL version (except SSL version 2 which has known
-weaknesses) and sets the allowed ciphers to secure ones.</p>
-
-<p>The second line tells M2Crypto to perform certificate validation. The flags shown above are typical for clients,
-and requires the server to send a certificate. The depth parameter tells how long certificate chains are allowed -
-9 is pretty common default, although probably too long in practice.</p>
-
-<p>The third line loads the allowed root (certificate authority or CA) certificates.
-Most Linux distributions come with CA certificates in suitable format. You
-could also download the <a href="http://mxr.mozilla.org/seamonkey/source//security/nss/lib/ckfw/builtins/certdata.txt?raw=1">certdata.txt</a>
-file from the <a href="http://www.mozilla.org/projects/security/pki/nss/">NSS</a>
-project and convert it
-with the little M2Crypto utility script <a href="http://svn.osafoundation.org/m2crypto/trunk/demo/x509/certdata2pem.py">demo/x509/certdata2pem.py</a>.</p>
-
-<p>The fourth line creates an SSL connection object with the secure context.</p>
-
-<p>The fifth line connects to the server. During this time we perform the last security step: just after connection, but before
-exchanging any data, we compare the commonName (or subjectAltName DNS field) field in the certificate the server returned to the
-server address we tried to connect to. This happens automatically with SSL.Connection and the Twisted wrapper class, and anything
-that uses those. In all other cases you must do the check manually. It is recommended you call the SSL.Checker to do the actual check.</p>
-
-<p>SSL servers are different in that they typically do not require the client to send a certificate, so there is usually no certificate
-checking. Also, it is typically useless to perform host name checking.</p>
-
-</DIV>
-
-<DIV CLASS="SECT1">
-<H1 CLASS="SECT1">Code Samples</H1>
-
-<p>The best samples of how to use the various SSL objects are in the tests directory, and the test_ssl.py file specifically.
-There are additional samples in the demo directory, but they are not quaranteed to be up to date.</p>
-
-<p>NOTE: The tests and demos
-may not be secure as is. Use the information above on how to make them secure.</p>
-</DIV>
-
-<DIV
-CLASS="SECT1"
-><H1
-CLASS="SECT1"
-><A
-NAME="SSLDUMP"
->ssldump</A
-></H1
->
-<P>ssldump "is an SSLv3/TLS network protocol analyser. It identifies
- TCP connections on the chosen network interface and attempts to interpret
- them as SSLv3/TLS traffic. When it identifies SSLv3/TLS traffic, it
- decodes the records and displays them in a textual form to stdout. If
- provided with the appropriate keying material, it will also decrypt the
- connections and display the application data traffic.
- </P>
-
- <P>
- If linked with OpenSSL, ssldump can display certificates in decoded form
- and decrypt traffic (provided that it has the appropriate keying
- material)."
- </P>
-
- <P>ssldump is written by Eric Rescorla.
- </P>
-</DIV
->
-
-</BODY>
-</HTML>
diff --git a/doc/howto.ssl.rst b/doc/howto.ssl.rst
new file mode 100644
index 0000000..ab9b17d
--- /dev/null
+++ b/doc/howto.ssl.rst
@@ -0,0 +1,129 @@
+.. _howto-ssl:
+
+HOWTO: Programming SSL in Python with M2Crypto
+==============================================
+
+:author: Pheng Siong Ng <ngps@netmemetic.com> and Heikki Toivonen (heikki@osafoundation.org)
+:copyright: © 2000, 2001 by Ng Pheng Siong,
+ portions © 2006 by Open Source Applications Foundation
+
+Introduction
+============
+
+`M2Crypto <https://gitlab.com/m2crypto/m2crypto/>`__ is a
+`Python <http://www.python.org>`__ interface to
+`OpenSSL <http://www.openssl.org>`__. It makes available to the Python
+programmer SSL functionality to implement clients and servers, S/MIME
+v2, RSA, DSA, DH, symmetric ciphers, message digests and HMACs.
+
+This document demonstrates programming HTTPS with M2Crypto.
+
+A bit of history
+================
+
+M2Crypto was created during the time of Python 1.5, which features a
+module httplib providing client-side HTTP functionality. M2Crypto sports
+a httpslib based on httplib.
+
+Beginning with version 2.0, Python's socket module provided
+(rudimentary) SSL support. Also in the same version, httplib was
+enhanced with class HTTPConnection, which is more sophisticated than the
+old class HTTP, and HTTPSConnection, which does HTTPS.
+
+Subsequently, M2Crypto.httpslib grew a compatible (but not identical)
+class HTTPSConnection.
+
+The primary interface difference between the two HTTPSConnection classes
+is that M2Crypto's version accepts an M2Crypto.SSL.Context instance as a
+parameter, whereas Python 2.x's SSL support does not permit Pythonic
+control of the SSL context.
+
+Within the implementations, Python's ``HTTPSConnection`` employs a
+``FakeSocket`` object, which collects all input from the SSL connection
+before returning it to the application as a ``StringIO`` buffer, whereas
+M2Crypto's ``HTTPSConnection`` uses a buffering
+``M2Crypto.BIO.IOBuffer`` object that works over the underlying
+M2Crypto.SSL.Connection directly.
+
+Since then M2Crypto has gained a Twisted wrapper that allows securing
+Twisted SSL connections with M2Crypto.
+
+Secure SSL
+==========
+
+It is recommended that you read the book Network Security with OpenSSL
+by John Viega, Matt Messier and Pravir Chandra, ISBN 059600270X.
+
+Using M2Crypto does not automatically make an SSL connection secure.
+There are various steps that need to be made before we can make that
+claim. Let's see how a simple client can establish a secure
+connection::
+
+ ctx = SSL.Context()
+ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, depth=9)
+ if ctx.load_verify_locations('ca.pem') != 1: raise Exception('No CA certs')
+ s = SSL.Connection(ctx)
+ s.connect(server_address)
+ # Normal protocol (for example HTTP) commands follow
+
+The first line creates an SSL context. The defaults allow any SSL
+version (except SSL version 2 which has known weaknesses) and sets the
+allowed ciphers to secure ones.
+
+The second line tells M2Crypto to perform certificate validation. The
+flags shown above are typical for clients, and requires the server to
+send a certificate. The depth parameter tells how long certificate
+chains are allowed - 9 is pretty common default, although probably too
+long in practice.
+
+The third line loads the allowed root (certificate authority or CA)
+certificates. Most Linux distributions come with CA certificates in
+suitable format. You could also download the
+`certdata.txt <http://mxr.mozilla.org/seamonkey/source//security/nss/lib/ckfw/builtins/certdata.txt?raw=1>`__
+file from the
+`NSS <http://www.mozilla.org/projects/security/pki/nss/>`__ project and
+convert it with the little M2Crypto utility script
+`demo/x509/certdata2pem.py <http://svn.osafoundation.org/m2crypto/trunk/demo/x509/certdata2pem.py>`__.
+
+The fourth line creates an SSL connection object with the secure
+context.
+
+The fifth line connects to the server. During this time we perform the
+last security step: just after connection, but before exchanging any
+data, we compare the commonName (or subjectAltName DNS field) field in
+the certificate the server returned to the server address we tried to
+connect to. This happens automatically with SSL.Connection and the
+Twisted wrapper class, and anything that uses those. In all other cases
+you must do the check manually. It is recommended you call the
+SSL.Checker to do the actual check.
+
+SSL servers are different in that they typically do not require the
+client to send a certificate, so there is usually no certificate
+checking. Also, it is typically useless to perform host name checking.
+
+Code Samples
+============
+
+The best samples of how to use the various SSL objects are in the tests
+directory, and the test\_ssl.py file specifically. There are additional
+samples in the demo directory, but they are not quaranteed to be up to
+date.
+
+NOTE: The tests and demos may not be secure as is. Use the information
+above on how to make them secure.
+
+ssldump
+=======
+
+ssldump "is an SSLv3/TLS network protocol analyser. It identifies TCP
+connections on the chosen network interface and attempts to interpret
+them as SSLv3/TLS traffic. When it identifies SSLv3/TLS traffic, it
+decodes the records and displays them in a textual form to stdout. If
+provided with the appropriate keying material, it will also decrypt the
+connections and display the application data traffic.
+
+If linked with OpenSSL, ssldump can display certificates in decoded form
+and decrypt traffic (provided that it has the appropriate keying
+material)."
+
+ssldump is written by Eric Rescorla.
diff --git a/doc/index.rst b/doc/index.rst
index 6241266..a472668 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -1,8 +1,3 @@
-.. M2Crypto documentation master file, created by
- sphinx-quickstart on Thu Apr 20 11:15:12 2017.
- You can adapt this file completely to your liking, but it should at least
- contain the root `toctree` directive.
-
Welcome to M2Crypto's documentation!
====================================
@@ -14,6 +9,18 @@ Contents:
M2Crypto
+HOWTOs
+======
+
+* :ref:`howto-ca`
+
+* :ref:`howto-ssl`
+
+* :ref:`howto-smime`
+
+* :ref:`zserverssl-howto`
+
+
Indices and tables
==================