aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/algos.txt72
-rw-r--r--doc/build_log.txt11
-rw-r--r--doc/building.txt49
-rw-r--r--doc/conf.py17
-rw-r--r--doc/contrib.txt71
-rw-r--r--doc/download.txt103
-rw-r--r--doc/examples.txt42
-rw-r--r--doc/faq.txt4
-rw-r--r--doc/filters.txt3
-rw-r--r--doc/firststep.txt29
-rw-r--r--doc/index.txt122
-rw-r--r--doc/intro.txt80
-rw-r--r--doc/old/tutorial.tex880
-rw-r--r--doc/pgpkey.txt (renamed from doc/pgpkeys.txt)0
-rw-r--r--doc/pubkey.txt330
-rw-r--r--doc/ssl.txt2
-rw-r--r--doc/support.txt20
-rw-r--r--doc/x509.txt577
18 files changed, 746 insertions, 1666 deletions
diff --git a/doc/algos.txt b/doc/algos.txt
index 3d4050c11..b82d8d5c0 100644
--- a/doc/algos.txt
+++ b/doc/algos.txt
@@ -1,3 +1,6 @@
+
+.. _algo_list:
+
Algorithms
========================================
@@ -9,46 +12,39 @@ primitives, including:
* Public key cryptography
- * Encryption algorithms RSA, ElGamal, DLIES (padding schemes OAEP,
- PKCS #1 v1.5)
-
- * Signature algorithms RSA, DSA, ECDSA, GOST 34.10-2001,
- Nyberg-Rueppel, Rabin-Williams (padding schemes PSS, PKCS #1 v1.5,
- X9.31)
-
- * Key agreement techniques Diffie-Hellman and ECDH
+ * Encryption algorithms RSA, ElGamal, DLIES (padding schemes OAEP,
+ PKCS #1 v1.5)
+ * Signature algorithms RSA, DSA, ECDSA, GOST 34.10-2001,
+ Nyberg-Rueppel, Rabin-Williams (padding schemes PSS, PKCS #1 v1.5,
+ X9.31)
+ * Key agreement techniques Diffie-Hellman and ECDH
* Hash functions
- * NIST hashes: SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512
+ * NIST hashes: SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512
- * RIPE hashes: RIPEMD-160 and RIPEMD-128
+ * RIPE hashes: RIPEMD-160 and RIPEMD-128
- * SHA-3 candidates Skein-512, Keccak, and Blue Midnight Wish-512
+ * SHA-3 candidates Skein-512, Keccak, and Blue Midnight Wish-512
- * Other common hash functions Whirlpool and Tiger
+ * Other common hash functions Whirlpool and Tiger
- * National standard hashes HAS-160 and GOST 34.11
+ * National standard hashes HAS-160 and GOST 34.11
- * Obsolete or insecure hashes MD5, MD4, MD2
+ * Obsolete or insecure hashes MD5, MD4, MD2
- * Non-cryptographic checksums Adler32, CRC24, CRC32
+ * Non-cryptographic checksums Adler32, CRC24, CRC32
* Block ciphers
- * AES (Rijndael) and AES candidates Serpent, Twofish, MARS, CAST-256, RC6
-
- * DES, and variants 3DES and DESX
-
- * National/telecom block ciphers SEED, KASUMI, MISTY1, GOST 28147, Skipjack
-
- * Other block ciphers including Blowfish, CAST-128, IDEA, Noekeon,
- TEA, XTEA, RC2, RC5, SAFER-SK, and Square
-
- * Block cipher constructions Luby-Rackoff and Lion
-
- * Block cipher modes ECB, CBC, CBC/CTS, CFB, OFB, CTR, XTS and
- authenticated cipher mode EAX
+ * AES (Rijndael) and AES candidates Serpent, Twofish, MARS, CAST-256, RC6
+ * DES, and variants 3DES and DESX
+ * National/telecom block ciphers SEED, KASUMI, MISTY1, GOST 28147, Skipjack
+ * Other block ciphers including Blowfish, CAST-128, IDEA, Noekeon,
+ TEA, XTEA, RC2, RC5, SAFER-SK, and Square
+ * Block cipher constructions Luby-Rackoff and Lion
+ * Block cipher modes ECB, CBC, CBC/CTS, CFB, OFB, CTR, XTS and
+ authenticated cipher mode EAX
* Stream ciphers ARC4, Salsa20/XSalsa20, Turing, and WiderWake4+1
@@ -57,21 +53,17 @@ primitives, including:
* Public Key Infrastructure
- * X.509 certificates (including generating new self-signed and CA
- certs) and CRLs
-
- * Certificate path validation
-
- * PKCS #10 certificate requests (creation and certificate issue)
+ * X.509 certificates (including generating new self-signed and CA
+ certs) and CRLs
+ * Certificate path validation
+ * PKCS #10 certificate requests (creation and certificate issue)
* Other cryptographic utility functions including
- * Key derivation functions for passwords: PBKDF1 (PKCS #5 v1.5),
- PBKDF2 (PKCS #5 v2.0), OpenPGP S2K (RFC 2440)
-
- * General key derivation functions KDF1 and KDF2 from IEEE 1363
-
- * PRFs from ANSI X9.42, SSL v3.0, TLS v1.0
+ * Key derivation functions for passwords: PBKDF1 (PKCS #5 v1.5),
+ PBKDF2 (PKCS #5 v2.0), OpenPGP S2K (RFC 2440)
+ * General key derivation functions KDF1 and KDF2 from IEEE 1363
+ * PRFs from ANSI X9.42, SSL v3.0, TLS v1.0
Recommended Algorithms
---------------------------------
diff --git a/doc/build_log.txt b/doc/build_log.txt
index 968c9e912..de6197389 100644
--- a/doc/build_log.txt
+++ b/doc/build_log.txt
@@ -1,13 +1,12 @@
-.. _build_log:
-
Build Log
========================================
-To report build results (successful or not), email Jack
-([email protected]) your results and relevant system
-information (OS versions, compiler name and version, CPU architecture
-and other hardware information, configuration settings).
+To report build results (successful or not), email the `development
+list <http://lists.randombit.net/mailman/listinfo/botan-devel/>`_ your
+results and relevant system information (OS versions, compiler name
+and version, CPU architecture and other hardware information,
+configuration settings).
Debian reports the build results for 1.8 on `a number of platforms
<http://buildd.debian.org/pkg.cgi?pkg=botan1.8>`_.
diff --git a/doc/building.txt b/doc/building.txt
index fba56196d..6784a0141 100644
--- a/doc/building.txt
+++ b/doc/building.txt
@@ -55,10 +55,10 @@ system, and use that. It will print a display at the end showing which
algorithms have and have not been enabled. For instance on one system
we might see lines like::
- INFO: Skipping mod because CPU incompatible - asm_amd64 mp_amd64 mp_asm64 sha1_amd64
- INFO: Skipping mod because OS incompatible - cryptoapi_rng win32_stats
- INFO: Skipping mod because compiler incompatible - mp_ia32_msvc
- INFO: Skipping mod because loaded on request only - bzip2 gnump openssl qt_mutex zlib
+ INFO: Skipping, by request only - bzip2 gnump openssl qt_mutex zlib
+ INFO: Skipping, incompatible CPU - aes_intel aes_ssse3 asm_x86_64 mp_asm64 mp_x86_64 sha1_x86_64
+ INFO: Skipping, incompatible OS - beos_stats cryptoapi_rng win32_crit_section win32_stats
+ INFO: Skipping, incompatible compiler - mp_msvc64 mp_x86_32_msvc
The ones that are 'loaded on request only' have to be explicitly asked
for, because they rely on third party libraries which your system
@@ -168,9 +168,27 @@ compiler to look for both include files and library files in
place where they will be in the default compiler search paths (consult
your documentation and/or local expert for details).
-Trickier Things
+.. _amalgamation:
+
+The Amalgamation Build
----------------------------------------
+You can also configure Botan to be built using only a single source
+file; this is quite convenient if you plan to embed the library into
+another application. To do so, run ``configure.py`` with
+whatever arguments you would ordinarily use, along with the option
+``--gen-amalgamation``. This will create two (rather large)
+files, ``botan_all.h`` and ``botan_all.cpp``.
+
+Whenever you would have included a botan header, you can then include
+``botan_all.h``, and include ``botan_all.cpp`` along
+with the rest of the source files in your build. If you want to be
+able to easily switch between amalgamated and non-amalgamated versions
+(for instance to take advantage of prepackaged versions of botan on
+operating systems that support it), you can instead ignore
+``botan_all.h`` and use the headers from
+``build/include`` as normal.
+
Modules Relying on Third Party Libraries
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -196,27 +214,6 @@ enabled at build time; these include:
required. Note that (unlike GNU MP) OpenSSL's versions are not
always faster than the versions built into botan.
-.. _amalgamation:
-
-Amalgamation
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-You can also configure Botan to be built using only a single source
-file; this is quite convenient if you plan to embed the library into
-another application. To do so, run ``configure.py`` with
-whatever arguments you would ordinarily use, along with the option
-``--gen-amalgamation``. This will create two (rather large)
-files, ``botan_all.h`` and ``botan_all.cpp``.
-
-Whenever you would have included a botan header, you can then include
-``botan_all.h``, and include ``botan_all.cpp`` along
-with the rest of the source files in your build. If you want to be
-able to easily switch between amalgamated and non-amalgamated versions
-(for instance to take advantage of prepackaged versions of botan on
-operating systems that support it), you can instead ignore
-``botan_all.h`` and use the headers from
-``build/include`` as normal.
-
Multiple Builds
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/doc/conf.py b/doc/conf.py
index f4884cb69..d802afa28 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -70,11 +70,11 @@ release = '%d.%d.%d' % (botan_version.release_major,
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
+today_fmt = '%Y-%m-%d'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
-exclude_patterns = ['_build']
+exclude_patterns = []
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
@@ -115,7 +115,7 @@ html_theme = 'default'
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
-#html_title = None
+html_title = 'Botan'
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
@@ -132,7 +132,7 @@ html_theme = 'default'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
+html_static_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
@@ -217,12 +217,3 @@ latex_show_urls = True
# If false, no module index is generated.
#latex_domain_indices = True
-
-# -- Options for manual page output --------------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [
- ('index', 'botan', u'botan Documentation',
- [u'Jack Lloyd'], 1)
-]
diff --git a/doc/contrib.txt b/doc/contrib.txt
deleted file mode 100644
index 2ad420747..000000000
--- a/doc/contrib.txt
+++ /dev/null
@@ -1,71 +0,0 @@
-
-Contributing
-========================================
-
-Contributions to the library are most certainly welcome. To increase
-the chances your patch will actually make it into releases in a timely
-fashion, here are some guidelines for patch submission.
-
-Getting The Latest Sources
-----------------------------------------
-
-Botan's development occurs using a distributed version control system
-called `Monotone <http://www.monotone.ca>`_.
-
-The main branch of development occurs on the branch named
-``net.randombit.botan``; this is probably the branch you want,
-especially if you are planning on making major changes. To
-download that branch and set up a new workspace, run::
-
- $ mtn db init --db=botan.mtn
- $ mtn pull --db=botan.mtn randombit.net 'net.randombit.botan'
- [...]
- $ mtn checkout --db=botan.mtn --branch=net.randombit.botan
- [...]
-
-By default the ``checkout`` command will place the workspace in a
-directory with the same name as the branch you are checking out. If
-you want a different directory name, just include it after the
-``--branch`` option (you can also rename this directory at any time).
-
-If this is the first time you've connected to the server, Monotone
-will print::
-
- mtn: first time connecting to server randombit.net
- mtn: I'll assume it's really them, but you might want to double-check
- mtn: their key's fingerprint: 8c0b868f2247215c63c96983b1c8ca0f0f0cfd9a
-
-The fingerprint shown above was the correct one as of September 21,
-2010.
-
-To pull further changes, from anywhere in the workspace run these
-commands::
-
- $ mtn pull
- [...]
- $ mtn update
- [summary of changes]
-
-The ``mtn update`` command will give you a summary of which files
-changed; to view the full changelog, run ``mtn log``.
-
-Monotone's distributed nature means you can check into your database
-while continuing to merge changes made upstream. This is particularly
-useful if your change is large or invasive, as you can checkpoint your
-progress over time.
-
-If you are making a large number of changes, you may want to start up
-a new branch that occasionally merges against the mainline; check the
-monotone documentation for details.
-
-After you finish your changes, you can review them using ``mtn diff``
-to diff against the latest official head; send the output to the
-mailing list for review and inclusion.
-
-Don't forget to update the file ``credits.txt`` with your information,
-if you want to be listed as a contributor. Also, if your patch is
-substantial enough to be considered copyrightable, add yourself to
-``license.txt``.
-
-Patches are best directed to the `botan-devel
-<http://lists.randombit.net/mailman/listinfo/botan-devel>`_.
diff --git a/doc/download.txt b/doc/download.txt
new file mode 100644
index 000000000..8d4e2436c
--- /dev/null
+++ b/doc/download.txt
@@ -0,0 +1,103 @@
+
+Getting The Latest Sources
+========================================
+
+Latest Releases
+----------------------------------------
+
+All releases are signed with a :doc:`PGP key <pgpkey>`.
+
+Unsure which release you want? Check the :ref:`FAQ <devel_vs_stable>`.
+
+.. only:: not website
+
+ .. note::
+
+ If you are viewing this documentation offline, a more recent
+ version may be available at http://botan.randombit.net/download.html
+
+Current Stable Release
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The current stable release is `1.8.11
+<http://botan.randombit.net/news/releases/1_8_11.html>`_ which was
+released on 2010-11-02.
+
+Sources:
+
+`1.8.11 tar/gz <http://botan.randombit.net/files/Botan-1.8.11.tgz>`_
+(`1.8.11 tar/gz sig <http://botan.randombit.net/files/Botan-1.8.11.tgz.asc>`_),
+
+`1.8.11 tar/bzip <http://botan.randombit.net/files/Botan-1.8.11.tbz>`_
+(`1.8.11 tar/bzip sig <http://botan.randombit.net/files/Botan-1.8.11.tbz.asc>`_)
+
+Windows binary installer for use with Visual C++ 2008:
+
+`1.8.11 x86-32 installer
+<http://botan.randombit.net/files/win32/botan-1.8.11_win32.exe>`_
+
+`1.8.11 x86-64 installer
+<http://botan.randombit.net/files/win32/botan-1.8.11_win64.exe>`_
+
+Current Development Release
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The current development release is `1.9.16
+<http://botan.randombit.net/news/releases/1_9_16.html>`_ which was
+released on 2011-04-11.
+
+Sources:
+
+`1.9.16 tar/gz <http://botan.randombit.net/files/Botan-1.9.16.tgz>`_
+(`1.9.16 tar/gz sig <http://botan.randombit.net/files/Botan-1.9.16.tgz.asc>`_),
+
+`1.9.16 tar/bzip <http://botan.randombit.net/files/Botan-1.9.16.tbz>`_
+(`1.9.16 tar/bzip sig <http://botan.randombit.net/files/Botan-1.9.16.tbz.asc>`_)
+
+Windows binary installer for use with Visual C++ 2010:
+
+`1.9.17-pre x86-32 installer
+<http://botan.randombit.net/files/win32/botan-1.9.17_win32.exe>`_
+
+`1.9.17-pre x86-64 installer
+<http://botan.randombit.net/files/win32/botan-1.9.17_win64.exe>`_
+
+Accessing Version Control
+----------------------------------------
+
+Botan's development occurs using a distributed version control system
+called `Monotone <http://www.monotone.ca>`_.
+
+The main branch of development occurs on the branch named
+``net.randombit.botan``; this is probably the branch you want. To
+download that branch and set up a new workspace, run::
+
+ $ mtn db init --db=botan.mtn
+ $ mtn pull --db=botan.mtn randombit.net 'net.randombit.botan'
+ [...]
+ $ mtn checkout --db=botan.mtn --branch=net.randombit.botan
+ [...]
+
+By default the ``checkout`` command will place the workspace in a directory
+with the same name as the branch you are checking out. If you want a
+different directory name, just include it after the ``--branch`` option (you
+can also rename this directory at any time).
+
+If this is the first time you've connected to the server, Monotone
+will print::
+
+ mtn: first time connecting to server randombit.net
+ mtn: I'll assume it's really them, but you might want to double-check
+ mtn: their key's fingerprint: 8c0b868f2247215c63c96983b1c8ca0f0f0cfd9a
+
+The fingerprint shown above was the correct one as of September 21, 2010.
+
+To pull further changes, from anywhere in the workspace run these commands::
+
+ $ mtn pull
+ [...]
+ $ mtn update
+ [summary of changes]
+
+The ``mtn update`` command will give you a summary of which files changed;
+to view the full changelog, run ``mtn log``.
diff --git a/doc/examples.txt b/doc/examples.txt
deleted file mode 100644
index b9296829a..000000000
--- a/doc/examples.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-
-Examples
-========================================
-
-X.509 Certificate Examples
-----------------------------------------
-
-PKCS #10 Certificate Requests
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. literalinclude:: examples/pkcs10.cpp
-
-Self Signed Certificate
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Generate a 2048 bit RSA key, and then create a self-signed X.509v3
-certificate with that key. If the do_CA variable is set to true, then
-it will be marked for CA use, otherwise it will get extensions
-appropriate for use with a client certificate. The private key is
-stored as an encrypted PKCS #8 object in another file.
-
-.. literalinclude:: examples/self_sig.cpp
-
-Certificate Authority
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Implement the functionality of a simple CA: read in a CA certificate,
-the associated private key, and a PKCS #10 certificate request. Sign
-the request and print the new certificate to stdout.
-
-File names are hardcoded for simplicity. The CA certificate is
-expected in "cacert.pem", the private key is expected in
-"caprivate.pem", and "req.pem" is a PKCS #10 certificate request.
-
-.. literalinclude:: examples/ca.cpp
-
-ASN.1 Parsing
-----------------------------------------
-
-This example is a simple ASN.1 parser
-
-.. literalinclude:: examples/asn1.cpp
diff --git a/doc/faq.txt b/doc/faq.txt
index 822deaa5d..38be253a7 100644
--- a/doc/faq.txt
+++ b/doc/faq.txt
@@ -1,6 +1,4 @@
-.. _faq:
-
Frequently Asked Questions
========================================
@@ -14,6 +12,8 @@ standards and de-facto standards like X.509v3 certificates, and
various useful constructs like format-preserving encryption, all or
nothing transforms, and secret splitting.
+.. _devel_vs_stable:
+
Which release should I use?
----------------------------------------
diff --git a/doc/filters.txt b/doc/filters.txt
index 7df1da5af..1af8c10f3 100644
--- a/doc/filters.txt
+++ b/doc/filters.txt
@@ -658,8 +658,7 @@ byte onto the next filter -- a 1 or a 0, which specifies whether the
signature verified or not (respectively).
For more information about PK algorithms (including creating the
-appropriate objects to pass to the constructors), see
-:ref:`public_key_crypto`.
+appropriate objects to pass to the constructors), see :doc:`pubkey`.
Encoders
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/doc/firststep.txt b/doc/firststep.txt
index 0576e9c06..fb4eb583e 100644
--- a/doc/firststep.txt
+++ b/doc/firststep.txt
@@ -16,19 +16,22 @@ Initializing the Library
There is a set of core services that the library needs access to while
it is performing requests. To ensure these are set up, you must create
-a ``LibraryInitializer`` object (usually called 'init' in Botan
-example code; 'botan\_library' or 'botan\_init' may make more sense in
-real applications) prior to making any calls to Botan. This object's
-lifetime must exceed that of all other Botan objects your application
-creates; for this reason the best place to create the
-``LibraryInitializer`` is at the start of your ``main``
-function, since this guarantees that it will be created first and
-destroyed last (via standard C++ RAII rules). The initializer does
-things like setting up the memory allocation system and algorithm
-lookup tables, finding out if there is a high resolution timer
-available to use, and similar such matters. With no arguments, the
-library is initialized with various default settings. So (unless you
-are writing threaded code; see below), all you need is::
+an object of type
+
+.. cpp:class:: LibraryInitializer
+
+prior to making any other library calls. Typically this will be named
+something like ``init`` or ``botan_init``. The object lifetime must
+exceed that of all other Botan objects your application creates; for
+this reason the best place to create the ``LibraryInitializer`` is at
+the start of your ``main`` function, since this guarantees that it
+will be created first and destroyed last (via standard C++ RAII
+rules). The initializer does things like setting up the memory
+allocation system and algorithm lookup tables, finding out if there is
+a high resolution timer available to use, and similar such
+matters. With no arguments, the library is initialized with various
+default settings. So (unless you are writing threaded code; see
+below), all you need is::
Botan::LibraryInitializer init;
diff --git a/doc/index.txt b/doc/index.txt
index 2f55ea362..442d0b6b9 100644
--- a/doc/index.txt
+++ b/doc/index.txt
@@ -1,13 +1,119 @@
-Botan Reference Manual
+.. _contents:
+
+A friendly C++ crypto library
+========================================
+
+Botan is a :doc:`BSD-licensed <license>` crypto library for C++. It
+provides applications with most any :doc:`cryptographic algorithm
+<algos>` you might be looking for, along with :doc:`SSL/TLS <ssl>`,
+:doc:`X.509 certificates and CRLs <x509>`, a :doc:`pipeline-style
+message processing system <filters>`, and a wide variety of other
+features. A third party open source implementation of `SSHv2
+<http://www.netsieben.com/products/ssh/>`_ that uses botan is also
+available.
+
+.. only:: html and website
+
+ See :doc:`download` for information about getting the latest version.
+
+The core of botan is written in C++98 with no dependencies besides the
+STL and the rest of the ISO standard library, but the library also
+includes optional modules which make further assumptions about their
+environment, providing features such as compression (using zlib or
+bzip2), entropy gathering, and secure memory allocation. Assembly
+implementations of key algorithms like SHA-1 and multiple precision
+integer routines for x86 and x86-64 processors are also included.
+
+It runs on most common operating systems and can be used with a number
+of different commercial and open source compilers. The :doc:`build log
+<build_log>` contains information about recently tested targets. It is
+already included in most major package distributions, including
+\
+`Fedora <https://admin.fedoraproject.org/pkgdb/acls/name/botan>`_,
+`EPEL <http://download.fedora.redhat.com/pub/epel/beta/6/SRPMS/repoview/botan.html>`_ (for RHEL/CentOS),
+`Debian <http://packages.debian.org/search?keywords=libbotan>`_,
+`Ubuntu <http://packages.ubuntu.com/search?keywords=botan>`_,
+`Gentoo <http://packages.gentoo.org/package/botan>`_,
+`Arch Linux <http://www.archlinux.org/packages/extra/x86_64/botan/>`_,
+`Slackbuild <http://slackbuilds.org/result/?search=Botan>`_,
+`FreeBSD <http://www.freshports.org/security/botan>`_,
+`NetBSD <ftp://ftp.netbsd.org/pub/pkgsrc/current/pkgsrc/security/botan/README.html>`_,
+`Cygwin <http://cygwin.com/packages/botan/>`_,
+`MacPorts <http://www.macports.org/ports.php?by=name&amp;substr=botan>`_,
+`OpenPKG <http://www.openpkg.org/product/packages/?package=botan>`_, and
+`T2 SDE <http://www.t2-project.org/packages/botan.html>`_ and has
+more than a few :doc:`known users <users>`.
+
+It was started as a personal project by `Jack Lloyd
+<http:://www.randombit.net>`_, who continues to be the maintainer and
+release manager. Since the first release in 2001, many individuals and
+organizations have contributed bug fixes and new features. There have
+been over 150 releases in the decade since the first publicly released
+version; the :doc:`release notes <log>` and `news archive
+<http://botan.randombit.net/news>`_ have more information about the
+release history.
+
+In addition to C++ you can use botan from Python or Perl, though the
+current bindings only wrap portions of the library.
+
+See the :doc:`faq` for a list of common questions and answers.
+
+If you need help or have questions, send a mail to the `development
+mailing list
+<http://lists.randombit.net/mailman/listinfo/botan-devel/>`_.
+"Philosophical" bug reports, announcements of programs using the
+library, and related topics are also welcome. :doc:`Commercial support
+options <support>` are also available.
+
+If you find what you believe to be a bug, please file a ticket in
+`Bugzilla <http://bugs.randombit.net/>`_.
+
+A useful reference while reading this manual is the `Doxygen
+documentation <http://botan.randombit.net/doxygen>`_.
+
+Recommended Reading
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+It's a very good idea if you have some knowledge of cryptography
+*before* trying to use the library. This is an area where it is very
+easy to make mistakes, and where things are often subtle and/or
+counterintuitive. Obviously the library tries to provide things at a
+high level precisely to minimize the number of ways things can go
+wrong, but naive use will almost certainly not result in a secure
+system.
+
+Especially recommended are:
+
+- *Cryptography Engineering*
+ Niels Ferguson, Bruce Schneier, and Tadayoshi Kohno
+
+- *Security Engineering -- A Guide to Building Dependable Distributed Systems*
+ Ross Anderson
+
+- *Handbook of Applied Cryptography*
+ Alfred J. Menezes, Paul C. Van Oorschot, and Scott A. Vanstone
+ (`available online <http://www.cacr.math.uwaterloo.ca/hac/>`_)
+
+Documentation Contents
=================================
-Contents:
+.. toctree::
+ :hidden:
+
+ algos
+ build_log
+ download
+ faq
+ license
+ log
+ pgpkey
+ support
+ users
.. toctree::
:maxdepth: 2
- intro
building
firststep
filters
@@ -22,17 +128,7 @@ Contents:
passhash
rng
fpe
- examples
- algos
- faq
- pgpkeys
- license
credits
- contrib
- support
- users
- build_log
- log
Indices and tables
==================
diff --git a/doc/intro.txt b/doc/intro.txt
deleted file mode 100644
index 01e65da86..000000000
--- a/doc/intro.txt
+++ /dev/null
@@ -1,80 +0,0 @@
-
-Introduction
-=================================
-
-Botan is a BSD-licensed crypto library for C++. It provides
-applications with the ability to use a number of cryptographic
-algorithms, as well as SSL/TLS, X.509 certificates and CRLs, PKCS #10
-certificate requests, a filter/pipe message processing system, and a
-wide variety of other features. A third party open source
-implementation of `SSHv2 <http://www.netsieben.com/products/ssh/>`_
-that uses botan is also available.
-
-The core of botan is written in C++98 with no dependencies besides the
-STL and the rest of the ISO standard library, but the library also
-includes optional modules which make further assumptions about their
-environment, providing features such as compression (using zlib or
-bzip2), entropy gathering, and secure memory allocation. Assembly
-implementations of key algorithms like SHA-1 and multiple precision
-integer routines for x86 and x86-64 processors are also included.
-
-It runs on most common operating systems and can be used with a number
-of different commercial and open source compilers. It is already
-included in most major Linux and BSD distros, as well as in Cygwin and
-MacPorts. The :ref:`build log <build_log>` contains information about
-recently tested targets.
-
-The primary system targets are 32 and 64 bit CPUs, with a flat memory
-address space of at least 32 bits. Given the choice between optimizing
-for 32 bit systems and 64 bit systems, 64 bit is preferred, on the
-general theory that where performance is a real concern, modern 64 bit
-processors are the obvious choice. Smaller devices like handhelds,
-settop boxes, and smart phones may also be capable.
-
-It was started as a personal project by `Jack Lloyd
-<http:://www.randombit.net>`_, who continues to be the maintainer and
-release manager. Since the first release in 2001, many individuals and
-organizations have contributed bug fixes and new features. There have
-been over 140 releases in the decade since the first publicly released
-version; the :ref:`release notes <relnotes>` and news archive have
-more information about the release history.
-
-In addition to C++ you can use botan from Python or Perl, though the
-current bindings only wrap portions of the library.
-
-See the :ref:`faq` for a list of common questions and answers.
-
-If you need help or have questions, send a mail to the `development
-mailing list
-<http://lists.randombit.net/mailman/listinfo/botan-devel/>`_.
-"Philosophical" bug reports, announcements of programs using the
-library, and related topics are also welcome.
-
-If you find what you believe to be a bug, please file a ticket in
-`Bugzilla <http://bugs.randombit.net/>`_.
-
-A useful reference while reading this manual is the `Doxygen
-documentation <http://botan.randombit.net/doxygen>`_.
-
-Recommended Reading
----------------------------------
-
-It's a very good idea if you have some knowledge of cryptography
-*before* trying to use the library. This is an area where it is very
-easy to make mistakes, and where things are often subtle and/or
-counterintuitive. Obviously the library tries to provide things at
-a high level precisely to minimize the number of ways things can go
-wrong, but naive use will almost certainly not result in a secure
-system.
-
-Especially recommended are:
-
- - *Cryptography Engineering*
- Niels Ferguson, Bruce Schneier, and Tadayoshi Kohno
-
- - *Security Engineering -- A Guide to Building Dependable Distributed Systems*
- Ross Anderson
-
- - *Handbook of Applied Cryptography* Alfred J. Menezes, Paul C. Van
- Oorschot, and Scott A. Vanstone (available online at
- http://www.cacr.math.uwaterloo.ca/hac/)
diff --git a/doc/old/tutorial.tex b/doc/old/tutorial.tex
deleted file mode 100644
index f220d765a..000000000
--- a/doc/old/tutorial.tex
+++ /dev/null
@@ -1,880 +0,0 @@
-\documentclass{article}
-
-\setlength{\textwidth}{6.5in} % 1 inch side margins
-\setlength{\textheight}{9in} % ~1 inch top and bottom margins
-
-\setlength{\headheight}{0in}
-\setlength{\topmargin}{0in}
-\setlength{\headsep}{0in}
-
-\setlength{\oddsidemargin}{0in}
-\setlength{\evensidemargin}{0in}
-
-\title{\textbf{Botan Tutorial}}
-\author{Jack Lloyd \\
- \texttt{[email protected]}}
-\date{2009/07/08}
-
-\newcommand{\filename}[1]{\texttt{#1}}
-\newcommand{\manpage}[2]{\texttt{#1}(#2)}
-
-\newcommand{\macro}[1]{\texttt{#1}}
-
-\newcommand{\function}[1]{\textbf{#1}}
-\newcommand{\type}[1]{\texttt{#1}}
-\renewcommand{\arg}[1]{\textsl{#1}}
-\newcommand{\variable}[1]{\textsl{#1}}
-
-\begin{document}
-
-\maketitle
-
-\tableofcontents
-
-\parskip=5pt
-\pagebreak
-
-\section{Introduction}
-
-This document essentially sets up various simple scenarios and then
-shows how to solve the problems using Botan. It's fairly simple, and
-doesn't cover many of the available APIs and algorithms, especially
-the more obscure or unusual ones. It is a supplement to the API
-documentation and the example applications, which are included in the
-distribution.
-
-To quote the Perl man page: '``There's more than one way to do it.''
-Divining how many more is left as an exercise to the reader.'
-
-This is \emph{not} a general introduction to cryptography, and most simple
-terms and ideas are not explained in any great detail.
-
-Finally, most of the code shown in this tutorial has not been tested, it was
-just written down from memory. If you find errors, please let me know.
-
-\section{Initializing the Library}
-
-The first step to using Botan is to create a \type{LibraryInitializer} object,
-which handles creating various internal structures, and also destroying them at
-shutdown. Essentially:
-
-\begin{verbatim}
-#include <botan/botan.h>
-/* include other headers here */
-
-int main()
- {
- LibraryInitializer init;
- /* now do stuff */
- return 0;
- }
-\end{verbatim}
-
-\section{Hashing a File}
-
-\section{Symmetric Cryptography}
-
-\subsection{Encryption with a passphrase}
-
-Probably the most common crypto problem is encrypting a file (or some data that
-is in-memory) using a passphrase. There are a million ways to do this, most of
-them bad. In particular, you have to protect against weak passphrases,
-people reusing a passphrase many times, accidental and deliberate modification,
-and a dozen other potential problems.
-
-We'll start with a simple method that is commonly used, and show the problems
-that can arise. Each subsequent solution will modify the previous one to
-prevent one or more common problems, until we arrive at a good version.
-
-In these examples, we'll always use Serpent in Cipher-Block Chaining
-(CBC) mode. Whenever we need a hash function, we'll use SHA-256, since
-that is a common and well-known hash that is thought to be secure.
-
-In all examples, we choose to derive the Initialization Vector (IV) from the
-passphrase. Another (probably more common) alternative is to generate the IV
-randomly and include it at the beginning of the message. Either way is
-acceptable, and can be secure. The method used here was chosen to make for more
-interesting examples (because it's harder to get right), and may not be an
-appropriate choice for some environments.
-
-First, some notation. The passphrase is stored as a \type{std::string} named
-\variable{passphrase}. The input and output files (\variable{infile} and
-\variable{outfile}) are of types \type{std::ifstream} and \type{std::ofstream}
-(respectively).
-
-\subsubsection{First try}
-
-We hash the passphrase with SHA-256, and use the resulting hash to key
-Serpent. To generate the IV, we prepend a single '0' character to the
-passphrase, hash it, and truncate it to 16 bytes (which is Serpent's
-block size).
-
-\begin{verbatim}
- HashFunction* hash = get_hash("SHA-256");
-
- SymmetricKey key = hash->process(passphrase);
- SecureVector<byte> raw_iv = hash->process('0' + passphrase);
- InitializationVector iv(raw_iv, 16);
-
- Pipe pipe(get_cipher("Serpent/CBC/PKCS7", key, iv, ENCRYPTION));
-
- pipe.start_msg();
- infile >> pipe;
- pipe.end_msg();
- outfile << pipe;
-\end{verbatim}
-
-\subsubsection{Problem 1: Buffering}
-
-There is a problem with the above code, if the input file is fairly large as
-compared to available memory. Specifically, all the encrypted data is stored
-in memory, and then flushed to \variable{outfile} in a single go at the very
-end. If the input file is big (say, a gigabyte), this will be most problematic.
-
-The solution is to use a \type{DataSink} to handle the output for us (writing
-to \arg{outfile} will be implicit with writing to the \type{Pipe}). We can do
-this by replacing the last few lines with:
-
-\begin{verbatim}
- Pipe pipe(get_cipher("Serpent/CBC/PKCS7", key, iv, ENCRYPTION),
- new DataSink_Stream(outfile));
-
- pipe.start_msg();
- infile >> pipe;
- pipe.end_msg();
-\end{verbatim}
-
-\subsubsection{Problem 2: Deriving the key and IV}
-
-Hash functions like SHA-256 are deterministic; if the same passphrase
-is supplied twice, then the key (and in our case, the IV) will be the
-same. This is very dangerous, and could easily open the whole system
-up to attack. What we need to do is introduce a salt (or nonce) into
-the generation of the key from the passphrase. This will mean that the
-key will not be the same each time the same passphrase is typed in by
-a user.
-
-There is another problem with using a bare hash function to derive
-keys. While it's inconceivable (based on our current understanding of
-thermodynamics and theories of computation) that an attacker could
-brute-force a 256-bit key, it would be fairly simple for them to
-compute the SHA-256 hashes of various common passwords ('password',
-the name of the dog, the significant other's middle name, favorite
-sports team) and try those as keys. So we want to slow the attacker
-down if we can, and an easy way to do that is to iterate the hash
-function a bunch of times (say, 1024 to 4096 times). This will involve
-only a small amount of effort for a legitimate user (since they only
-have to compute the hashes once, when they type in their passphrase),
-but an attacker, trying out a large list of potential passphrases,
-will be seriously annoyed (and slowed down) by this.
-
-In this iteration of the example, we'll kill these two birds with one
-stone, and derive the key from the passphrase using a PBKDF
-(Password-Based Key Derivation Function). In this example, we use
-PBKDF2 with Hash Message Authentication Code (HMAC(SHA-256)), which is
-specified in PKCS \#5. We replace the first four lines of code from
-the first example with:
-
-\begin{verbatim}
- PBKDF* pbkdf = get_pbkdf("PBKDF2(SHA-256)");
- // hard-coded iteration count for simplicity; should be sufficient
- pbkdf->set_iterations(10000);
- // 8 octets == 64-bit salt; again, good enough
- pbkdf->new_random_salt(8);
- SecureVector<byte> the_salt = pbkdf->current_salt();
-
- // 48 octets == 32 for key + 16 for IV
- SecureVector<byte> key_and_IV = pbkdf->derive_key(48, passphrase).bits_of();
-
- SymmetricKey key(key_and_IV, 32);
- InitializationVector iv(key_and_IV + 32, 16);
-\end{verbatim}
-
-To complete the example, we have to remember to write out the salt (stored in
-\variable{the\_salt}) at the beginning of the file. The receiving side needs to
-know this value in order to restore it (by calling the \variable{pbkdf} object's
-\function{change\_salt} function) so it can derive the same key and IV from the
-passphrase.
-
-\subsubsection{Problem 3: Protecting against modification}
-
-As it is, an attacker can undetectably alter the message while it is
-in transit. It is vital to remember that encryption does not imply
-authentication (except when using special modes that are specifically
-designed to provide authentication along with encryption, like OCB and
-EAX). For this purpose, we will append a message authentication code
-to the encrypted message. Specifically, we will generate an extra 256
-bits of key data, and use it to key the ``HMAC(SHA-256)'' MAC
-function. We don't want to have the MAC and the cipher to share the
-same key; that is very much a no-no.
-
-\begin{verbatim}
- // 80 octets == 32 for cipher key + 16 for IV + 32 for hmac key
- SecureVector<byte> keys_and_IV = pbkdf->derive_key(80, passphrase);
-
- SymmetricKey key(keys_and_IV, 32);
- InitializationVector iv(keys_and_IV + 32, 16);
- SymmetricKey mac_key(keys_and_IV + 32 + 16, 32);
-
- Pipe pipe(new Fork(
- new Chain(
- get_cipher("Serpent/CBC/PKCS7", key, iv, ENCRYPTION),
- new DataSink_Stream(outfile)
- ),
- new MAC_Filter("HMAC(SHA-256)", mac_key)
- )
- );
-
- pipe.start_msg();
- infile >> pipe;
- pipe.end_msg();
-
- // now read the MAC from message #2. Message numbers start from 0
- SecureVector<byte> hmac = pipe.read_all(1);
- outfile.write((const char*)&hmac[0], hmac.size());
-\end{verbatim}
-
-The receiver can check the size of the file (in bytes), and since it knows how
-long the MAC is, can figure out how many bytes of ciphertext there are. Then it
-reads in that many bytes, sending them to a Serpent/CBC decryption object
-(which could be obtained by calling \verb|get_cipher| with an argument of
-\type{DECRYPTION} instead of \type{ENCRYPTION}), and storing the final bytes to
-authenticate the message with.
-
-\subsubsection{Problem 4: Cleaning up the key generation}
-
-The method used to derive the keys and IV is rather inelegant, and it would be
-nice to clean that up a bit, algorithmically speaking. A nice solution for this
-is to generate a master key from the passphrase and salt, and then generate the
-two keys and the IV (the cryptovariables) from that.
-
-Starting from the master key, we derive the cryptovariables using a KDF
-algorithm, which is designed, among other things, to ``separate'' keys so that
-we can derive several different keys from the single master key. For this
-purpose, we will use KDF2, which is a generally useful KDF function (defined in
-IEEE 1363a, among other standards). The use of different labels (``cipher
-key'', etc) makes sure that each of the three derived variables will have
-different values.
-
-\begin{verbatim}
- PBKDF* pbkdf = get_pbkdf("PBKDF2(SHA-256)");
- // hard-coded iteration count for simplicity; should be sufficient
- pbkdf->set_iterations(10000);
- // 8 octet == 64-bit salt; again, good enough
- pbkdf->new_random_salt(8);
- // store the salt so we can write it to a file later
- SecureVector<byte> the_salt = pbkdf->current_salt();
-
- SymmetricKey master_key = pbkdf->derive_key(48, passphrase);
-
- KDF* kdf = get_kdf("KDF2(SHA-256)");
-
- SymmetricKey key = kdf->derive_key(32, master_key, "cipher key");
- SymmetricKey mac_key = kdf->derive_key(32, master_key, "hmac key");
- InitializationVector iv = kdf->derive_key(16, master_key, "cipher iv");
-\end{verbatim}
-
-\subsubsection{Final version}
-
-Here is the final version of the encryption code, with all the changes we've
-made:
-
-\begin{verbatim}
- PBKDF* pbkdf = get_pbkdf("PBKDF2(SHA-256)");
- pbkdf->set_iterations(10000);
- pbkdf->new_random_salt(8);
- SecureVector<byte> the_salt = pbkdf->current_salt();
-
- SymmetricKey master_key = pbkdf->derive_key(48, passphrase);
-
- KDF* kdf = get_kdf("KDF2(SHA-256)");
-
- SymmetricKey key = kdf->derive_key(32, master_key, "cipher key");
- SymmetricKey mac_key = kdf->derive_key(32, masterkey, "hmac key");
- InitializationVector iv = kdf->derive_key(16, masterkey, "cipher iv");
-
- Pipe pipe(new Fork(
- new Chain(
- get_cipher("Serpent/CBC/PKCS7", key, iv, ENCRYPTION),
- new DataSink_Stream(outfile)
- ),
- new MAC_Filter("HMAC(SHA-256)", mac_key)
- )
- );
-
- outfile.write((const char*)&the_salt[0], the_salt.size());
-
- pipe.start_msg();
- infile >> pipe;
- pipe.end_msg();
-
- SecureVector<byte> hmac = pipe.read_all(1);
- outfile.write((const char*)&hmac[0], hmac.size());
-\end{verbatim}
-
-\subsubsection{Another buffering technique}
-
-Sometimes the use of \type{DataSink\_Stream} is not practical for whatever
-reason. In this case, an alternate buffering mechanism might be useful. Here is
-some code which will write all the processed data as quickly as possible, so
-that memory pressure is reduced in the case of large inputs.
-
-\begin{verbatim}
- pipe.start_msg();
- SecureBuffer<byte, 1024> buffer;
- while(infile.good())
- {
- infile.read((char*)&buffer[0], buffer.size());
- u32bit got_from_infile = infile.gcount();
- pipe.write(buffer, got_from_infile);
-
- if(infile.eof())
- pipe.end_msg();
-
- while(pipe.remaining() > 0)
- {
- u32bit buffered = pipe.read(buffer, buffer.size());
- outfile.write((const char*)&buffer[0], buffered);
- }
- }
- if(infile.bad() || (infile.fail() && !infile.eof()))
- throw Some_Exception();
-\end{verbatim}
-
-\pagebreak
-
-\subsection{Authentication}
-
-After doing the encryption routines, doing message authentication keyed off a
-passphrase is not very difficult. In fact it's much easier than the encryption
-case, for the following reasons: a) we only need one key, and b) we don't have
-to store anything, so all the input can be done in a single step without
-worrying about it taking up a lot of memory if the input file is large.
-
-In this case, we'll hex-encode the salt and the MAC, and output them both to
-standard output (the salt followed by the MAC).
-
-\begin{verbatim}
- PBKDF* pbkdf = get_pbkdf("PBKDF2(SHA-256)");
- pbkdf->set_iterations(10000);
- pbkdf->new_random_salt(8);
- OctetString the_salt = pbkdf->current_salt();
-
- SymmetricKey hmac_key = pbkdf->derive_key(32, passphrase);
-
- Pipe pipe(new MAC_Filter("HMAC(SHA-256)", mac_key),
- new Hex_Encoder
- );
-
- std::cout << the_salt.to_string(); // hex encoded
-
- pipe.start_msg();
- infile >> pipe;
- pipe.end_msg();
- std::cout << pipe.read_all_as_string() << std::endl;
-\end{verbatim}
-
-\subsection{User Authentication}
-
-Doing user authentication off a shared passphrase is fairly easy. Essentially,
-a challenge-response protocol is used - the server sends a random challenge,
-and the client responds with an appropriate response to the challenge. The idea
-is that only someone who knows the passphrase can generate or check to see if a
-response is valid.
-
-Let's say we use 160-bit (20 byte) challenges, which seems fairly
-reasonable. We can create this challenge using the global random
-number generator (RNG):
-
-\begin{verbatim}
- byte challenge[20];
- Global_RNG::randomize(challenge, sizeof(challenge), Nonce);
- // send challenge to client
-\end{verbatim}
-
-After reading the challenge, the client generates a response based on
-the challenge and the passphrase. In this case, we will do it by
-repeatedly hashing the challenge, the passphrase, and (if applicable)
-the previous digest. We iterate this construction 10000 times, to make
-brute force attacks on the passphrase hard to do. Since we are already
-using 160-bit challenges, a 160-bit response seems warranted, so we'll
-use SHA-1.
-
-\begin{verbatim}
- HashFunction* hash = get_hash("SHA-1");
- SecureVector<byte> digest;
- for(u32bit j = 0; j != 10000; j++)
- {
- hash->update(digest, digest.size());
- hash->update(passphrase);
- hash->update(challenge, challenge.size());
- digest = hash->final();
- }
- delete hash;
- // send value of digest to the server
-\end{verbatim}
-
-Upon receiving the response from the client, the server computes what the
-response should have been based on the challenge it sent out, and the
-passphrase. If the two responses match, the client is authenticated.
-Otherwise, it is not.
-
-An alternate method is to use PBKDF2 again, using the challenge as the salt. In
-this case, the response could (for example) be the hash of the key produced by
-PBKDF2. There is no reason to have an explicit iteration loop, as PBKDF2 is
-designed to prevent dictionary attacks (assuming PBKDF2 is set up for a large
-iteration count internally).
-
-\pagebreak
-
-\section{Public Key Cryptography}
-
-\subsection{Basic Operations}
-
-In this section, we'll assume we have a \type{X509\_PublicKey*} named
-\arg{pubkey}, and, if necessary, a private key type (a
-\type{PKCS8\_PrivateKey*}) named \arg{privkey}. A description of these types,
-how to create them, and related details appears later in this tutorial. In this
-section, we will use various functions that are defined in
-\filename{look\_pk.h} -- you will have to include this header explicitly.
-
-\subsubsection{Encryption}
-
-Basically, pick an encoding method, create a \type{PK\_Encryptor} (with
-\function{get\_pk\_encryptor}()), and use it. But first we have to make sure
-the public key can actually be used for public key encryption. For encryption
-(and decryption), the key could be RSA, ElGamal, or (in future versions) some
-other public key encryption scheme, like Rabin or an elliptic curve scheme.
-
-\begin{verbatim}
- PK_Encrypting_Key* key = dynamic_cast<PK_Encrypting_Key*>(pubkey);
- if(!key)
- error();
- PK_Encryptor* enc = get_pk_encryptor(*key, "EME1(SHA-256)");
-
- byte msg[] = { /* ... */ };
-
- // will also accept a SecureVector<byte> as input
- SecureVector<byte> ciphertext = enc->encrypt(msg, sizeof(msg));
-\end{verbatim}
-
-\subsubsection{Decryption}
-
-This is essentially the same as the encryption operation, but using a private
-key instead. One major difference is that the decryption operation can fail due
-to the fact that the ciphertext was invalid (most common padding schemes, such
-as ``EME1(SHA-256)'', include various pieces of redundancy, which are checked
-after decryption).
-
-\begin{verbatim}
- PK_Decrypting_Key* key = dynamic_cast<PK_Decrypting_Key*>(privkey);
- if(!key)
- error();
- PK_Decryptor* dec = get_pk_decryptor(*key, "EME1(SHA-256)");
-
- byte msg[] = { /* ... */ };
-
- SecureVector<byte> plaintext;
-
- try {
- // will also accept a SecureVector<byte> as input
- plaintext = dec->decrypt(msg, sizeof(msg));
- }
- catch(Decoding_Error)
- {
- /* the ciphertext was invalid */
- }
-\end{verbatim}
-
-\subsubsection{Signature Generation}
-
-There is one difficulty with signature generation that does not occur with
-encryption or decryption. Specifically, there are various padding methods which
-can be useful for different signature algorithms, and not all are appropriate
-for all signature schemes. The following table breaks down what algorithms
-support which encodings:
-
-\begin{tabular}{|c|c|c|} \hline
-Signature Algorithm & Usable Encoding Methods & Preferred Encoding(s) \\ \hline
-DSA / NR & EMSA1 & EMSA1 \\ \hline
-RSA & EMSA1, EMSA2, EMSA3, EMSA4 & EMSA3, EMSA4 \\ \hline
-Rabin-Williams & EMSA2, EMSA4 & EMSA2, EMSA4 \\ \hline
-\end{tabular}
-
-For new applications, use EMSA4 with both RSA and Rabin-Williams, as it is
-significantly more secure than the alternatives. However, most current
-applications/libraries only support EMSA2 with Rabin-Williams and EMSA3 with
-RSA. Given this, you may be forced to use less secure encoding methods for the
-near future. In these examples, we punt on the problem, and hard-code using
-EMSA1 with SHA-256.
-
-\begin{verbatim}
- Public_Key* key = /* loaded or generated somehow */
- PK_Signer* signer = get_pk_signer(*key, "EMSA1(SHA-256)");
-
- byte msg[] = { /* ... */ };
-
- /*
- You can also repeatedly call update(const byte[], u32bit), followed
- by a call to signature(), which will return the final signature of
- all the data that was passed through update(). sign_message() is
- just a stub that calls update() once, and returns the value of
- signature().
- */
-
- SecureVector<byte> signature = signer->sign_message(msg, sizeof(msg));
-\end{verbatim}
-
-\pagebreak
-
-\subsubsection{Signature Verification}
-
-In addition to all the problems with choosing the correct padding method,
-there is yet another complication with verifying a signature. Namely, there are
-two varieties of signature algorithms - those providing message recovery (that
-is, the value that was signed can be directly recovered by someone verifying
-the signature), and those without message recovery (the verify operation simply
-returns if the signature was valid, without telling you exactly what was
-signed). This leads to two slightly different implementations of the
-verification operation, which user code has to work with. As you can see
-however, the implementation is still not at all difficult.
-
-\begin{verbatim}
- PK_Verifier* verifier = 0;
-
- PK_Verifying_with_MR_Key* key1 =
- dynamic_cast<PK_Verifying_with_MR_Key*>(pubkey);
- PK_Verifying_wo_MR_Key* key2 =
- dynamic_cast<PK_Verifying_wo_MR_Key*>(pubkey);
-
- if(key1)
- verifier = get_pk_verifier(*key1, "EMSA1(SHA-256)");
- else if(key2)
- verifier = get_pk_verifier(*key2, "EMSA1(SHA-256)");
- else
- error();
-
- byte msg[] = { /* ... */ };
- byte sig[] = { /* ... */ };
-
- /*
- Like PK_Signer, you can also do repeated calls to
- void update(const byte some_data[], u32bit length)
- followed by a call to
- bool check_signature(const byte the_sig[], u32bit length)
- which will return true (valid signature) or false (bad signature).
- The function verify_message() is a simple wrapper around update() and
- check_signature().
-
- */
- bool is_valid = verifier->verify_message(msg, sizeof(msg), sig, sizeof(sig));
-\end{verbatim}
-
-\subsubsection{Key Agreement}
-
-WRITEME
-
-\pagebreak
-
-\subsection{Working with Keys}
-
-\subsubsection{Reading Public Keys (X.509 format)}
-
-There are two separate ways to read X.509 public keys. Remember that the X.509
-public keys are simply that: public keys. There is no associated information
-(such as the owner of that key) included with the public key itself. If you
-need that kind of information, you'll need to use X.509 certificates.
-
-However, there are surely times when a simple public key is sufficient. The
-most obvious is when the key is implicitly trusted, for example if access
-and/or modification of it is controlled by something else (like filesystem
-ACLs). In other cases, it is a perfectly reasonable proposition to use them
-over the network as an anonymous key exchange mechanism. This is, admittedly,
-vulnerable to man-in-the-middle attacks, but it's simple enough that it's hard
-to mess up (see, for example, Peter Guttman's paper ``Lessons Learned in
-Implementing and Deploying Crypto Software'' in Usenix '02).
-
-The way to load a key is basically to set up a \type{DataSource} and then call
-\function{X509::load\_key}, which will return a \type{X509\_PublicKey*}. For
-example:
-
-\begin{verbatim}
- DataSource_Stream somefile("somefile.pem"); // has 3 public keys
- X509_PublicKey* key1 = X509::load_key(somefile);
- X509_PublicKey* key2 = X509::load_key(somefile);
- X509_PublicKey* key3 = X509::load_key(somefile);
- // Now we have them all loaded. Huzah!
-\end{verbatim}
-
-At this point you can use \function{dynamic\_cast} to find the operations the
-key supports (by seeing if a cast to \type{PK\_Encrypting\_Key},
-\type{PK\_Verifying\_with\_MR\_Key}, or \type{PK\_Verifying\_wo\_MR\_Key}
-succeeds).
-
-There is a variant of \function{X509::load\_key} (and of
-\function{PKCS8::load\_key}, described in the next section) which take a
-filename (as a \type{std::string}). These are just convenience functions which
-create the appropriate \type{DataSource} for you and call the main
-\function{X509::load\_key}.
-
-\subsubsection{Reading Private Keys (PKCS \#8 format)}
-
-This is very similar to reading raw public keys, with the difference that the
-key may be encrypted with a user passphrase:
-
-\begin{verbatim}
- // rng is a RandomNumberGenerator, like AutoSeeded_RNG
-
- DataSource_Stream somefile("somefile");
- std::string a_passphrase = /* get from the user */
- PKCS8_PrivateKey* key = PKCS8::load_key(somefile, rng, a_passphrase);
-\end{verbatim}
-
-You can, by the way, convert a \type{PKCS8\_PrivateKey} to a
-\type{X509\_PublicKey} simply by casting it (with \function{dynamic\_cast}), as
-the private key type is derived from \type{X509\_PublicKey}. As with
-\type{X509\_PublicKey}, you can use \function{dynamic\_cast} to figure out what
-operations the private key is capable of; in particular, you can attempt to
-cast it to \type{PK\_Decrypting\_Key}, \type{PK\_Signing\_Key}, or
-\type{PK\_Key\_Agreement\_Key}.
-
-Sometimes you can get away with having a static passphrase passed to
-\function{load\_key}. Typically, however, you'll have to do some user
-interaction to get the appropriate passphrase. In that case you'll want to use
-the \type{UI} related interface, which is fully described in the API
-documentation.
-
-\subsubsection{Generating New Private Keys}
-
-Generate a new private key is the one operation which requires you to
-explicitly name the type of key you are working with. There are (currently) two
-kinds of public key algorithms in Botan: ones based on the integer
-factorization (IF) problem (RSA and Rabin-Williams), and ones based on the
-discrete logarithm (DL) problem (DSA, Diffie-Hellman, Nyberg-Rueppel, and
-ElGamal). Since discrete logarithm parameters (primes and generators) can be
-shared among many keys, there is the notion of these being a combined type
-(called \type{DL\_Group}).
-
-To create a new DL-based private key, simply pass a desired \type{DL\_Group} to
-the constructor of the private key - a new public/private key pair will be
-generated. Since in IF-based algorithms, the modulus used isn't shared by other
-keys, we don't use this notion. You can create a new key by passing in a
-\type{u32bit} telling how long (in bits) the key should be.
-
-There are quite a few ways to get a \type{DL\_Group} object. The best is to use
-the function \function{get\_dl\_group}, which takes a string naming a group; it
-will either return that group, if it knows about it, or throw an
-exception. Names it knows about include ``IETF-n'' where n is 768, 1024, 1536,
-2048, 3072, or 4096, and ``DSA-n'', where n is 512, 768, or 1024. The IETF
-groups are the ones specified for use with IPSec, and the DSA ones are the
-default DSA parameters specified by Java's JCE. For DSA and Nyberg-Rueppel, use
-the ``DSA-n'' groups, and for Diffie-Hellman and ElGamal, use the ``IETF-n''
-groups.
-
-You can also generate a new random group. This is not recommend, because it is
-very slow, particularly for ``safe'' primes, which are needed for
-Diffie-Hellman and ElGamal.
-
-Some examples:
-
-\begin{verbatim}
- RSA_PrivateKey rsa1(512); // 512-bit RSA key
- RSA_PrivateKey rsa2(2048); // 2048-bit RSA key
-
- RW_PrivateKey rw1(1024); // 1024-bit Rabin-Williams key
- RW_PrivateKey rw2(1536); // 1536-bit Rabin-Williams key
-
- DSA_PrivateKey dsa(get_dl_group("DSA-512")); // 512-bit DSA key
- DH_PrivateKey dh(get_dl_group("IETF-4096")); // 4096-bit DH key
- NR_PrivateKey nr(get_dl_group("DSA-1024")); // 1024-bit NR key
- ElGamal_PrivateKey elg(get_dl_group("IETF-1536")); // 1536-bit ElGamal key
-\end{verbatim}
-
-To export your newly created private key, use the PKCS \#8 routines in
-\filename{pkcs8.h}:
-
-\begin{verbatim}
- std::string a_passphrase = /* get from the user */
- std::string the_key = PKCS8::PEM_encode(rsa2, a_passphrase);
-\end{verbatim}
-
-You can read the key back in using \function{PKCS8::load\_key}, described in
-the section ``Reading Private Keys (PKCS \#8 format)'', above. Unfortunately,
-this only works with keys that have an assigned algorithm identifier and
-standardized format. Currently this is only the RSA, DSA, DH, and ElGamal
-algorithms, though RW and NR keys can also be imported and exported by
-assigning them an OID (this can be done either through a configuration file, or
-by calling the function \function{OIDS::add\_oid} in \filename{oids.h}). Be
-aware that the OID and format for ElGamal keys is not exactly standard, but
-there does exist at least one other crypto library which will accept the
-format.
-
-The raw public can be exported using:
-
-\begin{verbatim}
- std::string the_public_key = X509::PEM_encode(rsa2);
-\end{verbatim}
-
-\pagebreak
-
-\section{X.509v3 Certificates}
-
-Using certificates is rather complicated, so only the very basic mechanisms are
-going to be covered here. The section ``Setting up a CA'' goes into reasonable
-detail about CRLs and certificate requests, but there is a lot that isn't
-covered (else this section would get quite long and complicated).
-
-\subsection{Importing and Exporting Certificates}
-
-Importing and exporting X.509 certificates is easy. Simply call the constructor
-with either a \type{DataSource\&}, or the name of a file:
-
-\begin{verbatim}
- X509_Certificate cert1("cert1.pem");
-
- /* This file contains two certificates, concatenated */
- DataSource_Stream in("certs2_and_3.pem");
-
- X509_Certificate cert2(in); // read the first cert
- X509_Certificate cert3(in); // read the second cert
-\end{verbatim}
-
-Exporting the certificate is a simple matter of calling the member function
-\function{PEM\_encode}(), which returns a \type{std::string} containing the
-certificate in PEM encoding.
-
-\begin{verbatim}
- std::cout << cert3.PEM_encode();
- some_ostream_object << cert1.PEM_encode();
- std::string cert2_str = cert2.PEM_encode();
-\end{verbatim}
-
-\subsection{Verifying Certificates}
-
-Verifying a certificate requires that we build up a chain of trust, starting
-from the root (usually a commercial CA), down through some number of
-intermediate CAs, and finally reaching the actual certificate in
-question. Thus, to verify, we actually have to have all those certificates
-on hand (or at the very least, know where we can get the ones we need).
-
-The class which handles both storing certificates, and verifying them, is
-called \type{X509\_Store}. We'll start by assuming that we have all the
-certificates we need, and just want to verify a cert. This is done by calling
-the member function \function{validate\_cert}, which takes the
-\type{X509\_Certificate} in question, and an optional argument of type
-\type{Cert\_Usage} (which is ignored here; read the section in the API doc
-titled ``Verifying Certificates for information). It returns an enum;
-\type{X509\_Code}, which, for most purposes, is either \type{VERIFIED}, or
-something else (which specifies what circumstance caused the certificate to be
-considered invalid). Really, that's it.
-
-Now, how to let \type{X509\_Store} know about all those certificates and CRLs
-we have lying around? The simplest method is to add them directly, using the
-functions \function{add\_cert}, \function{add\_certs},
-\function{add\_trusted\_certs}, and \function{add\_crl}; for details, consult
-the API doc or read the \filename{x509stor.h} header. There is also a much more
-elegant and powerful method: \type{Certificate\_Store}s. A certificate store
-refers to an object that knows how to retrieve certificates from some external
-source (a file, an LDAP directory, a HTTP server, a SQL database, or anything
-else). By calling the function \function{add\_new\_certstore}, you can register
-a new certificate store, which \type{X509\_Store} will use to find certificates
-it needs. Thus, you can get away with only adding whichever root CA cert(s) you
-want to use, letting some online source handle the storage of all intermediate
-X.509 certificates. The API documentation has a more complete discussion of
-\type{Certificate\_Store}.
-
-\subsection{Setting up a CA}
-
-WRITEME
-
-\pagebreak
-
-\section{Special Topics}
-
-This chapter is for subjects that don't really fit into the API documentation
-or into other chapters of the tutorial.
-
-\subsection{GUIs}
-
-There is nothing particularly special about using Botan in a GUI-based
-application. However there are a few tricky spots, as well as a few ways to
-take advantage of an event-based application.
-
-\subsubsection{Initialization}
-
-Generally you will create the \type{LibraryInitializer} somewhere in
-\texttt{main}, before entering the event loop. One problem is that some GUI
-libraries take over \texttt{main} and drop you right into the event loop; the
-question then is how to initialize the library? The simplest way is probably to
-have a static flag that marks if you have already initialized the library or
-not. When you enter the event loop, check to see if this flag has not been set,
-and if so, initialize the library using the function-based initializers. Using
-\type{LibraryInitializer} obviously won't work in this case, since it would be
-destroyed as soon as the current event handler finished. You then deinitialize
-the library whenever your application is signaled to quit.
-
-\subsubsection{Interacting With the Library}
-
-In the simple case, the user will do stuff asynchronously, and then in response
-your code will do things like encrypt a file or whatever, which can all be done
-synchronously, since the data is right there for you. An application doing
-something like this is basically going to look exactly like a command line
-application that uses Botan, the only major difference being that the calls to
-the library are inside event handlers.
-
-Much harder is something like an SSH client, where you're acting as a layer
-between two asynchronous things (the user and the network). This actually isn't
-restricted to GUIs at all (text-mode SSH clients have to deal with most of the
-same problems), but it is probably more common with a GUI app. The following
-discussion is fairly vague, but hopefully somewhat useful.
-
-There are a few facilities in Botan that are primarily designed to be used by
-applications based on an event loop. See the section ``User Interfaces'' in the
-main API doc for details.
-
-\subsubsection{Entropy}
-
-One nice advantage of using a GUI is opening a new method of gathering entropy
-for the library. This is especially handy on Windows, where the available
-sources of entropy are pretty questionable. In many versions,
-\texttt{CryptGenRandom} is really rather poor, and the Toolhelp functions may
-not provide much data on a small system (such as a handheld). For example, in
-GTK+, you can use the following callback to get information about mouse
-movements:
-
-\begin{verbatim}
-static gint add_entropy(GtkWidget* widget, GdkEventMotion* event)
- {
- if(event)
- Global_RNG::add_entropy(event, sizeof(GdkEventMotion));
- return FALSE;
- }
-\end{verbatim}
-
-And then register it with your main GTK window (presumably named
-\variable{window}) as follows:
-
-\begin{verbatim}
-gtk_signal_connect(GTK_OBJECT(window), "motion_notify_event",
- GTK_SIGNAL_FUNC(add_entropy), NULL);
-
-gtk_widget_set_events(window, GDK_POINTER_MOTION_MASK);
-\end{verbatim}
-
-Even though we're catching all mouse movements, and hashing the results into
-the entropy pool, this doesn't use up more than a few percent of even a
-relatively slow desktop CPU. Note that in the case of using X over a network,
-catching all mouse events would cause large amounts of X traffic over the
-network, which might make your application slow, or even unusable (I haven't
-tried it, though).
-
-This could be made nicer if the collection function did something like
-calculating deltas between each run, storing them into a buffer, and then when
-enough of them have been added, hashing them and send them all to the PRNG in
-one shot. This would not only reduce load, but also prevent the PRNG from
-overestimating the amount of entropy it's getting, since its estimates don't
-(can't) take history into account. For example, you could move the mouse back
-and forth one pixel, and the PRNG would think it was getting a full load of
-entropy each time, when actually it was getting (at best) a bit or two.
-
-\end{document}
diff --git a/doc/pgpkeys.txt b/doc/pgpkey.txt
index 1d2f3debc..1d2f3debc 100644
--- a/doc/pgpkeys.txt
+++ b/doc/pgpkey.txt
diff --git a/doc/pubkey.txt b/doc/pubkey.txt
index f12aae0b5..6ff016038 100644
--- a/doc/pubkey.txt
+++ b/doc/pubkey.txt
@@ -1,60 +1,55 @@
-.. _public_key_crypto:
-
Public Key Cryptography
=================================
-Public key cryptography (also called assymmetric cryptography) is a
-collection of techniques allowing for encryption, signatures, and key
-agreement.
+Public key cryptography (also called assymmetric cryptography) is a collection
+of techniques allowing for encryption, signatures, and key agreement.
Key Objects
----------------------------------------
-Public and private keys are represented by classes ``Public_Key`` and
-it's subclass ``Private_Key``. The use of inheritence here means that
-a ``Private_Key`` can be converted into a reference to a public key.
+Public and private keys are represented by classes ``Public_Key`` and it's
+subclass ``Private_Key``. The use of inheritence here means that a
+``Private_Key`` can be converted into a reference to a public key.
None of the functions on ``Public_Key`` and ``Private_Key`` itself are
particularly useful for users of the library, because 'bare' public key
-operations are *very insecure*. The only purpose of these functions is
-to provide a clean interface that higher level operations can be built
-on. So really the only thing you need to know is that when a function
-takes a reference to a ``Public_Key``, it can take any public key or
-private key, and similiarly for ``Private_Key``.
+operations are *very insecure*. The only purpose of these functions is to
+provide a clean interface that higher level operations can be built on. So
+really the only thing you need to know is that when a function takes a
+reference to a ``Public_Key``, it can take any public key or private key, and
+similiarly for ``Private_Key``.
Types of ``Public_Key`` include ``RSA_PublicKey``, ``DSA_PublicKey``,
-``ECDSA_PublicKey``, ``DH_PublicKey``, ``ECDH_PublicKey``,
-``RW_PublicKey``, ``NR_PublicKey``,, and ``GOST_3410_PublicKey``.
-There are cooresponding ``Private_Key`` classes for each of these
-algorithms.
+``ECDSA_PublicKey``, ``DH_PublicKey``, ``ECDH_PublicKey``, ``RW_PublicKey``,
+``NR_PublicKey``,, and ``GOST_3410_PublicKey``. There are cooresponding
+``Private_Key`` classes for each of these algorithms.
.. _creating_new_private_keys:
Creating New Private Keys
----------------------------------------
-Creating a new private key requires two things: a source of
-random numbers (see :ref:`random_number_generators`) and some
-algorithm specific parameters that define the *security level*
-of the resulting key. For instance, the security level of an RSA
-key is (at least in part) defined by the length of the public key
-modulus in bits. So to create a new RSA private key, you would call
+Creating a new private key requires two things: a source of random numbers
+(see :ref:`random_number_generators`) and some algorithm specific parameters
+that define the *security level* of the resulting key. For instance, the
+security level of an RSA key is (at least in part) defined by the length of
+the public key modulus in bits. So to create a new RSA private key, you would
+call
.. cpp:function:: RSA_PrivateKey::RSA_PrivateKey(RandomNumberGenerator& rng, size_t bits)
A constructor that creates a new random RSA private key with a modulus
of length *bits*.
-Algorithms based on the discrete-logarithm problem uses what is called
-a *group*; a group can safely be used with many keys, and for some
-operations, like key agreement, the two keys *must* use the same
-group. There are currently two kinds of discrete logarithm groups
-supported in botan: the integers modulo a prime, represented by
-:ref:`dl_group`, and elliptic curves in GF(p), represented by
-:ref:`ec_group`. A rough generalization is that the larger the group
-is, the more secure the algorithm is, but coorespondingly the slower
-the operations will be.
+Algorithms based on the discrete-logarithm problem uses what is called a
+*group*; a group can safely be used with many keys, and for some operations,
+like key agreement, the two keys *must* use the same group. There are
+currently two kinds of discrete logarithm groups supported in botan: the
+integers modulo a prime, represented by :ref:`dl_group`, and elliptic curves
+in GF(p), represented by :ref:`ec_group`. A rough generalization is that the
+larger the group is, the more secure the algorithm is, but coorespondingly the
+slower the operations will be.
Given a ``DL_Group``, you can create new DSA, Diffie-Hellman, and
Nyberg-Rueppel key pairs with
@@ -71,12 +66,11 @@ Nyberg-Rueppel key pairs with
.. cpp:function:: ElGamal_PrivateKey::ElGamal_PrivateKey(RandomNumberGenerator& rng, \
const DL_Group& group, const BigInt& x = 0)
- The optional *x* parameter to each of these contructors is a private
- key value. This allows you to create keys where the private key is
- formed by some special technique; for instance you can use the hash
- of a password (see :ref:`pbkdf` for how to do that) as a private key
- value. Normally, you would leave the value as zero, letting the
- class generate a new random key.
+ The optional *x* parameter to each of these contructors is a private key
+ value. This allows you to create keys where the private key is formed by
+ some special technique; for instance you can use the hash of a password (see
+ :ref:`pbkdf` for how to do that) as a private key value. Normally, you would
+ leave the value as zero, letting the class generate a new random key.
Finally, given an ``EC_Group`` object, you can create a new ECDSA,
ECDH, or GOST 34.10-2001 private key with
@@ -94,11 +88,10 @@ ECDH, or GOST 34.10-2001 private key with
Generating RSA keys
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-This example will generate an RSA key of a specified bitlength, and
-put it into a pair of key files. One is the public key in X.509 format
-(PEM encoded), the private key is in PKCS #8 format (also PEM
-encoded), either encrypted or unencrypted depending on if a password
-was given.
+This example will generate an RSA key of a specified bitlength, and put it
+into a pair of key files. One is the public key in X.509 format (PEM encoded),
+the private key is in PKCS #8 format (also PEM encoded), either encrypted or
+unencrypted depending on if a password was given.
.. literalinclude:: examples/rsa_kgen.cpp
@@ -110,15 +103,14 @@ This example generates a 2048 bit DSA key
.. literalinclude:: examples/dsa_kgen.cpp
-
.. _serializing_private_keys:
Serializing Private Keys Using PKCS #8
----------------------------------------
-The standard format for serializing a private key is PKCS #8, the
-operations for which are defined in ``pkcs8.h``. It supports both
-unencrypted and encrypted storage.
+The standard format for serializing a private key is PKCS #8, the operations
+for which are defined in ``pkcs8.h``. It supports both unencrypted and
+encrypted storage.
.. cpp:function:: SecureVector<byte> PKCS8::BER_encode(const Private_Key& key, \
RandomNumberGenerator& rng, const std::string& password, const std::string& pbe_algo = "")
@@ -134,23 +126,22 @@ unencrypted and encrypted storage.
.. cpp:function:: std::string PKCS8::PEM_encode(const Private_Key& key, \
RandomNumberGenerator& rng, const std::string& pass, const std::string& pbe_algo = "")
- This formats the key in the same manner as ``BER_encode``, but
- additionally encodes it into a text format with identifying
- headers. Using PEM encoding is *highly* recommended for many
- reasons, including compatibility with other software, for
- transmission over 8-bit unclean channels, because it can be
- identified by a human without special tools, and because it
- sometimes allows more sane behavior of tools that process the data.
+ This formats the key in the same manner as ``BER_encode``, but additionally
+ encodes it into a text format with identifying headers. Using PEM encoding
+ is *highly* recommended for many reasons, including compatibility with other
+ software, for transmission over 8-bit unclean channels, because it can be
+ identified by a human without special tools, and because it sometimes allows
+ more sane behavior of tools that process the data.
Unencrypted serialization is also supported.
.. warning::
- In most situations, using unecrypted private key storage is a bad
- idea, because anyone can come along and grab the private key without
- having to know any passwords or other secrets. Unless you have very
- particular security requirements, always use the versions that
- encrypt the key based on a passphrase, described above.
+ In most situations, using unecrypted private key storage is a bad idea,
+ because anyone can come along and grab the private key without having to
+ know any passwords or other secrets. Unless you have very particular
+ security requirements, always use the versions that encrypt the key based on
+ a passphrase, described above.
.. cpp:function:: SecureVector<byte> PKCS8::BER_encode(const Private_Key& key)
@@ -176,27 +167,25 @@ decrypt, if necessary) a PKCS #8 private key:
.. cpp:function:: Private_Key* PKCS8::load_key(const std::string& filename, \
RandomNumberGenerator& rng, const std::string& passphrase = "")
-These functions will return an object allocated key object based on
-the data from whatever source it is using (assuming, of course, the
-source is in fact storing a representation of a private key, and the
-decryption was sucessful). The encoding used (PEM or BER) need not be
-specified; the format will be detected automatically. The key is
-allocated with ``new``, and should be released with ``delete`` when
-you are done with it. The first takes a generic ``DataSource`` that
-you have to create - the other is a simple wrapper functions that take
-either a filename or a memory buffer and create the appropriate
-``DataSource``.
-
-The versions taking a ``std::string`` attempt to decrypt using the
-password given (if the key is encrypted; if it is not, the passphase
-value will be ignored). If the passphrase does not decrypt the key, an
-exception will be thrown.
-
-The ones taking a ``User_Interface`` provide a simple callback
-interface which makes handling incorrect passphrases and such a bit
-simpler. A ``User_Interface`` has very little to do with talking to
-users; it's just a way to glue together Botan and whatever user
-interface you happen to be using.
+These functions will return an object allocated key object based on the data
+from whatever source it is using (assuming, of course, the source is in fact
+storing a representation of a private key, and the decryption was
+sucessful). The encoding used (PEM or BER) need not be specified; the format
+will be detected automatically. The key is allocated with ``new``, and should
+be released with ``delete`` when you are done with it. The first takes a
+generic ``DataSource`` that you have to create - the other is a simple wrapper
+functions that take either a filename or a memory buffer and create the
+appropriate ``DataSource``.
+
+The versions taking a ``std::string`` attempt to decrypt using the password
+given (if the key is encrypted; if it is not, the passphase value will be
+ignored). If the passphrase does not decrypt the key, an exception will be
+thrown.
+
+The ones taking a ``User_Interface`` provide a simple callback interface which
+makes handling incorrect passphrases and such a bit simpler. A
+``User_Interface`` has very little to do with talking to users; it's just a
+way to glue together Botan and whatever user interface you happen to be using.
.. note::
@@ -208,28 +197,25 @@ To use ``User_Interface``, derive a subclass and implement:
.. cpp:function:: std::string User_Interface::get_passphrase(const std::string& what, \
const std::string& source, UI_Result& result) const
- The ``what`` argument specifies what the passphrase is needed for
- (for example, PKCS #8 key loading passes ``what`` as "PKCS #8
- private key"). This lets you provide the user with some indication
- of *why* your application is asking for a passphrase; feel free to
- pass the string through ``gettext(3)`` or moral equivalent for i18n
- purposes. Similarly, ``source`` specifies where the data in question
- came from, if available (for example, a file name). If the source is
- not available for whatever reason, then ``source`` will be an empty
- string; be sure to account for this possibility.
-
- The function returns the passphrase as the return value, and a
- status code in ``result`` (either ``OK`` or ``CANCEL_ACTION``). If
- ``CANCEL_ACTION`` is returned in ``result``, then the return value
- will be ignored, and the caller will take whatever action is
- necessary (typically, throwing an exception stating that the
- passphrase couldn't be determined). In the specific case of PKCS #8
- key decryption, a ``Decoding_Error`` exception will be thrown; your
- UI should assume this can happen, and provide appropriate error
- handling (such as putting up a dialog box informing the user of the
+ The ``what`` argument specifies what the passphrase is needed for (for
+ example, PKCS #8 key loading passes ``what`` as "PKCS #8 private key"). This
+ lets you provide the user with some indication of *why* your application is
+ asking for a passphrase; feel free to pass the string through ``gettext(3)``
+ or moral equivalent for i18n purposes. Similarly, ``source`` specifies where
+ the data in question came from, if available (for example, a file name). If
+ the source is not available for whatever reason, then ``source`` will be an
+ empty string; be sure to account for this possibility.
+
+ The function returns the passphrase as the return value, and a status code
+ in ``result`` (either ``OK`` or ``CANCEL_ACTION``). If ``CANCEL_ACTION`` is
+ returned in ``result``, then the return value will be ignored, and the
+ caller will take whatever action is necessary (typically, throwing an
+ exception stating that the passphrase couldn't be determined). In the
+ specific case of PKCS #8 key decryption, a ``Decoding_Error`` exception will
+ be thrown; your UI should assume this can happen, and provide appropriate
+ error handling (such as putting up a dialog box informing the user of the
situation, and canceling the operation in progress).
-
.. _serializing_public_keys:
Serializing Public Keys
@@ -256,36 +242,34 @@ To import and export public keys, use:
DL_Group
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-As described in :ref:`creating_new_private_keys`, a discrete logarithm
-group can be shared among many keys, even keys created by users who do
-not trust each other. However, it is necessary to trust the entity who
-created the group; that is why organization like NIST use algorithms
-which generate groups in a deterministic way such that creating a
-bogus group would require breaking some trusted cryptographic
-primitive like SHA-2.
+As described in :ref:`creating_new_private_keys`, a discrete logarithm group
+can be shared among many keys, even keys created by users who do not trust
+each other. However, it is necessary to trust the entity who created the
+group; that is why organization like NIST use algorithms which generate groups
+in a deterministic way such that creating a bogus group would require breaking
+some trusted cryptographic primitive like SHA-2.
Instantiating a ``DL_Group`` simply requires calling
.. cpp:function:: DL_Group::DL_Group(const std::string& name)
- The *name* parameter is a specially formatted string that consists
- of three things, the type of the group ("modp" or "dsa"), the
- creator of the group, and the size of the group in bits, all
- delimited by '/' characters.
-
- Currently all "modp" groups included in botan are ones defined by
- the Internet Engineering Task Force, so the provider is "ietf", and
- the strings look like "modp/ietf/N" where N can be any of 768, 1024,
- 1536, 2048, 3072, 4096, 6144, or 8192. This group type is used
- for Diffie-Hellman and ElGamal algorithms.
-
- The other type, "dsa" is used for DSA and Nyberg-Rueppel keys. They
- can also be used with Diffie-Hellman and ElGamal, but this is less
- common. The currently available groups are "dsa/jce/N" for N in 512,
- 768, or 1024, and "dsa/botan/N" with N being 2048 or 3072. The
- "jce" groups are the standard DSA groups used in the Java
- Cryptography Extensions, while the "botan" groups were randomly
- generated using the FIPS 186-3 algorithm by the library maintainers.
+ The *name* parameter is a specially formatted string that consists of three
+ things, the type of the group ("modp" or "dsa"), the creator of the group,
+ and the size of the group in bits, all delimited by '/' characters.
+
+ Currently all "modp" groups included in botan are ones defined by the
+ Internet Engineering Task Force, so the provider is "ietf", and the strings
+ look like "modp/ietf/N" where N can be any of 768, 1024, 1536, 2048, 3072,
+ 4096, 6144, or 8192. This group type is used for Diffie-Hellman and ElGamal
+ algorithms.
+
+ The other type, "dsa" is used for DSA and Nyberg-Rueppel keys. They can
+ also be used with Diffie-Hellman and ElGamal, but this is less common. The
+ currently available groups are "dsa/jce/N" for N in 512, 768, or 1024, and
+ "dsa/botan/N" with N being 2048 or 3072. The "jce" groups are the standard
+ DSA groups used in the Java Cryptography Extensions, while the "botan"
+ groups were randomly generated using the FIPS 186-3 algorithm by the library
+ maintainers.
You can generate a new random group using
@@ -338,26 +322,25 @@ Each public key type has a function
.. cpp:function:: bool Public_Key::check_key(RandomNumberGenerator& rng, bool strong)
- This function performs a number of algorithm-specific tests that the
- key seems to be mathematically valid and consistent, and returns
- true if all of the tests pass.
+ This function performs a number of algorithm-specific tests that the key
+ seems to be mathematically valid and consistent, and returns true if all of
+ the tests pass.
It does not have anything to do with the validity of the key for any
- particular use, nor does it have anything to do with certificates
- that link a key (which, after all, is just some numbers) with a user
- or other entity. If *strong* is ``true``, then it does "strong"
- checking, which includes expensive operations like primality
- checking.
+ particular use, nor does it have anything to do with certificates that link
+ a key (which, after all, is just some numbers) with a user or other
+ entity. If *strong* is ``true``, then it does "strong" checking, which
+ includes expensive operations like primality checking.
Encryption
---------------------------------
-Safe public key encryption requires the use of a padding scheme which
-hides the underlying mathematical properties of the algorithm.
-Additionally, they will add randomness, so encrypting the same
-plaintext twice produces two different ciphertexts.
+Safe public key encryption requires the use of a padding scheme which hides
+the underlying mathematical properties of the algorithm. Additionally, they
+will add randomness, so encrypting the same plaintext twice produces two
+different ciphertexts.
-The primary interface for encryption is
+The primary interface for encryption is
.. cpp:class:: PK_Encryptor
@@ -371,30 +354,28 @@ The primary interface for encryption is
.. cpp:function:: size_t maximum_input_size() const
- Returns the maximum size of the message that can be processed,
- in bytes. If you call :cpp:func:`PK_Encryptor::encrypt` with a
- value larger than this the operation will fail with an
- exception.
-
-:cpp:class:`PK_Encryptor` is only an interface - to actually encrypt
-you have to create an implementation, of which there are currently two
-available in the library, :cpp:class:`PK_Encryptor_EME` and
-:cpp:class:`DLIES_Encryptor`. DLIES is a standard method (from IEEE
-1363) that uses a key agreement technique such as DH or ECDH to
-perform message encryption. Normally, public key encryption is done
-using algorithms which support it directly, such as RSA or ElGamal;
+ Returns the maximum size of the message that can be processed, in
+ bytes. If you call :cpp:func:`PK_Encryptor::encrypt` with a value larger
+ than this the operation will fail with an exception.
+
+:cpp:class:`PK_Encryptor` is only an interface - to actually encrypt you have
+to create an implementation, of which there are currently two available in the
+library, :cpp:class:`PK_Encryptor_EME` and :cpp:class:`DLIES_Encryptor`. DLIES
+is a standard method (from IEEE 1363) that uses a key agreement technique such
+as DH or ECDH to perform message encryption. Normally, public key encryption
+is done using algorithms which support it directly, such as RSA or ElGamal;
these use the EME class:
.. cpp:class:: PK_Encryptor_EME
.. cpp:function:: PK_Encryptor_EME(const Public_Key& key, std::string eme)
- With *key* being the key you want to encrypt messages to. The
- padding method to use is specified in *eme*.
+ With *key* being the key you want to encrypt messages to. The padding
+ method to use is specified in *eme*.
- The recommended values for *eme* is "EME1(SHA-1)" or
- "EME1(SHA-256)". If you need compatability with protocols using
- the PKCS #1 v1.5 standard, you can also use "EME-PKCS1-v1_5".
+ The recommended values for *eme* is "EME1(SHA-1)" or "EME1(SHA-256)". If
+ you need compatability with protocols using the PKCS #1 v1.5 standard,
+ you can also use "EME-PKCS1-v1_5".
.. cpp:class:: DLIES_Encryptor
@@ -407,10 +388,9 @@ these use the EME class:
:ref:`key_derivation_function`) and *mac* is a
MessageAuthenticationCode.
-The decryption classes are named ``PK_Decryptor``,
-``PK_Decryptor_EME``, and ``DLIES_Decryptor``. They are created in the
-exact same way, except they take the private key, and the processing
-function is named ``decrypt``.
+The decryption classes are named ``PK_Decryptor``, ``PK_Decryptor_EME``, and
+``DLIES_Decryptor``. They are created in the exact same way, except they take
+the private key, and the processing function is named ``decrypt``.
Signatures
@@ -425,22 +405,22 @@ Signature generation is performed using
Signature_Format format = IEEE_1363)
Constructs a new signer object for the private key *key* using the
- signature format *emsa*. The key must support signature operations.
- In the current version of the library, this includes RSA, DSA,
- ECDSA, GOST 34.10-2001, Nyberg-Rueppel, and Rabin-Williams. Other
- signature schemes may be supported in the future.
-
- Currently available values for *emsa* include EMSA1, EMSA2, EMSA3,
- EMSA4, and Raw. All of them, except Raw, take a parameter naming a
- message digest function to hash the message with. The Raw encoding
- signs the input directly; if the message is too big, the signing
- operation will fail. Raw is not useful except in very specialized
- applications. Examples are "EMSA1(SHA-1)" and "EMSA4(SHA-256)".
-
- For RSA, use EMSA4 (also called PSS) unless you need compatability
- with software that uses the older PKCS #1 v1.5 standard, in which
- case use EMSA3 (also called "EMSA-PKCS1-v1_5"). For DSA, ECDSA,
- GOST 34.10-2001, and Nyberg-Rueppel, you should use EMSA1.
+ signature format *emsa*. The key must support signature operations. In
+ the current version of the library, this includes RSA, DSA, ECDSA, GOST
+ 34.10-2001, Nyberg-Rueppel, and Rabin-Williams. Other signature schemes
+ may be supported in the future.
+
+ Currently available values for *emsa* include EMSA1, EMSA2, EMSA3, EMSA4,
+ and Raw. All of them, except Raw, take a parameter naming a message
+ digest function to hash the message with. The Raw encoding signs the
+ input directly; if the message is too big, the signing operation will
+ fail. Raw is not useful except in very specialized applications. Examples
+ are "EMSA1(SHA-1)" and "EMSA4(SHA-256)".
+
+ For RSA, use EMSA4 (also called PSS) unless you need compatability with
+ software that uses the older PKCS #1 v1.5 standard, in which case use
+ EMSA3 (also called "EMSA-PKCS1-v1_5"). For DSA, ECDSA, GOST 34.10-2001,
+ and Nyberg-Rueppel, you should use EMSA1.
The *format* defaults to ``IEEE_1363`` which is the only available
format for RSA. For DSA and ECDSA, you can also use
diff --git a/doc/ssl.txt b/doc/ssl.txt
index 8f2ad3a2a..7b61fa88c 100644
--- a/doc/ssl.txt
+++ b/doc/ssl.txt
@@ -1,4 +1,6 @@
+.. _ssl_api:
+
SSL and TLS
========================================
diff --git a/doc/support.txt b/doc/support.txt
index a341d5830..288ed8aa0 100644
--- a/doc/support.txt
+++ b/doc/support.txt
@@ -6,14 +6,14 @@ Commercial support is currently available for Botan from a couple of
sources. If you provide services related to Botan, email the
development list and your information can be added here.
- * `FlexSecure GmbH <http://www.flexsecure.de>`_ offers support for
- both Botan and `InSiTo <http://www.flexsecure.eu/insito/>`_
- libraries. Developers from FlexSecure have done extensive work
- with Botan in the past, and many new features to Botan have been
- implemented and contributed by them. More information at
- http://www.flexsecure.eu/insito/support.html
+* `FlexSecure GmbH <http://www.flexsecure.de>`_ offers support for
+ both Botan and `InSiTo <http://www.flexsecure.eu/insito/>`_
+ libraries. Developers from FlexSecure have done extensive work
+ with Botan in the past, and many new features to Botan have been
+ implemented and contributed by them. More information at
+ http://www.flexsecure.eu/insito/support.html
- * `Jack Lloyd <http://www.randombit.net>`_ can provide services
- relating to Botan including performance analysis of application
- code using Botan, review of cryptographic use and designs for
- security flaws, and implementing new features.
+* `Jack Lloyd <http://www.randombit.net>`_ can provide services
+ relating to Botan including performance analysis of application
+ code using Botan, review of cryptographic use and designs for
+ security flaws, and implementing new features.
diff --git a/doc/x509.txt b/doc/x509.txt
index 05adeaaad..d31a84498 100644
--- a/doc/x509.txt
+++ b/doc/x509.txt
@@ -5,84 +5,77 @@ Certificate Handling
=================================
A certificate is a binding between some identifying information
-(called a *subject*) and a public key. This binding is asserted
-by a signature on the certificate, which is placed there by some
-authority (the *issuer*) that at least claims that it knows the
-subject named in the certificate really "owns" the private key
-corresponding to the public key in the certificate.
+(called a *subject*) and a public key. This binding is asserted by a
+signature on the certificate, which is placed there by some authority
+(the *issuer*) that at least claims that it knows the subject named in
+the certificate really "owns" the private key corresponding to the
+public key in the certificate.
-The major certificate format in use today is X.509v3, designed by ISO and
-further hacked on by dozens (hundreds?) of other organizations.
+The major certificate format in use today is X.509v3, designed by ISO
+and further hacked on by dozens (hundreds?) of other organizations.
When working with certificates, the main class to remember is
-``X509_Certificate``. You can read an object of this type, but you
-can't create one on the fly; a CA object is necessary for making a new
-certificate. So for the most part, you only have to worry about
-reading them in, verifying the signatures, and getting the bits of
-data in them (most commonly the public key, and the information about
-the user of that key). An X.509v3 certificate can contain a literally
-infinite number of items related to all kinds of things. Botan doesn't
-support a lot of them, because nobody uses them and they're an
-impossible mess to work with. This section only documents the most
+``X509_Certificate``. You can read an object of this type, but you can't create
+one on the fly; a CA object is necessary for making a new certificate. So for
+the most part, you only have to worry about reading them in, verifying the
+signatures, and getting the bits of data in them (most commonly the public key,
+and the information about the user of that key). An X.509v3 certificate can
+contain a literally infinite number of items related to all kinds of
+things. Botan doesn't support a lot of them, because nobody uses them and
+they're an impossible mess to work with. This section only documents the most
commonly used ones of the ones that are supported; for the rest, read
-``x509cert.h`` and ``asn1_obj.h`` (which has the
-definitions of various common ASN.1 constructs used in X.509).
+``x509cert.h`` and ``asn1_obj.h`` (which has the definitions of various common
+ASN.1 constructs used in X.509).
So what's in an X.509 certificate?
-----------------------------------
-Obviously, you want to be able to get the public key. This is achieved
-by calling the member function ``subject_public_key``, which will
-return a ``Public_Key``\*. As to what to do with this, read about
-``load_key`` in :ref:`serializing_public_keys`. In the general case,
-this could be any kind of public key, though 99% of the time it will
-be an RSA key. However, Diffie-Hellman, DSA, and ECDSA keys are also
-supported, so be careful about how you treat this. It is also a wise
-idea to examine the value returned by ``constraints``, to see what
-uses the public key is approved for.
-
-The second major piece of information you'll want is the
-name/email/etc of the person to whom this certificate is
-assigned. Here is where things get a little nasty. X.509v3 has two
-(well, mostly just two...) different places where you can stick
-information about the user: the *subject* field, and in an extension
-called *subjectAlternativeName*. The *subject* field is supposed to
-only included the following information: country, organization, an
-organizational sub-unit name, and a so-called common name. The common
-name is usually the name of the person, or it could be a title
-associated with a position of some sort in the organization. It may
-also include fields for state/province and locality. What a locality
-is, nobody knows, but it's usually given as a city name.
-
-Botan doesn't currently support any of the Unicode variants used in
-ASN.1 (UTF-8, UCS-2, and UCS-4), any of which could be used for the
-fields in the DN. This could be problematic, particularly in Asia and
-other areas where non-ASCII characters are needed for most names. The
-UTF-8 and UCS-2 string types *are* accepted (in fact, UTF-8 is
-used when encoding much of the time), but if any of the characters
-included in the string are not in ISO 8859-1 (ie 0 ... 255), an
-exception will get thrown. Currently the ``ASN1_String`` type
-holds its data as ISO 8859-1 internally (regardless of local character
-set); this would have to be changed to hold UCS-2 or UCS-4 in order to
-support Unicode (also, many interfaces in the X.509 code would have to
-accept or return a ``std::wstring`` instead of a
-``std::string``).
-
-Like the distinguished names, subject alternative names can contain a
-lot of things that Botan will flat out ignore (most of which you would
-likely never want to use). However, there are three very useful pieces
-of information that this extension might hold: an email address
-([email protected]), a DNS name (somehost.example.com), or a URI
-(http://www.example.com).
-
-So, how to get the information? Call ``subject_info`` with the name of
-the piece of information you want, and it will return a
-``std::string`` that is either empty (signifying that the certificate
-doesn't have this information), or has the information
-requested. There are several names for each possible item, but the
-most easily readable ones are: "Name", "Country", "Organization",
-"Organizational Unit", "Locality", "State", "RFC822", "URI", and
-"DNS". These values are returned as a ``std::string``.
+Obviously, you want to be able to get the public key. This is achieved by
+calling the member function ``subject_public_key``, which will return a
+``Public_Key``\*. As to what to do with this, read about ``load_key`` in
+:ref:`serializing_public_keys`. In the general case, this could be any kind of
+public key, though 99% of the time it will be an RSA key. However,
+Diffie-Hellman, DSA, and ECDSA keys are also supported, so be careful about how
+you treat this. It is also a wise idea to examine the value returned by
+``constraints``, to see what uses the public key is approved for.
+
+The second major piece of information you'll want is the name/email/etc of the
+person to whom this certificate is assigned. Here is where things get a little
+nasty. X.509v3 has two (well, mostly just two...) different places where you
+can stick information about the user: the *subject* field, and in an extension
+called *subjectAlternativeName*. The *subject* field is supposed to only
+included the following information: country, organization, an organizational
+sub-unit name, and a so-called common name. The common name is usually the name
+of the person, or it could be a title associated with a position of some sort
+in the organization. It may also include fields for state/province and
+locality. What a locality is, nobody knows, but it's usually given as a city
+name.
+
+Botan doesn't currently support any of the Unicode variants used in ASN.1
+(UTF-8, UCS-2, and UCS-4), any of which could be used for the fields in the
+DN. This could be problematic, particularly in Asia and other areas where
+non-ASCII characters are needed for most names. The UTF-8 and UCS-2 string
+types *are* accepted (in fact, UTF-8 is used when encoding much of the time),
+but if any of the characters included in the string are not in ISO 8859-1 (ie 0
+... 255), an exception will get thrown. Currently the ``ASN1_String`` type
+holds its data as ISO 8859-1 internally (regardless of local character set);
+this would have to be changed to hold UCS-2 or UCS-4 in order to support
+Unicode (also, many interfaces in the X.509 code would have to accept or return
+a ``std::wstring`` instead of a ``std::string``).
+
+Like the distinguished names, subject alternative names can contain a lot of
+things that Botan will flat out ignore (most of which you would likely never
+want to use). However, there are three very useful pieces of information that
+this extension might hold: an email address ([email protected]), a DNS name
+(somehost.example.com), or a URI (http://www.example.com).
+
+So, how to get the information? Call ``subject_info`` with the name of the
+piece of information you want, and it will return a ``std::string`` that is
+either empty (signifying that the certificate doesn't have this information),
+or has the information requested. There are several names for each possible
+item, but the most easily readable ones are: "Name", "Country", "Organization",
+"Organizational Unit", "Locality", "State", "RFC822", "URI", and "DNS". These
+values are returned as a ``std::string``.
You can also get information about the issuer of the certificate in the same
way, using ``issuer_info``.
@@ -90,18 +83,16 @@ way, using ``issuer_info``.
X.509v3 Extensions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-X.509v3 specifies a large number of possible extensions. Botan
-supports some, but by no means all of them. This section lists which
-ones are supported, and notes areas where there may be problems with
-the handling.
+X.509v3 specifies a large number of possible extensions. Botan supports some,
+but by no means all of them. This section lists which ones are supported, and
+notes areas where there may be problems with the handling.
- Key Usage and Extended Key Usage: No problems known.
- - Basic Constraints: No problems known. The default for a v1/v2
- certificate is assume it's a CA if and only if the option
- "x509/default_to_ca" is set. A v3 certificate is marked as a CA if
- (and only if) the basic constraints extension is present and set
- for a CA cert.
+ - Basic Constraints: No problems known. The default for a v1/v2 certificate is
+ assume it's a CA if and only if the option "x509/default_to_ca" is set. A v3
+ certificate is marked as a CA if (and only if) the basic constraints
+ extension is present and set for a CA cert.
- Subject Alternative Names: Only the "rfc822Name", "dNSName", and
"uniformResourceIdentifier" fields will be stored; all others are
@@ -113,26 +104,25 @@ the handling.
- Authority Key Identifier: Only the version using KeyIdentifier is
supported. If the GeneralNames version is used and the extension is
- critical, an exception is thrown. If both the KeyIdentifier and
- GeneralNames versions are present, then the KeyIdentifier will be
- used, and the GeneralNames ignored.
+ critical, an exception is thrown. If both the KeyIdentifier and GeneralNames
+ versions are present, then the KeyIdentifier will be used, and the
+ GeneralNames ignored.
- Subject Key Identifier: No problems known.
Revocation Lists
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-It will occasionally happen that a certificate must be revoked before
-its expiration date. Examples of this happening include the private
-key being compromised, or the user to which it has been assigned
-leaving an organization. Certificate revocation lists are an answer to
-this problem (though online certificate validation techniques are
-starting to become somewhat more popular). Every once in a while the
-CA will release a new CRL, listing all certificates that have been
-revoked. Also included is various pieces of information like what time
-a particular certificate was revoked, and for what reason. In most
-systems, it is wise to support some form of certificate revocation,
-and CRLs handle this easily.
+It will occasionally happen that a certificate must be revoked before its
+expiration date. Examples of this happening include the private key being
+compromised, or the user to which it has been assigned leaving an
+organization. Certificate revocation lists are an answer to this problem
+(though online certificate validation techniques are starting to become
+somewhat more popular). Every once in a while the CA will release a new CRL,
+listing all certificates that have been revoked. Also included is various
+pieces of information like what time a particular certificate was revoked, and
+for what reason. In most systems, it is wise to support some form of
+certificate revocation, and CRLs handle this easily.
For most users, processing a CRL is quite easy. All you have to do is call the
constructor, which will take a filename (or a ``DataSource&``). The CRLs
@@ -161,7 +151,15 @@ Reading Certificates
---------------------------------
``X509_Certificate`` has two constructors, each of which takes a source of
-data; a filename to read, and a ``DataSource&``.
+data; a filename to read, and a ``DataSource&``::
+
+ X509_Certificate cert1("cert1.pem");
+
+ /* This file contains two certificates, concatenated */
+ DataSource_Stream in("certs2_and_3.pem");
+
+ X509_Certificate cert2(in); // read the first cert
+ X509_Certificate cert3(in); // read the second cert
.. _x509_store:
@@ -175,11 +173,10 @@ we hit the top of the certificate tree somewhere. It would be a might huge pain
to have to handle all of that manually in every application, so there is
something that does it for you: ``X509_Store``.
-The basic operations are: put certificates and CRLs into it, search
-for certificates, and attempt to verify certificates. That's about
-it. In the future, there will be support for online retrieval of
-certificates and CRLs (eg with the HTTP cert-store interface
-currently under consideration by PKIX).
+The basic operations are: put certificates and CRLs into it, search for
+certificates, and attempt to verify certificates. That's about it. In the
+future, there will be support for online retrieval of certificates and CRLs (eg
+with the HTTP cert-store interface currently under consideration by PKIX).
Adding Certificates
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -197,17 +194,15 @@ functions:
The versions that take a ``DataSource&`` will add all the certificates
that it can find in that source.
-All of them add the cert(s) to the store. The "trusted" certificates
-are the ones that you are willing to trust for certification
-purposes. For example, say your application is working with
-certificates that are owned by employees of some company, and all of
-their certificates are signed by the company CA, whose certificate is
-in turned signed by a commercial root CA. What you would then do is
-include the certificate of the commercial CA with your application,
-and read it in as a trusted certificate. From there, you could verify
-the company CA's certificate, and then use that to verify the end
-user's certificates. Only self-signed certificates may be considered
-trusted.
+All of them add the cert(s) to the store. The "trusted" certificates are the
+ones that you are willing to trust for certification purposes. For example, say
+your application is working with certificates that are owned by employees of
+some company, and all of their certificates are signed by the company CA, whose
+certificate is in turned signed by a commercial root CA. What you would then do
+is include the certificate of the commercial CA with your application, and read
+it in as a trusted certificate. From there, you could verify the company CA's
+certificate, and then use that to verify the end user's certificates. Only
+self-signed certificates may be considered trusted.
Adding CRLs
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -231,38 +226,36 @@ be read by both Botan and other libraries/applications.
Certificate Stores
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-An object of type ``Certificate_Store`` is a generalized interface to
-an external source for certificates (and CRLs). Examples of such a
-store would be one that looked up the certificates in a SQL database,
-or by contacting a CGI script running on a HTTP server. There are
-currently three mechanisms for looking up a certificate, and one for
-retrieving CRLs. By default, most of these mechanisms will return an
-empty ``std::vector`` of ``X509_Certificate``. This storage mechanism
-is *only* queried when doing certificate validation: it allows you to
-distribute only the root key with an application, and let some online
-method handle getting all the other certificates that are needed to
-validate an end entity certificate. In particular, the search routines
-will not attempt to access the external database.
-
-The three certificate lookup methods are ``by_SKID`` (Subject Key
-Identifier), ``by_name`` (the CommonName DN entry), and ``by_email``
-(stored in either the distinguished name, or in a
-subjectAlternativeName extension). The name and email versions take a
-``std::string``, while the SKID version takes a ``SecureVector<byte>``
-containing the subject key identifier in raw binary. You can choose
-not to implement ``by_name`` or ``by_email``, but ``by_SKID`` is
-mandatory to implement, and, currently, is the only version that is
-used by ``X509_Store``.
-
-Finally, there is a method for finding CRLs, called ``get_crls_for``,
-that takes an ``X509_Certificate`` object, and returns a
-``std::vector`` of ``X509_CRL``. While normally there will be only one
-CRL, the use of the vector makes it easy to return no CRLs (eg, if the
-certificate store doesn't support retrieving them), or return multiple
-ones (for example, if the certificate store can't determine precisely
-which key was used to sign the certificate). Implementing the function
-is optional, and by default will return no CRLs. If it is available,
-it will be used by ``X509_CRL``.
+An object of type ``Certificate_Store`` is a generalized interface to an
+external source for certificates (and CRLs). Examples of such a store would be
+one that looked up the certificates in a SQL database, or by contacting a CGI
+script running on a HTTP server. There are currently three mechanisms for
+looking up a certificate, and one for retrieving CRLs. By default, most of
+these mechanisms will return an empty ``std::vector`` of
+``X509_Certificate``. This storage mechanism is *only* queried when doing
+certificate validation: it allows you to distribute only the root key with an
+application, and let some online method handle getting all the other
+certificates that are needed to validate an end entity certificate. In
+particular, the search routines will not attempt to access the external
+database.
+
+The three certificate lookup methods are ``by_SKID`` (Subject Key Identifier),
+``by_name`` (the CommonName DN entry), and ``by_email`` (stored in either the
+distinguished name, or in a subjectAlternativeName extension). The name and
+email versions take a ``std::string``, while the SKID version takes a
+``SecureVector<byte>`` containing the subject key identifier in raw binary. You
+can choose not to implement ``by_name`` or ``by_email``, but ``by_SKID`` is
+mandatory to implement, and, currently, is the only version that is used by
+``X509_Store``.
+
+Finally, there is a method for finding CRLs, called ``get_crls_for``, that
+takes an ``X509_Certificate`` object, and returns a ``std::vector`` of
+``X509_CRL``. While normally there will be only one CRL, the use of the vector
+makes it easy to return no CRLs (eg, if the certificate store doesn't support
+retrieving them), or return multiple ones (for example, if the certificate
+store can't determine precisely which key was used to sign the
+certificate). Implementing the function is optional, and by default will return
+no CRLs. If it is available, it will be used by ``X509_CRL``.
As for using such a store, you have to tell ``X509_Store`` about it
with
@@ -275,84 +268,86 @@ with
Verifying Certificates
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-There is a single function in ``X509_Store`` related to verifying a
-certificate:
-
-.. .cpp:function:: X509_Code X509_Store::validate_cert(const X509_Certificate& cert, Cert_Usage usage = ANY)
-
-This function will return ``VERIFIED`` if the certificate can
-safely be considered valid for the usage(s) described by ``usage``,
-and an error code if it is not. Naturally, things are a bit more
-complicated than that. The enum ``Cert_Usage`` is defined inside
-the ``X509_Store`` class, it (currently) can take on any of the
-values ``ANY`` (any usage is OK), ``TLS_SERVER`` (for SSL/TLS
-server authentication), ``TLS_CLIENT`` (for SSL/TLS client
-authentication), ``CODE_SIGNING``, ``EMAIL_PROTECTION`` (email
-encryption, usually this means S/MIME), ``TIME_STAMPING`` (in
-theory any time stamp application, usually IETF PKIX's Time Stamp
-Protocol), or ``CRL_SIGNING``. Note that Microsoft's code signing
-system, certainly the most widely used, uses a completely different
-(and mostly undocumented) method for marking certificates for code
-signing.
-
-First, how does it know if a certificate is valid? A certificate is
-valid if both of the following hold: a) the signature in the
-certificate can be verified using the public key in the issuer's
-certificate, and b) the issuer's certificate is a valid CA
-certificate. Note that this definition is recursive. We get out of
-this by "bottoming out" when we reach a certificate that we consider
-trusted. In general this will either be a commercial root CA, or an
-organization or application specific CA.
-
-There are a few other restrictions (validity periods, key usage
-restrictions, etc), but the above summarizes the major points of the
-validation algorithm. In theory, Botan implements the certificate path
-validation algorithm given in RFC 2459, but in practice it does not
-(yet), because we don't support the X.509v3 policy or name constraint
-extensions.
-
-Possible values for ``usage`` are ``TLS_SERVER``, ``TLS_CLIENT``,
-``CODE_SIGNING``, ``EMAIL_PROTECTION``, ``CRL_SIGNING``, and
-``TIME_STAMPING``, and ``ANY``. The default ``ANY`` does not mean
-valid for any use, it means "is valid for some usage". This is usually
-what you want; requiring that a random certificate support a
-particular usage will likely result in a lot of failures, unless your
-application is very careful to always issue certificates with the
-proper extensions, and you never use certificates generated by other
-apps.
+Verifying a certificate requires that we build up a chain of trust, starting
+from the root (usually a commercial CA), down through some number of
+intermediate CAs, and finally reaching the actual certificate in
+question. Thus, to verify, we actually have to have all those certificates on
+hand (or at the very least, know where we can get the ones we need).
+
+The class which handles both storing certificates, and verifying them,
+is
+
+.. cpp:class:: X509_Store
+
+.. cpp:type:: Cert_Usage
+
+ Can be any of:
+ * ``ANY`` (any usage is OK)
+ * ``CRL_SIGNING``
+ * ``TLS_SERVER`` (for SSL/TLS server authentication)
+ * ``TLS_CLIENT`` (for SSL/TLS client authentication)
+ * ``CODE_SIGNING``
+ * ``EMAIL_PROTECTION`` (usually this means S/MIME)
+ * ``TIME_STAMPING`` (in theory any time stamp application,
+ usually IETF PKIX's Time Stamp Protocol)
+
+.. cpp:function:: X509_Code validate_cert(const X509_Certificate& cert, \
+ Cert_Usage usage = ANY)
+
+ Return ``VERIFIED`` if the certificate can safely be considered
+ valid for the usage(s) described by *usage*, and an error code if
+ it is not.
+
+First, how does :cpp:class`X509_Store::validate_cert` know if a certificate is
+valid? A certificate is valid if both of the following hold: a) the signature
+in the certificate can be verified using the public key in the issuer's
+certificate, and b) the issuer's certificate is a valid CA certificate. Note
+that this definition is recursive. We get out of this by "bottoming out" when
+we reach a certificate that we consider trusted. In general this will either be
+a commercial root CA, or an organization or application specific CA.
+
+There are a few other restrictions (validity periods, key usage restrictions,
+etc), but the above summarizes the major points of the validation algorithm. In
+theory, Botan implements the certificate path validation algorithm given in RFC
+2459, but in practice it does not (yet), because we don't support the X.509v3
+policy or name constraint extensions.
+
+The default ``ANY`` does not mean valid for any use, it means "is valid for
+some usage". This is usually what you want; requiring that a random certificate
+support a particular usage will likely result in a lot of failures, unless your
+application is very careful to always issue certificates with the proper
+extensions, and you never use certificates generated by other apps.
Return values for ``validate_cert`` (and ``add_crl``) include:
- - VERIFIED: The certificate is valid for the specified use.
+* VERIFIED: The certificate is valid for the specified use.
+* INVALID_USAGE: The certificate cannot be used for the specified use.
- - INVALID_USAGE: The certificate cannot be used for the specified use.
+* CANNOT_ESTABLISH_TRUST: The root certificate was not marked as trusted.
- - CANNOT_ESTABLISH_TRUST: The root certificate was not marked as
- trusted.
+* CERT_CHAIN_TOO_LONG: The certificate chain exceeded the length
+ allowed by a basicConstraints extension.
- - CERT_CHAIN_TOO_LONG: The certificate chain exceeded the length
- allowed by a basicConstraints extension.
+* SIGNATURE_ERROR: An invalid signature was found
- - SIGNATURE_ERROR: An invalid signature was found
+* POLICY_ERROR: Some problem with the certificate policies was found.
- - POLICY_ERROR: Some problem with the certificate policies was found.
-
- - CERT_FORMAT_ERROR: Some format problem was found in a certificate.
- - CERT_ISSUER_NOT_FOUND: The issuer of a certificate could not be found.
- - CERT_NOT_YET_VALID: The certificate is not yet valid.
- - CERT_HAS_EXPIRED: The certificate has expired.
- - CERT_IS_REVOKED: The certificate has been revoked.
- - CRL_FORMAT_ERROR: Some format problem was found in a CRL.
- - CRL_ISSUER_NOT_FOUND: The issuer of a CRL could not be found.
- - CRL_NOT_YET_VALID: The CRL is not yet valid.
- - CRL_HAS_EXPIRED: The CRL has expired.
- - CA_CERT_CANNOT_SIGN: The CA certificate found does not have an
- contain a public key that allows signature verification.
- - CA_CERT_NOT_FOR_CERT_ISSUER: The CA cert found is not allowed to
- issue certificates.
- - CA_CERT_NOT_FOR_CRL_ISSUER: The CA cert found is not allowed to
- issue CRLs.
- - UNKNOWN_X509_ERROR: Some other error occurred.
+* CERT_FORMAT_ERROR: Some format problem was found in a certificate.
+* CERT_ISSUER_NOT_FOUND: The issuer of a certificate could not be found.
+* CERT_NOT_YET_VALID: The certificate is not yet valid.
+* CERT_HAS_EXPIRED: The certificate has expired.
+* CERT_IS_REVOKED: The certificate has been revoked.
+* CRL_FORMAT_ERROR: Some format problem was found in a CRL.
+* CRL_ISSUER_NOT_FOUND: The issuer of a CRL could not be found.
+* CRL_NOT_YET_VALID: The CRL is not yet valid.
+* CRL_HAS_EXPIRED: The CRL has expired.
+* CA_CERT_CANNOT_SIGN: The CA certificate found does not have an
+ contain a public key that allows signature verification.
+* CA_CERT_NOT_FOR_CERT_ISSUER: The CA cert found is not allowed to
+ issue certificates.
+* CA_CERT_NOT_FOR_CRL_ISSUER: The CA cert found is not allowed to
+ issue CRLs.
+* UNKNOWN_X509_ERROR: Some other error occurred.
Certificate Authorities
---------------------------------
@@ -418,38 +413,40 @@ certificates, along with any new ones. This is done by calling
function returns a new ``X509_CRL`` to make available for
clients.
-The ``CRL_Entry`` type is a structure that contains, at a minimum, the
-serial number of the revoked certificate. As serial numbers are never
-repeated, the pairing of an issuer and a serial number (should)
-distinctly identify any certificate. In this case, we represent the
-serial number as a ``SecureVector<byte>`` called ``serial``. There are
-two additional (optional) values, an enumeration called ``CRL_Code``
-that specifies the reason for revocation (``reason``), and an object
-that represents the time that the certificate became invalid (if this
-information is known).
+The ``CRL_Entry`` type is a structure that contains, at a minimum, the serial
+number of the revoked certificate. As serial numbers are never repeated, the
+pairing of an issuer and a serial number (should) distinctly identify any
+certificate. In this case, we represent the serial number as a
+``SecureVector<byte>`` called ``serial``. There are two additional (optional)
+values, an enumeration called ``CRL_Code`` that specifies the reason for
+revocation (``reason``), and an object that represents the time that the
+certificate became invalid (if this information is known).
If you wish to remove an old entry from the CRL, insert a new entry for the
-same cert, with a ``reason`` code of ``DELETE_CRL_ENTRY``. For example,
-if a revoked certificate has expired 'normally', there is no reason to continue
-to explicitly revoke it, since clients will reject the cert as expired in any
+same cert, with a ``reason`` code of ``DELETE_CRL_ENTRY``. For example, if a
+revoked certificate has expired 'normally', there is no reason to continue to
+explicitly revoke it, since clients will reject the cert as expired in any
case.
Self-Signed Certificates
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Generating a new self-signed certificate can often be useful, for
-example when setting up a new root CA, or for use in email
-applications. The library provides a utility function for this:
+Generating a new self-signed certificate can often be useful, for example when
+setting up a new root CA, or for use in email applications. The library
+provides a utility function for this:
.. cpp:function:: X509_Certificate create_self_signed_cert( \
const X509_Cert_Options& opts, const Private_Key& key)
-Where ``key`` is obviously the private key you wish to use (the public key,
-used in the certificate itself, is extracted from the private key), and
-``opts`` is an structure that has various bits of information that will be
-used in creating the certificate (this structure, and its use, is discussed
-below). This function is found in the header ``x509self.h``. There is an
-example of using this function in the ``self_sig`` example.
+ Where *key* is the private key you wish to use (the public key,
+ used in the certificate itself, is extracted from the private key),
+ and *opts* is an structure that has various bits of information
+ that will be used in creating the certificate (this structure, and
+ its use, is discussed below).
+
+An example:
+
+.. literalinclude:: examples/self_sig.cpp
Creating PKCS #10 Requests
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -460,77 +457,71 @@ certificate requests:
.. cpp:function:: PKCS10_Request create_cert_req( \
const X509_Cert_Options& opts, const Private_Key& key)
-This function acts quite similarly to ``create_self_signed_cert``,
-except it instead returns a PKCS #10 certificate request. After
-creating it, one would typically transmit it to a CA, who signs it and
-returns a freshly minted X.509 certificate. There is an example of
-using this function in the ``pkcs10`` example.
+This function acts quite similarly to
+:cpp:func:`create_self_signed_cert`, except it instead returns a PKCS
+#10 certificate request. After creating it, one would typically
+transmit it to a CA, who signs it and returns a freshly minted X.509
+certificate.
+
+An example:
+
+.. literalinclude:: examples/pkcs10.cpp
Certificate Options
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-What is this ``X509_Cert_Options`` thing we've been passing around?
-It's a class representing a bunch of information that will end up
-being stored into the certificate. This information comes in 3 major
-flavors: information about the subject (CA or end-user), the validity
-period of the certificate, and restrictions on the usage of the
-certificate.
+What is this ``X509_Cert_Options`` thing we've been passing around? It's a
+class representing a bunch of information that will end up being stored into
+the certificate. This information comes in 3 major flavors: information about
+the subject (CA or end-user), the validity period of the certificate, and
+restrictions on the usage of the certificate.
-First and foremost is a number of ``std::string`` members, which
-contains various bits of information about the user: ``common_name``,
-``serial_number``, ``country``, ``organization``, ``org_unit``,
-``locality``, ``state``, ``email``, ``dns_name``, and ``uri``. As many
-of these as possible should be filled it (especially an email
-address), though the only required ones are ``common_name`` and
-``country``.
+First and foremost is a number of ``std::string`` members, which contains
+various bits of information about the user: ``common_name``, ``serial_number``,
+``country``, ``organization``, ``org_unit``, ``locality``, ``state``,
+``email``, ``dns_name``, and ``uri``. As many of these as possible should be
+filled it (especially an email address), though the only required ones are
+``common_name`` and ``country``.
There is another value that is only useful when creating a PKCS #10 request,
which is called ``challenge``. This is a challenge password, which you can
later use to request certificate revocation (*if* the CA supports doing
revocations in this manner).
-Then there is the validity period; these are set with ``not_before``
-and ``not_after``. Both of these functions also take a
-``std::string``, which specifies when the certificate should start
-being valid, and when it should stop being valid. If you don't set the
-starting validity period, it will automatically choose the current
-time. If you don't set the ending time, it will choose the starting
-time plus a default time period. The arguments to these functions
-specify the time in the following format: "2002/11/27 1:50:14". The
-time is in 24-hour format, and the date is encoded as
-year/month/day. The date must be specified, but you can omit the time
-or trailing parts of it, for example "2002/11/27 1:50" or
-"2002/11/27".
-
-Lastly, you can set constraints on a key. The one you're mostly likely
-to want to use is to create (or request) a CA certificate, which can
-be done by calling the member function ``CA_key``. This should only be
-used when needed.
+Then there is the validity period; these are set with ``not_before`` and
+``not_after``. Both of these functions also take a ``std::string``, which
+specifies when the certificate should start being valid, and when it should
+stop being valid. If you don't set the starting validity period, it will
+automatically choose the current time. If you don't set the ending time, it
+will choose the starting time plus a default time period. The arguments to
+these functions specify the time in the following format: "2002/11/27
+1:50:14". The time is in 24-hour format, and the date is encoded as
+year/month/day. The date must be specified, but you can omit the time or
+trailing parts of it, for example "2002/11/27 1:50" or "2002/11/27".
+
+Lastly, you can set constraints on a key. The one you're mostly likely to want
+to use is to create (or request) a CA certificate, which can be done by calling
+the member function ``CA_key``. This should only be used when needed.
Other constraints can be set by calling the member functions
-``add_constraints`` and ``add_ex_constraints``. The
-first takes a ``Key_Constraints`` value, and replaces any
-previously set value. If no value is set, then the certificate key is
-marked as being valid for any usage. You can set it to any of the
-following (for more than one usage, OR them together):
-``DIGITAL_SIGNATURE``, ``NON_REPUDIATION``,
-``KEY_ENCIPHERMENT``, ``DATA_ENCIPHERMENT``,
-``KEY_AGREEMENT``, ``KEY_CERT_SIGN``, ``CRL_SIGN``,
-``ENCIPHER_ONLY``, ``DECIPHER_ONLY``. Many of these have quite
-special semantics, so you should either consult the appropriate
-standards document (such as RFC 3280), or just not call
-``add_constraints``, in which case the appropriate values will
-be chosen for you.
-
-The second function, ``add_ex_constraints``, allows you to specify an
-OID that has some meaning with regards to restricting the key to
-particular usages. You can, if you wish, specify any OID you like, but
-there is a set of standard ones that other applications will be able
-to understand. These are the ones specified by the PKIX standard, and
-are named "PKIX.ServerAuth" (for TLS server authentication),
-"PKIX.ClientAuth" (for TLS client authentication), "PKIX.CodeSigning",
-"PKIX.EmailProtection" (most likely for use with S/MIME),
+``add_constraints`` and ``add_ex_constraints``. The first takes a
+``Key_Constraints`` value, and replaces any previously set value. If no value
+is set, then the certificate key is marked as being valid for any usage. You
+can set it to any of the following (for more than one usage, OR them together):
+``DIGITAL_SIGNATURE``, ``NON_REPUDIATION``, ``KEY_ENCIPHERMENT``,
+``DATA_ENCIPHERMENT``, ``KEY_AGREEMENT``, ``KEY_CERT_SIGN``, ``CRL_SIGN``,
+``ENCIPHER_ONLY``, ``DECIPHER_ONLY``. Many of these have quite special
+semantics, so you should either consult the appropriate standards document
+(such as RFC 3280), or just not call ``add_constraints``, in which case the
+appropriate values will be chosen for you.
+
+The second function, ``add_ex_constraints``, allows you to specify an OID that
+has some meaning with regards to restricting the key to particular usages. You
+can, if you wish, specify any OID you like, but there is a set of standard ones
+that other applications will be able to understand. These are the ones
+specified by the PKIX standard, and are named "PKIX.ServerAuth" (for TLS server
+authentication), "PKIX.ClientAuth" (for TLS client authentication),
+"PKIX.CodeSigning", "PKIX.EmailProtection" (most likely for use with S/MIME),
"PKIX.IPsecUser", "PKIX.IPsecTunnel", "PKIX.IPsecEndSystem", and
-"PKIX.TimeStamping". You can call "add_ex_constraints" any number of
-times - each new OID will be added to the list to include in the
-certificate.
+"PKIX.TimeStamping". You can call "add_ex_constraints" any number of times -
+each new OID will be added to the list to include in the certificate.