aboutsummaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/Makefile60
-rw-r--r--doc/algos.txt78
-rw-r--r--doc/api.tex2959
-rw-r--r--doc/bigint.txt64
-rw-r--r--doc/building.tex444
-rw-r--r--doc/building.txt403
-rw-r--r--doc/conf.py223
-rw-r--r--doc/credits.txt158
-rw-r--r--doc/examples/GNUmakefile21
-rw-r--r--doc/examples/asn1.cpp312
-rw-r--r--doc/examples/base64.cpp80
-rw-r--r--doc/examples/bcrypt.cpp45
-rw-r--r--doc/examples/bench.cpp107
-rw-r--r--doc/examples/benchmark.cpp46
-rw-r--r--doc/examples/bzip.cpp116
-rw-r--r--doc/examples/ca.cpp76
-rw-r--r--doc/examples/cert_verify.cpp35
-rw-r--r--doc/examples/checksum.cpp37
-rw-r--r--doc/examples/cms_dec.cpp120
-rw-r--r--doc/examples/cms_enc.cpp59
-rw-r--r--doc/examples/cpuid.cpp46
-rw-r--r--doc/examples/cryptobox.cpp53
-rw-r--r--doc/examples/decrypt.cpp173
-rw-r--r--doc/examples/dh.cpp73
-rw-r--r--doc/examples/dsa_kgen.cpp58
-rw-r--r--doc/examples/dsa_sign.cpp81
-rw-r--r--doc/examples/dsa_ver.cpp98
-rw-r--r--doc/examples/eax_test.cpp251
-rw-r--r--doc/examples/eax_tv.txt461
-rw-r--r--doc/examples/ecdsa.cpp61
-rw-r--r--doc/examples/encrypt.cpp193
-rw-r--r--doc/examples/encrypt2.cpp66
-rw-r--r--doc/examples/factor.cpp154
-rw-r--r--doc/examples/fpe.cpp151
-rw-r--r--doc/examples/gen_certs.cpp134
-rw-r--r--doc/examples/gtk/Makefile18
-rw-r--r--doc/examples/gtk/dsa.cpp566
-rw-r--r--doc/examples/gtk/gtk_ui.cpp79
-rw-r--r--doc/examples/gtk/gtk_ui.h27
-rw-r--r--doc/examples/gtk/readme.txt18
-rw-r--r--doc/examples/hash.cpp58
-rw-r--r--doc/examples/hash_fd.cpp70
-rw-r--r--doc/examples/hash_quickly.cpp98
-rw-r--r--doc/examples/hasher.cpp55
-rw-r--r--doc/examples/hasher2.cpp75
-rw-r--r--doc/examples/keywrap.cpp38
-rw-r--r--doc/examples/make_prime.cpp79
-rw-r--r--doc/examples/new_engine.cpp106
-rw-r--r--doc/examples/package.cpp70
-rw-r--r--doc/examples/passhash.cpp50
-rw-r--r--doc/examples/pkcs10.cpp70
-rw-r--r--doc/examples/pqg_gen.cpp121
-rw-r--r--doc/examples/read_ssh.cpp129
-rw-r--r--doc/examples/readme.txt77
-rw-r--r--doc/examples/rng_test.cpp126
-rw-r--r--doc/examples/row_encryptor.cpp171
-rw-r--r--doc/examples/rsa_dec.cpp129
-rw-r--r--doc/examples/rsa_enc.cpp151
-rw-r--r--doc/examples/rsa_kgen.cpp66
-rw-r--r--doc/examples/rsa_manykey.cpp42
-rw-r--r--doc/examples/self_sig.cpp83
-rw-r--r--doc/examples/sig_gen.cpp96
-rw-r--r--doc/examples/stack.cpp88
-rw-r--r--doc/examples/tls_client.cpp96
-rw-r--r--doc/examples/tls_server.cpp108
-rw-r--r--doc/examples/toolbox.cpp235
-rw-r--r--doc/examples/tss.cpp44
-rw-r--r--doc/examples/x509info.cpp35
-rw-r--r--doc/filters.txt782
-rw-r--r--doc/fips140.tex156
-rw-r--r--doc/indent.el16
-rw-r--r--doc/index.txt27
-rw-r--r--doc/internals.tex179
-rw-r--r--doc/intro.txt169
-rw-r--r--doc/license.txt90
-rw-r--r--doc/log.txt3425
-rw-r--r--doc/lowlevel.txt641
-rw-r--r--doc/old/architecture.pdf (renamed from doc/architecture.pdf)bin463402 -> 463402 bytes
-rw-r--r--doc/old/insito_manual.pdf (renamed from doc/insito_manual.pdf)bin150405 -> 150405 bytes
-rw-r--r--doc/old/tutorial.tex (renamed from doc/tutorial.tex)0
-rw-r--r--doc/old/tutorial2.tex (renamed from doc/tutorial2.tex)0
-rw-r--r--doc/pgpkeys.txt71
-rw-r--r--doc/pubkey.txt398
-rw-r--r--doc/python.tex68
-rwxr-xr-xdoc/python/cipher.py44
-rwxr-xr-xdoc/python/cryptobox.py36
-rwxr-xr-xdoc/python/nisttest.py61
-rw-r--r--doc/python/results.txt60
-rwxr-xr-xdoc/python/rng_test.py22
-rwxr-xr-xdoc/python/rsa.py47
-rwxr-xr-xdoc/scripts/print_deps.py70
-rwxr-xr-xdoc/scripts/update_deps.py41
-rw-r--r--doc/thanks.txt53
-rw-r--r--doc/x509.txt543
94 files changed, 5443 insertions, 12326 deletions
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 000000000..152fa3e09
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,60 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = _build
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html singlehtml latex latexpdf text man
+
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+
+clean:
+ -rm -rf $(BUILDDIR)/*
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ make -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
diff --git a/doc/algos.txt b/doc/algos.txt
new file mode 100644
index 000000000..0221405d6
--- /dev/null
+++ b/doc/algos.txt
@@ -0,0 +1,78 @@
+Algorithms
+=================================
+
+Recommended Algorithms
+---------------------------------
+
+This section is by no means the last word on selecting which
+algorithms to use. However, Botan includes a sometimes bewildering
+array of possible algorithms, and unless you're familiar with the
+latest developments in the field, it can be hard to know what is
+secure and what is not. The following attributes of the algorithms
+were evaluated when making this list: security, standardization,
+patent status, support by other implementations, and efficiency (in
+roughly that order).
+
+It is intended as a set of simple guidelines for developers, and
+nothing more. It's entirely possible that there are algorithms in
+Botan that will turn out to be more secure than the ones listed, but
+the algorithms listed here are (currently) thought to be safe.
+
+ - Block ciphers: AES or Serpent in CBC, CTR, or XTS mode
+
+ - Hash functions: SHA-256, SHA-512
+
+ - MACs: HMAC with any recommended hash function
+
+ - Public Key Encryption: RSA with "EME1(SHA-256)"
+
+ - Public Key Signatures: RSA with EMSA4 and any recommended
+ hash, or DSA or ECDSA with "EMSA1(SHA-256)"
+
+ - Key Agreement: Diffie-Hellman or ECDH, with "KDF2(SHA-256)"
+
+Algorithms Listing
+---------------------------------
+
+Botan includes a very sizable number of cryptographic algorithms. In
+nearly all cases, you never need to know the header file or type name
+to use them. However, you do need to know what string (or strings) are
+used to identify that algorithm. These names conform to those set out
+by SCAN (Standard Cryptographic Algorithm Naming), which is a document
+that specifies how strings are mapped onto algorithm objects, which is
+useful for a wide variety of crypto APIs (SCAN is oriented towards
+Java, but Botan and several other non-Java libraries also make at
+least some use of it). For full details, read the SCAN document, which
+can be found at
+http://www.users.zetnet.co.uk/hopwood/crypto/scan/
+
+Many of these algorithms can take options (such as the number of
+rounds in a block cipher, the output size of a hash function,
+etc). These are shown in the following list; all of them default to
+reasonable values. There are algorithm-specific limits on most of
+them. When you see something like "HASH" or "BLOCK", that means
+you should insert the name of some algorithm of that type. There are
+no defaults for those options.
+
+A few very obscure algorithms are skipped; if you need one of them,
+you'll know it, and you can look in the appropriate header to see what
+that classes' ``name`` function returns (the names tend to
+match that in SCAN, if it's defined there).
+
+ - ROUNDS: The number of rounds in a block cipher.
+ - OUTSZ: The output size of a hash function or MAC
+
+**Block Ciphers:** "AES-128", "AES-192", "AES-256", "Blowfish",
+"CAST-128", "CAST-256", "DES", "DESX", "TripleDES", "GOST-28147-89",
+"IDEA", "KASUMI", "MARS", "MISTY1(ROUNDS)", "Noekeon", "RC2",
+"RC5(ROUNDS)", "RC6", "SAFER-SK(ROUNDS)", "SEED", "Serpent",
+"Skipjack", "Square", "TEA", "Twofish", "XTEA"
+
+**Stream Ciphers:** "ARC4", "MARK4", "Salsa20", "Turing",
+"WiderWake4+1-BE"
+
+**Hash Functions:** "HAS-160", "GOST-34.11", "MD2", "MD4", "MD5",
+"RIPEMD-128", "RIPEMD-160", "SHA-160", "SHA-256", "SHA-384",
+"SHA-512", "Skein-512", "Tiger(OUTSZ)", "Whirlpool"
+
+**MACs:** "HMAC(HASH)", "CMAC(BLOCK)", "X9.19-MAC"
diff --git a/doc/api.tex b/doc/api.tex
deleted file mode 100644
index 434b717e4..000000000
--- a/doc/api.tex
+++ /dev/null
@@ -1,2959 +0,0 @@
-\documentclass{article}
-
-\setlength{\textwidth}{6.5in}
-\setlength{\textheight}{9in}
-
-\setlength{\headheight}{0in}
-\setlength{\topmargin}{0in}
-\setlength{\headsep}{0in}
-
-\setlength{\oddsidemargin}{0in}
-\setlength{\evensidemargin}{0in}
-
-\title{\textbf{Botan Reference Manual}}
-\author{}
-\date{2010/06/14}
-
-\newcommand{\filename}[1]{\texttt{#1}}
-\newcommand{\manpage}[2]{\texttt{#1}(#2)}
-
-\newcommand{\macro}[1]{\texttt{#1}}
-
-\newcommand{\function}[1]{\textbf{#1}}
-\newcommand{\keyword}[1]{\texttt{#1}}
-\newcommand{\type}[1]{\texttt{#1}}
-\renewcommand{\arg}[1]{\textsl{#1}}
-\newcommand{\namespace}[1]{\texttt{#1}}
-
-\newcommand{\url}[1]{\texttt{#1}}
-
-\newcommand{\ie}[0]{\emph{i.e.}}
-\newcommand{\eg}[0]{\emph{e.g.}}
-
-\begin{document}
-
-\maketitle
-
-\tableofcontents
-
-\parskip=5pt
-
-\pagebreak
-
-\section{Introduction}
-
-Botan is a C++ library that attempts to provide the most common
-cryptographic algorithms and operations in an easy to use, efficient,
-and portable way. It runs on a wide variety of systems, and can be
-used with a number of different compilers.
-
-The base library is written in ISO C++, so it can be ported with
-minimal fuss, but Botan also supports a modules system. This system
-exposes system dependent code to the library through portable
-interfaces, extending the set of services available to users.
-
-\subsection{Recommended Reading}
-
-It's a very good idea if you have some knowledge of cryptography prior
-to trying to use this stuff. You really should read at least one and
-ideally all of these books before seriously using the library.
-
-\setlength{\parskip}{5pt}
-
-\noindent
-\textit{Cryptography Engineering}, Niels Ferguson, Bruce Schneier, and
-Tadayoshi Kohno; Wiley
-
-\noindent
-\textit{Security Engineering -- A Guide to Building Dependable
- Distributed Systems}, Ross Anderson; Wiley
-
-\noindent
-\textit{Handbook of Applied Cryptography}, Alfred J. Menezes,
-Paul C. Van Oorschot, and Scott A. Vanstone; CRC Press (available
-online at \url{http://www.cacr.math.uwaterloo.ca/hac/})
-
-\subsection{Targets}
-
-Botan's primary targets (system-wise) 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, Botan is
-written to prefer 64-bit, on the theory that where performance is a
-real concern, modern 64-bit processors are the obvious choice.
-
-Smaller handhelds, set-top boxes, and the bigger smart phones and smart
-cards, are also capable of using Botan. However, Botan uses a
-large amount of code space (up to several megabytes, depending upon
-the compiler and options used), which could be prohibitive in some
-systems. Usage of RAM is modest, usually under 64K.
-
-Botan's design makes it quite easy to remove unused algorithms in such
-a way that applications do not need to be recompiled to work, even
-applications that use the algorithms in question. They can ask Botan
-if the algorithm exists, and if Botan says yes, ask the library to
-give them such an object for that algorithm.
-
-\section{Getting Started}
-
-\subsection{Basic Conventions}
-
-With a very small number of exceptions, declarations in the library
-are contained within the namespace \namespace{Botan}. Botan declares
-several \keyword{typedef}'ed types to help buffer it against changes
-in machine architecture. These types are used extensively in the
-interface, thus it would be often be convenient to use them without
-the \namespace{Botan} prefix. You can do so by \keyword{using} the
-namespace \namespace{Botan\_types} (this way you can use the type
-names without the namespace prefix, but the remainder of the library
-stays out of the global namespace). The included types are \type{byte}
-and \type{u32bit}, which are unsigned integer types.
-
-The headers for Botan are usually available in the form
-\filename{botan/headername.h}. For brevity in this documentation,
-headers are always just called \filename{headername.h}, but they
-should be used with the \filename{botan/} prefix in your actual code.
-
-\subsection{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 \type{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
-\type{LibraryInitializer} is at the start of your \function{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:
-
-\texttt{Botan::LibraryInitializer init;}
-
-at the start of your \texttt{main}.
-
-The constructor takes an optional string that specifies arguments.
-Currently the only possible argument is ``thread\_safe'', which must
-have an boolean argument (for instance ``thread\_safe=false'' or
-``thread\_safe=true''). If ``thread\_safe'' is specified as true the
-library will attempt to register a mutex type to properly guard access
-to shared resources. However these locks do not protect individual
-Botan objects: explicit locking must be used if you wish to share a
-single object between threads.
-
-If you do not create a \type{LibraryInitializer} object, all library
-operations will fail, because it will be unable to do basic things
-like allocate memory or get random bits. You should never create more
-than one \type{LibraryInitializer}.
-
-It is not strictly necessary to create a \type{LibraryInitializer};
-the actual code performing the initialization and shutdown are in
-static member functions of \type{LibraryInitializer}, called
-\function{initialize} and \function{deinitialize}. A
-\type{LibraryInitializer} merely provides a convenient RAII wrapper
-for the operations (thus for the internal library state as well).
-
-\subsection{Pitfalls}
-
-There are a few things to watch out for to prevent problems when using Botan.
-
-Never allocate any kind of Botan object globally. The problem with
-doing this is that the constructor for such an object will be called
-before the library is initialized. Many Botan objects will, in their
-constructor, make one or more calls into the library global state
-object. Access to this object is checked, so an exception should be
-thrown (rather than a memory access violation or undetected
-uninitialized object access). A rough equivalent that will work is to
-keep a global pointer to the object, initializing it after creating
-your \type{LibraryInitializer}. Merely making the
-\type{LibraryInitializer} also global will probably not help, because
-C++ does not make very strong guarantees about the order that such
-objects will be created.
-
-The same rule applies for making sure the destructors of all your
-Botan objects are called before the \type{LibraryInitializer} is
-destroyed. This implies you can't have static variables that are Botan
-objects inside functions or classes; in many C++ runtimes, these
-objects will be destroyed after main has returned.
-
-Botan's memory object classes (\type{MemoryRegion},
-\type{MemoryVector}, \type{SecureVector}) are extremely primitive, and
-meant only for secure storage of potentially sensitive data like
-keys. They do not meet the requirements for an STL container object
-and you should not try to use them with STL algorithms. For a
-general-purpose container, use \type{std::vector}.
-
-Use a \function{try}/\function{catch} block inside your
-\function{main} function, and catch any \type{std::exception} throws
-(remember to catch by reference, as \type{std::exception}'s
-\function{what} method is polymorphic). This is not strictly required,
-but if you don't, and Botan throws an exception, the runtime will call
-\function{std::terminate}, which usually calls \function{abort} or
-something like it, leaving you (or worse, a user of your application)
-wondering what went wrong.
-
-\subsection{Information Flow: Pipes and Filters}
-
-Many common uses of cryptography involve processing one or more
-streams of data. Botan provides services that make setting up data
-flows through various operations, such as compression, encryption, and
-base64 encoding. Each of these operations is implemented in what are
-called \emph{filters} in Botan. A set of filters are created and
-placed into a \emph{pipe}, and information ``flows'' through the pipe
-until it reaches the end, where the output is collected for
-retrieval. If you're familiar with the Unix shell environment, this
-design will sound quite familiar.
-
-Here is an example that uses a pipe to base64 encode some strings:
-
-\begin{verbatim}
- Pipe pipe(new Base64_Encoder); // pipe owns the pointer
- pipe.start_msg();
- pipe.write(``message 1'');
- pipe.end_msg(); // flushes buffers, increments message number
-
- // process_msg(x) is start_msg() && write(x) && end_msg()
- pipe.process_msg(``message2'');
-
- std::string m1 = pipe.read_all_as_string(0); // ``message1''
- std::string m2 = pipe.read_all_as_string(1); // ``message2''
-\end{verbatim}
-
-Bytestreams in the pipe are grouped into messages; blocks of data that
-are processed in an identical fashion (\ie, with the same sequence of
-\type{Filter}s). Messages are delimited by calls to
-\function{start\_msg} and \function{end\_msg}. Each message in a pipe
-has its own identifier, which currently is an integer that increments
-up from zero.
-
-As you can see, the \type{Base64\_Encoder} was allocated using
-\keyword{new}; but where was it deallocated? When a filter object is
-passed to a \type{Pipe}, the pipe takes ownership of the object, and
-will deallocate it when it is no longer needed.
-
-There are two different ways to make use of messages. One is to send
-several messages through a \type{Pipe} without changing the
-\type{Pipe}'s configuration, so you end up with a sequence of
-messages; one use of this would be to send a sequence of identically
-encrypted UDP packets, for example (note that the \emph{data} need not
-be identical; it is just that each is encrypted, encoded, signed, etc
-in an identical fashion). Another is to change the filters that are
-used in the \type{Pipe} between each message, by adding or removing
-\type{Filter}s; functions that let you do this are documented in the
-Pipe API section.
-
-Botan has about 40 filters that perform different operations on data.
-Here's code that uses one of them to encrypt a string with AES:
-
-\begin{verbatim}
- AutoSeeded_RNG rng,
- SymmetricKey key(rng, 16); // a random 128-bit key
- InitializationVector iv(rng, 16); // a random 128-bit IV
-
- // The algorithm we want is specified by a string
- Pipe pipe(get_cipher(``AES-128/CBC'', key, iv, ENCRYPTION));
-
- pipe.process_msg(``secrets'');
- pipe.process_msg(``more secrets'');
-
- MemoryVector<byte> c1 = pipe.read_all(0);
-
- byte c2[4096] = { 0 };
- u32bit got_out = pipe.read(c2, sizeof(c2), 1);
- // use c2[0...got_out]
-\end{verbatim}
-
-Note the use of \type{AutoSeeded\_RNG}, which is a random number
-generator. If you want to, you can explicitly set up the random number
-generators and entropy sources you want to, however for 99\% of cases
-\type{AutoSeeded\_RNG} is preferable.
-
-\type{Pipe} also has convenience methods for dealing with
-\type{std::iostream}s. Here is an example of those, using the
-\type{Bzip\_Compression} filter (included as a module; if you have
-bzlib available, check \filename{building.pdf} for how to enable it)
-to compress a file:
-
-\begin{verbatim}
- std::ifstream in(``data.bin'', std::ios::binary)
- std::ofstream out(``data.bin.bz2'', std::ios::binary)
-
- Pipe pipe(new Bzip_Compression);
-
- pipe.start_msg();
- in >> pipe;
- pipe.end_msg();
- out << pipe;
-\end{verbatim}
-
-However there is a hitch to the code above; the complete contents of
-the compressed data will be held in memory until the entire message
-has been compressed, at which time the statement \verb|out << pipe| is
-executed, and the data is freed as it is read from the pipe and
-written to the file. But if the file is very large, we might not have
-enough physical memory (or even enough virtual memory!) for that to be
-practical. So instead of storing the compressed data in the pipe for
-reading it out later, we divert it directly to the file:
-
-\begin{verbatim}
- std::ifstream in(``data.bin'', std::ios::binary)
- std::ofstream out(``data.bin.bz2'', std::ios::binary)
-
- Pipe pipe(new Bzip_Compression, new DataSink_Stream(out));
-
- pipe.start_msg();
- in >> pipe;
- pipe.end_msg();
-\end{verbatim}
-
-This is the first code we've seen so far that uses more than one
-filter in a pipe. The output of the compressor is sent to the
-\type{DataSink\_Stream}. Anything written to a \type{DataSink\_Stream}
-is written to a file; the filter produces no output. As soon as the
-compression algorithm finishes up a block of data, it will send it along,
-at which point it will immediately be written to disk; if you were to
-call \verb|pipe.read_all()| after \verb|pipe.end_msg()|, you'd get an
-empty vector out.
-
-Here's an example using two computational filters:
-
-\begin{verbatim}
- AutoSeeded_RNG rng,
- SymmetricKey key(rng, 32);
- InitializationVector iv(rng, 16);
-
- Pipe encryptor(get_cipher("AES/CBC/PKCS7", key, iv, ENCRYPTION),
- new Base64_Encoder);
-
- encryptor.start_msg();
- file >> encryptor;
- encryptor.end_msg(); // flush buffers, complete computations
- std::cout << encryptor;
-\end{verbatim}
-
-\subsection{Fork}
-
-It is common that you might receive some data and want to
-perform more than one operation on it (\ie, encrypt it with Serpent
-and calculate the SHA-256 hash of the plaintext at the same
-time). That's where \type{Fork} comes in. \type{Fork} is a filter that
-takes input and passes it on to \emph{one or more} \type{Filter}s
-that are attached to it. \type{Fork} changes the nature of the pipe
-system completely. Instead of being a linked list, it becomes a tree.
-
-Each \type{Filter} in the fork is given its own output buffer, and
-thus its own message. For example, if you had previously written two
-messages into a \type{Pipe}, then you start a new one with a
-\type{Fork} that has three paths of \type{Filter}'s inside it, you
-add three new messages to the \type{Pipe}. The data you put into the
-\type{Pipe} is duplicated and sent into each set of \type{Filter}s,
-and the eventual output is placed into a dedicated message slot in the
-\type{Pipe}.
-
-Messages in the \type{Pipe} are allocated in a depth-first manner. This is only
-interesting if you are using more than one \type{Fork} in a single \type{Pipe}.
-As an example, consider the following:
-
-\begin{verbatim}
- Pipe pipe(new Fork(
- new Fork(
- new Base64_Encoder,
- new Fork(
- NULL,
- new Base64_Encoder
- )
- ),
- new Hex_Encoder
- )
- );
-\end{verbatim}
-
-In this case, message 0 will be the output of the first \type{Base64\_Encoder},
-message 1 will be a copy of the input (see below for how \type{Fork} interprets
-NULL pointers), message 2 will be the output of the second
-\type{Base64\_Encoder}, and message 3 will be the output of the
-\type{Hex\_Encoder}. As you can see, this results in message numbers being
-allocated in a top to bottom fashion, when looked at on the screen. However,
-note that there could be potential for bugs if this is not anticipated. For
-example, if your code is passed a \type{Filter}, and you assume it is a
-``normal'' one that only uses one message, your message offsets would be
-wrong, leading to some confusion during output.
-
-If Fork's first argument is a null pointer, but a later argument is
-not, then Fork will feed a copy of its input directly through. Here's
-a case where that is useful:
-
-\begin{verbatim}
- // have std::string ciphertext, auth_code, key, iv, mac_key;
-
- Pipe pipe(new Base64_Decoder,
- get_cipher(``AES-128'', key, iv, DECRYPTION),
- new Fork(
- 0
- new MAC_Filter(``HMAC(SHA-1)'', mac_key)
- )
- );
-
- pipe.process_msg(ciphertext);
- std::string plaintext = pipe.read_all_as_string(0);
- SecureVector<byte> mac = pipe.read_all(1);
-
- if(mac != auth_code)
- error();
-\end{verbatim}
-
-Here we wanted to not only decrypt the message, but send the decrypted
-text through an additional computation, in order to compute the
-authentication code.
-
-Any \type{Filter}s that are attached to the \type{Pipe} after the
-\type{Fork} are implicitly attached onto the first branch created by
-the fork. For example, let's say you created this \type{Pipe}:
-
-\begin{verbatim}
-Pipe pipe(new Fork(new Hash_Filter("MD5"), new Hash_Filter("SHA-1")),
- new Hex_Encoder);
-\end{verbatim}
-
-And then called \function{start\_msg}, inserted some data, then
-\function{end\_msg}. Then \arg{pipe} would contain two messages. The
-first one (message number 0) would contain the MD5 sum of the input in
-hex encoded form, and the other would contain the SHA-1 sum of the
-input in raw binary. However, it's much better to use a \type{Chain}
-instead.
-
-\subsubsection{Chain}
-
-A \type{Chain} filter creates a chain of \type{Filter}s and
-encapsulates them inside a single filter (itself). This allows a
-sequence of filters to become a single filter, to be passed into or
-out of a function, or to a \type{Fork} constructor.
-
-You can call \type{Chain}'s constructor with up to 4 \type{Filter*}s
-(they will be added in order), or with an array of \type{Filter*}s and
-a \type{u32bit} that tells \type{Chain} how many \type{Filter*}s are
-in the array (again, they will be attached in order). Here's the
-example from the last section, using chain instead of relying on the
-obscure rule that version used.
-
-\begin{verbatim}
- Pipe pipe(new Fork(
- new Chain(new Hash_Filter("MD5"), new Hex_Encoder),
- new Hash_Filter("SHA-1")
- )
- );
-\end{verbatim}
-
-\subsection{The Pipe API}
-
-\subsubsection{Initializing Pipe}
-
-By default, \type{Pipe} will do nothing at all; any input placed into
-the \type{Pipe} will be read back unchanged. Obviously, this has
-limited utility, and presumably you want to use one or more
-\type{Filter}s to somehow process the data. First, you can choose a
-set of \type{Filter}s to initialize the \type{Pipe} via the
-constructor. You can pass it either a set of up to 4 \type{Filter*}s,
-or a pre-defined array and a length:
-
-\begin{verbatim}
- Pipe pipe1(new Filter1(/*args*/), new Filter2(/*args*/),
- new Filter3(/*args*/), new Filter4(/*args*/));
- Pipe pipe2(new Filter1(/*args*/), new Filter2(/*args*/));
-
- Filter* filters[5] = {
- new Filter1(/*args*/), new Filter2(/*args*/), new Filter3(/*args*/),
- new Filter4(/*args*/), new Filter5(/*args*/) /* more if desired... */
- };
- Pipe pipe3(filters, 5);
-\end{verbatim}
-
-This is by far the most common way to initialize a \type{Pipe}. However,
-occasionally a more flexible initialization strategy is necessary; this is
-supported by 4 member functions: \function{prepend}(\type{Filter*}),
-\function{append}(\type{Filter*}), \function{pop}(), and \function{reset}().
-These functions may only be used while the \type{Pipe} in question is not in
-use; that is, either before calling \function{start\_msg}, or after
-\function{end\_msg} has been called (and no new calls to \function{start\_msg}
-have been made yet).
-
-The function \function{reset}() removes all the \type{Filter}s that
-the \type{Pipe} is currently using~--~it is reset to an initialize,
-``empty'' state. Any data that is being retained by the \type{Pipe}
-is retained after a \function{reset}(), and \function{reset}() does
-not affect the message numbers (discussed later).
-
-Calling \function{prepend} and \function{append} will either prepend
-or append the passed \type{Filter} object to the list of
-transformations. For example, if you \function{prepend} a
-\type{Filter} implementing encryption, and the \type{Pipe} already had
-a \type{Filter} that hex encoded the input, then the next set of
-input would be first encrypted, then hex encoded. Alternately, if you
-called \function{append}, then the input would be first be hex
-encoded, and then encrypted (which is not terribly useful in this
-particular example).
-
-Finally, calling \function{pop}() will remove the first transformation
-of the \type{Pipe}. Say we had called \function{prepend} to put an
-encryption \type{Filter} into a \type{Pipe}; calling \function{pop}()
-would remove this \type{Filter} and return the \type{Pipe} to its
-state before we called \function{prepend}.
-
-\subsubsection{Giving Data to a Pipe}
-
-Input to a \type{Pipe} is delimited into messages, which can be read from
-independently (\ie, you can read 5 bytes from one message, and then all of
-another message, without either read affecting any other messages). The
-messages are delimited by calls to \function{start\_msg} and
-\function{end\_msg}. In between these two calls, you can write data into a
-\type{Pipe}, and it will be processed by the \type{Filter}(s) that it
-contains. Writes at any other time are invalid, and will result in an
-exception.
-
-As to writing, you can call any of the functions called \function{write}(),
-that can take any of: a \type{byte[]}/\type{u32bit} pair, a
-\type{SecureVector<byte>}, a \type{std::string}, a \type{DataSource\&}, or a
-single \type{byte}.
-
-Sometimes, you may want to do only a single write per message. In this case,
-you can use the \function{process\_msg} series of functions, which start a
-message, write their argument into the \type{Pipe}, and then end the
-message. In this case you would not make any explicit calls to
-\function{start\_msg}/\function{end\_msg}. The version of \function{write}
-that takes a single \type{byte} is not supported by \function{process\_msg},
-but all the other variants are.
-
-\type{Pipe} can also be used with the \verb|>>| operator, and will accept a
-\type{std::istream}, (or on Unix systems with the \verb|fd_unix| module), a
-Unix file descriptor. In either case, the entire contents of the file will be
-read into the \type{Pipe}.
-
-\subsubsection{Getting Output from a Pipe}
-
-Retrieving the processed data from a \type{Pipe} is a bit more complicated, for
-various reasons. In particular, because \type{Pipe} will separate each message
-into a separate buffer, you have to be able to retrieve data from each message
-independently. Each of \type{Pipe}'s read functions has a final parameter that
-specifies what message to read from (as a 32-bit integer). If this parameter is
-set to \type{Pipe::DEFAULT\_MESSAGE}, it will read the current default message
-(\type{DEFAULT\_MESSAGE} is also the default value of this parameter). The
-parameter will not be mentioned in further discussion of the reading API, but
-it is always there (unless otherwise noted).
-
-Reading is done with a variety of functions. The most basic are \type{u32bit}
-\function{read}(\type{byte} \arg{out}[], \type{u32bit} \arg{len}) and
-\type{u32bit} \function{read}(\type{byte\&} \arg{out}). Each reads into
-\arg{out} (either up to \arg{len} bytes, or a single byte for the one taking a
-\type{byte\&}), and returns the total number of bytes read. There is a variant
-of these functions, all named \function{peek}, which performs the same
-operations, but does not remove the bytes from the message (reading is a
-destructive operation with a \type{Pipe}).
-
-There are also the functions \type{SecureVector<byte>} \function{read\_all}(),
-and \type{std::string} \function{read\_all\_as\_string}(), which return the
-entire contents of the message, either as a memory buffer, or a
-\type{std::string} (which is generally only useful if the \type{Pipe} has
-encoded the message into a text string, such as when a \type{Base64\_Encoder}
-is used).
-
-To determine how many bytes are left in a message, call \type{u32bit}
-\function{remaining}() (which can also take an optional message
-number). Finally, there are some functions for managing the default message
-number: \type{u32bit} \function{default\_msg}() will return the current default
-message, \type{u32bit} \function{message\_count}() will return the total number
-of messages (0...\function{message\_count}()-1), and
-\function{set\_default\_msg}(\type{u32bit} \arg{msgno}) will set a new default
-message number (which must be a valid message number for that \type{Pipe}). The
-ability to set the default message number is particularly important in the case
-of using the file output operations (\verb|<<| with a \type{std::ostream} or
-Unix file descriptor), because there is no way to specify it explicitly when
-using the output operator.
-
-\subsection{A Filter Example}
-
-Here is some code that takes one or more filenames in \arg{argv} and
-calculates the result of several hash functions for each file. The complete
-program can be found as \filename{hasher.cpp} in the Botan distribution. For
-brevity, error checking has been removed.
-
-\begin{verbatim}
- string name[3] = { "MD5", "SHA-1", "RIPEMD-160" };
- Botan::Filter* hash[3] = {
- new Botan::Chain(new Botan::Hash_Filter(name[0]),
- new Botan::Hex_Encoder),
- new Botan::Chain(new Botan::Hash_Filter(name[1]),
- new Botan::Hex_Encoder),
- new Botan::Chain(new Botan::Hash_Filter(name[2]),
- new Botan::Hex_Encoder) };
-
- Botan::Pipe pipe(new Botan::Fork(hash, COUNT));
-
- for(u32bit j = 1; argv[j] != 0; j++)
- {
- ifstream file(argv[j]);
- pipe.start_msg();
- file >> pipe;
- pipe.end_msg();
- file.close();
- for(u32bit k = 0; k != 3; k++)
- {
- pipe.set_default_msg(3*(j-1)+k);
- cout << name[k] << "(" << argv[j] << ") = " << pipe << endl;
- }
- }
-\end{verbatim}
-
-
-\subsection{Filter Catalog}
-
-This section contains descriptions of every \type{Filter} included in
-the portable sections of Botan. \type{Filter}s provided by modules
-are documented elsewhere.
-
-\subsubsection{Keyed Filters}
-
-A few sections ago, it was mentioned that \type{Pipe} can process multiple
-messages, treating each of them the same. Well, that was a bit of a
-lie. There are some algorithms (in particular, block ciphers not in ECB mode,
-and all stream ciphers) that change their state as data is put through them.
-
-Naturally, you might well want to reset the keys or (in the case of block
-cipher modes) IVs used by such filters, so multiple messages can be processed
-using completely different keys, or new IVs, or new keys and IVs, or whatever.
-And in fact, even for a MAC or an ECB block cipher, you might well want to
-change the key used from message to message.
-
-Enter \type{Keyed\_Filter}, which acts as an abstract interface for
-any filter that is uses keys: block cipher modes, stream ciphers,
-MACs, and so on. It has two functions, \function{set\_key} and
-\function{set\_iv}. Calling \function{set\_key} will, naturally, set
-(or reset) the key used by the algorithm. Setting the IV only makes
-sense in certain algorithms -- a call to \function{set\_iv} on an
-object that doesn't support IVs will be ignored. You \emph{must} call
-\function{set\_key} before calling \function{set\_iv}: while not all
-\type{Keyed\_Filter} objects require this, you should assume it is
-required anytime you are using a \type{Keyed\_Filter}.
-
-Here's a example:
-
-\begin{verbatim}
- Keyed_Filter *cast, *hmac;
- Pipe pipe(new Base64_Decoder,
- // Note the assignments to the cast and hmac variables
- cast = new CBC_Decryption("CAST-128", "PKCS7", cast_key, iv),
- new Fork(
- 0, // Read the section 'Fork' to understand this
- new Chain(
- hmac = new MAC_Filter("HMAC(SHA-1)", mac_key, 12),
- new Base64_Encoder
- )
- )
- );
- pipe.start_msg();
- [use pipe for a while, decrypt some stuff, derive new keys and IVs]
- pipe.end_msg();
-
- cast->set_key(cast_key2);
- cast->set_iv(iv2);
- hmac->set_key(mac_key2);
-
- pipe.start_msg();
- [use pipe for some other things]
- pipe.end_msg();
-\end{verbatim}
-
-There are some requirements to using \type{Keyed\_Filter} that you must
-follow. If you call \function{set\_key} or \function{set\_iv} on a filter that
-is owned by a \type{Pipe}, you must do so while the \type{Pipe} is
-``unlocked''. This refers to the times when no messages are being processed by
-\type{Pipe} -- either before \type{Pipe}'s \function{start\_msg} is called, or
-after \function{end\_msg} is called (and no new call to \function{start\_msg}
-has happened yet). Doing otherwise will result in undefined behavior, probably
-silently getting invalid output.
-
-And remember: if you're resetting both values, reset the key \emph{first}.
-
-\subsubsection{Cipher Filters}
-
-Getting a hold of a \type{Filter} implementing a cipher is very
-easy. Make sure you're including the header \filename{lookup.h}, and
-then call \function{get\_cipher}. You will pass the return value
-directly into a \type{Pipe}. There are a couple different functions
-which do varying levels of initialization:
-
-\function{get\_cipher}(\type{std::string} \arg{cipher\_spec},
- \type{SymmetricKey} \arg{key},
- \type{InitializationVector} \arg{iv},
- \type{Cipher\_Dir} \arg{dir});
-
-\function{get\_cipher}(\type{std::string} \arg{cipher\_spec},
- \type{SymmetricKey} \arg{key},
- \type{Cipher\_Dir} \arg{dir});
-
-The version that doesn't take an IV is useful for things that don't
-use them, like block ciphers in ECB mode, or most stream ciphers. If
-you specify a \arg{cipher\_spec} that does want a IV, and you use the
-version that doesn't take one, an exception will be thrown. The
-\arg{dir} argument can be either \type{ENCRYPTION} or
-\type{DECRYPTION}.
-
-The \arg{cipher\_spec} is a string that specifies what cipher is to be
-used. The general syntax for \arg{cipher\_spec} is ``STREAM\_CIPHER'',
-``BLOCK\_CIPHER/MODE'', or ``BLOCK\_CIPHER/MODE/PADDING''. In the case
-of stream ciphers, no mode is necessary, so just the name is
-sufficient. A block cipher requires a mode of some sort, which can be
-``ECB'', ``CBC'', ``CFB(n)'', ``OFB'', ``CTR-BE'', or ``EAX(n)''. The
-argument to CFB mode is how many bits of feedback should be used. If
-you just use ``CFB'' with no argument, it will default to using a
-feedback equal to the block size of the cipher. EAX mode also takes an
-optional bit argument, which tells EAX how large a tag size to
-use~--~generally this is the size of the block size of the cipher,
-which is the default if you don't specify any argument.
-
-In the case of the ECB and CBC modes, a padding method can also be
-specified. If it is not supplied, ECB defaults to not padding, and CBC
-defaults to using PKCS \#5/\#7 compatible padding. The padding methods
-currently available are ``NoPadding'', ``PKCS7'', ``OneAndZeros'', and
-``CTS''. CTS padding is currently only available for CBC mode, but the
-others can also be used in ECB mode.
-
-Some example \arg{cipher\_spec} arguments are: ``AES-128/CBC'',
-``Blowfish/CTR-BE'', ``Serpent/XTS'', and ``AES-256/EAX''.
-
-``CTR-BE'' refers to counter mode where the counter is incremented as
-if it were a big-endian encoded integer. This is compatible with most
-other implementations, but it is possible some will use the
-incompatible little endian convention. This version would be denoted
-as ``CTR-LE'' if it were supported.
-
-``EAX'' is a new cipher mode designed by Wagner, Rogaway, and
-Bellare. It is an authenticated cipher mode (that is, no separate
-authentication is needed), has provable security, and is free from
-patent entanglements. It runs about half as fast as most of the other
-cipher modes (like CBC, OFB, or CTR), which is not bad considering you
-don't need to use an authentication code.
-
-\subsubsection{Hashes and MACs}
-
-Hash functions and MACs don't need anything special when it comes to
-filters. Both just take their input and produce no output until
-\function{end\_msg()} is called, at which time they complete the hash or MAC
-and send that as output.
-
-These \type{Filter}s take a string naming the type to be used. If for some
-reason you name something that doesn't exist, an exception will be thrown.
-
-\noindent
-\function{Hash\_Filter}(\type{std::string} \arg{hash},
- \type{u32bit} \arg{outlength}):
-
-This type hashes its input with \arg{hash}. When \function{end\_msg} is called
-on the owning \type{Pipe}, the hash is completed and the digest is sent on to
-the next thing in the pipe. The argument \arg{outlength} specifies how much of
-the output of the hash will be passed along to the next filter when
-\function{end\_msg} is called. By default, it will pass the entire hash.
-
-Examples of names for \function{Hash\_Filter} are ``SHA-1'' and ``Whirlpool''.
-
-\noindent
-\function{MAC\_Filter}(\type{std::string} \arg{mac},
- \type{const SymmetricKey\&} \arg{key},
- \type{u32bit} \arg{outlength}):
-
-The constructor for a \type{MAC\_Filter} takes a key, used in calculating the
-MAC, and a length parameter, which has semantics the same as the one
-passed to \type{Hash\_Filter}s constructor.
-
-Examples for \arg{mac} are ``HMAC(SHA-1)'', ``CMAC(AES-128)'', and the
-exceptionally long, strange, and probably useless name
-``CMAC(Lion(Tiger(20,3),MARK-4,1024))''.
-
-\subsubsection{PK Filters}
-
-There are four classes in this category, \type{PK\_Encryptor\_Filter},
-\type{PK\_Decryptor\_Filter}, \type{PK\_Signer\_Filter}, and
-\type{PK\_Verifier\_Filter}. Each takes a pointer to an object of the
-appropriate type (\type{PK\_Encryptor}, \type{PK\_Decryptor}, etc) that is
-deleted by the destructor. These classes are found in \filename{pk\_filts.h}.
-
-Three of these, for encryption, decryption, and signing are much the
-same in terms of dataflow - ach of them buffers its input until the
-end of the message is marked with a call to the \function{end\_msg}
-function. Then they encrypt, decrypt, or sign the entire input as a
-single blob and send the output (the ciphertext, the plaintext, or the
-signature) into the next filter.
-
-Signature verification works a little differently, because it needs to
-know what the signature is in order to check it. You can either pass
-this in along with the constructor, or call the function
-\function{set\_signature} -- with this second method, you need to keep
-a pointer to the filter around so you can send it this command. In
-either case, after \function{end\_msg} is called, it will try to
-verify the signature (if the signature has not been set by either
-method, an exception will be thrown here). It will then send a single
-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), read the section
-``Public Key Cryptography'' in this manual.
-
-\subsubsection{Encoders}
-
-Often you want your data to be in some form of text (for sending over channels
-that aren't 8-bit clean, printing it, etc). The filters \type{Hex\_Encoder}
-and \type{Base64\_Encoder} will convert arbitrary binary data into hex or
-base64 formats. Not surprisingly, you can use \type{Hex\_Decoder} and
-\type{Base64\_Decoder} to convert it back into its original form.
-
-Both of the encoders can take a few options about how the data should be
-formatted (all of which have defaults). The first is a \type{bool} which
-says if the encoder should insert line breaks. This defaults to
-false. Line breaks don't matter either way to the decoder, but it makes the
-output a bit more appealing to the human eye, and a few transport mechanisms
-(notably some email systems) limit the maximum line length.
-
-The second encoder option is an integer specifying how long such lines will be
-(obviously this will be ignored if line-breaking isn't being used). The default
-tends to be in the range of 60-80 characters, but is not specified. If
-you want a specific value, set it. Otherwise the default should be fine.
-
-Lastly, \type{Hex\_Encoder} takes an argument of type \type{Case}, which can be
-\type{Uppercase} or \type{Lowercase} (default is \type{Uppercase}). This
-specifies what case the characters A-F should be output as. The base64 encoder
-has no such option, because it uses both upper and lower case letters for its
-output.
-
-The decoders both take a single option, which tells it how the object
-should behave in the case of invalid input. The enum (called
-\type{Decoder\_Checking}) can take on any of three values:
-\type{NONE}, \type{IGNORE\_WS}, and \type{FULL\_CHECK}. With
-\type{NONE} (the default, for compatibility with previous releases),
-invalid input (for example, a ``z'' character in supposedly hex input)
-will be ignored. With \type{IGNORE\_WS}, whitespace will be ignored by
-the decoder, but receiving other non-valid data will raise an
-exception. Finally, \type{FULL\_CHECK} will raise an exception for
-\emph{any} characters not in the encoded character set, including
-whitespace.
-
-You can find the declarations for these types in \filename{hex.h} and
-\filename{base64.h}.
-
-\subsection{Rolling Your Own}
-
-The system of filters and pipes was designed in an attempt to make it
-as simple as possible to write new \type{Filter} objects. There are
-four functions that need to be implemented by an object deriving from
-\type{Filter}:
-
-\noindent
-\type{void} \function{write}(\type{byte} \arg{input}[], \type{u32bit}
-\arg{length}):
-
-The \function{write} function is what is called when a filter receives input
-for it to process. The filter is \emph{not} required to process it right away;
-many filters buffer their input before producing any output. A filter will
-usually have \function{write} called many times during its lifetime.
-
-\noindent
-\type{void} \function{send}(\type{byte} \arg{output}[], \type{u32bit}
-\arg{length}):
-
-Eventually, a filter will want to produce some output to send along to the next
-filter in the pipeline. It does so by calling \function{send} with whatever it
-wants to send along to the next filter. There is also a version of
-\function{send} taking a single byte argument, as a convenience.
-
-\noindent
-\type{void} \function{start\_msg()}:
-
-This function is optional. Implement it if your \type{Filter} would like to do
-some processing or setup at the start of each message (for an example, see the
-Zlib compression module).
-
-\noindent
-\type{void} \function{end\_msg()}:
-
-Implementing the \function{end\_msg} function is optional. It is
-called when it has been requested that filters finish up their
-computations. The filter should finish up with whatever computation it
-is working on (for example, a compressing filter would flush the
-compressor and \function{send} the final block), and empty any buffers
-in preparation for processing a fresh new set of input.
-
-Additionally, if necessary, filters can define a constructor that
-takes any needed arguments, and a destructor to deal with deallocating
-memory, closing files, etc.
-
-\section{Public Key Cryptography}
-
-Let's create a 1024-bit RSA private key, encode the public key as a
-PKCS \#1 file with PEM encoding (which can be understood by many other
-cryptographic programs)
-
-\begin{verbatim}
-// everyone does:
-AutoSeeded_RNG rng;
-
-// Alice
-RSA_PrivateKey priv_rsa(rng, 1024 /* bits */);
-
-std::string alice_pem = X509::PEM_encode(priv_rsa);
-
-// send alice_pem to Bob, who does
-
-// Bob
-std::auto_ptr<Public_Key> alice(load_key(alice_pem));
-
-RSA_PublicKey* alice_rsa = dynamic_cast<RSA_PublicKey>(alice);
-if(alice_rsa)
- {
- /* ... */
- }
-
-\end{verbatim}
-
-\subsection{Creating PK Algorithm Key Objects}
-
-The library has interfaces for encryption, signatures, etc that do not require
-knowing the exact algorithm in use (for example RSA and Rabin-Williams
-signatures are handled by the exact same code path).
-
-One place where we \emph{do} need to know exactly what kind of
-algorithm is in use is when we are creating a key (\emph{But}: read
-the section ``Importing and Exporting PK Keys'', later in this
-manual).
-
-There are currently three kinds of public key algorithms in Botan:
-ones based on integer factorization (RSA and Rabin-Williams), ones
-based on the discrete logarithm problem in the integers modulo a prime
-(DSA, Diffie-Hellman, Nyberg-Rueppel, and ElGamal), and ones based on
-the discrete logarithm problem in an elliptic curve (ECDSA, ECDH, GOST
-34.10). The systems based on discrete logarithms (in either regular
-integers or elliptic curves) use a group (a mathematical term), which
-can be shared among many keys. An elliptic curve group is represented
-by the class \type{EC\_Domain\_Params}, while a modulo-prime group is
-represented by a \type{DL\_Group}.
-
-There are two ways to create a DL private key (such as
-\type{DSA\_PrivateKey}). One is to pass in just a \type{DL\_Group}
-object -- a new key will automatically be generated. The other
-involves passing in a group to use, along with both the public and
-private values (private value first).
-
-Since in integer factorization 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, or you can copy an
-pre-existing key by passing in the appropriate parameters (primes, exponents,
-etc). For RSA and Rabin-Williams (the two IF schemes in Botan), the parameters
-are all \type{BigInt}s: prime 1, prime 2, encryption exponent, decryption
-exponent, modulus. The last two are optional, since they can easily be derived
-from the first three.
-
-\subsubsection{Creating a DL\_Group}
-
-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, you
-should only use the ``DSA-n'' groups, while Diffie-Hellman and ElGamal can use
-either type (keep in mind that some applications/standards require DH/ELG to
-use DSA-style primes, while others require strong prime groups).
-
-You can also generate a new random group. This is not recommend, because it is
-quite slow, especially for safe primes.
-
-\subsection{Key Checking}
-
-Most public key algorithms have limitations or restrictions on their
-parameters. For example RSA requires an odd exponent, and algorithms based on
-the discrete logarithm problem need a generator $> 1$.
-
-Each low-level public key type has a function named \function{check\_key} that
-takes a \type{bool}. This function returns a Boolean value that declares
-whether or not the key is valid (from an algorithmic standpoint). For example,
-it will check to make sure that the prime parameters of a DSA key are, in fact,
-prime. 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
-\function{check\_key}'s argument is \type{true}, then it does ``strong''
-checking, which includes expensive operations like primality checking.
-
-Keys are always checked when they are loaded or generated, so typically there
-is no reason to use this function directly. However, you can disable or reduce
-the checks for particular cases (public keys, loaded private keys, generated
-private keys) by setting the right config toggle (see the section on the
-configuration subsystem for details).
-
-\subsection{Getting a PK algorithm object}
-
-The key types, like \type{RSA\_PrivateKey}, do not implement any kind
-of padding or encoding (which is necessary for security). To get an
-object that knows how to do padding, use the wrapper classes included
-in \filename{pubkey.h}. These take a key, along with a string that
-specifies what hashing and encoding method(s) to use. Examples of such
-strings are ``EME1(SHA-256)'' for OAEP encryption and
-``EMSA4(SHA-256)'' for PSS signatures (where the message is hashed
-using SHA-256).
-
-Here are some basic examples (using an RSA key) to give you a feel for
-the possibilities. These examples assume \type{rsakey} is an
-\type{RSA\_PrivateKey}, since otherwise we would not be able to create
-a decryption or signature object with it (you can create encryption or
-signature verification objects with public keys, naturally).
-
-\begin{verbatim}
- // PKCS #1 v2.0 / IEEE 1363 compatible encryption
- PK_Encryptor_EME rsa_enc_pkcs1_v2(rsakey, "EME1(SHA-1)");
- // PKCS #1 v1.5 compatible encryption
- PK_Encryptor_EME rsa_enc_pkcs1_v15(rsakey, "PKCS1v15")
-
- // This object can decrypt things encrypted by rsa_
- PK_Decryptor_EME rsa_dec_pkcs1_v2(rsakey, "EME1(SHA-1)");
-
- // PKCS #1 v1.5 compatible signatures
- PK_Signer rsa_sign_pkcs1_v15(rsakey, "EMSA3(MD5)");
- PK_Verifier rsa_verify_pkcs1_v15(rsakey, "EMSA3(MD5)");
-
- // PKCS #1 v2.1 compatible signatures
- PK_Signer rsa_sign_pkcs1_v2(rsakey, "EMSA4(SHA-1)");
- PK_Verifier rsa_verify_pkcs1_v2(rsakey, "EMSA4(SHA-1)");
-\end{verbatim}
-
-\subsection{Encryption}
-
-The \type{PK\_Encryptor} and \type{PK\_Decryptor} classes are the
-interface for encryption and decryption, respectively.
-
-Calling \function{encrypt} with a \type{byte} array, a length
-parameter, and an RNG object will return the input encrypted with
-whatever scheme is being used. Calling the similar \function{decrypt}
-will perform the inverse operation. You can also do these operations
-with \type{SecureVector<byte>}s. In all cases, the output is returned
-via a \type{SecureVector<byte>}.
-
-If you attempt an operation with a larger size than the key can
-support (this limit varies based on the algorithm, the key size, and
-the padding method used (if any)), an exception will be thrown. You
-can call \function{maximum\_input\_size} to find out the maximum size
-input (in bytes) that you can safely use with any particular key.
-
-Available public key encryption algorithms in Botan are RSA and
-ElGamal. The encoding methods are EME1, denoted by ``EME1(HASHNAME)'',
-PKCS \#1 v1.5, called ``PKCS1v15'' or ``EME-PKCS1-v1\_5'', and raw
-encoding (``Raw'').
-
-For compatibility reasons, PKCS \#1 v1.5 is recommend for use with
-ElGamal (most other implementations of ElGamal do not support any
-other encoding format). RSA can also be used with PKCS \# 1 encoding,
-but because of various possible attacks, EME1 is the preferred
-encoding. EME1 requires the use of a hash function: unless a competent
-applied cryptographer tells you otherwise, you should use SHA-256 or
-SHA-512.
-
-Don't use ``Raw'' encoding unless you need it for backward
-compatibility with old protocols. There are many possible attacks
-against both ElGamal and RSA when they are used in this way.
-
-\subsection{Signatures}
-
-The signature algorithms look quite a bit like the hash functions. You
-can repeatedly call \function{update}, giving more and more of a
-message you wish to sign, and then call \function{signature}, which
-will return a signature for that message. If you want to do it all in
-one shot, call \function{sign\_message}, which will just call
-\function{update} with its argument and then return whatever
-\function{signature} returns. Generating a signature requires random
-numbers with some schemes, so \function{signature} and
-\function{sign\_message} both take a \type{RandomNumberGenerator\&}.
-
-You can validate a signature by updating the verifier class, and finally seeing
-the if the value returned from \function{check\_signature} is true (you pass
-the supposed signature to the \function{check\_signature} function as a byte
-array and a length or as a \type{MemoryRegion<byte>}). There is another
-function, \function{verify\_message}, which takes a pair of byte array/length
-pairs (or a pair of \type{MemoryRegion<byte>} objects), the first of which is
-the message, the second being the (supposed) signature. It returns true if the
-signature is valid and false otherwise.
-
-Available public key signature algorithms in Botan are RSA, DSA,
-ECDSA, GOST-34.11, Nyberg-Rueppel, and Rabin-Williams. Signature
-encoding methods 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.
-
-There are various interactions that make certain encoding schemes and
-signing algorithms more or less useful.
-
-EMSA2 is the usual method for encoding Rabin-William signatures, so
-for compatibility with other implementations you may have to use
-that. EMSA4 (also called PSS), also works with Rabin-Williams. EMSA1
-and EMSA3 do \emph{not} work with Rabin-Williams.
-
-RSA can be used with any of the available encoding methods. EMSA4 is
-by far the most secure, but is not (as of now) widely
-implemented. EMSA3 (also called ``EMSA-PKCS1-v1\_5'') is commonly used
-with RSA (for example in SSL). EMSA1 signs the message digest
-directly, without any extra padding or encoding. This may be useful,
-but is not as secure as either EMSA3 or EMSA4. EMSA2 may be used but
-is not recommended.
-
-For DSA, ECDSA, GOST-34.11, and Nyberg-Rueppel, you should use
-EMSA1. None of the other encoding methods are particularly useful for
-these algorithms.
-
-\subsection{Key Agreement}
-
-You can get a hold of a \type{PK\_Key\_Agreement\_Scheme} object by
-calling \function{get\_pk\_kas} with a key that is of a type that
-supports key agreement (such as a Diffie-Hellman key stored in a
-\type{DH\_PrivateKey} object), and the name of a key derivation
-function. This can be ``Raw'', meaning the output of the primitive
-itself is returned as the key, or ``KDF1(hash)'' or ``KDF2(hash)''
-where ``hash'' is any string you happen to like (hopefully you like
-strings like ``SHA-256'' or ``RIPEMD-160''), or
-``X9.42-PRF(keywrap)'', which uses the PRF specified in ANSI X9.42. It
-takes the name or OID of the key wrap algorithm that will be used to
-encrypt a content encryption key.
-
-How key agreement works is that you trade public values with some
-other party, and then each of you runs a computation with the other's
-value and your key (this should return the same result to both
-parties). This computation can be called by using
-\function{derive\_key} with either a byte array/length pair, or a
-\type{SecureVector<byte>} than holds the public value of the other
-party. The last argument to either call is a number that specifies how
-long a key you want.
-
-Depending on the KDF you're using, you \emph{might not} get back a key
-of the size you requested. In particular ``Raw'' will return a number
-about the size of the Diffie-Hellman modulus, and KDF1 can only return
-a key that is the same size as the output of the hash. KDF2, on the
-other hand, will always give you a key exactly as long as you request,
-regardless of the underlying hash used with it. The key returned is a
-\type{SymmetricKey}, ready to pass to a block cipher, MAC, or other
-symmetric algorithm.
-
-The public value that should be used can be obtained by calling
-\function{public\_data}, which exists for any key that is associated with a
-key agreement algorithm. It returns a \type{SecureVector<byte>}.
-
-``KDF2(SHA-256)'' is by far the preferred algorithm for key derivation
-in new applications. The X9.42 algorithm may be useful in some
-circumstances, but unless you need X9.42 compatibility, KDF2 is easier
-to use.
-
-There is a Diffie-Hellman example included in the distribution, which you may
-want to examine.
-
-\subsection{Importing and Exporting PK Keys}
-
-[This section mentions \type{Pipe} and \type{DataSource}, which is not covered
-until later in the manual. Please read those sections for more about
-\type{Pipe} and \type{DataSource} and their uses.]
-
-There are many, many different (often conflicting) standards surrounding public
-key cryptography. There is, thankfully, only two major standards surrounding
-the representation of a public or private key: X.509 (for public keys), and
-PKCS \#8 (for private keys). Other crypto libraries, like OpenSSL and B-SAFE,
-also support these formats, so you can easily exchange keys with software that
-doesn't use Botan.
-
-In addition to ``plain'' public keys, Botan also supports X.509 certificates.
-These are documented in the section ``Certificate Handling'', later in this
-manual.
-
-\subsubsection{Public Keys}
-
-The interfaces for doing either of these are quite similar. Let's look at the
-X.509 stuff first:
-\begin{verbatim}
-namespace X509 {
- MemoryVector<byte> BER_encode(const Public_Key& key);
- std::string PEM_encode(const Public_Key& out);
-
- Public_Key* load_key(DataSource& in);
- Public_Key* load_key(const SecureVector<byte>& buffer);
-}
-\end{verbatim}
-
-The function \function{X509::BER\_encode} will take any
-\type{Public\_Key} and return a standard binary structure representing
-the key which can be read by many other crypto libraries.
-
-The function \function{X509::PEM\_encode} does the same, but
-additionally formats it into a text format with headers and base64
-encoding. Using PEM is \emph{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.
-
-For loading a public key, use one of the variants of
-\function{load\_key}. This function will return a newly allocated key
-based on the data from whatever source it is using (assuming, of
-course, the source is in fact storing a representation of a public
-key). The encoding used (PEM or BER) need not be specified; the format
-will be detected automatically. The key is allocated with
-\function{new}, and should be released with \function{delete} when you
-are done with it. The first takes a generic \type{DataSource} that you
-have to create~--~the others are simple wrapper functions that take
-either a filename or a memory buffer.
-
-Here's an example of loading a public key and then encrypting with it:
-
-\begin{verbatim}
- /* Might be RSA, might be ElGamal, might be ... */
- Public_Key* key = X509::load_key("pubkey.asc");
-
- /* This might throw an exception if the key doesn't support any
- encryption operations
- */
-
- PK_Encryptor_EME encryptor(*key, "EME1(SHA-1)");
-
- SecureVector<byte> ciphertext = encryptor.encrypt(msg, size_of_msg);
-\end{verbatim}
-
-\subsubsection{Private Keys}
-
-There are two different options for private key import/export. The first is a
-plaintext version of the private key. This is supported by the following
-functions:
-
-\begin{verbatim}
-namespace PKCS8 {
- SecureVector<byte> BER_encode(const Private_Key& key);
- std::string PEM_encode(const Private_Key& key);
-}
-\end{verbatim}
-
-These functions are similiar to the X.509 functions described
-previously. The only difference is that they take a
-\type{Private\_Key} object instead. In most situations, using these 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. For importing, the same
-functions can be used for encrypted and unencrypted keys.
-
-The other way to export a PKCS \#8 key is to first encode it in the
-same manner as done above, then encrypt it using a passphrase, and
-store the whole thing into another structure. This method is
-definitely preferred, since otherwise the private key is
-unprotected. The algorithms and structures used here are standardized
-by PKCS \#5 and PKCS \#8, and can be read by many other crypto
-libraries.
-
-\begin{verbatim}
-namespace PKCS8 {
- SecureVector<byte> BER_encode(const Private_Key& key,
- RandomNumberGenerator& rng,
- const std::string& pass,
- const std::string& pbe_algo = "");
-
- std::string PEM_encode(const Private_Key& key,
- RandomNumberGenerator& rng,
- const std::string& pass,
- const std::string& pbe_algo = "");
-}
-\end{verbatim}
-
-There are three new arguments needed here to support the encryption
-process in addition to the private key itself. The first is a
-\type{RandomNumberGenerator}, which is needed for various purposes
-internally. The \arg{pass} argument is the passphrase that will be
-used to encrypt the key. Both of these are required. The final
-(optional) argument is \arg{pbe}; this specifies a particular password
-based encryption (or PBE) algorithm. If you don't specify a PBE,
-a compiled in default will be used; this should be fine.
-
-Last but not least, there are some functions that will load (and
-decrypt, if necessary) a PKCS \#8 private key:
-
-\begin{verbatim}
-namespace PKCS8 {
- Private_Key* load_key(DataSource& in,
- RandomNumberGenerator& rng,
- const User_Interface& ui);
-
- Private_Key* load_key(DataSource& in,
- RandomNumberGenerator& rng,
- std::string passphrase = "");
-
- Private_Key* load_key(const std::string& filename,
- RandomNumberGenerator& rng,
- const User_Interface& ui);
-
- Private_Key* load_key(const std::string& filename,
- RandomNumberGenerator& rng,
- const std::string& passphrase = "");
-}
-\end{verbatim}
-
-The versions that take \type{std::string} \arg{passphrase}s are
-primarily for compatibility, but they are useful in limited
-circumstances. The \type{User\_Interface} versions are how
-\function{load\_key} is implemented, and provides for much more
-flexibility. If the passphrase passed in is not correct, then an
-exception is thrown and that is that. However, if you pass in an UI
-object, then the UI object can keep asking the user for the passphrase
-until they get it right (or until they cancel the action, though the
-UI interface). A \type{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. You can think of it as a user
-interface interface. The default \type{User\_Interface} is rather
-dumb, and acts rather like the versions taking the \type{std::string};
-it tries the passphrase passed in first, and then it cancels.
-
-All versions need access to a \type{RandomNumberGenerator} in order to
-perform probabilistic tests on the loaded key material.
-
-After loading a key, you can use \function{dynamic\_cast} to find out
-what operations it supports, and use it appropriately. Remember to
-\function{delete} the object once you are done with it.
-
-\subsubsection{Limitations}
-
-As of now Nyberg-Rueppel and Rabin-Williams keys cannot be imported or
-exported, because they have no official ASN.1 OID or definition. ElGamal keys
-can (as of Botan 1.3.8) be imported and exported, but the only other
-implementation that supports the format is Peter Gutmann's Cryptlib. If you
-can help it, stick to RSA and DSA.
-
-\emph{Note}: Currently NR and RW are given basic ASN.1 key formats (which
-mirror DSA and RSA, respectively), which means that, if they are assigned an
-OID, they can be imported and exported just as easily as RSA and DSA. You can
-assign them an OID by putting a line in a Botan configuration file, calling
-\function{OIDS::add\_oid}, or editing \filename{src/policy.cpp}. Be warned that
-it is possible that a future version will use a format that is different from
-the current one (\ie, a newly standardized format).
-
-\section{Certificate Handling}
-
-A certificate is a binding between some identifying information
-(called a \emph{subject}) and a public key. This binding is asserted
-by a signature on the certificate, which is placed there by some
-authority (the \emph{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.
-
-When working with certificates, the main class to remember is
-\type{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
-\filename{x509cert.h} and \filename{asn1\_obj.h} (which has the
-definitions of various common ASN.1 constructs used in X.509).
-
-\subsection{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 \function{subject\_public\_key}, which
-will return a \type{Public\_Key*}. As to what to do with this, read
-about \function{load\_key} in the section ``Importing and Exporting PK
-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
-and DSA keys are also supported, so be careful about how you treat
-this. It is also a wise idea to examine the value returned by
-\function{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 $\ldots$) different places where you can stick
-information about the user: the \emph{subject} field, and in an
-extension called \emph{subjectAlternativeName}. The \emph{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 \emph{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 \ldots 255), an
-exception will get thrown. Currently the \type{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 \type{std::wstring} instead of a
-\type{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.site2.com''), or a URI
-(``http://www.site3.com'').
-
-So, how to get the information? Call \function{subject\_info} with the
-name of the piece of information you want, and it will return a
-\type{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
-\type{std::string}.
-
-You can also get information about the issuer of the certificate in the same
-way, using \function{issuer\_info}.
-
-\subsubsection{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.
-
-\begin{list}{$\cdot$}
- \item Key Usage and Extended Key Usage: No problems known.
- \item
-
- \item 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.
-
- \item Subject Alternative Names: Only the ``rfc822Name'', ``dNSName'', and
- ``uniformResourceIdentifier'' fields will be stored; all others are
- ignored.
-
- \item Issuer Alternative Names: Same restrictions as the Subject Alternative
- Names extension. New certificates generated by Botan never include the
- issuer alternative name.
-
- \item 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.
-
- \item Subject Key Identifier: No problems known.
-\end{list}
-
-\subsubsection{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.
-
-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 \type{DataSource\&}). The CRLs
-can either be in raw BER/DER, or in PEM format; the constructor will figure out
-which format without any extra information. For example:
-
-\begin{verbatim}
- X509_CRL crl1("crl1.der");
-
- DataSource_Stream in("crl2.pem");
- X509_CRL crl2(in);
-\end{verbatim}
-
-After that, pass the \type{X509\_CRL} object to a \type{X509\_Store} object
-with \type{X509\_Code} \function{add\_crl}(\type{X509\_CRL}), and all future
-verifications will take into account the certificates listed, assuming
-\function{add\_crl} returns \type{VERIFIED}. If it doesn't return
-\type{VERIFIED}, then the return value is an error code signifying that the CRL
-could not be processed due to some problem (which could range from the issuing
-certificate not being found, to the CRL having some format problem). For more
-about the \type{X509\_Store} API, read the section later in this chapter.
-
-\subsection{Reading Certificates}
-
-\type{X509\_Certificate} has two constructors, each of which takes a source of
-data; a filename to read, and a \type{DataSource\&}.
-
-\subsection{Storing and Using Certificates}
-
-If you read a certificate, you probably want to verify the signature on
-it. However, consider that to do so, we may have to verify the signature on the
-certificate that we used to verify the first certificate, and on and on until
-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: \type{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).
-
-\subsubsection{Adding Certificates}
-
-You can add new certificates to a certificate store using any of these
-functions:
-
-\function{add\_cert}(\type{const X509\_Certificate\&} \arg{cert},
- \type{bool} \arg{trusted} \type{= false})
-
-\function{add\_certs}(\type{DataSource\&} \arg{source})
-
-\function{add\_trusted\_certs}(\type{DataSource\&} \arg{source})
-
-The versions that take a \type{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 have some reason to trust are genuine. 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.
-
-\subsubsection{Adding CRLs}
-
-\type{X509\_Code} \function{add\_crl}(\type{const X509\_CRL\&} \arg{crl});
-
-This will process the CRL and mark the revoked certificates. This will also
-work if a revoked certificate is added to the store sometime after the CRL is
-processed. The function can return an error code (listed later), or will return
-\type{VERIFIED} if everything completed successfully.
-
-\subsubsection{Storing Certificates}
-
-You can output a set of certificates by calling \function{PEM\_encode}, which
-will return a \type{std::string} containing each of the certificates in the
-store, PEM encoded and concatenated. This simple format can easily be read by
-both Botan and other libraries/applications.
-
-\subsubsection{Searching for Certificates}
-
-You can find certificates in the store with a series of functions contained
-in the \function{X509\_Store\_Search} namespace:
-
-\begin{verbatim}
-namespace X509_Store_Search {
-std::vector<X509_Certificate> by_email(const X509_Store& store,
- const std::string& email_addr);
-std::vector<X509_Certificate> by_name(const X509_Store& store,
- const std::string& name);
-std::vector<X509_Certificate> by_dns(const X509_Store&,
- const std::string& dns_name);
-}
-\end{verbatim}
-
-These functions will return a (possibly empty) vector of certificates from
-\arg{store} matching your search criteria. The email address and DNS name
-searches are case-insensitive but are sensitive to extra whitespace and so
-on. The name search will do case-insensitive substring matching, so, for
-example, calling \function{X509\_Store\_Search::by\_name}(\arg{your\_store},
-``dob'') will return certificates for ``J.R. 'Bob' Dobbs'' and
-``H. Dobbertin'', assuming both of those certificates are in \arg{your\_store}.
-
-You could then display the results to a user, and allow them to select the
-appropriate one. Searching using an email address as the key is usually more
-effective than the name, since email addresses are rarely shared.
-
-\subsubsection{Certificate Stores}
-
-An object of type \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 \type{std::vector} of \type{X509\_Certificate}. This storage
-mechanism is \emph{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 \function{by\_SKID} (Subject Key
-Identifier), \function{by\_name} (the CommonName DN entry), and
-\function{by\_email} (stored in either the distinguished name, or in a
-subjectAlternativeName extension). The name and email versions take a
-\type{std::string}, while the SKID version takes a \type{SecureVector<byte>}
-containing the subject key identifier in raw binary. You can choose not to
-implement \function{by\_name} or \function{by\_email}, but \function{by\_SKID}
-is mandatory to implement, and, currently, is the only version that is used by
-\type{X509\_Store}.
-
-Finally, there is a method for finding CRLs, called
-\function{get\_crls\_for}, that takes an \type{X509\_Certificate}
-object, and returns a \type{std::vector} of \type{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
-\type{X509\_CRL}.
-
-As for using such a store, you have to tell \type{X509\_Store} about
-it, by calling the \type{X509\_Store} member function
-
-\function{add\_new\_certstore}(\type{Certificate\_Store}* \arg{new\_store})
-
-The argument, \arg{new\_store}, will be deleted by \type{X509\_Store}'s
-destructor, so make sure to allocate it with \function{new}.
-
-\subsubsection{Verifying Certificates}
-
-There is a single function in \type{X509\_Store} related to verifying a
-certificate:
-
-\type{X509\_Code}
-\function{validate\_cert}(\type{const X509\_Certificate\&} \arg{cert},
- \type{Cert\_Usage} \arg{usage} = \type{ANY})
-
-This function will return \type{VERIFIED} if the certificate can
-safely be considered valid for the usage(s) described by \arg{usage},
-and an error code if it is not. Naturally, things are a bit more
-complicated than that. The enum \type{Cert\_Usage} is defined inside
-the \type{X509\_Store} class, it (currently) can take on any of the
-values \type{ANY} (any usage is OK), \type{TLS\_SERVER} (for SSL/TLS
-server authentication), \type{TLS\_CLIENT} (for SSL/TLS client
-authentication), \type{CODE\_SIGNING}, \type{EMAIL\_PROTECTION} (email
-encryption, usually this means S/MIME), \type{TIME\_STAMPING} (in
-theory any time stamp application, usually IETF PKIX's Time Stamp
-Protocol), or \type{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 \arg{usage} are \type{TLS\_SERVER},
-\type{TLS\_CLIENT}, \type{CODE\_SIGNING}, \type{EMAIL\_PROTECTION},
-\type{CRL\_SIGNING}, and \type{TIME\_STAMPING}, and \type{ANY}. The
-default \type{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 \function{validate\_cert} (and \function{add\_crl}) include:
-
-\begin{list}{$\cdot$}
- \item VERIFIED: The certificate is valid for the specified use.
- \item
- \item INVALID\_USAGE: The certificate cannot be used for the specified use.
-
- \item CANNOT\_ESTABLISH\_TRUST: The root certificate was not marked as
- trusted.
- \item CERT\_CHAIN\_TOO\_LONG: The certificate chain exceeded the length
- allowed by a basicConstraints extension.
- \item SIGNATURE\_ERROR: An invalid signature was found
- \item POLICY\_ERROR: Some problem with the certificate policies was found.
-
- \item CERT\_FORMAT\_ERROR: Some format problem was found in a certificate.
- \item CERT\_ISSUER\_NOT\_FOUND: The issuer of a certificate could not be
- found.
- \item CERT\_NOT\_YET\_VALID: The certificate is not yet valid.
- \item CERT\_HAS\_EXPIRED: The certificate has expired.
- \item CERT\_IS\_REVOKED: The certificate has been revoked.
-
- \item CRL\_FORMAT\_ERROR: Some format problem was found in a CRL.
- \item CRL\_ISSUER\_NOT\_FOUND: The issuer of a CRL could not be found.
- \item CRL\_NOT\_YET\_VALID: The CRL is not yet valid.
- \item CRL\_HAS\_EXPIRED: The CRL has expired.
-
- \item CA\_CERT\_CANNOT\_SIGN: The CA certificate found does not have an
- contain a public key that allows signature verification.
- \item CA\_CERT\_NOT\_FOR\_CERT\_ISSUER: The CA cert found is not allowed to
- issue certificates.
- \item CA\_CERT\_NOT\_FOR\_CRL\_ISSUER: The CA cert found is not allowed to
- issue CRLs.
-
- \item UNKNOWN\_X509\_ERROR: Some other error occurred.
-
-\end{list}
-
-\subsection{Certificate Authorities}
-
-Setting up a CA for X.509 certificates is perhaps the easiest thing to
-do related to X.509. A CA is represented by the type \type{X509\_CA},
-which can be found in \filename{x509\_ca.h}. A CA always needs its own
-certificate, which can either be a self-signed certificate (see below
-on how to create one) or one issued by another CA (see the section on
-PKCS \#10 requests). Creating a CA object is done by the following
-constructor:
-
-\begin{verbatim}
- X509_CA(const X509_Certificate& cert, const Private_Key& key);
-\end{verbatim}
-
-The private key is the private key corresponding to the public key in the
-CA's certificate.
-
-Requests for new certificates are supplied to a CA in the form on PKCS
-\#10 certificate requests (called a \type{PKCS10\_Request} object in
-Botan). These are decoded in a similar manner to
-certificates/CRLs/etc. A request is vetted by humans (who somehow
-verify that the name in the request corresponds to the name of the
-entity who requested it), and then signed by a CA key, generating a
-new certificate.
-
-\begin{verbatim}
- X509_Certificate sign_request(const PKCS10_Request&) const;
-\end{verbatim}
-
-\subsubsection{Generating CRLs}
-
-As mentioned previously, the ability to process CRLs is highly important in
-many PKI systems. In fact, according to strict X.509 rules, you must not
-validate any certificate if the appropriate CRLs are not available (though
-hardly any systems are that strict). In any case, a CA should have a valid CRL
-available at all times.
-
-Of course, you might be wondering what to do if no certificates have
-been revoked. Never fear; empty CRLs, which revoke nothing at all, can
-be issued. To generate a new, empty CRL, just call \type{X509\_CRL}
-\function{X509\_CA::new\_crl}(\type{u32bit}~\arg{seconds}~=~0)~--~it
-will create a new, empty, CRL. If \arg{seconds} is the default 0, then
-the normal default CRL next update time (the value of the
-``x509/crl/next\_update'') will be used. If not, then \arg{seconds}
-specifies how long (in seconds) it will be until the CRL's next update
-time (after this time, most clients will reject the CRL as too old).
-
-On the other hand, you may have issued a CRL before. In that case, you will
-want to issue a new CRL that contains all previously revoked
-certificates, along with any new ones. This is done by calling the
-\type{X509\_CA} member function
-\function{update\_crl}(\type{X509\_CRL}~\arg{old\_crl},
-\type{std::vector<CRL\_Entry>}~\arg{new\_revoked},
-\type{u32bit}~\arg{seconds}~=~0), where \type{X509\_CRL} is the last CRL this
-CA issued, and \arg{new\_revoked} is a list of any newly revoked certificates.
-The function returns a new \type{X509\_CRL} to make available for clients. The
-semantics for the \arg{seconds} argument is the same as \function{new\_crl}.
-
-The \type{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
-\type{SecureVector<byte>} called \arg{serial}. There are two additional
-(optional) values, an enumeration called \type{CRL\_Code} that specifies the
-reason for revocation (\arg{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 \arg{reason} code of \type{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.
-
-\subsubsection{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:
-
-\begin{verbatim}
-namespace X509 {
- X509_Certificate create_self_signed_cert(const X509_Cert_Options& opts,
- const Private_Key& key);
-}
-\end{verbatim}
-
-Where \arg{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
-\arg{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 \filename{x509self.h}. There is an
-example of using this function in the \filename{self\_sig} example.
-
-\subsubsection{Creating PKCS \#10 Requests}
-
-Also in \filename{x509self.h}, there is a function for generating new PKCS \#10
-certificate requests.
-
-\begin{verbatim}
-namespace X509 {
- PKCS10_Request create_cert_req(const X509_Cert_Options&,
- const Private_Key&);
-}
-\end{verbatim}
-
-This function acts quite similarly to \function{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
-\filename{pkcs10} example.
-
-\subsubsection{Certificate Options}
-
-What is this \type{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 \type{std::string} members, which contains
-various bits of information about the user: \arg{common\_name},
-\arg{serial\_number}, \arg{country}, \arg{organization}, \arg{org\_unit},
-\arg{locality}, \arg{state}, \arg{email}, \arg{dns\_name}, and \arg{uri}. As
-many of these as possible should be filled it (especially an email address),
-though the only required ones are \arg{common\_name} and \arg{country}.
-
-There is another value that is only useful when creating a PKCS \#10 request,
-which is called \arg{challenge}. This is a challenge password, which you can
-later use to request certificate revocation (\emph{if} the CA supports doing
-revocations in this manner).
-
-Then there is the validity period; these are set with \function{not\_before}
-and \function{not\_after}. Both of these functions also take a
-\type{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 \function{CA\_key}. This should only be used when needed.
-
-Other constraints can be set by calling the member functions
-\function{add\_constraints} and \function{add\_ex\_constraints}. The
-first takes a \type{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):
-\type{DIGITAL\_SIGNATURE}, \type{NON\_REPUDIATION},
-\type{KEY\_ENCIPHERMENT}, \type{DATA\_ENCIPHERMENT},
-\type{KEY\_AGREEMENT}, \type{KEY\_CERT\_SIGN}, \type{CRL\_SIGN},
-\type{ENCIPHER\_ONLY}, \type{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
-\function{add\_constraints}, in which case the appropriate values will
-be chosen for you.
-
-The second function, \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
-\function{add\_ex\_constraints} any number of times~--~each new OID will be
-added to the list to include in the certificate.
-
-\section{The Low-Level Interface}
-
-Botan has two different interfaces. The one documented in this section is meant
-more for implementing higher-level types (see the section on filters, earlier in
-this manual) than for use by applications. Using it safely requires a solid
-knowledge of encryption techniques and best practices, so unless you know, for
-example, what CBC mode and nonces are, and why PKCS \#1 padding is important,
-you should avoid this interface in favor of something working at a higher level
-(such as the CMS interface).
-
-\subsection{Basic Algorithm Abilities}
-
-There are a small handful of functions implemented by most of Botan's
-algorithm objects. Among these are:
-
-\noindent
-\type{std::string} \function{name}():
-
-Returns a human-readable string of the name of this algorithm. Examples of
-names returned are ``Blowfish'' and ``HMAC(MD5)''. You can turn names back into
-algorithm objects using the functions in \filename{lookup.h}.
-
-\noindent
-\type{void} \function{clear}():
-
-Clear out the algorithm's internal state. A block cipher object will
-``forget'' its key, a hash function will ``forget'' any data put into
-it, etc. The object will look and behave as it did when you initially
-allocated it.
-
-\noindent
-\function{clone}():
-
-This function is central to Botan's name-based interface. The \function{clone}
-has many different return types, such as \type{BlockCipher*} and
-\type{HashFunction*}, depending on what kind of object it is called on. Note
-that unlike Java's clone, this returns a new object in a ``pristine'' state;
-that is, operations done on the initial object before calling \function{clone}
-do not affect the initial state of the new clone.
-
-Cloned objects can (and should) be deallocated with the C++ \texttt{delete}
-operator.
-
-\subsection{Keys and IVs}
-
-Both symmetric keys and initialization values can be considered byte
-(or octet) strings. These are represented by the classes
-\type{SymmetricKey} and \type{InitializationVector}, which are
-subclasses of \type{OctetString}.
-
-Since often it's hard to distinguish between a key and IV, many things (such as
-key derivation mechanisms) return \type{OctetString} instead of
-\type{SymmetricKey} to allow its use as a key or an IV.
-
-\noindent
-\function{OctetString}(\type{u32bit} \arg{length}):
-
-This constructor creates a new random key of size \arg{length}.
-
-\noindent
-\function{OctetString}(\type{std::string} \arg{str}):
-
-The argument \arg{str} is assumed to be a hex string; it is converted to binary
-and stored. Whitespace is ignored.
-
-\noindent
-\function{OctetString}(\type{const byte} \arg{input}[], \type{u32bit}
-\arg{length}):
-
-This constructor copies its input.
-
-\subsection{Symmetrically Keyed Algorithms}
-
-Block ciphers, stream ciphers, and MACs are all keyed operations; to
-be useful, they have to be set to use a particular key, which is a
-randomly chosen string of bits of a specified length. The length
-required by any particular algorithm may vary, depending on both the
-algorithm specification and the implementation. You can query any
-botan object to find out what key length(s) it supports.
-
-To make this similarity in terms of keying explicit, all algorithms of
-those types are derived from the \type{SymmetricAlgorithm} base
-class. This type has three functions:
-
-\noindent
-\type{void} \function{set\_key}(\type{const byte} \arg{key}[], \type{u32bit}
-\arg{length}):
-
-Most algorithms only accept keys of certain lengths. If you attempt to call
-\function{set\_key} with a key length that is not supported, the exception
-\type{Invalid\_Key\_Length} will be thrown. There is also another version of
-\function{set\_key} that takes a \type{SymmetricKey} as an argument.
-
-\noindent
-\type{bool} \function{valid\_keylength}(\type{u32bit} \arg{length}) const:
-
-This function returns true if a key of the given length will be accepted by
-the cipher.
-
-There are also three constant data members of every
-\type{SymmetricAlgorithm} object, which specify what limits there are
-on keys which that object can accept:
-
-MAXIMUM\_KEYLENGTH: The maximum length of a key. Usually, this is at
-most 32 (256 bits), even if the algorithm supports more. In a few rare
-cases larger keys will be supported.
-
-MINIMUM\_KEYLENGTH: The minimum length of a key. This is at least 1.
-
-KEYLENGTH\_MULTIPLE: The length of the key must be a multiple of this value.
-
-In all cases, \function{set\_key} must be called on an object before any data
-processing (encryption, decryption, etc) is done by that object. If this is not
-done, the results are undefined -- that is to say, Botan reserves the right in
-this situation to do anything from printing a nasty, insulting message on the
-screen to dumping core.
-
-\subsection{Block Ciphers}
-
-Block ciphers implement the interface \type{BlockCipher}, found in
-\filename{base.h}, as well as the \type{SymmetricAlgorithm} interface.
-
-\noindent
-\type{void} \function{encrypt}(\type{const byte} \arg{in}[],
- \type{byte} \arg{out}[]) const
-
-\noindent
-\type{void} \function{encrypt}(\type{byte} \arg{block}[]) const
-
-These functions apply the block cipher transformation to \arg{in} and
-place the result in \arg{out}, or encrypts \arg{block} in place
-(\arg{in} may be the same as \arg{out}). Exactly one block will be
-encrypted; you can find out the block size of the cipher you are
-working with by calling the member function \function{block\_size}.
-\type{BlockCipher}s have similar functions \function{decrypt}, which
-perform the inverse operation.
-
-If you want to process multiple blocks in parallel, use
-\function{encrypt\_n} and \function{decrypt\_n}.
-
-\begin{verbatim}
-AES_128 cipher;
-SymmetricKey key(cipher.MAXIMUM_KEYLENGTH); // randomly created
-cipher.set_key(key);
-
-byte in[16] = { /* secrets */ };
-byte out[16];
-cipher.encrypt(in, out);
-\end{verbatim}
-
-\subsection{Stream Ciphers}
-
-Stream ciphers are somewhat different from block ciphers, in that encrypting
-data results in changing the internal state of the cipher. Also, you may
-encrypt any length of data in one go (in byte amounts).
-
-\noindent
-\type{void} \function{encrypt}(\type{const byte} \arg{in}[], \type{byte}
-\arg{out}[], \type{u32bit} \arg{length})
-
-\noindent
-\type{void} \function{encrypt}(\type{byte} \arg{data}[], \type{u32bit}
-\arg{length}):
-
-These functions encrypt the arbitrary length (well, less than 4 gigabyte long)
-string \arg{in} and place it into \arg{out}, or encrypts it in place in
-\arg{data}. The \function{decrypt} functions look just like
-\function{encrypt}.
-
-Stream ciphers implement the \type{SymmetricAlgorithm} interface.
-
-Some stream ciphers support random access to any point in their cipher
-stream. For such ciphers, calling \type{void} \function{seek}(\type{u32bit}
-\arg{byte}) will change the cipher's state so that it is as if the cipher had been
-keyed as normal, then encrypted \arg{byte} -- 1 bytes of data (so the next byte
-in the cipher stream is byte number \arg{byte}).
-
-\subsection{Hash Functions / Message Authentication Codes}
-
-Hash functions take their input without producing any output, only producing
-anything when all input has already taken place. MACs are very similar, but are
-additionally keyed. Both of these are derived from the base class
-\type{BufferedComputation}, which has the following functions.
-
-\noindent
-\type{size\_t} \function{output\_length}()
-
-Return the size of the output of this function.
-
-\type{void} \function{update}(\type{const byte} \arg{input}[], \type{u32bit}
-\arg{length})
-
-\noindent
-\type{void} \function{update}(\type{byte} \arg{input})
-
-\noindent
-\type{void} \function{update}(\type{const std::string \&} \arg{input})
-
-Updates the hash/mac calculation with \arg{input}.
-
-\noindent
-\type{void} \function{final}(\type{byte} \arg{out}[])
-
-\noindent
-\type{SecureVector<byte>} \function{final}():
-
-Complete the hash/MAC calculation and place the result into \arg{out}.
-For the argument taking an array, exactly \function{output\_length}()
-bytes will be written. After you call \function{final}, the hash
-function is reset to its initial state, so it may be reused
-immediately.
-
-The second method of using final is to call it with no arguments at
-all, as shown in the second prototype. It will return the hash/mac
-value in a memory buffer.
-
-There is also a pair of functions called \function{process}. They are
-a combination of a single \function{update}, and \function{final}.
-Both versions return the final value, rather than placing it an
-array. Calling \function{process} with a single byte value isn't
-available, mostly because it would rarely be useful.
-
-A MAC can be viewed (in most cases) as a keyed hash function, so
-classes that are derived from \type{MessageAuthenticationCode} have
-\function{update} and \function{final} classes just like a
-\type{HashFunction} (and like a \type{HashFunction}, after
-\function{final} is called, it can be used to make a new MAC right
-away; the key is kept around).
-
-A MAC has the \type{SymmetricAlgorithm} interface in addition to the
-\type{BufferedComputation} interface.
-
-\section{Random Number Generators}
-
-The random number generators provided in Botan are meant for creating
-keys, IVs, padding, nonces, and anything else that requires 'random'
-data. It is important to remember that the output of these classes
-will vary, even if they are supplied with ethe same seed (\ie, two
-\type{Randpool} objects with similar initial states will not produce
-the same output, because the value of high resolution timers is added
-to the state at various points).
-
-To ensure good quality output, a PRNG needs to be seeded with truly random data
-(such as that produced by a hardware RNG). Typically, you will use an
-\type{EntropySource} (see below). To add entropy to a PRNG, you can use
-\type{void} \function{add\_entropy}(\type{const byte} \arg{data}[],
-\type{u32bit} \arg{length}) or (better), use the \type{EntropySource}
-interface.
-
-Once a PRNG has been initialized, you can get a single byte of random data by
-calling \type{byte} \function{random()}, or get a large block by calling
-\type{void} \function{randomize}(\type{byte} \arg{data}[], \type{u32bit}
-\arg{length}), which will put random bytes into each member of the array from
-indexes 0 $\ldots$ \arg{length} -- 1.
-
-You can avoid all the problems inherent in seeding the PRNG by using the
-globally shared PRNG, described later in this section.
-
-\subsection{Randpool}
-
-\type{Randpool} is the primary PRNG within Botan. In recent versions all uses
-of it have been wrapped by an implementation of the X9.31 PRNG (see below). If
-for some reason you should have cause to create a PRNG instead of using the
-``global'' one owned by the library, it would be wise to consider the same on
-the grounds of general caution; while \type{Randpool} is designed with known
-attacks and PRNG weaknesses in mind, it is not an standard/official PRNG. The
-remainder of this section is a (fairly technical, though high-level) description
-of the algorithms used in this PRNG. Unless you have a specific interest in
-this subject, the rest of this section might prove somewhat uninteresting.
-
-\type{Randpool} has an internal state called pool, which is 512 bytes
-long. This is where entropy is mixed into and extracted from. There is also a
-small output buffer (called buffer), which holds the data which has already
-been generated but has just not been output yet.
-
-It is based around a MAC and a block cipher (which are currently HMAC(SHA-256)
-and AES-256). Where a specific size is mentioned, it should be taken as a
-multiple of the cipher's block size. For example, if a 256-bit block cipher
-were used instead of AES, all the sizes internally would double. Every time
-some new output is needed, we compute the MAC of a counter and a high
-resolution timer. The resulting MAC is XORed into the output buffer (wrapping
-as needed), and the output buffer is then encrypted with AES, producing 16
-bytes of output.
-
-After 8 blocks (or 128 bytes) have been produced, we mix the pool. To do this,
-we first rekey both the MAC and the cipher; the new MAC key is the MAC of the
-current pool under the old MAC key, while the new cipher key is the MAC of the
-current pool under the just-chosen MAC key. We then encrypt the entire pool in
-CBC mode, using the current (unused) output buffer as the IV. We then generate
-a new output buffer, using the mechanism described in the previous paragraph.
-
-To add randomness to the PRNG, we compute the MAC of the input and XOR the
-output into the start of the pool. Then we remix the pool and produce a new
-output buffer. The initial MAC operation should make it very hard for chosen
-inputs to harm the security of \type{Randpool}, and as HMAC should be able to
-hold roughly 256 bits of state, it is unlikely that we are wasting much input
-entropy (or, if we are, it doesn't matter, because we have a very abundant
-supply).
-
-\subsection{ANSI X9.31}
-
-\type{ANSI\_X931\_PRNG} is the standard issue X9.31 Appendix A.2.4 PRNG, though
-using AES-256 instead of 3DES as the block cipher. This PRNG implementation has
-been checked against official X9.31 test vectors.
-
-Internally, the PRNG holds a pointer to another PRNG (typically
-Randpool). This internal PRNG generates the key and seed used by the
-X9.31 algorithm, as well as the date/time vectors. Each time an X9.31
-PRNG object receives entropy, it passes it along to the PRNG it is
-holding, and then pulls out some random bits to generate a new key and
-seed. This PRNG considers itself seeded as soon as the internal PRNG
-is seeded.
-
-As of version 1.4.7, the X9.31 PRNG is by default used for all random number
-generation.
-
-\subsection{Entropy Sources}
-
-An \type{EntropySource} is an abstract representation of some method of gather
-``real'' entropy. This tends to be very system dependent. The \emph{only} way
-you should use an \type{EntropySource} is to pass it to a PRNG that will
-extract entropy from it -- never use the output directly for any kind of key or
-nonce generation!
-
-\type{EntropySource} has a pair of functions for getting entropy from
-some external source, called \function{fast\_poll} and
-\function{slow\_poll}. These pass a buffer of bytes to be written; the
-functions then return how many bytes of entropy were
-gathered. \type{EntropySource}s are usually used to seed the global
-PRNG using the functions found in the \namespace{Global\_RNG}
-namespace.
-
-Note for writers of \type{EntropySource}s: it isn't necessary to use any kind
-of cryptographic hash on your output. The data produced by an EntropySource is
-only used by an application after it has been hashed by the
-\type{RandomNumberGenerator} that asked for the entropy, thus any hashing
-you do will be wasteful of both CPU cycles and entropy.
-
-\section{User Interfaces}
-
-Botan has recently changed some infrastructure to better accommodate
-more complex user interfaces, in particular ones that are based on
-event loops. Primary among these was the fact that when doing
-something like loading a PKCS \#8 encoded private key, a passphrase
-might be needed, but then again it might not (a PKCS \#8 key doesn't
-have to be encrypted). Asking for a passphrase to decrypt an
-unencrypted key is rather pointless. Not only that, but the way to
-handle the user typing the wrong passphrase was complicated,
-undocumented, and inefficient.
-
-So now Botan has an object called \type{UI}, which provides a simple
-interface for the aspects of user interaction the library has to be
-concerned with. Currently, this means getting a passphrase from the
-user, and that's it (\type{UI} will probably be extended in the future
-to support other operations as they are needed). The base \type{UI}
-class is very stupid, because the library can't directly assume
-anything about the environment that it's running under (for example,
-if there will be someone sitting at the terminal, if the application
-is even \emph{attached} to a terminal, and so on). But since you can
-subclass \type{UI} to use whatever method happens to be appropriate
-for your application, this isn't a big deal.
-
-\begin{verbatim}
- std::string get_passphrase(const std::string& what,
- const std::string& source,
- UI_Result& result) const;
-\end{verbatim}
-
-The \arg{what} argument specifies what the passphrase is needed for (for
-example, PKCS \#8 key loading passes \arg{what} as ``PKCS \#8 private
-key''). This lets you provide the user with some indication of \emph{why} your
-application is asking for a passphrase; feel free to pass the string through
-\function{gettext(3)} or moral equivalent for i18n purposes. Similarly,
-\arg{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
-\arg{source} will be an empty string; be sure to account for this possibility
-when writing a \type{UI} subclass.
-
-The function returns the passphrase as the return value, and a status code in
-\arg{result} (either \type{OK} or \type{CANCEL\_ACTION}). If
-\type{CANCEL\_ACTION} is returned in \arg{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 \type{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).
-
-There is an example \type{UI} that uses GTK+ available on the web site. The
-\type{GTK\_UI} code is cleanly separated from the rest of the example, so if
-you happen to be using GTK+, you can copy (and/or adapt) that code for your
-application. If you write a \type{UI} object for another windowing system
-(Win32, Qt, wxWidgets, FOX, etc), and would like to make it available to users
-in general (ideally under a permissive license such as public domain or
-MIT/BSD), feel free to send in a copy.
-
-\section{Botan's Modules}
-
-Botan comes with a variety of modules that can be compiled into the system.
-These will not be available on all installations of the library, but you can
-check for their availability based on whether or not certain macros are
-defined.
-
-\subsection{Pipe I/O for Unix File Descriptors}
-
-This is a minor feature, but it comes in handy sometimes. In all
-installations of the library, Botan's \type{Pipe} object overloads the
-\keyword{<<} and \keyword{>>} operators for C++ iostream objects,
-which is usually more than sufficient for doing I/O.
-
-However, there are cases where the iostream hierarchy does not map well to
-local 'file types', so there is also the ability to do I/O directly with Unix
-file descriptors. This is most useful when you want to read from or write to
-something like a TCP or Unix-domain socket, or a pipe, since for simple file
-access it's usually easier to just use C++'s file streams.
-
-If \macro{BOTAN\_EXT\_PIPE\_UNIXFD\_IO} is defined, then you can use the
-overloaded I/O operators with Unix file descriptors. For an example of this,
-check out the \filename{hash\_fd} example, included in the Botan distribution.
-
-\subsection{Entropy Sources}
-
-All of these are used by the \function{Global\_RNG::seed} function if
-they are available. Since this function is called by the
-\type{LibraryInitializer} class when it is created, it is rare
-that you will need to deal with any of these classes directly. Even in
-the case of a long-running server that needs to renew its entropy
-poll, it is easier to call \function{Global\_RNG::seed} (see the
-section entitled ``The Global PRNG'' for more details).
-
-\noindent
-\type{EGD\_EntropySource}: Query an EGD socket. If the macro
-\macro{BOTAN\_EXT\_ENTROPY\_SRC\_EGD} is defined, it can be found in
-\filename{es\_egd.h}. The constructor takes a \type{std::vector<std::string>}
-that specifies the paths to look for an EGD socket.
-
-\noindent
-\type{Unix\_EntropySource}: This entropy source executes programs common on
-Unix systems (such as \filename{uptime}, \filename{vmstat}, and \filename{df})
-and adds it to a buffer. It's quite slow due to process overhead, and (roughly)
-1 bit of real entropy is in each byte that is output. It is declared in
-\filename{es\_unix.h}, if \macro{BOTAN\_EXT\_ENTROPY\_SRC\_UNIX} is
-defined. If you don't have \filename{/dev/urandom} \emph{or} EGD, this is
-probably the thing to use. For a long-running process on Unix, keep on object
-of this type around and run fast polls ever few minutes.
-
-\noindent
-\type{FTW\_EntropySource}: Walk through a filesystem (the root to start
-searching is passed as a string to the constructor), reading files. This tends
-to only be useful on things like \filename{/proc} that have a great deal of
-variability over time, and even then there is only a small amount of entropy
-gathered: about 1 bit of entropy for every 16 bits of output (and many hundreds
-of bits are read in order to get that 16 bits). It is declared in
-\filename{es\_ftw.h}, if \macro{BOTAN\_EXT\_ENTROPY\_SRC\_FTW} is defined. Only
-use this as a last resort. I don't really trust it, and neither should you.
-
-\noindent
-\type{Win32\_CAPI\_EntropySource}: This routines gathers entropy from
-a Win32 CAPI module. It takes an optional \type{std::string} that will
-specify what type of CAPI provider to use. The CAPI RNG is usually a
-default software-based PRNG, but there are a few providers that may
-use a hardware RNG. By default it will use the first provider listed
-in the option ``rng/ms\_capi\_prov\_type'' that is available on the
-machine (currently the providers ``RSA\_FULL'', ``INTEL\_SEC'',
-``FORTEZZA'', and ``RNG'' are recognized).
-
-\noindent
-\type{BeOS\_EntropySource}: Query system statistics using various BeOS-specific
-APIs.
-
-\noindent
-\type{Pthread\_EntropySource}: Attempt to gather entropy based on jitter
-between a number of threads competing for a single mutex. This entropy source
-is \emph{very} slow, and highly questionable in terms of security. However, it
-provides a worst-case fallback on systems that don't have Unix-like features,
-but do support POSIX threads. This module is currently unavailable due to
-problems on some systems.
-
-\subsection{Compressors}
-
-There are two compression algorithms supported by Botan, Zlib and Bzip2 (Gzip
-and Zip encoding will be supported in future releases). Only lossless
-compression algorithms are currently supported by Botan, because they tend to
-be the most useful for cryptography. However, it is very reasonable to consider
-supporting something like GSM speech encoding (which is lossy), for use in
-encrypted voice applications.
-
-You should always compress \emph{before} you encrypt, because encryption seeks
-to hide the redundancy that compression is supposed to try to find and remove.
-
-\subsubsection{Bzip2}
-
-To test for Bzip2, check to see if \macro{BOTAN\_EXT\_COMPRESSOR\_BZIP2} is
-defined. If so, you can include \filename{bzip2.h}, which will declare a pair
-of \type{Filter} objects: \type{Bzip2\_Compression} and
-\type{Bzip2\_Decompression}.
-
-You should be prepared to take an exception when using the decompressing
-filter, for if the input is not valid Bzip2 data, that is what you will
-receive. You can specify the desired level of compression to
-\type{Bzip2\_Compression}'s constructor as an integer between 1 and 9, 1
-meaning worst compression, and 9 meaning the best. The default is to use 9,
-since small values take the same amount of time, just use a little less memory.
-
-The Bzip2 module was contributed by Peter J. Jones.
-
-\subsubsection{Zlib}
-
-Zlib compression works much like Bzip2 compression. The only
-differences in this case are that the macro is
-\macro{BOTAN\_EXT\_COMPRESSOR\_ZLIB}, the header you need to include
-is called \filename{botan/zlib.h} (remember that you shouldn't just
-\verb|#include <zlib.h>|, or you'll get the regular zlib API, which is
-not what you want). The Botan classes for Zlib
-compression/decompression are called \type{Zlib\_Compression} and
-\type{Zlib\_Decompression}.
-
-Like Bzip2, a \type{Zlib\_Decompression} object will throw an exception if
-invalid (in the sense of not being in the Zlib format) data is passed into it.
-
-In the case of zlib's algorithm, a worse compression level will be faster than
-a very high compression ratio. For this reason, the Zlib compressor will
-default to using a compression level of 6. This tends to give a good trade off
-in terms of time spent to compression achieved. There are several factors you
-need to consider in order to decide if you should use a higher compression
-level:
-
-\begin{list}{$\cdot$}
- \item Better security: the less redundancy in the source text, the harder it
- is to attack your ciphertext. This is not too much of a concern,
- because with decent algorithms using sufficiently long keys, it doesn't
- really matter \emph{that} much (but it certainly can't hurt).
- \item
-
- \item Decreasing returns. Some simple experiments by the author showed
- minimal decreases in the size between level 6 and level 9 compression
- with large (1 to 3 megabyte) files. There was some difference, but it
- wasn't that much.
-
- \item CPU time. Level 9 zlib compression is often two to four times as slow
- as level 6 compression. This can make a substantial difference in the
- overall runtime of a program.
-\end{list}
-
-While the zlib compression library uses the same compression algorithm as the
-gzip and zip programs, the format is different. The zlib format is defined in
-RFC 1950.
-
-\subsubsection{Data Sources}
-
-A \type{DataSource} is a simple abstraction for a thing that stores bytes. This
-type is used heavily in the areas of the API related to ASN.1
-encoding/decoding. The following types are \type{DataSource}s: \type{Pipe},
-\type{SecureQueue}, and a couple of special purpose ones:
-\type{DataSource\_Memory} and \type{DataSource\_Stream}.
-
-You can create a \type{DataSource\_Memory} with an array of bytes and a length
-field. The object will make a copy of the data, so you don't have to worry
-about keeping that memory allocated. This is mostly for internal use, but if it
-comes in handy, feel free to use it.
-
-A \type{DataSource\_Stream} is probably more useful than the memory based
-one. Its constructors take either a \type{std::istream} or a
-\type{std::string}. If it's a stream, the data source will use the
-\type{istream} to satisfy read requests (this is particularly useful to use
-with \type{std::cin}). If the string version is used, it will attempt to open
-up a file with that name and read from it.
-
-\subsubsection{Data Sinks}
-
-A \type{DataSink} (in \filename{data\_snk.h}) is a \type{Filter} that
-takes arbitrary amounts of input, and produces no output. This means
-it's doing something with the data outside the realm of what
-\type{Filter}/\type{Pipe} can handle, for example, writing it to a
-file (which is what the \type{DataSink\_Stream} does). There is no
-need for \type{DataSink}s that write to a \type{std::string} or memory
-buffer, because \type{Pipe} can handle that by itself.
-
-Here's a quick example of using a \type{DataSink}, which encrypts
-\filename{in.txt} and sends the output to \filename{out.txt}. There is
-no explicit output operation; the writing of \filename{out.txt} is
-implicit.
-
-\begin{verbatim}
- DataSource_Stream in("in.txt");
- Pipe pipe(new CBC_Encryption("Blowfish", "PKCS7", key, iv),
- new DataSink_Stream("out.txt"));
- pipe.process_msg(in);
-\end{verbatim}
-
-A real advantage of this is that even if ``in.txt'' is large, only as
-much memory is needed for internal I/O buffers will be used.
-
-\section{Miscellaneous}
-
-This section has documentation for anything that just didn't fit into
-any of the major categories. Many of them (Timers, Allocators) will
-rarely be used in actual application code, but others, like the PBKDF
-algorithms, have a wide degree of applicability.
-
-\subsection{PBKDF Algorithms}
-
-There are various procedures (usually ad-hoc) for turning a
-passphrase into a (mostly) arbitrary length key for a symmetric
-cipher. A general interface for such algorithms is presented in
-\filename{pbkdf.h}. The main function is \function{derive\_key}, which
-takes a passphrase, a salt, an iteration count, and the desired length
-of the output key, and returns a key of that length, deterministically
-produced from the passphrase and salt. If an algorithm can't produce a
-key of that size, it will throw an exception (most notably, PKCS \#5's
-PBKDF1 can only produce strings between 1 and $n$ bytes, where $n$ is
-the output size of the underlying hash function).
-
-The purpose of the iteration count is to make the algorithm take
-longer to compute the final key (reducing the speed of brute-force
-attacks of various kinds). Most standards recommend an iteration count
-of at least 10000. Currently defined PBKDF algorithms are
-``PBKDF1(digest)'', ``PBKDF2(digest)'', and ``OpenPGP-S2K(digest)'';
-you can retrieve any of these using the \function{get\_pbkdf}, found in
-\filename{lookup.h}. As of this writing, ``PBKDF2(SHA-256)'' with
-10000 iterations and a 16 byte salt is recommend for new applications.
-
-\subsubsection{OpenPGP S2K}
-
-There are some oddities about OpenPGP's S2K algorithms that are
-documented here. For one thing, it uses the iteration count in a
-strange manner; instead of specifying how many times to iterate the
-hash, it tells how many \emph{bytes} should be hashed in total
-(including the salt). So the exact iteration count will depend on the
-size of the salt (which is fixed at 8 bytes by the OpenPGP standard,
-though the implementation will allow any salt size) and the size of
-the passphrase.
-
-To get what OpenPGP calls ``Simple S2K'', set iterations to 0, and do
-not specify a salt. To get ``Salted S2K'', again leave the iteration
-count at 0, but give an 8-byte salt. ``Salted and Iterated S2K''
-requires an 8-byte salt and some iteration count (this should be
-significantly larger than the size of the longest passphrase that
-might reasonably be used; somewhere from 1024 to 65536 would probably
-be about right). Using both a reasonably sized salt and a large
-iteration count is highly recommended to prevent password guessing
-attempts.
-
-\subsection{Password Hashing}
-
-Storing passwords for user authentication purposes in plaintext is the
-simplest but least secure method; when an attacker compromises the
-database in which the passwords are stored, they immediately gain
-access to all of them. Often passwords are reused among multiple
-services or machines, meaning once a password to a single service is
-known an attacker has a substantial head start on attacking other
-machines.
-
-The general approach is to store, instead of the password, the output
-of a one way function of the password. Upon receiving an
-authentication request, the authenticator can recompute the one way
-function and compare the value just computed with the one that was
-stored. If they match, then the authentication request succeeds. But
-when an attacker gains access to the database, they only have the
-output of the one way function, not the original password.
-
-Common hash functions such as SHA-256 are one way, but used alone they
-have problems for this purpose. What an attacker can do, upon gaining
-access to such a stored password database, is hash common dictionary
-words and other possible passwords, storing them in a list. Then he
-can search through his list; if a stored hash and an entry in his list
-match, then he has found the password. Even worse, this can happen
-\emph{offline}: an attacker can begin hashing common passwords days,
-months, or years before ever gaining access to the database. In
-addition, if two users choose the same password, the one way function
-output will be the same for both of them, which will be visible upon
-inspection of the database.
-
-There are two solutions to these problems: salting and
-iteration. Salting refers to including, along with the password, a
-randomly chosen value which perturbs the one way function. Salting can
-reduce the effectivness of offline dictionary generation (because for
-each potential password, an attacker would have to compute the one way
-function output for all possible salts - with a large enough salt,
-this can make the problem quite difficult). It also prevents the same
-password from producing the same output, as long as the salts do not
-collide. With a large salt (say 80 to 128 bits) this will be quite
-unlikely. Iteration refers to the general technique of forcing
-multiple one way function evaluations when computing the output, to
-slow down the operation. For instance if hashing a single password
-requires running SHA-256 100,000 times instead of just once, that will
-slow down user authentication by a factor of 100,000, but user
-authentication happens quite rarely, and usually there are more
-expensive operations that need to occur anyway (network and database
-I/O, etc). On the other hand, an attacker who is attempting to break a
-database full of stolen password hashes will be seriously
-inconvenienced by a factor of 100,000 slowdown; they will be able to
-only test at a rate of .0001\% of what they would without iterations
-(or, equivalently, will require 100,000 times as many zombie botnet
-hosts).
-
-There are many different ways of doing this password hashing
-operation, with common ones including Unix's crypt (which is based on
-DES) and OpenBSD's bcrypt (based on Blowfish). Other variants using
-MD5 or SHA-256 are also in use on various systems.
-
-Botan provides a technique called passhash9, in
-\filename{passhash9.h}, which is based on PBKDF2. Two functions are
-provided in this header, \function{generate\_passhash9} and
-\function{check\_passhash9}. The generate function takes the password
-to hash, a \type{RandomNumberGenerator}, and a work factor, which
-tells how many iterations to compute. The default work factor is 10
-(which means 100,000 iterations), but any non-zero value is accepted.
-The check function takes a password and a passhash9 output and checks
-if the password is the same as the one that was used to generate the
-passhash9 output, returning a boolean true (same) or false (not same).
-An example can be found in \filename{doc/examples/passhash.cpp}.
-
-Passhash9 currently uses HMAC(SHA-1) for the underlying PBKDF2
-psuedo-random function, but can be extended to use different
-algorithms in the future if necessary. For instance using a PRF based
-on Blowfish (a block cipher that requires 4 KiB of RAM for efficient
-execution) could be used to make hardware-based password cracking more
-expensive (this was one motivation for Blowfish's use in the bcrypt
-hashing scheme, in fact).
-
-\subsection{Checksums}
-
-Checksums are very similar to hash functions, and in fact share the same
-interface. But there are some significant differences, the major ones being
-that the output size is very small (usually in the range of 2 to 4 bytes), and
-is not cryptographically secure. But for their intended purpose (error
-checking), they perform very well. Some examples of checksums included in Botan
-are the Adler32 and CRC32 checksums.
-
-\subsection{Exceptions}
-
-Sooner or later, something is going to go wrong. Botan's behavior when
-something unusual occurs, like most C++ software, is to throw an exception.
-Exceptions in Botan are derived from the \type{Exception} class. You can see
-most of the major varieties of exceptions used in Botan by looking at
-\filename{exceptn.h}. The only function you really need to concern yourself
-with is \type{const char*} \function{what()}. This will return an error message
-relevant to the error that occurred. For example:
-
-\begin{verbatim}
-try {
- // various Botan operations
- }
-catch(Botan::Exception& e)
- {
- cout << "Botan exception caught: " << e.what() << endl;
- // error handling, or just abort
- }
-\end{verbatim}
-
-Botan's exceptions are derived from \type{std::exception}, so you don't need
-to explicitly check for Botan exceptions if you're already catching the ISO
-standard ones.
-
-\subsection{Threads and Mutexes}
-
-Botan includes a mutex system, which is used internally to lock some shared
-data structures that must be kept shared for efficiency reasons (mostly, these
-are in the allocation systems~--~handing out 1000 separate allocators hurts
-performance and makes caching memory blocks useless). This system is supported
-by the \texttt{mux\_pthr} module, implementing the \type{Mutex} interface for
-systems that have POSIX threads.
-
-If your application is using threads, you \emph{must} add the option
-``thread\_safe'' to the options string when you create the
-\type{LibraryInitializer} object. If you specify this option and no mutex type
-is available, an exception is thrown, since otherwise you would probably be
-facing a nasty crash.
-
-\subsection{Secure Memory}
-
-A major concern with mixing modern multiuser OSes and cryptographic
-code is that at any time the code (including secret keys) could be
-swapped to disk, where it can later be read by an attacker. Botan
-stores almost everything (and especially anything sensitive) in memory
-buffers that a) clear out their contents when their destructors are
-called, and b) have easy plugins for various memory locking functions,
-such as the \function{mlock}(2) call on many Unix systems.
-
-Two of the allocation method used (``malloc'' and ``mmap'') don't
-require any extra privileges on Unix, but locking memory does. At
-startup, each allocator type will attempt to allocate a few blocks
-(typically totaling 128k), so if you want, you can run your
-application \texttt{setuid} \texttt{root}, and then drop privileges
-immediately after creating your \type{LibraryInitializer}. If you end
-up using more than what's been allocated, some of your sensitive data
-might end up being swappable, but that beats running as \texttt{root}
-all the time.
-
-These classes should also be used within your own code for storing
-sensitive data. They are only meant for primitive data types (int,
-long, etc): if you want a container of higher level Botan objects, you
-can just use a \verb|std::vector|, since these objects know how to
-clear themselves when they are destroyed. You cannot, however, have a
-\verb|std::vector| (or any other container) of \type{Pipe}s or
-\type{Filter}s, because these types have pointers to other
-\type{Filter}s, and implementing copy constructors for these types
-would be both hard and quite expensive (vectors of pointers to such
-objects is fine, though).
-
-These types are not described in any great detail: for more information,
-consult the definitive sources~--~the header files \filename{secmem.h} and
-\filename{allocate.h}.
-
-\type{SecureBuffer} is a simple array type, whose size is specified at compile
-time. It will automatically convert to a pointer of the appropriate type, and
-has a number of useful functions, including \function{clear()}, and
-\type{u32bit} \function{size()}, which returns the length of the array. It is a
-template that takes as parameters a type, and a constant integer which is how
-long the array is (for example: \verb|SecureBuffer<byte, 8> key;|).
-
-\type{SecureVector} is a variable length array. Its size can be increased or
-decreased as need be, and it has a wide variety of functions useful for copying
-data into its buffer. Like \type{SecureBuffer}, it implements \function{clear}
-and \function{size}.
-
-\subsection{Allocators}
-
-The containers described above get their memory from allocators. As a
-user of the library, you can add new allocator methods at run time for
-containers, including the ones used internally by the library, to
-use. The interface to this is in \filename{allocate.h}. Code needing
-to allocate or deallocate memory calls \function{get\_allocator},
-which returns a pointer to an allocator object. This pointer should
-not be freed: the caller does not own the allocator (it is shared
-among multiple allocatore users, and uses a mutex to serialize access
-internally if necessary). It is possible to call
-\function{get\_allocator} with a specific name to request a particular
-type of allocator, otherwise, a default allocator type is returned.
-
-At start time, the only allocator known is a \type{Default\_Allocator}, which
-just allocates memory using \function{malloc}, and \function{memset}s it to 0
-when the memory is released. It is known by the name ``malloc''. If you ask for
-another type of allocator (``locking'' and ``mmap'' are currently used), and it
-is not available, some other allocator will be returned.
-
-You can add in a new allocator type using \function{add\_allocator\_type}. This
-function takes a string and a pointer to an allocator. The string gives this
-allocator type a name to which it can be referred when one is requesting it
-with \function{get\_allocator}. If an error occurs (such as the name being
-already registered), this function returns false. It will return true if the
-allocator was successfully registered. If you ask it to,
-\type{LibraryInitializer} will do this for you.
-
-Finally, you can set the default allocator type that will be returned using
-the policy setting ``default\_alloc'' to the name of any previously registered
-allocator.
-
-\subsection{BigInt}
-
-\type{BigInt} is Botan's implementation of a multiple-precision
-integer. Thanks to C++'s operator overloading features, using \type{BigInt} is
-often quite similar to using a native integer type. The number of functions
-related to \type{BigInt} is quite large. You can find most of them in
-\filename{bigint.h} and \filename{numthry.h}.
-
-Due to the sheer number of functions involved, only a few, which a regular user
-of the library might have to deal with, are mentioned here. Fully documenting
-the MPI library would take a significant while, so if you need to use it now,
-the best way to learn is to look at the headers.
-
-Probably the most important are the encoding/decoding functions, which
-transform the normal representation of a \type{BigInt} into some other form,
-such as a decimal string.
-
-\type{SecureVector<byte>} \function{BigInt::encode}(\type{BigInt},
-\type{Encoding})
-
-\noindent
-and
-
-\type{BigInt} \function{BigInt::decode}(\type{SecureVector<byte>},
-\type{Encoding})
-
-\type{Encoding} is an enum that has values \type{Binary}, \type{Octal},
-\type{Decimal}, and \type{Hexadecimal}. The parameter will default to
-\type{Binary}. These functions are static member functions, so they would be
-called like this:
-
-\begin{verbatim}
- BigInt n1; // some number
- SecureVector<byte> n1_encoded = BigInt::encode(n1);
- BigInt n2 = BigInt::decode(n1_encoded);
- // now n1 == n2
-\end{verbatim}
-
-There are also C++-style I/O operators defined for use with \type{BigInt}. The
-input operator understands negative numbers, hexadecimal numbers (marked with a
-leading ``0x''), and octal numbers (marked with a leading '0'). The '-' must
-come before the ``0x'' or '0' marker. The output operator will never adorn the
-output; for example, when printing a hexadecimal number, there will not be a
-leading ``0x'' (though a leading '-' will be printed if the number is
-negative). If you want such things, you'll have to do them yourself.
-
-\type{BigInt} has constructors that can create a \type{BigInt} from an unsigned
-integer or a string. You can also decode a \type{byte}[] / length pair into a
-BigInt. There are several other \type{BigInt} constructors, which I would
-seriously recommend you avoid, as they are only intended for use internally by
-the library, and may arbitrarily change, or be removed, in a future release.
-
-An random sampling of \type{BigInt} related functions:
-
-\type{u32bit} \function{BigInt::bytes}(): Return the size of this \type{BigInt}
-in bytes.
-
-\type{BigInt} \function{random\_prime(\type{u32bit} \arg{b})}: Return a prime
-number \arg{b} bits long.
-
-\type{BigInt} \function{gcd}(\type{BigInt} \arg{x}, \type{BigInt} \arg{y}):
-Returns the greatest common divisor of \arg{x} and \arg{y}. Uses the binary
-GCD algorithm.
-
-\type{bool} \function{is\_prime}(\type{BigInt} \arg{x}): Returns true if
-\arg{x} is a (possible) prime number. Uses the Miller-Rabin probabilistic
-primality test with fixed bases. For higher assurance, use
-\function{verify\_prime}, which uses more rounds and randomized 48-bit bases.
-
-\subsubsection{Efficiency Hints}
-
-If you can, always use expressions of the form \verb|a += b| over
-\verb|a = a + b|. The difference can be \emph{very} substantial,
-because the first form prevents at least one needless memory
-allocation, and possibly as many as three.
-
-If you're doing repeated modular exponentiations with the same modulus, create
-a \type{BarrettReducer} ahead of time. If the exponent or base is a constant,
-use the classes in \filename{mod\_exp.h}. This stuff is all handled for you by
-the normal high-level interfaces, of course.
-
-Never use the low-level MPI functions (those that begin with
-\texttt{bigint\_}). These are completely internal to the library, and
-may make arbitrarily strange and undocumented assumptions about their
-inputs, and don't check to see if they are true, on the assumption
-that only the library itself calls them, and that the library knows
-what the assumptions are. The interfaces for these functions can
-change completely without notice.
-
-\section{Algorithms}
-
-\subsection{Recommended Algorithms}
-
-This section is by no means the last word on selecting which
-algorithms to use. However, Botan includes a sometimes bewildering
-array of possible algorithms, and unless you're familiar with the
-latest developments in the field, it can be hard to know what is
-secure and what is not. The following attributes of the algorithms
-were evaluated when making this list: security, standardization,
-patent status, support by other implementations, and efficiency (in
-roughly that order).
-
-It is intended as a set of simple guidelines for developers, and
-nothing more. It's entirely possible that there are algorithms in
-Botan that will turn out to be more secure than the ones listed, but
-the algorithms listed here are (currently) thought to be safe.
-
-\begin{list}{$\cdot$}
- \item Block ciphers: AES or Serpent in CBC, CTR, or XTS mode
-
- \item Hash functions: SHA-256, SHA-512
-
- \item MACs: HMAC with any recommended hash function
-
- \item Public Key Encryption: RSA with ``EME1(SHA-256)''
-
- \item Public Key Signatures: RSA with EMSA4 and any recommended
- hash, or DSA or ECDSA with ``EMSA1(SHA-256)''
-
- \item Key Agreement: Diffie-Hellman or ECDH, with ``KDF2(SHA-256)''
-\end{list}
-
-\subsection{Algorithms Listing}
-
-Botan includes a very sizable number of cryptographic algorithms. In
-nearly all cases, you never need to know the header file or type name
-to use them. However, you do need to know what string (or strings) are
-used to identify that algorithm. These names conform to those set out
-by SCAN (Standard Cryptographic Algorithm Naming), which is a document
-that specifies how strings are mapped onto algorithm objects, which is
-useful for a wide variety of crypto APIs (SCAN is oriented towards
-Java, but Botan and several other non-Java libraries also make at
-least some use of it). For full details, read the SCAN document, which
-can be found at
-\url{http://www.users.zetnet.co.uk/hopwood/crypto/scan/}
-
-Many of these algorithms can take options (such as the number of
-rounds in a block cipher, the output size of a hash function,
-etc). These are shown in the following list; all of them default to
-reasonable values. There are algorithm-specific limits on most of
-them. When you see something like ``HASH'' or ``BLOCK'', that means
-you should insert the name of some algorithm of that type. There are
-no defaults for those options.
-
-A few very obscure algorithms are skipped; if you need one of them,
-you'll know it, and you can look in the appropriate header to see what
-that classes' \function{name} function returns (the names tend to
-match that in SCAN, if it's defined there).
-
-\begin{list}{$\cdot$}
- \item ROUNDS: The number of rounds in a block cipher.
- \item
- \item OUTSZ: The output size of a hash function or MAC
-\end{list}
-
-\vskip .05in
-\noindent
-\textbf{Block Ciphers:} ``AES'' (and ``AES-128'', ``AES-192'', and
-``AES-256''), ``Blowfish'', ``CAST-128'', ``CAST-256'', ``DES'',
-``DESX'', ``TripleDES'', ``GOST-28147-89'', ``IDEA'', ``KASUMI'',
-``MARS'', ``MISTY1(ROUNDS)'', ``Noekeon'', ``RC2'', ``RC5(ROUNDS)'',
-``RC6'', ``SAFER-SK(ROUNDS)'', ``SEED'', ``Serpent'', ``Skipjack'',
-``Square'', ``TEA'', ``Twofish'', ``XTEA''
-
-\noindent
-\textbf{Stream Ciphers:} ``ARC4'', ``MARK4'', ``Salsa20'', ``Turing'',
-``WiderWake4+1-BE''
-
-\noindent
-\textbf{Hash Functions:} ``HAS-160'', ``GOST-34.11'',
-``MD2'', ``MD4'', ``MD5'', ``RIPEMD-128'', ``RIPEMD-160'',
-``SHA-160'', ``SHA-256'', ``SHA-384'', ``SHA-512'', ``Skein-512'',
-``Tiger(OUTSZ)'', ``Whirlpool''
-
-\noindent
-\textbf{MACs:} ``HMAC(HASH)'', ``CMAC(BLOCK)'', ``X9.19-MAC''
-
-\section{Support and Further Information}
-
-\subsection{Patents}
-
-Some of the algorithms implemented by Botan may be covered by patents in some
-locations. Algorithms known to have patent claims on them in the United States
-and that are not available in a license-free/royalty-free manner include:
-IDEA, MISTY1, RC5, RC6, and Nyberg-Rueppel.
-
-You must not assume that, just because an algorithm is not listed here, it is
-not encumbered by patents. If you have any concerns about the patent status of
-any algorithm you are considering using in an application, please discuss it
-with your attorney.
-
-\subsection{Support}
-
-Questions or problems you have with Botan can be directed to the
-development mailing list. Joining this list is highly recommended if
-you're going to be using Botan, since often advance notice of upcoming
-changes is sent there. ``Philosophical'' bug reports, announcements of
-programs using Botan, and anything else having to do with Botan are
-also welcome.
-
-The lists can be found at
-\url{http://lists.randombit.net/mailman/listinfo/}.
-
-\subsection{Contact Information}
-
-A PGP key with a fingerprint of
-\verb|621D AF64 11E1 851C 4CF9 A2E1 6211 EBF1 EFBA DFBC| is used to sign all
-Botan releases. This key can be found in the file \filename{doc/pgpkeys.txt};
-PGP keys for the developers are also stored there.
-
-\vskip 5pt \noindent
-Web Site: \url{http://botan.randombit.net}
-
-\subsection{License}
-
-Copyright \copyright 2000-2010, Jack Lloyd
-
-Licensed under the same terms as the Botan source
-
-\end{document}
diff --git a/doc/bigint.txt b/doc/bigint.txt
new file mode 100644
index 000000000..1cdc685d3
--- /dev/null
+++ b/doc/bigint.txt
@@ -0,0 +1,64 @@
+BigInt
+========================================
+
+``BigInt`` is Botan's implementation of a multiple-precision
+integer. Thanks to C++'s operator overloading features, using ``BigInt`` is
+often quite similar to using a native integer type. The number of functions
+related to ``BigInt`` is quite large. You can find most of them in
+``botan/bigint.h`` and ``botan/numthry.h``.
+
+Probably the most important are the encoding/decoding functions, which
+transform the normal representation of a ``BigInt`` into some other
+form, such as a decimal string.
+
+.. cpp:function:: SecureVector<byte> BigInt::encode(const BigInt& n, Encoding enc = Binary)
+
+ This function encodes the BigInt n into a memory
+ vector. ``Encoding`` is an enum that has values ``Binary``,
+ ``Octal``, ``Decimal``, and ``Hexadecimal``.
+
+.. cpp:function:: BigInt BigInt::decode(const MemoryRegion<byte>& vec, Encoding enc)
+
+ Decode the integer from ``vec`` using the encoding specified.
+
+These functions are static member functions, so they would be called
+like this::
+
+ BigInt n1 = ...; // some number
+ SecureVector<byte> n1_encoded = BigInt::encode(n1);
+ BigInt n2 = BigInt::decode(n1_encoded);
+ assert(n1 == n2);
+
+There are also C++-style I/O operators defined for use with
+``BigInt``. The input operator understands negative numbers,
+hexadecimal numbers (marked with a leading "0x"), and octal numbers
+(marked with a leading '0'). The '-' must come before the "0x" or '0'
+marker. The output operator will never adorn the output; for example,
+when printing a hexadecimal number, there will not be a leading "0x"
+(though a leading '-' will be printed if the number is negative). If
+you want such things, you'll have to do them yourself.
+
+``BigInt`` has constructors that can create a ``BigInt`` from an
+unsigned integer or a string. You can also decode an array (a ``byte``
+pointer plus a length) into a ``BigInt`` using a constructor.
+
+Efficiency Hints
+----------------------------------------
+
+If you can, always use expressions of the form ``a += b`` over
+``a = a + b``. The difference can be *very* substantial,
+because the first form prevents at least one needless memory
+allocation, and possibly as many as three.
+
+If you're doing repeated modular exponentiations with the same modulus, create
+a ``BarrettReducer`` ahead of time. If the exponent or base is a constant,
+use the classes in ``mod_exp.h``. This stuff is all handled for you by
+the normal high-level interfaces, of course.
+
+Never use the low-level MPI functions (those that begin with
+``bigint_``). These are completely internal to the library, and
+may make arbitrarily strange and undocumented assumptions about their
+inputs, and don't check to see if they are true, on the assumption
+that only the library itself calls them, and that the library knows
+what the assumptions are. The interfaces for these functions can
+change completely without notice.
diff --git a/doc/building.tex b/doc/building.tex
deleted file mode 100644
index 7164f74eb..000000000
--- a/doc/building.tex
+++ /dev/null
@@ -1,444 +0,0 @@
-\documentclass{article}
-
-\setlength{\textwidth}{6.5in}
-\setlength{\textheight}{9in}
-
-\setlength{\headheight}{0in}
-\setlength{\topmargin}{0in}
-\setlength{\headsep}{0in}
-
-\setlength{\oddsidemargin}{0in}
-\setlength{\evensidemargin}{0in}
-
-\title{\textbf{Botan Build Guide}}
-\author{Jack Lloyd \\
- \texttt{[email protected]}}
-\date{2010-06-10}
-
-\newcommand{\filename}[1]{\texttt{#1}}
-\newcommand{\module}[1]{\texttt{#1}}
-
-\newcommand{\type}[1]{\texttt{#1}}
-\newcommand{\function}[1]{\textbf{#1}}
-\newcommand{\macro}[1]{\texttt{#1}}
-
-\begin{document}
-
-\maketitle
-
-\tableofcontents
-
-\parskip=5pt
-\pagebreak
-
-\section{Introduction}
-
-This document describes how to build Botan on Unix/POSIX and MS
-Windows systems. The POSIX oriented descriptions should apply to most
-common Unix systems (including MacOS X), along with POSIX-ish systems
-like BeOS, QNX, and Plan 9. Currently, systems other than Windows and
-POSIX (such as VMS, MacOS 9, OS/390, OS/400, ...) are not supported by
-the build system, primarily due to lack of access. Please contact the
-maintainer if you would like to build Botan on such a system.
-
-Botan's build is controlled by configure.py, which is a Python
-script. Python 2.5 or later is required. If you want to use the
-(incompatible) Python 3, you must first run the \texttt{2to3} script
-on it.
-
-\section{For the Impatient}
-
-\begin{verbatim}
-$ ./configure.py [--prefix=/some/directory]
-$ make
-$ make check
-$ make install
-\end{verbatim}
-
-Or using \verb|nmake|, if you're compiling on Windows with Visual
-C++. On platforms that do not understand the '\#!' convention for
-beginning script files, or that have Python installed in an unusual
-spot, you might need to prefix the \texttt{configure.py} command with
-\texttt{python} or \texttt{/path/to/python}.
-
-\section{Building the Library}
-
-The first step is to run \filename{configure.py}, which is a Python
-script that creates various directories, config files, and a Makefile
-for building everything. The script requires at least Python 2.5; any
-later version of Python 2.x should also work. Python 3.1 will also
-work but requires an extra step, see the section ``Using Python 3.1'',
-later in this document.
-
-The script will attempt to guess what kind of system you are trying
-to compile for (and will print messages telling you what it guessed).
-You can override this process by passing the options \verb|--cc|,
-\verb|--os|, and \verb|--cpu|.
-
-You can pass basically anything reasonable with \verb|--cpu|: the
-script knows about a large number of different architectures, their
-sub-models, and common aliases for them. You should only select the
-64-bit version of a CPU (such as ``sparc64'' or ``mips64'') if your
-operating system knows how to handle 64-bit object code -- a 32-bit
-kernel on a 64-bit CPU will generally not like 64-bit code.
-
-By default the script tries to figure out what will work on your
-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:
-
-\begin{verbatim}
- 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
-\end{verbatim}
-
-The ones that are 'loaded on request only' have to be explicitly asked
-for, because they rely on third party libraries which your system
-might not have. For instance to enable zlib support, add
-\verb|--with-zlib| to your invocation of \verb|configure.py|.
-
-You can control which algorithms and modules are built using the
-options \verb|--enable-modules=MODS| and
-\verb|--disable-modules=MODS|, for instance
-\verb|--enable-modules=zlib| and \verb|--disable-modules=rc5,idea|.
-Modules not listed on the command line will simply be loaded if needed
-or if configured to load by default. If you use \verb|--no-autoload|,
-only the most core modules will be included; you can then explicitly
-enable things that you want to use with enable-modules. This is useful
-for creating a minimal build targetted to a specific application.
-
-The script tries to guess what kind of makefile to generate, and it
-almost always guesses correctly (basically, Visual C++ uses NMAKE with
-Windows commands, and everything else uses Unix make with POSIX
-commands). Just in case, you can override it with
-\verb|--make-style=somestyle|. The styles Botan currently knows about
-are 'unix' (normal Unix makefiles), and 'nmake', the make variant
-commonly used by Windows compilers. To add a new variant (eg, a build
-script for VMS), you will need to create a new template file in
-\filename{src/build-data/makefile}.
-
-\subsection{POSIX / Unix}
-
-The basic build procedure on Unix and Unix-like systems is:
-
-\begin{verbatim}
- $ ./configure.py [--enable-modules=<list>] [--cc=CC]
- $ make
- # You may need to set your LD_LIBRARY_PATH or equivalent for ./check to run
- $ make check # optional, but a good idea
- $ make install
-\end{verbatim}
-
-On Unix systems the script will default to using GCC; use
-\texttt{--cc} if you want something else. For instance use
-\texttt{--cc=icc} for Intel C++ and \texttt{--cc=clang} for Clang.
-
-The \verb|make install| target has a default directory in which it
-will install Botan (typically \verb|/usr/local|). You can override
-this by using the \texttt{--prefix} argument to
-\filename{configure.py}, like so:
-
-\verb|./configure.py --prefix=/opt <other arguments>|
-
-On some systems shared libraries might not be immediately visible to
-the runtime linker. For example, on Linux you may have to edit
-\filename{/etc/ld.so.conf} and run \texttt{ldconfig} (as root) in
-order for new shared libraries to be picked up by the linker. An
-alternative is to set your \texttt{LD\_LIBRARY\_PATH} shell variable
-to include the directory that the Botan libraries were installed into.
-
-\subsection{Mac OS X}
-
-In general the Unix instructions above should apply, however OS X does
-not support \texttt{LD\_LIBRARY\_PATH}. Thomas Keller suggests instead
-running \verb|install_name_tool| between building and running the
-self-test program:
-
-\begin{verbatim}
- $ VERSION=1.9.10
- $ install_name_tool -change $(otool -X -D libbotan-$VERSION.dylib) \
- $PWD/libbotan-$VERSION.dylib check
-\end{verbatim}
-
-\subsection{MS Windows}
-
-If you don't want to deal with building botan on Windows, check the
-website; commonly prebuilt Windows binaries with installers are
-available, especially for stable versions.
-
-You need to have a copy of Python installed, and have both Python and
-your chosen compiler in your path. Open a command shell (or the SDK
-shell), and run:
-
-\begin{verbatim}
- > python configure.py --cc=msvc (or --cc=gcc for MinGW) [--cpu=CPU]
- > nmake
- > nmake check # optional, but recommended
- > nmake install
-\end{verbatim}
-
-For Win95 pre OSR2, the \verb|cryptoapi_rng| module will not work,
-because CryptoAPI didn't exist. And all versions of NT4 lack the
-ToolHelp32 interface, which is how \verb|win32_stats| does its slow
-polls, so a version of the library built with that module will not
-load under NT4. Later versions of Windows support both methods, so
-this shouldn't be much of an issue anymore.
-
-By default the install target will be 'C:\textbackslash botan'; you
-can modify this with the \texttt{--prefix} option.
-
-When building your applications, all you have to do is tell the
-compiler to look for both include files and library files in
-\verb|C:\botan|, and it will find both. Or you can move them to a
-place where they will be in the default compiler search paths (consult
-your documentation and/or local expert for details).
-
-\section{Trickier Things}
-
-\subsection{Modules Relying on Third Party Libraries}
-
-There are a fairly large number of modules included with Botan. Some
-of these are extremely useful, while others are only necessary in very
-unusual circumstances. Most are loaded (or not) automatically as
-necessary, but some require external libraries are thus must be
-enabled at build time; these include:
-
-\newcommand{\mod}[2]{\textbf{#1}: #2}
-
-\begin{list}{$\cdot$}
- \item \mod{bzip2}{Enables an application to perform bzip2
- compression and decompression using the library. Available on any
- system that has bzip2. To enable, use option \texttt{--with-bzip2}}
-
- \item \mod{zlib}{Enables an application to perform zlib compression
- and decompression using the library. Available on any system that
- has zlib. To enable, use option \texttt{--with-zlib}}
-
- \item \mod{gnump}{An engine that uses GNU MP to speed up PK
- operations. GNU MP 4.1 or later is required. To enable, use
- option \texttt{--with-gnump}}
-
- \item \mod{openssl}{An engine that uses OpenSSL to speed up public
- key operations and some ciphers/hashes. OpenSSL 0.9.7 or later is
- required. Note that, unlike GNU MP, OpenSSL's versions are not
- always faster than the versions built into botan. To enable, use
- option \texttt{--with-openssl}}
-
-\end{list}
-
-\subsection{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 \filename{configure.py} with
-whatever arguments you would ordinarily use, along with the option
-\texttt{--gen-amalgamation}. This will create two (rather large)
-files, \filename{botan\_all.h} and \filename{botan\_all.cpp}.
-
-Whenever you would have included a botan header, you can then include
-\filename{botan\_all.h}, and include \filename{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
-\filename{botan\_all.h} and use the headers from
-\filename{build/include} as normal.
-
-\subsection{Multiple Builds}
-
-It may be useful to run multiple builds with different
-configurations. Specify \verb|--build-dir=<dir>| to set up a build
-environment in a different directory.
-
-\subsection{Using Python 3.1}
-
-The versions of Python begininning with 3 are (intentionally)
-incompatible with the (currently more common) 2.x series. If you want
-to use Python 3.1 to set up the build, you'll have to use the
-\texttt{2to3} program (included in the Python distribution) on the
-script; this will convert the script to the Python 3.x dialect:
-
-\begin{verbatim}
- $ python ./configure.py
- File "configure.py", line 860
- except KeyError, e:
- ^
-SyntaxError: invalid syntax
- $ # incompatible python version, let's fix it
- $ 2to3 -w configure.py
-[...]
-RefactoringTool: Files that were modified:
-RefactoringTool: configure.py
- $ python ./configure.py
-[...]
-\end{verbatim}
-
-\subsection{Local Configuration}
-
-You may want to do something peculiar with the configuration; to
-support this there is a flag to \filename{configure.py} called
-\texttt{--with-local-config=<file>}. The contents of the file are
-inserted into \filename{build/build.h} which is (indirectly) included
-into every Botan header and source file.
-
-\subsection{Configuration Parameters}
-
-There are some configuration parameters which you may want to tweak
-before building the library. These can be found in
-\filename{config.h}. This file is overwritten every time the configure
-script is run (and does not exist until after you run the script for
-the first time).
-
-Also included in \filename{build/build.h} are macros which are defined
-if one or more extensions are available. All of them begin with
-\verb|BOTAN_HAS_|. For example, if \verb|BOTAN_HAS_COMPRESSOR_BZIP2|
-is defined, then an application using Botan can include
-\filename{<botan/bzip2.h>} and use the Bzip2 filters.
-
-\macro{BOTAN\_MP\_WORD\_BITS}: This macro controls the size of the
-words used for calculations with the MPI implementation in Botan. You
-can choose 8, 16, 32, or 64, with 32 being the default. You can use 8,
-16, or 32 bit words on any CPU, but the value should be set to the
-same size as the CPU's registers for best performance. You can only
-use 64-bit words if an assembly module (such as \module{mp\_ia32} or
-\module{mp\_asm64}) is used. If the appropriate module is available,
-64 bits are used, otherwise this is set to 32. Unless you are building
-for a 8 or 16-bit CPU, this isn't worth messing with.
-
-\macro{BOTAN\_VECTOR\_OVER\_ALLOCATE}: The memory container
-\type{SecureVector} will over-allocate requests by this amount (in
-elements). In several areas of the library, we grow a vector fairly often. By
-over-allocating by a small amount, we don't have to do allocations as often
-(which is good, because the allocators can be quite slow). If you \emph{really}
-want to reduce memory usage, set it to 0. Otherwise, the default should be
-perfectly fine.
-
-\macro{BOTAN\_DEFAULT\_BUFFER\_SIZE}: This constant is used as the size of
-buffers throughout Botan. A good rule of thumb would be to use the page size of
-your machine. The default should be fine for most, if not all, purposes.
-
-\section{Building Applications}
-
-\subsection{Unix}
-
-Botan usually links in several different system libraries (such as
-\texttt{librt} and \texttt{libz}), depending on which modules are
-configured at compile time. In many environments, particularly ones
-using static libraries, an application has to link against the same
-libraries as Botan for the linking step to succeed. But how does it
-figure out what libraries it \emph{is} linked against?
-
-The answer is to ask the \filename{botan-config} script. This
-basically solves the same problem all the other \filename{*-config}
-scripts solve, and in basically the same manner.
-
-There are 4 options:
-
-\texttt{--prefix[=DIR]}: If no argument, print the prefix where Botan
-is installed (such as \filename{/opt} or \filename{/usr/local}). If an
-argument is specified, other options given with the same command will
-execute as if Botan as actually installed at \filename{DIR} and not
-where it really is; or at least where \filename{botan-config} thinks
-it really is. I should mention that it
-
-\texttt{--version}: Print the Botan version number.
-
-\texttt{--cflags}: Print options that should be passed to the compiler
-whenever a C++ file is compiled. Typically this is used for setting
-include paths.
-
-\texttt{--libs}: Print options for which libraries to link to (this includes
-\texttt{-lbotan}).
-
-Your \filename{Makefile} can run \filename{botan-config} and get the
-options necessary for getting your application to compile and link,
-regardless of whatever crazy libraries Botan might be linked against.
-
-Botan also by default installs a file for \texttt{pkg-config},
-namespaced by the major and minor versions. So it can be used,
-for instance, as
-
-\begin{verbatim}
-$ pkg-config botan-1.9 --modversion
-1.9.8
-$ pkg-config botan-1.9 --cflags
--I/usr/local/include
-$ pkg-config botan-1.9 --libs
--L/usr/local/lib -lbotan -lm -lbz2 -lpthread -lrt
-\end{verbatim}
-
-\subsection{MS Windows}
-
-No special help exists for building applications on Windows. However,
-given that typically Windows software is distributed as binaries, this
-is less of a problem - only the developer needs to worry about it. As
-long as they can remember where they installed Botan, they just have
-to set the appropriate flags in their Makefile/project file.
-
-\section{Language Wrappers}
-
-\subsection{Building the Python wrappers}
-
-The Python wrappers for Botan use Boost.Python, so you must have Boost
-installed. To build the wrappers, add the flag
-
-\verb|--with-boost-python|
-
-to \verb|configure.py|. This will create a second makefile,
-\verb|Makefile.python|, with instructions for building the Python
-module. After building the library, execute
-
-\begin{verbatim}
-$ make -f Makefile.python
-\end{verbatim}
-
-to build the module. Currently only Unix systems are supported, and
-the Makefile assumes that the version of Python you want to build
-against is the same one you used to run \verb|configure.py|.
-
-To install the module, use the \verb|install| target.
-
-Examples of using the Python module can be seen in \filename{doc/python}
-
-\subsection{Building the Perl XS wrappers}
-
-To build the Perl XS wrappers, change your directory to
-\filename{src/wrap/perl-xs} and run \verb|perl Makefile.PL|, then run
-\verb|make| to build the module and \verb|make test| to run the test
-suite.
-
-\begin{verbatim}
-$ perl Makefile.PL
-Checking if your kit is complete...
-Looks good
-Writing Makefile for Botan
-$ make
-cp Botan.pm blib/lib/Botan.pm
-AutoSplitting blib/lib/Botan.pm (blib/lib/auto/Botan)
-/usr/bin/perl5.8.8 /usr/lib64/perl5/5.8.8/ExtUtils/xsubpp [...]
-g++ -c -Wno-write-strings -fexceptions -g [...]
-Running Mkbootstrap for Botan ()
-chmod 644 Botan.bs
-rm -f blib/arch/auto/Botan/Botan.so
-g++ -shared Botan.o -o blib/arch/auto/Botan/Botan.so \
- -lbotan -lbz2 -lpthread -lrt -lz \
-
-chmod 755 blib/arch/auto/Botan/Botan.so
-cp Botan.bs blib/arch/auto/Botan/Botan.bs
-chmod 644 blib/arch/auto/Botan/Botan.bs
-Manifying blib/man3/Botan.3pm
-$ make test
-PERL_DL_NONLAZY=1 /usr/bin/perl5.8.8 [...]
-t/base64......ok
-t/filt........ok
-t/hex.........ok
-t/oid.........ok
-t/pipe........ok
-t/x509cert....ok
-All tests successful.
-Files=6, Tests=83, 0 wallclock secs ( 0.08 cusr + 0.02 csys = 0.10 CPU)
-\end{verbatim}
-
-\end{document}
diff --git a/doc/building.txt b/doc/building.txt
new file mode 100644
index 000000000..2e52eee1c
--- /dev/null
+++ b/doc/building.txt
@@ -0,0 +1,403 @@
+
+Building Botan
+=================================
+
+This document describes how to build Botan on Unix/POSIX and MS
+Windows systems. The POSIX oriented descriptions should apply to most
+common Unix systems (including MacOS X), along with POSIX-ish systems
+like BeOS, QNX, and Plan 9. Currently, systems other than Windows and
+POSIX (such as VMS, MacOS 9, OS/390, OS/400, ...) are not supported by
+the build system, primarily due to lack of access. Please contact the
+maintainer if you would like to build Botan on such a system.
+
+Botan's build is controlled by configure.py, which is a `Python
+<http://www.python.org>`_ script. Python 2.5 or later is required.
+
+For the impatient, this works for most systems::
+
+ $ ./configure.py [--prefix=/some/directory]
+ $ make
+ $ make check
+ $ make install
+
+Or using ``nmake``, if you're compiling on Windows with Visual C++. On
+platforms that do not understand the '#!' convention for beginning
+script files, or that have Python installed in an unusual spot, you
+might need to prefix the ``configure.py`` command with ``python`` or
+``/path/to/python``::
+
+ $ python ./configure.py [arguments]
+
+Configuring the Build
+---------------------------------
+
+The first step is to run ``configure.py``, which is a Python script
+that creates various directories, config files, and a Makefile for
+building everything. The script requires at least Python 2.5; any
+later version of Python 2.x should also work. Python 3.1 will also
+work but requires an extra step; see :ref:`configure_with_python3` for
+details.
+
+The script will attempt to guess what kind of system you are trying to
+compile for (and will print messages telling you what it guessed).
+You can override this process by passing the options ``--cc``,
+``--os``, and ``--cpu``.
+
+You can pass basically anything reasonable with ``--cpu``: the script
+knows about a large number of different architectures, their
+sub-models, and common aliases for them. You should only select the
+64-bit version of a CPU (such as "sparc64" or "mips64") if your
+operating system knows how to handle 64-bit object code - a 32-bit
+kernel on a 64-bit CPU will generally not like 64-bit code.
+
+By default the script tries to figure out what will work on your
+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
+
+The ones that are 'loaded on request only' have to be explicitly asked
+for, because they rely on third party libraries which your system
+might not have. For instance to enable zlib support, add
+``--with-zlib`` to your invocation of ``configure.py``.
+
+You can control which algorithms and modules are built using the
+options ``--enable-modules=MODS`` and ``--disable-modules=MODS``, for
+instance ``--enable-modules=zlib`` and ``--disable-modules=rc5,idea``.
+Modules not listed on the command line will simply be loaded if needed
+or if configured to load by default. If you use ``--no-autoload``,
+only the most core modules will be included; you can then explicitly
+enable things that you want to use with ``--enable-modules``. This is
+useful for creating a minimal build targetted to a specific
+application, especially in conjuction with the amalgamation option;
+see :ref:`amalgamation`.
+
+The script tries to guess what kind of makefile to generate, and it
+almost always guesses correctly (basically, Visual C++ uses NMAKE with
+Windows commands, and everything else uses Unix make with POSIX
+commands). Just in case, you can override it with
+``--make-style=somestyle``. The styles Botan currently knows about are
+'unix' (normal Unix makefiles), and 'nmake', the make variant commonly
+used by Windows compilers. To add a new variant (eg, a build script
+for VMS), you will need to create a new template file in
+``src/build-data/makefile``.
+
+On Unix
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The basic build procedure on Unix and Unix-like systems is::
+
+ $ ./configure.py [--enable-modules=<list>] [--cc=CC]
+ $ make
+ # You may need to set your LD_LIBRARY_PATH or equivalent for ./check to run
+ $ make check # optional, but a good idea
+ $ make install
+
+On Unix systems the script will default to using GCC; use
+``--cc`` if you want something else. For instance use
+``--cc=icc`` for Intel C++ and ``--cc=clang`` for Clang.
+
+The ``make install`` target has a default directory in which it
+will install Botan (typically ``/usr/local``). You can override
+this by using the ``--prefix`` argument to
+``configure.py``, like so:
+
+``./configure.py --prefix=/opt <other arguments>``
+
+On some systems shared libraries might not be immediately visible to
+the runtime linker. For example, on Linux you may have to edit
+``/etc/ld.so.conf`` and run ``ldconfig`` (as root) in
+order for new shared libraries to be picked up by the linker. An
+alternative is to set your ``LD_LIBRARY_PATH`` shell variable
+to include the directory that the Botan libraries were installed into.
+
+On Mac OS X
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In general the Unix instructions above should apply, however OS X does
+not support ``LD_LIBRARY_PATH``. Thomas Keller suggests instead
+running ``install_name_tool`` between building and running the
+self-test program::
+
+ $ VERSION=1.10.0 # or whatever the current version is
+ $ install_name_tool -change $(otool -X -D libbotan-$VERSION.dylib) \
+ $PWD/libbotan-$VERSION.dylib check
+
+On MS Windows
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If you don't want to deal with building botan on Windows, check the
+website; commonly prebuilt Windows binaries with installers are
+available, especially for stable versions.
+
+You need to have a copy of Python installed, and have both Python and
+your chosen compiler in your path. Open a command shell (or the SDK
+shell), and run::
+
+ > python configure.py --cc=msvc (or --cc=gcc for MinGW) [--cpu=CPU]
+ > nmake
+ > nmake check # optional, but recommended
+ > nmake install
+
+For Win95 pre OSR2, the ``cryptoapi_rng`` module will not work,
+because CryptoAPI didn't exist. And all versions of NT4 lack the
+ToolHelp32 interface, which is how ``win32_stats`` does its slow
+polls, so a version of the library built with that module will not
+load under NT4. Later versions of Windows support both methods, so
+this shouldn't be much of an issue anymore.
+
+By default the install target will be ``C:\botan``; you can modify
+this with the ``--prefix`` option.
+
+When building your applications, all you have to do is tell the
+compiler to look for both include files and library files in
+``C:\botan``, and it will find both. Or you can move them to a
+place where they will be in the default compiler search paths (consult
+your documentation and/or local expert for details).
+
+Trickier Things
+----------------------------------------
+
+Modules Relying on Third Party Libraries
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+There are a fairly large number of modules included with Botan. Some
+of these are extremely useful, while others are only necessary in very
+unusual circumstances. Most are loaded (or not) automatically as
+necessary, but some require external libraries are thus must be
+enabled at build time; these include:
+
+ - ``--with-bzip2`` enables the filters providing bzip2 compression
+ and decompression. Requires the bzip2 development libraries to be
+ installed.
+
+ - ``--with-zlib`` enables the filters providing zlib compression
+ and decompression. Requires the zlib development libraries to be
+ installed.
+
+ - ``--with-gnump`` adds an alternative engine for public key cryptography
+ that uses the GNU MP library. GNU MP 4.1 or later is required.
+
+ - ``--with-openssl`` adds an engine that uses OpenSSL for some public
+ key operations and ciphers/hashes. OpenSSL 0.9.7 or later is
+ 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
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+It may be useful to run multiple builds with different
+configurations. Specify ``--build-dir=<dir>`` to set up a build
+environment in a different directory.
+
+
+.. _configure_with_python3:
+
+Configuring the Build With Python 3.1
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The versions of Python begininning with 3 are (intentionally)
+incompatible with the (currently more common) 2.x series. If you want
+to use Python 3.1 to set up the build, you'll have to use the
+``2to3`` program (included in the Python distribution) on the
+script; this will convert the script to the Python 3.x dialect::
+
+ $ python ./configure.py
+ File "configure.py", line 860
+ except KeyError, e:
+ ^
+ SyntaxError: invalid syntax
+ $ # incompatible python version, let's fix it
+ $ 2to3 -w configure.py
+ [...]
+ RefactoringTool: Files that were modified:
+ RefactoringTool: configure.py
+ $ python ./configure.py
+ [...]
+
+Local Configuration Settings
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You may want to do something peculiar with the configuration; to
+support this there is a flag to ``configure.py`` called
+``--with-local-config=<file>``. The contents of the file are
+inserted into ``build/build.h`` which is (indirectly) included
+into every Botan header and source file.
+
+Configuration Parameters
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+There are some configuration parameters which you may want to tweak
+before building the library. These can be found in ``config.h``. This
+file is overwritten every time the configure script is run (and does
+not exist until after you run the script for the first time).
+
+Also included in ``build/build.h`` are macros which let applications
+check which features are included in the current version of the
+library. All of them begin with ``BOTAN_HAS_``. For example, if
+``BOTAN_HAS_BLOWFISH`` is defined, then an application can include
+``<botan/blowfish.h>`` and use the Blowfish class.
+
+``BOTAN_MP_WORD_BITS``: This macro controls the size of the words used
+for calculations with the MPI implementation in Botan. You can choose
+8, 16, 32, or 64. Normally this defaults to either 32 or 64, depending
+on the processor. Unless you are building for a 8 or 16-bit CPU, this
+isn't worth messing with.
+
+``BOTAN_VECTOR_OVER_ALLOCATE``: The memory container ``SecureVector``
+will over-allocate requests by this amount (in elements). In several
+areas of the library, we grow a vector fairly often. By
+over-allocating by a small amount, we don't have to do allocations as
+often (which is good, because the allocators can be quite slow). If
+you *really* want to reduce memory usage, set it to 0. Otherwise, the
+default should be perfectly fine.
+
+``BOTAN_DEFAULT_BUFFER_SIZE``: This constant is used as the size of
+buffers throughout Botan. A good rule of thumb would be to use the
+page size of your machine. The default should be fine for most
+purposes.
+
+Building Applications
+----------------------------------------
+
+Unix
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Botan usually links in several different system libraries (such as
+``librt`` and ``libz``), depending on which modules are
+configured at compile time. In many environments, particularly ones
+using static libraries, an application has to link against the same
+libraries as Botan for the linking step to succeed. But how does it
+figure out what libraries it *is* linked against?
+
+The answer is to ask the ``botan-config`` script. This
+basically solves the same problem all the other ``*-config``
+scripts solve, and in basically the same manner.
+
+There are 4 options:
+
+``--prefix[=DIR]``: If no argument, print the prefix where Botan
+is installed (such as ``/opt`` or ``/usr/local``). If an
+argument is specified, other options given with the same command will
+execute as if Botan as actually installed at ``DIR`` and not
+where it really is; or at least where ``botan-config`` thinks
+it really is. I should mention that it
+
+``--version``: Print the Botan version number.
+
+``--cflags``: Print options that should be passed to the compiler
+whenever a C++ file is compiled. Typically this is used for setting
+include paths.
+
+``--libs``: Print options for which libraries to link to (this includes
+``-lbotan``).
+
+Your ``Makefile`` can run ``botan-config`` and get the
+options necessary for getting your application to compile and link,
+regardless of whatever crazy libraries Botan might be linked against.
+
+Botan also by default installs a file for ``pkg-config``,
+namespaced by the major and minor versions. So it can be used,
+for instance, as::
+
+ $ pkg-config botan-1.10 --modversion
+ 1.10.0
+ $ pkg-config botan-1.10 --cflags
+ -I/usr/local/include
+ $ pkg-config botan-1.10 --libs
+ -L/usr/local/lib -lbotan -lm -lbz2 -lpthread -lrt
+
+MS Windows
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+No special help exists for building applications on Windows. However,
+given that typically Windows software is distributed as binaries, this
+is less of a problem - only the developer needs to worry about it. As
+long as they can remember where they installed Botan, they just have
+to set the appropriate flags in their Makefile/project file.
+
+Language Wrappers
+----------------------------------------
+
+Building the Python wrappers
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The Python wrappers for Botan use Boost.Python, so you must have Boost
+installed. To build the wrappers, pass the flag
+``--with-boost-python`` to ``configure.py``. This will create a second
+makefile, ``Makefile.python``, with instructions for building the
+Python module. After building the library, execute::
+
+ $ make -f Makefile.python
+
+to build the module. Currently only Unix systems are supported, and
+the Makefile assumes that the version of Python you want to build
+against is the same one you used to run ``configure.py``.
+
+To install the module, use the ``install`` target.
+
+Examples of using the Python module can be seen in
+``doc/examples/python``
+
+Building the Perl XS wrappers
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To build the Perl XS wrappers, change your directory to
+``src/wrap/perl-xs`` and run ``perl Makefile.PL``, then run
+``make`` to build the module and ``make test`` to run the test
+suite::
+
+ $ perl Makefile.PL
+ Checking if your kit is complete...
+ Looks good
+ Writing Makefile for Botan
+ $ make
+ cp Botan.pm blib/lib/Botan.pm
+ AutoSplitting blib/lib/Botan.pm (blib/lib/auto/Botan)
+ /usr/bin/perl5.8.8 /usr/lib64/perl5/5.8.8/ExtUtils/xsubpp [...]
+ g++ -c -Wno-write-strings -fexceptions -g [...]
+ Running Mkbootstrap for Botan ()
+ chmod 644 Botan.bs
+ rm -f blib/arch/auto/Botan/Botan.so
+ g++ -shared Botan.o -o blib/arch/auto/Botan/Botan.so \
+ -lbotan -lbz2 -lpthread -lrt -lz \
+
+ chmod 755 blib/arch/auto/Botan/Botan.so
+ cp Botan.bs blib/arch/auto/Botan/Botan.bs
+ chmod 644 blib/arch/auto/Botan/Botan.bs
+ Manifying blib/man3/Botan.3pm
+ $ make test
+ PERL_DL_NONLAZY=1 /usr/bin/perl5.8.8 [...]
+ t/base64......ok
+ t/filt........ok
+ t/hex.........ok
+ t/oid.........ok
+ t/pipe........ok
+ t/x509cert....ok
+ All tests successful.
+ Files=6, Tests=83, 0 wallclock secs ( 0.08 cusr + 0.02 csys = 0.10 CPU)
diff --git a/doc/conf.py b/doc/conf.py
new file mode 100644
index 000000000..c3f8677fa
--- /dev/null
+++ b/doc/conf.py
@@ -0,0 +1,223 @@
+# -*- coding: utf-8 -*-
+#
+# botan documentation build configuration file, created by
+# sphinx-quickstart on Sun Apr 3 11:41:06 2011.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+sys.path.insert(0, os.pardir)
+
+import botan_version
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = []
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.txt'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'botan'
+copyright = u'2000-2011, Jack Lloyd'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '%d.%d' % (botan_version.major, botan_version.minor)
+# The full version, including alpha/beta/rc tags.
+release = '%d.%d.%d%s' % (botan_version.major,
+ botan_version.minor,
+ botan_version.patch,
+ botan_version.release_suffix)
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# 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'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# 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']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'botandoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+ ('index', 'botan.tex', u'botan Documentation',
+ u'Jack Lloyd', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# 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/credits.txt b/doc/credits.txt
index 636a99f99..076498756 100644
--- a/doc/credits.txt
+++ b/doc/credits.txt
@@ -1,78 +1,80 @@
-This is at least a partial credits-file of people that have
-contributed to the Botan project. It is sorted by name and formatted
-to allow easy grepping and beautification by scripts. The fields are:
-name (N), email (E), web-address (W), PGP key ID and fingerprint (P),
-description (D), and snail-mail address (S).
-
-Thanks,
- Jack Lloyd
-----------
-
-N: Charles Brockman
-W: http://www.securitygenetics.com/
-D: documentation editing
-S: Oregon, USA
-
-N: Martin Doering
-D: GF(p) arithmetic
-
-N: Olivier de Gaalon
-D: SQLite encryption codec (src/wrap/sqlite)
-
-N: Matthew Gregan
-D: Binary file I/O support, allocator fixes
-
-N: Hany Greiss
-D: Windows porting
-
-N: Manuel Hartl
-W: http://www.flexsecure.de/
-D: ECDSA, ECDH
-
-N: Yves Jerschow
-D: Optimizations for memory load/store and HMAC
-D: Support for IPv4 addresses in X.509 alternative names
-S: Germany
-
-N: Matt Johnston
-D: Allocator fixes and optimizations, decompressor fixes
-
-N: Peter J. Jones
-D: Bzip2 compression module
-S: Colorado, USA
-
-N: Justin Karneges
-D: Qt support modules (mutexes and types), X.509 API design
-
-N: Jack Lloyd
-W: http://www.randombit.net/
-P: 3F69 2E64 6D92 3BBE E7AE 9258 5C0F 96E8 4EC1 6D6B
-D: Original designer/author, maintainer 2001-current
-S: Vermont, USA
-
-N: Joel Low
-D: DLL symbol visibility and Windows DLL support in general
-
-N: Christoph Ludwig
-D: GP(p) arithmetic
-
-N: Vaclav Ovsik
-D: Perl XS module (src/wrap/perl-xs)
-
-N: Luca Piccarreta
-D: x86/amd64 assembler, BigInt optimizations, Win32 mutex module
-S: Italy
-
-N: Falko Strenzke
-W: http://www.flexsecure.de/
-D: GF(p) arithmetic, CVC, Shanks-Tonelli algorithm
-S: Darmstadt, Germany
+
+Credits
+========================================
+
+This is at least a partial credits-file of people that have contributed
+to botan. It is sorted by name and formatted to allow easy grepping
+and beautification by scripts. The fields are name (N), email (E),
+web-address (W), PGP key ID and fingerprint (P), description (D), and
+snail-mail address (S).
+
+::
+
+ N: Charles Brockman
+ W: http://www.securitygenetics.com/
+ D: documentation editing
+ S: Oregon, USA
+
+ N: Martin Doering
+ D: GF(p) arithmetic
+
+ N: Olivier de Gaalon
+ D: SQLite encryption codec (src/wrap/sqlite)
+
+ N: Matthew Gregan
+ D: Binary file I/O support, allocator fixes
+
+ N: Hany Greiss
+ D: Windows porting
+
+ N: Manuel Hartl
+ W: http://www.flexsecure.de/
+ D: ECDSA, ECDH
+
+ N: Yves Jerschow
+ D: Optimizations for memory load/store and HMAC
+ D: Support for IPv4 addresses in X.509 alternative names
+ S: Germany
+
+ N: Matt Johnston
+ D: Allocator fixes and optimizations, decompressor fixes
+
+ N: Peter J. Jones
+ D: Bzip2 compression module
+ S: Colorado, USA
+
+ N: Justin Karneges
+ D: Qt support modules (mutexes and types), X.509 API design
+
+ N: Jack Lloyd
+ W: http://www.randombit.net/
+ P: 3F69 2E64 6D92 3BBE E7AE 9258 5C0F 96E8 4EC1 6D6B
+ D: Original designer/author, maintainer 2001-current
+ S: Vermont, USA
+
+ N: Joel Low
+ D: DLL symbol visibility and Windows DLL support in general
+
+ N: Christoph Ludwig
+ D: GP(p) arithmetic
+
+ N: Vaclav Ovsik
+ D: Perl XS module (src/wrap/perl-xs)
+
+ N: Luca Piccarreta
+ D: x86/amd64 assembler, BigInt optimizations, Win32 mutex module
+ S: Italy
+
+ N: Falko Strenzke
+ W: http://www.flexsecure.de/
+ D: GF(p) arithmetic, CVC, Shanks-Tonelli algorithm
+ S: Darmstadt, Germany
diff --git a/doc/examples/GNUmakefile b/doc/examples/GNUmakefile
deleted file mode 100644
index 44fcfeea5..000000000
--- a/doc/examples/GNUmakefile
+++ /dev/null
@@ -1,21 +0,0 @@
-
-BOTAN_CONFIG = botan-config
-
-CXX = g++
-CFLAGS = -O2 -ansi -W -Wall -I../../build/include
-LIBS = -L../.. -lbotan
-
-SRCS=$(wildcard *.cpp)
-
-PROGS=$(patsubst %.cpp,%,$(SRCS))
-
-all: $(PROGS)
-
-clean:
- @rm -f $(PROGS)
-
-%: %.cpp
- $(CXX) $(CFLAGS) $? $(LIBS) -o $@
-
-eax_test: eax_test.cpp
- $(CXX) $(CFLAGS) $? $(LIBS) -lboost_regex -o $@
diff --git a/doc/examples/asn1.cpp b/doc/examples/asn1.cpp
deleted file mode 100644
index b0a6aa104..000000000
--- a/doc/examples/asn1.cpp
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-/*
- A simple ASN.1 parser, similiar to 'dumpasn1' or 'openssl asn1parse', though
- without some of the bells and whistles of those. Primarily used for testing
- the BER decoder. The output format is modeled loosely on 'asn1parse -i'
-
- The output is actually less precise than the other decoders named, because
- the underlying BER_Decoder hides quite a bit from userspace, such as the use
- of indefinite length encodings (and the EOC markers). At some point it will
- also hide the constructed string types from the user, but right now you'll
- seem them as-is.
-
- Written by Jack Lloyd, November 9-10, 2003
- - Nov 22: Updated to new BER_Object format (tag -> class_tag/type_tag)
- - Nov 25: Much improved BIT STRING output
- Can deal with non-constructed taggings
- Can produce UTF-8 output
-*/
-
-// Set this if your terminal understands UTF-8; otherwise output is in Latin-1
-#define UTF8_TERMINAL 1
-
-/*
- What level the outermost layer of stuff is at. Probably 0 or 1; asn1parse
- uses 0 as the outermost, while 1 makes more sense to me. 2+ doesn't make
- much sense at all.
-*/
-#define INITIAL_LEVEL 0
-
-#include <botan/botan.h>
-#include <botan/bigint.h>
-#include <botan/der_enc.h>
-#include <botan/ber_dec.h>
-#include <botan/asn1_obj.h>
-#include <botan/oids.h>
-#include <botan/pem.h>
-#include <botan/charset.h>
-using namespace Botan;
-
-#include <stdio.h>
-#include <ctype.h>
-
-void decode(BER_Decoder&, u32bit);
-void emit(const std::string&, u32bit, u32bit, const std::string& = "");
-std::string type_name(ASN1_Tag);
-
-int main(int argc, char* argv[])
- {
- if(argc != 2)
- {
- printf("Usage: %s <file>\n", argv[0]);
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- try {
- DataSource_Stream in(argv[1]);
-
- if(!PEM_Code::matches(in))
- {
- BER_Decoder decoder(in);
- decode(decoder, INITIAL_LEVEL);
- }
- else
- {
- std::string label; // ignored
- BER_Decoder decoder(PEM_Code::decode(in, label));
- decode(decoder, INITIAL_LEVEL);
- }
-
- }
- catch(std::exception& e)
- {
- printf("%s\n", e.what());
- return 1;
- }
- return 0;
- }
-
-void decode(BER_Decoder& decoder, u32bit level)
- {
- BER_Object obj = decoder.get_next_object();
-
- while(obj.type_tag != NO_OBJECT)
- {
- const ASN1_Tag type_tag = obj.type_tag;
- const ASN1_Tag class_tag = obj.class_tag;
- const u32bit length = obj.value.size();
-
- /* hack to insert the tag+length back in front of the stuff now
- that we've gotten the type info */
- DER_Encoder encoder;
- encoder.add_object(type_tag, class_tag, obj.value, obj.value.size());
- SecureVector<byte> bits = encoder.get_contents();
-
- BER_Decoder data(bits);
-
- if(class_tag & CONSTRUCTED)
- {
- BER_Decoder cons_info(obj.value);
- if(type_tag == SEQUENCE)
- {
- emit("SEQUENCE", level, length);
- decode(cons_info, level+1);
- }
- else if(type_tag == SET)
- {
- emit("SET", level, length);
- decode(cons_info, level+1);
- }
- else
- {
- std::string name;
-
- if((class_tag & APPLICATION) || (class_tag & CONTEXT_SPECIFIC) ||
- (class_tag & PRIVATE))
- {
- name = "cons [" + to_string(type_tag) + "]";
-
- if(class_tag & APPLICATION)
- name += " appl";
- if(class_tag & CONTEXT_SPECIFIC)
- name += " context";
- if(class_tag & PRIVATE)
- name += " private";
- }
- else
- name = type_name(type_tag) + " (cons)";
-
- emit(name, level, length);
- decode(cons_info, level+1);
- }
- }
- else if(class_tag == APPLICATION || class_tag == CONTEXT_SPECIFIC ||
- class_tag == PRIVATE)
- {
- bool not_text = false;
-
- for(u32bit j = 0; j != bits.size(); j++)
- if(!isgraph(bits[j]) && !isspace(bits[j]))
- not_text = true;
-
- Pipe pipe(((not_text) ? new Hex_Encoder : 0));
- pipe.process_msg(bits);
- emit("[" + to_string(type_tag) + "]", level, length,
- pipe.read_all_as_string());
- }
- else if(type_tag == OBJECT_ID)
- {
- OID oid;
- data.decode(oid);
-
- std::string out = OIDS::lookup(oid);
- if(out != oid.as_string())
- out += " [" + oid.as_string() + "]";
-
- emit(type_name(type_tag), level, length, out);
- }
- else if(type_tag == INTEGER)
- {
- BigInt number;
- data.decode(number);
-
- SecureVector<byte> rep;
-
- /* If it's small, it's probably a number, not a hash */
- if(number.bits() <= 16)
- rep = BigInt::encode(number, BigInt::Decimal);
- else
- rep = BigInt::encode(number, BigInt::Hexadecimal);
-
- std::string str;
- for(u32bit j = 0; j != rep.size(); j++)
- str += (char)rep[j];
-
- emit(type_name(type_tag), level, length, str);
- }
- else if(type_tag == BOOLEAN)
- {
- bool boolean;
- data.decode(boolean);
- emit(type_name(type_tag),
- level, length, (boolean ? "true" : "false"));
- }
- else if(type_tag == NULL_TAG)
- {
- emit(type_name(type_tag), level, length);
- }
- else if(type_tag == OCTET_STRING)
- {
- SecureVector<byte> bits;
- data.decode(bits, type_tag);
- bool not_text = false;
-
- for(u32bit j = 0; j != bits.size(); j++)
- if(!isgraph(bits[j]) && !isspace(bits[j]))
- not_text = true;
-
- Pipe pipe(((not_text) ? new Hex_Encoder : 0));
- pipe.process_msg(bits);
- emit(type_name(type_tag), level, length, pipe.read_all_as_string());
- }
- else if(type_tag == BIT_STRING)
- {
- SecureVector<byte> bits;
- data.decode(bits, type_tag);
-
- std::vector<bool> bit_set;
-
- for(u32bit j = 0; j != bits.size(); j++)
- for(u32bit k = 0; k != 8; k++)
- bit_set.push_back((bool)((bits[bits.size()-j-1] >> (7-k)) & 1));
-
- std::string bit_str;
- for(u32bit j = 0; j != bit_set.size(); j++)
- {
- bool the_bit = bit_set[bit_set.size()-j-1];
-
- if(!the_bit && bit_str.size() == 0)
- continue;
- bit_str += (the_bit ? "1" : "0");
- }
-
- emit(type_name(type_tag), level, length, bit_str);
- }
- else if(type_tag == PRINTABLE_STRING ||
- type_tag == NUMERIC_STRING ||
- type_tag == IA5_STRING ||
- type_tag == T61_STRING ||
- type_tag == VISIBLE_STRING ||
- type_tag == UTF8_STRING ||
- type_tag == BMP_STRING)
- {
- ASN1_String str;
- data.decode(str);
- if(UTF8_TERMINAL)
- emit(type_name(type_tag), level, length,
- Charset::transcode(str.iso_8859(),
- LATIN1_CHARSET, UTF8_CHARSET));
- else
- emit(type_name(type_tag), level, length, str.iso_8859());
- }
- else if(type_tag == UTC_TIME || type_tag == GENERALIZED_TIME)
- {
- X509_Time time;
- data.decode(time);
- emit(type_name(type_tag), level, length, time.readable_string());
- }
- else
- fprintf(stderr, "Unknown tag: class=%02X, type=%02X\n",
- class_tag, type_tag);
-
- obj = decoder.get_next_object();
- }
- }
-
-void emit(const std::string& type, u32bit level, u32bit length,
- const std::string& value)
- {
- const u32bit LIMIT = 128;
- const u32bit BIN_LIMIT = 64;
-
- int written = 0;
- written += printf(" d=%2d, l=%4d: ", level, length);
- for(u32bit j = INITIAL_LEVEL; j != level; j++)
- written += printf(" ");
- written += printf("%s ", type.c_str());
-
- bool should_skip = false;
- if(value.length() > LIMIT) should_skip = true;
- if((type == "OCTET STRING" || type == "BIT STRING") &&
- value.length() > BIN_LIMIT)
- should_skip = true;
-
- if(value != "" && !should_skip)
- {
- if(written % 2 == 0) printf(" ");
- while(written < 50) written += printf(" ");
- printf(":%s\n", value.c_str());
- }
- else
- printf("\n");
- }
-
-std::string type_name(ASN1_Tag type)
- {
- if(type == PRINTABLE_STRING) return "PRINTABLE STRING";
- if(type == NUMERIC_STRING) return "NUMERIC STRING";
- if(type == IA5_STRING) return "IA5 STRING";
- if(type == T61_STRING) return "T61 STRING";
- if(type == UTF8_STRING) return "UTF8 STRING";
- if(type == VISIBLE_STRING) return "VISIBLE STRING";
- if(type == BMP_STRING) return "BMP STRING";
-
- if(type == UTC_TIME) return "UTC TIME";
- if(type == GENERALIZED_TIME) return "GENERALIZED TIME";
-
- if(type == OCTET_STRING) return "OCTET STRING";
- if(type == BIT_STRING) return "BIT STRING";
-
- if(type == INTEGER) return "INTEGER";
- if(type == NULL_TAG) return "NULL";
- if(type == OBJECT_ID) return "OBJECT";
- if(type == BOOLEAN) return "BOOLEAN";
- return "(UNKNOWN)";
- }
diff --git a/doc/examples/base64.cpp b/doc/examples/base64.cpp
deleted file mode 100644
index dbe8d19e3..000000000
--- a/doc/examples/base64.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
-* Encode/decode base64 strings
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <fstream>
-#include <iostream>
-#include <string>
-#include <vector>
-#include <cstring>
-#include <cstdlib>
-#include <botan/botan.h>
-
-int main(int argc, char* argv[])
- {
- if(argc < 2)
- {
- std::cout << "Usage: " << argv[0] << " [-w] [-c n] [-e|-d] files...\n"
- " -e : Encode input to base64 strings (default) \n"
- " -d : Decode base64 input\n"
- " -w : Wrap lines\n"
- " -c n: Wrap lines at column n, default 78\n";
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- int column = 78;
- bool wrap = false;
- bool encoding = true;
- std::vector<std::string> files;
-
- for(int j = 1; argv[j] != 0; j++)
- {
- std::string this_arg = argv[j];
-
- if(this_arg == "-w")
- wrap = true;
- else if(this_arg == "-e");
- else if(this_arg == "-d")
- encoding = false;
- else if(this_arg == "-c")
- {
- if(argv[j+1])
- { column = atoi(argv[j+1]); j++; }
- else
- {
- std::cout << "No argument for -c option" << std::endl;
- return 1;
- }
- }
- else files.push_back(argv[j]);
- }
-
- for(unsigned int j = 0; j != files.size(); j++)
- {
- std::istream* stream;
- if(files[j] == "-") stream = &std::cin;
- else stream = new std::ifstream(files[j].c_str());
-
- if(!*stream)
- {
- std::cout << "ERROR, couldn't open " << files[j] << std::endl;
- continue;
- }
-
- Botan::Pipe pipe((encoding) ?
- ((Botan::Filter*)new Botan::Base64_Encoder(wrap, column)) :
- ((Botan::Filter*)new Botan::Base64_Decoder));
- pipe.start_msg();
- *stream >> pipe;
- pipe.end_msg();
- pipe.set_default_msg(j);
- std::cout << pipe;
- if(files[j] != "-") delete stream;
- }
- return 0;
- }
diff --git a/doc/examples/bcrypt.cpp b/doc/examples/bcrypt.cpp
deleted file mode 100644
index 27a98cf33..000000000
--- a/doc/examples/bcrypt.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-* Bcrypt example
-* (C) 2011 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/botan.h>
-#include <botan/bcrypt.h>
-#include <iostream>
-
-using namespace Botan;
-
-int main(int argc, char* argv[])
- {
- if(argc != 2 && argc != 3)
- {
- std::cout << "Usage: " << argv[0] << " password\n"
- << " " << argv[0] << " password passhash\n";
- return 1;
- }
-
- LibraryInitializer init;
-
- if(argc == 2)
- {
- AutoSeeded_RNG rng;
-
- std::cout << generate_bcrypt(argv[1], rng, 12) << "\n";
- }
- else if(argc == 3)
- {
- if(strlen(argv[2]) != 60)
- {
- std::cout << "Note: hash " << argv[2]
- << " has wrong length and cannot be valid\n";
- }
-
- const bool ok = check_bcrypt(argv[1], argv[2]);
-
- std::cout << "Password is " << (ok ? "valid" : "NOT valid") << "\n";
- }
-
- return 0;
- }
diff --git a/doc/examples/bench.cpp b/doc/examples/bench.cpp
deleted file mode 100644
index 20e6ec40b..000000000
--- a/doc/examples/bench.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/benchmark.h>
-#include <botan/init.h>
-#include <botan/auto_rng.h>
-#include <botan/libstate.h>
-
-using namespace Botan;
-
-#include <iostream>
-
-namespace {
-
-const std::string algos[] = {
- "AES-128",
- "AES-192",
- "AES-256",
- "Blowfish",
- "CAST-128",
- "CAST-256",
- "DES",
- "DESX",
- "TripleDES",
- "GOST",
- "IDEA",
- "KASUMI",
- "Lion(SHA-256,Turing,8192)",
- "Luby-Rackoff(SHA-512)",
- "MARS",
- "MISTY1",
- "Noekeon",
- "RC2",
- "RC5(12)",
- "RC5(16)",
- "RC6",
- "SAFER-SK(10)",
- "SEED",
- "Serpent",
- "Skipjack",
- "Square",
- "TEA",
- "Twofish",
- "XTEA",
- "Adler32",
- "CRC32",
- "GOST-34.11",
- "HAS-160",
- "MD2",
- "MD4",
- "MD5",
- "RIPEMD-128",
- "RIPEMD-160",
- "SHA-160",
- "SHA-256",
- "SHA-384",
- "SHA-512",
- "Skein-512",
- "Tiger",
- "Whirlpool",
- "CMAC(AES-128)",
- "HMAC(SHA-1)",
- "X9.19-MAC",
- "",
-};
-
-void benchmark_algo(const std::string& algo,
- RandomNumberGenerator& rng)
- {
- u32bit milliseconds = 3000;
- Algorithm_Factory& af = global_state().algorithm_factory();
-
- std::map<std::string, double> speeds =
- algorithm_benchmark(algo, af, rng, milliseconds, 16*1024);
-
- std::cout << algo << ":";
-
- for(std::map<std::string, double>::const_iterator i = speeds.begin();
- i != speeds.end(); ++i)
- {
- std::cout << " " << i->second << " [" << i->first << "]";
- }
- std::cout << "\n";
- }
-
-}
-
-int main(int argc, char* argv[])
- {
- LibraryInitializer init;
-
- AutoSeeded_RNG rng;
-
- if(argc == 1) // no args, benchmark everything
- {
- for(u32bit i = 0; algos[i] != ""; ++i)
- benchmark_algo(algos[i], rng);
- }
- else
- {
- for(int i = 1; argv[i]; ++i)
- benchmark_algo(argv[i], rng);
- }
- }
diff --git a/doc/examples/benchmark.cpp b/doc/examples/benchmark.cpp
deleted file mode 100644
index 7ad1775e2..000000000
--- a/doc/examples/benchmark.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/botan.h>
-#include <botan/benchmark.h>
-
-#include <iostream>
-#include <string>
-#include <map>
-#include <cstdlib>
-
-int main(int argc, char* argv[])
- {
- if(argc <= 2)
- {
- std::cout << "Usage: " << argv[0] << " seconds <algo1> <algo2> ...\n";
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- Botan::AutoSeeded_RNG rng;
-
- Botan::Algorithm_Factory& af = Botan::global_state().algorithm_factory();
-
- double ms = 1000 * std::atof(argv[1]);
-
- for(size_t i = 2; argv[i]; ++i)
- {
- std::string algo = argv[i];
-
- std::map<std::string, double> results =
- algorithm_benchmark(algo, af, rng, ms, 16*1024);
-
- std::cout << algo << ":\n";
- for(std::map<std::string, double>::iterator r = results.begin();
- r != results.end(); ++r)
- {
- std::cout << " " << r->first << ": " << r->second << " MiB/s\n";
- }
- std::cout << "\n";
- }
- }
diff --git a/doc/examples/bzip.cpp b/doc/examples/bzip.cpp
deleted file mode 100644
index 6137bb6af..000000000
--- a/doc/examples/bzip.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
-* Bzip2 Compression/Decompression
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <string>
-#include <cstring>
-#include <vector>
-#include <fstream>
-#include <iostream>
-#include <botan/botan.h>
-
-/*
-* If Bzip2 isn't included, we know nothing works at compile time, but
-* we wait to fail at runtime. Otherwise I would get 2-3 mails a month
-* about how this was failing to compile (even with an informative
-* #error message explaining the situation) because bzip2 wasn't
-* included in the build.
-*/
-
-#if defined(BOTAN_HAS_COMPRESSOR_BZIP2)
- #include <botan/bzip2.h>
-#endif
-
-const std::string SUFFIX = ".bz2";
-
-int main(int argc, char* argv[])
- {
- if(argc < 2)
- {
- std::cout << "Usage: " << argv[0]
- << " [-s] [-d] [-1...9] <filenames>" << std::endl;
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- std::vector<std::string> files;
- bool decompress = false, small = false;
- int level = 9;
-
- for(int j = 1; argv[j] != 0; j++)
- {
- if(std::strcmp(argv[j], "-d") == 0) { decompress = true; continue; }
- if(std::strcmp(argv[j], "-s") == 0) { small = true; continue; }
- if(std::strcmp(argv[j], "-1") == 0) { level = 1; continue; }
- if(std::strcmp(argv[j], "-2") == 0) { level = 2; continue; }
- if(std::strcmp(argv[j], "-3") == 0) { level = 3; continue; }
- if(std::strcmp(argv[j], "-4") == 0) { level = 4; continue; }
- if(std::strcmp(argv[j], "-5") == 0) { level = 5; continue; }
- if(std::strcmp(argv[j], "-6") == 0) { level = 6; continue; }
- if(std::strcmp(argv[j], "-7") == 0) { level = 7; continue; }
- if(std::strcmp(argv[j], "-8") == 0) { level = 8; continue; }
- if(std::strcmp(argv[j], "-9") == 0) { level = 9; continue; }
- files.push_back(argv[j]);
- }
-
- try {
-
- Botan::Filter* bzip = 0;
-#ifdef BOTAN_HAS_COMPRESSOR_BZIP2
- if(decompress)
- bzip = new Botan::Bzip_Decompression(small);
- else
- bzip = new Botan::Bzip_Compression(level);
-#endif
-
- if(!bzip)
- {
- std::cout << "Sorry, support for bzip2 not compiled into Botan\n";
- return 1;
- }
-
- Botan::Pipe pipe(bzip);
-
- for(unsigned int j = 0; j != files.size(); j++)
- {
- std::string infile = files[j], outfile = files[j];
- if(!decompress)
- outfile = outfile += SUFFIX;
- else
- outfile = outfile.replace(outfile.find(SUFFIX),
- SUFFIX.length(), "");
-
- std::ifstream in(infile.c_str(), std::ios::binary);
- std::ofstream out(outfile.c_str(), std::ios::binary);
- if(!in)
- {
- std::cout << "ERROR: could not read " << infile << std::endl;
- continue;
- }
- if(!out)
- {
- std::cout << "ERROR: could not write " << outfile << std::endl;
- continue;
- }
-
- pipe.start_msg();
- in >> pipe;
- pipe.end_msg();
- pipe.set_default_msg(j);
- out << pipe;
-
- in.close();
- out.close();
- }
- }
- catch(std::exception& e)
- {
- std::cout << "Exception caught: " << e.what() << std::endl;
- return 1;
- }
- return 0;
- }
diff --git a/doc/examples/ca.cpp b/doc/examples/ca.cpp
deleted file mode 100644
index 8dd3e981f..000000000
--- a/doc/examples/ca.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-/*
- 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 out the new certificate.
-
- File names are hardcoded for simplicity.
- cacert.pem: The CA's certificate (perhaps created by self_sig)
- caprivate.pem: The CA's private key
- req.pem: The user's PKCS #10 certificate request
-*/
-
-#include <botan/botan.h>
-#include <botan/x509_ca.h>
-#include <botan/time.h>
-using namespace Botan;
-
-#include <iostream>
-#include <memory>
-
-int main(int argc, char* argv[])
- {
- if(argc != 5)
- {
- std::cout << "Usage: " << argv[0] << " <passphrase> "
- << "<ca cert> <ca key> <pkcs10>" << std::endl;
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- try
- {
- const std::string arg_passphrase = argv[1];
- const std::string arg_ca_cert = argv[2];
- const std::string arg_ca_key = argv[3];
- const std::string arg_req_file = argv[4];
-
- AutoSeeded_RNG rng;
-
- X509_Certificate ca_cert(arg_ca_cert);
-
- std::auto_ptr<PKCS8_PrivateKey> privkey(
- PKCS8::load_key(arg_ca_key, rng, arg_passphrase)
- );
-
- X509_CA ca(ca_cert, *privkey, "SHA-256");
-
- // got a request
- PKCS10_Request req(arg_req_file);
-
- // you would insert checks here, and perhaps modify the request
- // (this example should be extended to show how)
-
- // now sign the request
- X509_Time start_time(system_time());
- X509_Time end_time(system_time() + 365 * 60 * 60 * 24);
-
- X509_Certificate new_cert = ca.sign_request(req, rng,
- start_time, end_time);
-
- // send the new cert back to the requestor
- std::cout << new_cert.PEM_encode();
- }
- catch(std::exception& e)
- {
- std::cout << e.what() << std::endl;
- return 1;
- }
- return 0;
- }
diff --git a/doc/examples/cert_verify.cpp b/doc/examples/cert_verify.cpp
deleted file mode 100644
index 04bcbecad..000000000
--- a/doc/examples/cert_verify.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-* Simple example of a certificate validation
-* (C) 2010 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/botan.h>
-#include <botan/x509cert.h>
-#include <botan/x509stor.h>
-
-#include <stdio.h>
-
-using namespace Botan;
-
-int main()
- {
- LibraryInitializer init;
-
- X509_Certificate ca_cert("ca_cert.pem");
- X509_Certificate subject_cert("http_cert.pem");
-
- X509_Store cert_store;
-
- cert_store.add_cert(ca_cert, /*trusted=*/true);
-
- X509_Code code = cert_store.validate_cert(subject_cert);
-
- if(code == VERIFIED)
- printf("Cert validated\n");
- else
- printf("Cert did not validate, code = %d\n", code);
-
- return 0;
- }
diff --git a/doc/examples/checksum.cpp b/doc/examples/checksum.cpp
deleted file mode 100644
index dba7a7d70..000000000
--- a/doc/examples/checksum.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/botan.h>
-#include <botan/filters.h>
-
-#include <iostream>
-
-using namespace Botan;
-
-int main(int argc, char* argv[])
- {
- if(argc != 2)
- {
- std::cout << "Usage: " << argv[0] << " filename\n";
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- Pipe pipe(new Fork(
- new Chain(new Hash_Filter("CRC24"), new Hex_Encoder),
- new Chain(new Hash_Filter("CRC32"), new Hex_Encoder),
- new Chain(new Hash_Filter("Adler32"), new Hex_Encoder)
- ));
-
- DataSource_Stream in(argv[1]);
-
- pipe.process_msg(in);
-
- std::cout << pipe.read_all_as_string(0) << "\n";
- std::cout << pipe.read_all_as_string(1) << "\n";
- std::cout << pipe.read_all_as_string(2) << "\n";
- }
diff --git a/doc/examples/cms_dec.cpp b/doc/examples/cms_dec.cpp
deleted file mode 100644
index 84355fb4a..000000000
--- a/doc/examples/cms_dec.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/botan.h>
-#include <botan/pkcs8.h>
-#include <botan/cms_dec.h>
-using namespace Botan;
-
-#include <iostream>
-#include <memory>
-
-int main(int argc, char* argv[])
- {
- if(argc != 2)
- {
- std::cout << "Usage: " << argv[0] << " <filename>\n";
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- try {
- AutoSeeded_RNG rng;
-
- X509_Certificate mycert("mycert.pem");
- PKCS8_PrivateKey* mykey = PKCS8::load_key("mykey.pem", rng, "cut");
-
- X509_Certificate yourcert("yourcert.pem");
- X509_Certificate cacert("cacert.pem");
- X509_Certificate int_ca("int_ca.pem");
-
- X509_Store store;
- store.add_cert(mycert);
- store.add_cert(yourcert);
- store.add_cert(cacert, true);
- store.add_cert(int_ca);
-
- DataSource_Stream message(argv[1]);
-
- CMS_Decoder decoder(message, store, mykey);
-
- while(decoder.layer_type() != CMS_Decoder::DATA)
- {
- CMS_Decoder::Status status = decoder.layer_status();
- CMS_Decoder::Content_Type content = decoder.layer_type();
-
- if(status == CMS_Decoder::FAILURE)
- {
- std::cout << "Failure reading CMS data" << std::endl;
- break;
- }
-
- if(content == CMS_Decoder::DIGESTED)
- {
- std::cout << "Digested data, hash = " << decoder.layer_info()
- << std::endl;
- std::cout << "Hash is "
- << ((status == CMS_Decoder::GOOD) ? "good" : "bad")
- << std::endl;
- }
-
- if(content == CMS_Decoder::SIGNED)
- {
- // how to handle multiple signers? they can all exist within a
- // single level...
-
- std::cout << "Signed by " << decoder.layer_info() << std::endl;
- //std::cout << "Sign time: " << decoder.xxx() << std::endl;
- std::cout << "Signature is ";
- if(status == CMS_Decoder::GOOD)
- std::cout << "valid";
- else if(status == CMS_Decoder::BAD)
- std::cout << "bad";
- else if(status == CMS_Decoder::NO_KEY)
- std::cout << "(cannot check, no known cert)";
- std::cout << std::endl;
- }
- if(content == CMS_Decoder::ENVELOPED ||
- content == CMS_Decoder::COMPRESSED ||
- content == CMS_Decoder::AUTHENTICATED)
- {
- if(content == CMS_Decoder::ENVELOPED)
- std::cout << "Enveloped";
- if(content == CMS_Decoder::COMPRESSED)
- std::cout << "Compressed";
- if(content == CMS_Decoder::AUTHENTICATED)
- std::cout << "MACed";
-
- std::cout << ", algo = " << decoder.layer_info() << std::endl;
-
- if(content == CMS_Decoder::AUTHENTICATED)
- {
- std::cout << "MAC status is ";
- if(status == CMS_Decoder::GOOD)
- std::cout << "valid";
- else if(status == CMS_Decoder::BAD)
- std::cout << "bad";
- else if(status == CMS_Decoder::NO_KEY)
- std::cout << "(cannot check, no key)";
- std::cout << std::endl;
- }
- }
- decoder.next_layer();
- }
-
- if(decoder.layer_type() == CMS_Decoder::DATA)
- std::cout << "Message is \"" << decoder.get_data()
- << '"' << std::endl;
- else
- std::cout << "No data anywhere?" << std::endl;
- }
- catch(std::exception& e)
- {
- std::cerr << e.what() << std::endl;
- }
- return 0;
- }
diff --git a/doc/examples/cms_enc.cpp b/doc/examples/cms_enc.cpp
deleted file mode 100644
index 2cf813987..000000000
--- a/doc/examples/cms_enc.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/botan.h>
-#include <botan/cms_enc.h>
-using namespace Botan;
-
-#include <iostream>
-#include <fstream>
-#include <memory>
-
-int main()
- {
- Botan::LibraryInitializer init;
-
- try {
-
- X509_Certificate mycert("mycert.pem");
- X509_Certificate mycert2("mycert2.pem");
- X509_Certificate yourcert("yourcert.pem");
- X509_Certificate cacert("cacert.pem");
- X509_Certificate int_ca("int_ca.pem");
-
- AutoSeeded_RNG rng;
-
- X509_Store store;
- store.add_cert(mycert);
- store.add_cert(mycert2);
- store.add_cert(yourcert);
- store.add_cert(int_ca);
- store.add_cert(cacert, true);
-
- const std::string msg = "prioncorp: we don't toy\n";
-
- CMS_Encoder encoder(msg);
-
- encoder.compress("Zlib");
- encoder.digest();
- encoder.encrypt(rng, mycert);
-
- /*
- PKCS8_PrivateKey* mykey = PKCS8::load_key("mykey.pem", rng, "cut");
- encoder.sign(store, *mykey);
- */
-
- SecureVector<byte> raw = encoder.get_contents();
- std::ofstream out("out.der");
-
- out.write((const char*)raw.begin(), raw.size());
- }
- catch(std::exception& e)
- {
- std::cerr << e.what() << std::endl;
- }
- return 0;
- }
diff --git a/doc/examples/cpuid.cpp b/doc/examples/cpuid.cpp
deleted file mode 100644
index 6d4cc7593..000000000
--- a/doc/examples/cpuid.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <iostream>
-#include <string>
-#include <botan/cpuid.h>
-
-using namespace Botan;
-
-namespace {
-
-void print_if_feature(const std::string& feature_name, bool exists)
- {
- std::cout << (exists ? '+' : '-') << " " << feature_name << "\n";
- }
-
-void print_header(const std::string& descr)
- {
- std::cout << "\n" << descr << "\n-----\n";
- }
-
-}
-
-int main()
- {
- CPUID::initialize();
-
- std::cout << "Cache line size = " << CPUID::cache_line_size() << "\n";
-
- print_header("SIMD instruction sets");
- print_if_feature("SSE2", CPUID::has_sse2());
- print_if_feature("SSSE3", CPUID::has_ssse3());
- print_if_feature("SSE4.1", CPUID::has_sse41());
- print_if_feature("SSE4.2", CPUID::has_sse42());
- print_if_feature("AVX", CPUID::has_avx());
- print_if_feature("AltiVec", CPUID::has_altivec());
-
- print_header("Other extensions");
- print_if_feature("RDTSC", CPUID::has_rdtsc());
- print_if_feature("PCMUL", CPUID::has_pcmuludq());
- print_if_feature("AES-NI", CPUID::has_aes_ni());
- print_if_feature("MOVBE", CPUID::has_movbe());
- }
diff --git a/doc/examples/cryptobox.cpp b/doc/examples/cryptobox.cpp
deleted file mode 100644
index 38d750d17..000000000
--- a/doc/examples/cryptobox.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/botan.h>
-#include <botan/cryptobox.h>
-#include <fstream>
-#include <iostream>
-#include <vector>
-
-using namespace Botan;
-
-int main(int argc, char* argv[])
- {
- LibraryInitializer init;
-
- AutoSeeded_RNG rng;
-
- if(argc != 3)
- {
- std::cout << "Usage: cryptobox pass filename\n";
- return 1;
- }
-
- std::string pass = argv[1];
- std::string filename = argv[2];
-
- std::ifstream input(filename.c_str(), std::ios::binary);
-
- std::vector<byte> file_contents;
- while(input.good())
- {
- byte filebuf[4096] = { 0 };
- input.read((char*)filebuf, sizeof(filebuf));
- size_t got = input.gcount();
-
- file_contents.insert(file_contents.end(), filebuf, filebuf+got);
- }
-
- std::string ciphertext = CryptoBox::encrypt(&file_contents[0],
- file_contents.size(),
- pass, rng);
-
- std::cout << ciphertext;
-
- /*
- std::cout << CryptoBox::decrypt((const byte*)&ciphertext[0],
- ciphertext.length(),
- pass);
- */
- }
diff --git a/doc/examples/decrypt.cpp b/doc/examples/decrypt.cpp
deleted file mode 100644
index ea510c5e9..000000000
--- a/doc/examples/decrypt.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-/*
-Decrypt files encrypted with the 'encrypt' example application.
-
-I'm being lazy and writing the output to stdout rather than stripping
-off the ".enc" suffix and writing it there. So all diagnostics go to
-stderr so there is no confusion.
-*/
-
-#include <fstream>
-#include <iostream>
-#include <string>
-#include <vector>
-#include <cstring>
-#include <memory>
-
-#include <botan/botan.h>
-
-#if defined(BOTAN_HAS_COMPRESSOR_ZLIB)
- #include <botan/zlib.h>
-#endif
-
-using namespace Botan;
-
-SecureVector<byte> b64_decode(const std::string&);
-
-int main(int argc, char* argv[])
- {
- if(argc < 2)
- {
- std::cout << "Usage: " << argv[0] << " [-p passphrase] file\n"
- << " -p : Use this passphrase to decrypt\n";
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- std::string filename, passphrase;
-
- for(int j = 1; argv[j] != 0; j++)
- {
- if(std::strcmp(argv[j], "-p") == 0)
- {
- if(argv[j+1])
- {
- passphrase = argv[j+1];
- j++;
- }
- else
- {
- std::cout << "No argument for -p option" << std::endl;
- return 1;
- }
- }
- else
- {
- if(filename != "")
- {
- std::cout << "You can only specify one file at a time\n";
- return 1;
- }
- filename = argv[j];
- }
- }
-
- if(passphrase == "")
- {
- std::cout << "You have to specify a passphrase!" << std::endl;
- return 1;
- }
-
- std::ifstream in(filename.c_str());
- if(!in)
- {
- std::cout << "ERROR: couldn't open " << filename << std::endl;
- return 1;
- }
-
- std::string algo;
-
- try {
- std::string header, salt_str, mac_str;
- std::getline(in, header);
- std::getline(in, algo);
- std::getline(in, salt_str);
- std::getline(in, mac_str);
-
- if(header != "-------- ENCRYPTED FILE --------")
- {
- std::cout << "ERROR: File is missing the usual header" << std::endl;
- return 1;
- }
-
- const BlockCipher* cipher_proto = global_state().algorithm_factory().prototype_block_cipher(algo);
-
- if(!cipher_proto)
- {
- std::cout << "Don't know about the block cipher \"" << algo << "\"\n";
- return 1;
- }
-
- const u32bit key_len = cipher_proto->maximum_keylength();
- const u32bit iv_len = cipher_proto->block_size();
-
- std::auto_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(SHA-1)"));
-
- const u32bit PBKDF2_ITERATIONS = 8192;
-
- SecureVector<byte> salt = b64_decode(salt_str);
-
- SymmetricKey bc_key = pbkdf->derive_key(key_len, "BLK" + passphrase,
- &salt[0], salt.size(),
- PBKDF2_ITERATIONS);
-
- InitializationVector iv = pbkdf->derive_key(iv_len, "IVL" + passphrase,
- &salt[0], salt.size(),
- PBKDF2_ITERATIONS);
-
- SymmetricKey mac_key = pbkdf->derive_key(16, "MAC" + passphrase,
- &salt[0], salt.size(),
- PBKDF2_ITERATIONS);
-
- Pipe pipe(new Base64_Decoder,
- get_cipher(algo + "/CBC", bc_key, iv, DECRYPTION),
-#ifdef BOTAN_HAS_COMPRESSOR_ZLIB
- new Zlib_Decompression,
-#endif
- new Fork(
- 0,
- new Chain(new MAC_Filter("HMAC(SHA-1)", mac_key),
- new Base64_Encoder)
- )
- );
-
- pipe.start_msg();
- in >> pipe;
- pipe.end_msg();
-
- std::string our_mac = pipe.read_all_as_string(1);
- if(our_mac != mac_str)
- std::cout << "WARNING: MAC in message failed to verify\n";
-
- std::cout << pipe.read_all_as_string(0);
- }
- catch(Algorithm_Not_Found)
- {
- std::cout << "Don't know about the block cipher \"" << algo << "\"\n";
- return 1;
- }
- catch(Decoding_Error)
- {
- std::cout << "Bad passphrase or corrupt file\n";
- return 1;
- }
- catch(std::exception& e)
- {
- std::cout << "Exception caught: " << e.what() << std::endl;
- return 1;
- }
- return 0;
- }
-
-SecureVector<byte> b64_decode(const std::string& in)
- {
- Pipe pipe(new Base64_Decoder);
- pipe.process_msg(in);
- return pipe.read_all();
- }
diff --git a/doc/examples/dh.cpp b/doc/examples/dh.cpp
deleted file mode 100644
index 652c7b136..000000000
--- a/doc/examples/dh.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-* (C) 2009-2010 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/botan.h>
-#include <botan/dh.h>
-#include <botan/pubkey.h>
-using namespace Botan;
-
-#include <iostream>
-#include <memory>
-
-int main()
- {
- Botan::LibraryInitializer init;
-
- try
- {
- AutoSeeded_RNG rng;
-
- // Alice and Bob agree on a DH domain to use
- DL_Group shared_domain("modp/ietf/1024");
-
- // Alice creates a DH key and sends (the public part) to Bob
- DH_PrivateKey private_a(rng, shared_domain);
-
- // Alice sends to Bob her public key:
- MemoryVector<byte> public_a = private_a.public_value();
-
- // Bob creates a key with a matching group
- DH_PrivateKey private_b(rng, shared_domain);
-
- // Bob sends his public key to Alice
- MemoryVector<byte> public_b = private_b.public_value();
-
- PK_Key_Agreement ka1(private_a, "KDF2(SHA-1)");
- PK_Key_Agreement ka2(private_b, "KDF2(SHA-1)");
-
- /*
- * Preferably, include some salt or parameter that binds this key
- * generation to the current session (for instance a session
- * identifier, if guaranteed unique, would be a good choice). Or
- * anything else that both sides can agree on that will never
- * repeat.
- */
- const std::string ka_salt = "alice and bob agree on a key";
-
- SymmetricKey alice_key = ka1.derive_key(32, public_b, ka_salt);
- SymmetricKey bob_key = ka2.derive_key(32, public_a, ka_salt);
-
- if(alice_key == bob_key)
- {
- std::cout << "The two keys matched, everything worked\n";
- std::cout << "The shared key was: " << alice_key.as_string() << "\n";
- }
- else
- {
- std::cout << "The two keys didn't match! Hmmm...\n";
- std::cout << "Alice's key was: " << alice_key.as_string() << "\n";
- std::cout << "Bob's key was: " << bob_key.as_string() << "\n";
- }
-
- // Now use the shared key for encryption or MACing or whatever
- }
- catch(std::exception& e)
- {
- std::cout << e.what() << std::endl;
- return 1;
- }
- return 0;
- }
diff --git a/doc/examples/dsa_kgen.cpp b/doc/examples/dsa_kgen.cpp
deleted file mode 100644
index fe3157370..000000000
--- a/doc/examples/dsa_kgen.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*
-* Generate a 1024 bit DSA key and put it into a file. The public key
-* format is that specified by X.509, while the private key format is
-* PKCS #8.
-*/
-
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <botan/botan.h>
-#include <botan/dsa.h>
-#include <botan/rng.h>
-using namespace Botan;
-
-#include <memory>
-
-int main(int argc, char* argv[])
- {
- if(argc != 1 && argc != 2)
- {
- std::cout << "Usage: " << argv[0] << " [passphrase]" << std::endl;
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- std::ofstream priv("dsapriv.pem");
- std::ofstream pub("dsapub.pem");
- if(!priv || !pub)
- {
- std::cout << "Couldn't write output files" << std::endl;
- return 1;
- }
-
- try
- {
- AutoSeeded_RNG rng;
-
- DL_Group group(rng, DL_Group::DSA_Kosherizer, 2048, 256);
-
- DSA_PrivateKey key(rng, group);
-
- pub << X509::PEM_encode(key);
- if(argc == 1)
- priv << PKCS8::PEM_encode(key);
- else
- priv << PKCS8::PEM_encode(key, rng, argv[1]);
- }
- catch(std::exception& e)
- {
- std::cout << "Exception caught: " << e.what() << std::endl;
- }
- return 0;
- }
diff --git a/doc/examples/dsa_sign.cpp b/doc/examples/dsa_sign.cpp
deleted file mode 100644
index 5f02c0dc1..000000000
--- a/doc/examples/dsa_sign.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
-* DSA signature generation example
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <iostream>
-#include <iomanip>
-#include <fstream>
-#include <string>
-#include <memory>
-
-#include <botan/botan.h>
-#include <botan/pubkey.h>
-#include <botan/dsa.h>
-using namespace Botan;
-
-const std::string SUFFIX = ".sig";
-
-int main(int argc, char* argv[])
- {
- if(argc != 4)
- {
- std::cout << "Usage: " << argv[0] << " keyfile messagefile passphrase"
- << std::endl;
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- try {
- std::string passphrase(argv[3]);
-
- std::ifstream message(argv[2], std::ios::binary);
- if(!message)
- {
- std::cout << "Couldn't read the message file." << std::endl;
- return 1;
- }
-
- std::string outfile = argv[2] + SUFFIX;
- std::ofstream sigfile(outfile.c_str());
- if(!sigfile)
- {
- std::cout << "Couldn't write the signature to "
- << outfile << std::endl;
- return 1;
- }
-
- AutoSeeded_RNG rng;
-
- std::auto_ptr<PKCS8_PrivateKey> key(
- PKCS8::load_key(argv[1], rng, passphrase)
- );
-
- DSA_PrivateKey* dsakey = dynamic_cast<DSA_PrivateKey*>(key.get());
-
- if(!dsakey)
- {
- std::cout << "The loaded key is not a DSA key!\n";
- return 1;
- }
-
- PK_Signer signer(*dsakey, "EMSA1(SHA-1)");
-
- DataSource_Stream in(message);
- byte buf[4096] = { 0 };
- while(u32bit got = in.read(buf, sizeof(buf)))
- signer.update(buf, got);
-
- Pipe pipe(new Base64_Encoder);
- pipe.process_msg(signer.signature(rng));
- sigfile << pipe.read_all_as_string() << std::endl;
- }
- catch(std::exception& e)
- {
- std::cout << "Exception caught: " << e.what() << std::endl;
- }
- return 0;
- }
diff --git a/doc/examples/dsa_ver.cpp b/doc/examples/dsa_ver.cpp
deleted file mode 100644
index a666259c1..000000000
--- a/doc/examples/dsa_ver.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-/*
-Grab an DSA public key from the file given as an argument, grab a
-signature from another file, and verify the message (which, suprise,
-is also in a file).
-
-The signature format isn't particularly standard: take the IEEE 1363
-signature format, encoded into base64 with a trailing newline.
-*/
-
-#include <iostream>
-#include <iomanip>
-#include <fstream>
-#include <cstdlib>
-#include <string>
-#include <memory>
-
-#include <botan/botan.h>
-#include <botan/pubkey.h>
-#include <botan/dsa.h>
-using namespace Botan;
-
-namespace {
-
-SecureVector<byte> b64_decode(const std::string& in)
- {
- Pipe pipe(new Base64_Decoder);
- pipe.process_msg(in);
- return pipe.read_all();
- }
-
-}
-
-int main(int argc, char* argv[])
- {
- if(argc != 4)
- {
- std::cout << "Usage: " << argv[0]
- << " keyfile messagefile sigfile" << std::endl;
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- std::ifstream message(argv[2], std::ios::binary);
- if(!message)
- {
- std::cout << "Couldn't read the message file." << std::endl;
- return 1;
- }
-
- std::ifstream sigfile(argv[3]);
- if(!sigfile)
- {
- std::cout << "Couldn't read the signature file." << std::endl;
- return 1;
- }
-
- try {
- std::string sigstr;
- getline(sigfile, sigstr);
-
- std::auto_ptr<X509_PublicKey> key(X509::load_key(argv[1]));
- DSA_PublicKey* dsakey = dynamic_cast<DSA_PublicKey*>(key.get());
- if(!dsakey)
- {
- std::cout << "The loaded key is not a DSA key!\n";
- return 1;
- }
-
- SecureVector<byte> sig = b64_decode(sigstr);
-
- PK_Verifier ver(*dsakey, "EMSA1(SHA-1)");
-
- DataSource_Stream in(message);
- byte buf[4096] = { 0 };
- while(u32bit got = in.read(buf, sizeof(buf)))
- ver.update(buf, got);
-
- bool ok = ver.check_signature(sig);
-
- if(ok)
- std::cout << "Signature verified\n";
- else
- std::cout << "Signature did NOT verify\n";
- }
- catch(std::exception& e)
- {
- std::cout << "Exception caught: " << e.what() << std::endl;
- return 1;
- }
- return 0;
- }
diff --git a/doc/examples/eax_test.cpp b/doc/examples/eax_test.cpp
deleted file mode 100644
index 32311800d..000000000
--- a/doc/examples/eax_test.cpp
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <fstream>
-#include <iostream>
-#include <sstream>
-#include <boost/regex.hpp>
-
-#include <botan/botan.h>
-#include <botan/eax.h>
-
-using namespace Botan;
-
-namespace {
-
-unsigned from_string(const std::string& s)
- {
- std::istringstream stream(s);
- unsigned n;
- stream >> n;
- return n;
- }
-
-std::string seq(unsigned n)
- {
- std::string s;
-
- for(unsigned i = 0; i != n; ++i)
- {
- unsigned char b = (i & 0xFF);
-
- const char bin2hex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
-
- s += bin2hex[(b >> 4)];
- s += bin2hex[(b & 0x0f)];
- }
-
- return s;
- }
-
-void eax_test(const std::string& algo,
- const std::string& key_str,
- const std::string& nonce_str,
- const std::string& header_str,
- const std::string& tag_str,
- const std::string& plaintext_str,
- const std::string& ciphertext)
- {
- /*
- printf("EAX(algo=%s key=%s nonce=%s header=%s tag=%s pt=%s ct=%s)\n",
- algo.c_str(), key_str.c_str(), nonce_str.c_str(), header_str.c_str(), tag_str.c_str(),
- plaintext_str.c_str(), ciphertext.c_str());
- */
-
- SymmetricKey key(key_str);
- InitializationVector iv(nonce_str);
-
- EAX_Encryption* enc;
-
- Pipe pipe(new Hex_Decoder,
- enc = new EAX_Encryption(get_block_cipher(algo)),
- new Hex_Encoder);
-
- enc->set_key(key);
- enc->set_iv(iv);
-
- OctetString header(header_str);
-
- enc->set_header(header.begin(), header.length());
-
- pipe.start_msg();
- pipe.write(plaintext_str);
- pipe.end_msg();
-
- std::string out = pipe.read_all_as_string();
-
- if(out != ciphertext + tag_str)
- {
- printf("BAD enc %s '%s' != '%s%s'\n", algo.c_str(),
- out.c_str(), ciphertext.c_str(), tag_str.c_str());
- }
- else
- printf("OK enc %s\n", algo.c_str());
-
- try
- {
- EAX_Decryption* dec;
- Pipe pipe2(new Hex_Decoder,
- dec = new EAX_Decryption(get_block_cipher(algo)),
- new Hex_Encoder);
-
- dec->set_key(key);
- dec->set_iv(iv);
-
- dec->set_header(header.begin(), header.length());
-
- pipe2.start_msg();
- pipe2.write(ciphertext);
- pipe2.write(tag_str);
- pipe2.end_msg();
-
- std::string out2 = pipe2.read_all_as_string();
-
- if(out2 != plaintext_str)
- {
- printf("BAD decrypt %s '%s'\n", algo.c_str(), out2.c_str());
- }
- else
- printf("OK decrypt %s\n", algo.c_str());
- }
- catch(std::exception& e)
- {
- printf("%s\n", e.what());
- }
-
- }
-
-std::pair<std::string, int> translate_algo(const std::string& in)
- {
- if(in == "aes (16 byte key)")
- return std::make_pair("AES-128", 16);
-
- if(in == "blowfish (8 byte key)")
- return std::make_pair("Blowfish", 8);
-
- if(in == "rc2 (8 byte key)")
- return std::make_pair("RC2", 8);
-
- if(in == "rc5 (8 byte key)")
- return std::make_pair("RC5", 8);
-
- if(in == "rc6 (16 byte key)")
- return std::make_pair("RC6", 16);
-
- if(in == "safer-sk128 (16 byte key)")
- return std::make_pair("SAFER-SK(10)", 16);
-
- if(in == "twofish (16 byte key)")
- return std::make_pair("Twofish", 16);
-
- if(in == "des (8 byte key)")
- return std::make_pair("DES", 8);
-
- if(in == "3des (24 byte key)")
- return std::make_pair("TripleDES", 24);
-
- // These 3 are disabled due to differences in base algorithm.
-
-#if 0
- // XTEA: LTC uses little endian, Botan (and Crypto++) use big-endian
- // I swapped to LE in XTEA and the vectors did match
- if(in == "xtea (16 byte key)")
- return std::make_pair("XTEA", 16);
-
- // Skipjack: LTC uses big-endian, Botan (and Crypto++) use
- // little-endian I am not sure if that was the full difference
- // though, was unable to replicate LTC's EAX vectors with Skipjack
- if(in == "skipjack (10 byte key)")
- return std::make_pair("Skipjack", 10);
-
- // Noekeon: unknown cause, though LTC's lone test vector does not
- // match Botan
-
- if(in == "noekeon (16 byte key)")
- return std::make_pair("Noekeon", 16);
-
-#endif
-
- return std::make_pair("", 0);
- }
-
-std::string rep(const std::string& s_in, unsigned n)
- {
- std::string s_out;
-
- for(unsigned i = 0; i != n; ++i)
- s_out += s_in[i % s_in.size()];
-
- return s_out;
- }
-
-void run_tests(std::istream& in)
- {
- std::string algo;
- std::string key;
-
- while(in.good())
- {
- std::string line;
-
- std::getline(in, line);
-
- if(line == "")
- continue;
-
- if(line.size() > 5 && line.substr(0, 4) == "EAX-")
- {
- std::pair<std::string, int> name_and_keylen =
- translate_algo(line.substr(4));
-
- algo = name_and_keylen.first;
- key = seq(name_and_keylen.second);
- }
- else if(algo != "")
- {
- boost::regex vec_regex("^([ 0-9]{3}): (.*), (.*)$");
-
- boost::smatch what;
-
- if(boost::regex_match(line, what, vec_regex, boost::match_extra))
- {
- unsigned n = from_string(what[1]);
- std::string ciphertext = what[2];
- std::string tag = what[3];
-
- std::string plaintext = seq(n);
- std::string header = seq(n);
- std::string nonce = seq(n);
-
- eax_test(algo, key, nonce, header, tag,
- plaintext, ciphertext);
-
- key = rep(tag, key.size()); // repeat as needed
- }
- }
- }
-
-
- }
-
-}
-
-int main()
- {
- std::ifstream in("eax_tv.txt");
-
- Botan::LibraryInitializer init;
-
- if(!in)
- {
- std::cerr << "Couldn't read input file\n";
- return 1;
- }
-
- run_tests(in);
-
- }
diff --git a/doc/examples/eax_tv.txt b/doc/examples/eax_tv.txt
deleted file mode 100644
index 95cd7c1ab..000000000
--- a/doc/examples/eax_tv.txt
+++ /dev/null
@@ -1,461 +0,0 @@
-EAX Test Vectors. Uses the 00010203...NN-1 pattern for header/nonce/plaintext/key. The outputs
-are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous
-step repeated sufficiently.
-
-EAX-aes (16 byte key)
- 0: , 9AD07E7DBFF301F505DE596B9615DFFF
- 1: 47, 57C4AC75A42D05260AFA093ACD4499ED
- 2: C4E2, 26C5AB00325306772E6F6E4C8093F3D2
- 3: 16177B, 852260F91F27898D4FC176E311F6E1D1
- 4: F09F68BE, 700766CA231643B5D60C3B91B1B700C1
- 5: 8472705EDF, AC4C3359326EEA4CF71FC03E0E0292F2
- 6: 14C25EB5FD0D, 8DBD749CA79CCF11C1B370F8C975858C
- 7: F6A37F60670A85, AFBD1D5921557187504ADE61014C9622
- 8: 1AACFEAE8FBAD833, 82F477325D6F76BB81940AE25F9801C2
- 9: 069414324EC293697C, B980E21C09CA129B69E9032D980A9DC5
- 10: D8174DE9A2FC92B7DA9C, 1E42CC58BA2C8BFD83806444EA29DB61
- 11: 2C087DEA30F8B7EE510990, 83DB400A080C4D43CAA6EC3F1085A923
- 12: F36B93C272A703D3422C6A11, 1370C3AF2F3392916364BBBCC2C62EC1
- 13: A0F33477BAE2E28E6747AA3193, B626DC719528CAC65DB0EF94E35422CE
- 14: FCF5193506052E8BFA095C1A5205, F5BD02E0B3C91CC7D6FAAA8A9A76CE6A
- 15: 3797D7F8599B8EEAB39C56241880DC, 0B70003E77146B903F06EF294FECD517
- 16: C4BAD0E0356FFD369110C048D45D81BE, DE7C2B1D83BE2CC8EA402ABE1038BB79
- 17: AF5C358BD31CDCAC2F0EA5252F1C3BE1E4, 2D700986F93B22DFE6695C2A243B4E42
- 18: 7DEF9056FBDAF491D7206B26B19DEF617AA1, E71A7D00BE972D85C77931D7591B2151
- 19: 6E9B2C0A90BF9D38A6EA3B5D2B9B2D97F938EB, 5B483D7F15C39602C2918181E57DA341
- 20: 7C5F68DEE9BBA3B04F11D5FC7C9C7FE6E8B5025C, 0AE6A12D37A9C10BB1A494E16705DC05
- 21: AF0A886BF673BC72045FC074F06A0176C96105E2E6, 06B2DC9A2868C23F86D710E01E37E07B
- 22: 5F228A986DFE4301EDBAF07A02E114F1B30932995CD1, 74EBF68627C78B1FD024A59B56B2A8FA
- 23: 911322F60555118CBECD8DD82F186AC19514316E8D48BA, B6A8BAF2F175CD0C71B63B1EF37E185E
- 24: E7F52730CFB808EFDB376A5D5DF31A7EF8292DC5FC37E9BC, BA2AD158A2D2E5CE01296402B592E1DB
- 25: B3F8D7CA47D8D86E94D670AFBAFA3B8D9E186C97DC029D4705, 709D2D2B9975D4729C19D4EAC430E65E
- 26: 7178FEC027AFADDC2C03518E75CF34D207CAC2EB1537A0DBA520, A315F034CE5E66601444402520F55DE2
- 27: FC230B2B8522F53459D0B968421469BBA7E683ACB0190393B2870F, 48679A78E470E175CF3D3E9B46CEDFCE
- 28: 35A641127C78C721ECDC50866C21637FDC9515E41CE60F09015EA713, 0062987222F6412B7AAF8A9ABF6FBF98
- 29: 3D42D6C113421743C08A6F682CFA0E517D5531BB66241C02EC4DCC26F7, B1AAFE11FA2D6E0C870177DDD7F98FF0
- 30: DAD065B4669B7C59C8392D8E7BD7E64BC01CEFFF27E335B25A328D356F0E, 8973B9B9ECF26DAB58CCF0787EE928E5
- 31: EBE626F9E241FD233D9781C359430C982667AA26921B62E98FAEC502C01B0B, 2AC0D7052A2CDCCE8E26FEA7595198AA
- 32: 64D842B66796A797C2B4C6905742FDF2148FFC445E192F9E03B53810C082F788, 9778B345EC12D222DCC6DBABD2651750
-
-EAX-blowfish (8 byte key)
- 0: , D8C4C23A6AC0B7B7
- 1: 2A, 5E0E4BDDB60772FB
- 2: 7695, 7581B16CCC9C45F1
- 3: EB14C8, 6223A121CFA216C7
- 4: 5A5C809C, 4A47658796337D6A
- 5: 8BC2041181, E1FBA8DBA00571FC
- 6: 89C666F015FA, 2B4A76A0E699FCFE
- 7: 86C1FA92484AF6, 31B3B738A261D6F5
- 8: D1F401C145C9328B, 4C4A045EB489F59C
- 9: 70C9C7753698324A73, AB298B5B20567EB4
- 10: A50D9D88DC101B6DC8D2, 529DFCBFD13B8E6C
- 11: 7CC2885C2BE79C44F28FF2, 566255022B40C81C
- 12: 6902D58347C29250EE07981C, 34619AF18E14C690
- 13: AB6C3C4AD3EC45143392B642DA, E6D2DD323DA175BB
- 14: 7065B28BA8AB67B2FB7B6D5E3FAF, AEDCAA54F4B0772F
- 15: CBBA14A74AD4ADC0EF036EDAE42D51, F2BFFA4D81BAC034
- 16: 60A315193F58144F5701D547C79FEEED, 912FDBDB05467DF5
-
-EAX-xtea (16 byte key)
- 0: , 86881D824E3BC561
- 1: EE, 4C3505F04611D9C2
- 2: 80C8, 6A3428BEEAD60738
- 3: BF88E7, 04F1E99E9F5906C2
- 4: E06574B7, 33B0153AAEF9776F
- 5: 42D950AF63, 4A0F415640322FDF
- 6: C30F6AD46EC9, 9646FE909D2B95CB
- 7: A0049FCA856A14, A0257289C6BBF278
- 8: 2814B0C1358440E0, C4B0A2354925E887
- 9: BF4F062B52C1E489CF, B56442A3CA57A041
- 10: 63DF433956831B8780FC, ADF9ED0B46DCA19E
- 11: C317FD079817F50E0E8A16, 2EA0EC993FC603AE
- 12: 2BD12FDDD81EB11660346D2A, FBC6F69125BBA88D
- 13: 85D356536FE2843C6BBE60EDBC, BB2FEFD04F230E79
- 14: 22493009DB01B4746F4927A8C4FB, 64CC08471D93C9AC
- 15: C0F3C0DB08DC93FBA725D1E02DE084, 77B762213DDCCFFE
- 16: 568B66D3112556BD98FF9339E9C002E5, C8355F508219FE0C
-
-EAX-rc5 (8 byte key)
- 0: , 169C7954341EF44D
- 1: 22, DABFDA9A0B0BA067
- 2: 2E54, 6A3D6D9AA5877C5A
- 3: 2A6ECF, 2A34A3AF5DE8919E
- 4: 9CC5F84F, D3F673EDAF75E3B5
- 5: FF5611756C, CC647FAAC8D49BF1
- 6: 74C939BEB31C, C335999CCFE8F5FA
- 7: 7976B6F7709B5F, 2A7969C5FD063A88
- 8: 421EEC5022276174, 2C9BFB1EAC3C54A2
- 9: 6A4761CD266B1C0ECB, 3EA3CCEBC85FAC4E
- 10: 7C09201098E764239A2E, 8043ABA9BF4D5AEE
- 11: 8CE26277562F646DE33C88, D72AED48895E3B40
- 12: 52150F44D37D121560DA87F6, 58E865E22B485906
- 13: BA0A73B45F93ECFBFC3AB3D8D0, 683D52FA47FB1A52
- 14: 96546CBE01054AD24CC95DB54724, D80D0D530E5D1DDE
- 15: 61E654BB18CD26FC36C09F874DC2C7, C65884CB9D9FEC1E
- 16: 1D77B8BF02CDEAB4A707C07628826D5B, F18D1730C3D64701
-
-EAX-rc6 (16 byte key)
- 0: , 1DF8B0B92A3F0C951C425AF4830E63FD
- 1: 1A, 8A2959EBBE90180999994DEB7036DB85
- 2: 435D, 7EF00CB57DB7B4155DB530D75CE6B025
- 3: 08A6CF, 2ED6AF0F2D5BAB05F623D389480A01F2
- 4: A86E54D3, FC69547C8BD922A5BF2F7B26C4D20F98
- 5: ED0822E439, 0007A3C6DEFC6C912C0E5B853B520368
- 6: 7BEFC7FD4054, D32C43A4D1086D57C5BCFAEE04EBC600
- 7: 5235E58E79287C, A27E9C781327C0FC7C55410EB0C828A9
- 8: CEB5EE99BE521F4D, 547F46383987F2A3582A81A3BCF9B280
- 9: 0358B063D5F99C3770, C0A73730512CDA6AD49599775D59EDA1
- 10: 434B9AEE07DFADD0A332, 499BD88881E558E09A8E822BE27D2496
- 11: D47849E650F350BB622D74, 638E37A84E7FAAF8F5D77F1B061773DC
- 12: 814592F568284085E79A024B, 9EB1405E8422FE50BC0D88D837A2C650
- 13: 6F2B55EC91B591082053AF692E, C48F91EF01AA43A1EE3B36D233DDD48B
- 14: 506CBDD2901838EE2F178B6953DA, 03778957F536509BFCA577B23A18F726
- 15: 446EE435D3D1848B51BB8C5F7BE4A1, 1129EAEAADE534940546D43242A4C839
- 16: FB9D2B150C42465B1685D8F069CC06DB, 41E2940F5DC63CB4E2FBEC25ED8A31E6
- 17: 9684F683260107BE8FEBBEE1D3EEDAA7BD, BAE7C116F7FF96631F4ACEE95C65CEF3
- 18: 5082B1FE48CD3AB58F63C2DCFDD4069AC736, 19AC7B8EE315CBB7131A283851B32266
- 19: 8C72AE495B6F003A3C784D144E84E88885F78E, FA4CEC023740A8D670E351FBCF62C1CB
- 20: 815D6361C7AE34C9D796ADF9C71ABC46AEF88BC9, 9A1F7288C61A6623B9A82748137ED7CC
- 21: 904A853E2E96BD2B85AAB3F5DFB900E9B3642EE667, 9AA90DBDD461CAD20495DCFBCB513DD2
- 22: 79D738A462F727B3D3C529ED999B6FDCCD991D1C5A4D, BF0987BEDDE650D73CAE7D380FED3431
- 23: B2DEFDB7D503A84E83155A04B8DE8C8DBB68C2FC475007, B7CE900CF43CD518024123C76F6DA328
- 24: 9E723E15439E12F6C46DF8A309AE1E97B6FD18436259CFB0, DF8B6E1E23512CC4CF5FF531A1908F69
- 25: A7F0AD03CEBCC9202718AA164886E1026975306A664C5AC7A9, 4A771BF8B9A4325705C85E5499FD98E9
- 26: A53A92AD1C6835F28E04EF591E783D36F3D76E489B31B87BEB7A, AA263B52A6E6A043DE4D7029D4DC73F5
- 27: 79BE3C38291A7F77E932C8A9DEAC08DE6442EA9B3895B101A14E7B, 33B84DE06342E675E019CD0237292ED0
- 28: FA108123C5A69571CFDFE8C3D00535121FDE3096DDC0D700F8F26A5A, 764025D7CA1A3F2C54D28956423B0C77
- 29: 36EC2D67FD977BD2B73DB6D8EB756B3EADA13690E1B6DFC12A4781B34B, 4BC6B38DE3B02283D92F4DF19A5C48C5
- 30: 96D3243C945905C9732B5927E46F00886D511463B38C86002FC26B65AB8C, 5B5511CDEC35687AB8425AB22D58B4F1
- 31: 9CF83B87BEA3374AF7722E999863E3DABB858B0383383EAC7757F5B80FD44B, 1E0CBC961940FDA93B73A92DACFD67F3
- 32: CE3BC3C9FA5EF4AFE5272B3EDD24B1B003FED2C2E501528CFF44D3FABFF52CB4, DC94FDDC78AAB2B7CAA1E1EF149AC355
-
-EAX-safer+ (16 byte key)
- 0: , B120C7B37450C46189712E4DFD1F0C44
- 1: CA, 82BA1869C5FF1EF2A4F6ADC1E7DC1F1D
- 2: DD20, 6BD5601B16C9943A84AC1F99A176E6D1
- 3: C1C09F, 0911DC63AA414C004E2BD825BECDC93B
- 4: 27E43F59, BD858F084B082F76814DC385E1FB20D1
- 5: 2A9A92F246, 5ADC4A32491934AC0BD00FCE686B26F1
- 6: 52C78C0CD6F4, F35886F46C03EDCA10B3D01CF07B1E0A
- 7: 23E0D3CED3795F, FE33D96FC98B78A30C0A412C60E93992
- 8: CD3FC9961559F239, 9982364A61609FC41068260267231EE9
- 9: 6EA46CB7AD7505C1BC, BB15053EF0F78B9091B3064118F3E9BF
- 10: 05D9BA230A56CCA0703A, 1338E68E3DC992B6EB2685C668E75869
- 11: 7AAD6049DFDCA6771AE42B, 35267E431051E1812495615324C4CBE6
- 12: 8695091532B83B23C296F620, 7B2EEA861E9A91E6B6A911E10FC3FDD1
- 13: D909DA4BC7372ACAEA78E6A0EE, EA6C1CD16180DF0B07F4E204A4B4FACB
- 14: 7DEC8443600D0563AEFE87A2064F, DA454728069B3B409889664783588189
- 15: C042FE656742CD2FE5D9C212D18C6C, 5929E4AECC2CA047BAE948E7023FE4D0
- 16: 0B84D3CF59EEF7319633F4A397D47CF8, 31F892FFDB7535DF5D9143456E404163
- 17: 8C9E57AAFA7969B142742B63AB73286600, C418231C44F96660DDBA8C26B3BB3681
- 18: E9EED66D370A3A6A39C7E0E570D96F807EAC, A4AFE8D1D3C31B956A3BDBD043E7A665
- 19: 1A5D47992DA5597D1449B4C8DD47B7404C7657, F3ECEE5182014FC3365FDBC4C33CC06A
- 20: E7C7945FD1AFD3F5DCE666D8A5A2E8A3C11A7A5F, 86D78B2FBA7597B8806BED505B52BDF6
- 21: 9E2165B47B29CBC4ACD50660E011D691F061209969, E9B1E860BD02085177E1A94E1EE6F3F0
- 22: 48EA2945C8DD3FE09407BAC8973A861DB15B788C8FFD, 502926712EDB1B3DD13806052C6C75D7
- 23: F37D46B35B60819EA52B00457D79155C04B55972D0DFA9, BB2B7D210BF0570F422640BF81F39B9E
- 24: 12E85C0C78227205CC682360C79E35BF58EC6551CF8FE2D0, 042990D7A58D458C570A15DD375DB4E7
- 25: 4F6C15109DE980DD14A7F4C27F48671E4787C53A564232F427, B097A5990D8067DD89C21473150C070F
- 26: AAC472E49DB101B564A8A01E2C80C0C6AE9065D332C2DE79FAB6, ACDD587A7DB86542E195DF73AF1C1CBC
- 27: B9912CE18019C31692A1F7E11D9CCB20297ACCB9DC62C47C01D2C2, B0ACBF028CA5B15E0035D2EB8CA916BE
- 28: B4F2B1FE14A1ECDC9C8EA1A0120395E6ED1E69D3FC85DD0F3F90F350, 9A561EBC769369B95B9CB74FC6AC27D3
- 29: 3FE397C8AD02689B7437A37861F0907AF1F6014A293B46419348771C5A, 6B7BEB9BD5018FECD71BE5081C7C2544
- 30: 5019089142199F7207E1B7731B8B247A18A685B231499DF12A73F5D67D37, 307E93446777005BA1B088F178A0DB6E
- 31: EAE8F9F02F8DB3D70B78B08CFB0949D99F1A86C958A8E3823736BCEAB86BE1, 6C94F48591C18BF9C450515B73379973
- 32: B9C795F7A87305B4AD36DBA10B3B1C70B329D29E49C8C6A932D96A74334AEE4A, D18E6E233FEFD6E5C7148BDC1504299C
-
-EAX-twofish (16 byte key)
- 0: , DB0C02CB069E3773296D3BD4A87A381B
- 1: 99, 7D21D19E9C440F68E99F1F2EA2668694
- 2: 0696, EA590EC417C88E23FD23917F9ECFB0C6
- 3: B9B082, 82D4C9B68DDB02C906496413E13A2D68
- 4: D6B29D74, 5BCE5CA4F662E883BF7FCAAE5FB2CE01
- 5: A59C9CB009, CBFB04226D1029A7EC9D64A48A6729BE
- 6: F4924FE3E355, 3D85B3900DECA0528C815F1447A1F209
- 7: 679C88D52FB519, 931C7A863C3701D8015FDBD8696C6C30
- 8: 26DA41C0D115375E, 7627E23E791A4DCB0FA5ED71B1ED2288
- 9: 8FEC6EB7016AD2B178, F65ED0286A724F0CB2EA317D5022B0D8
- 10: B5F22415B1334133C531, 87C4F3A8991BBB85984BC4D3305A5CF1
- 11: 23E1D0ED2E820AFE7DA2FE, 100499F1093FAB2ECF73B643594E98E3
- 12: 79519ABA91F46B8DAD6D5335, FBDCD1FCDB20AB99135F28A714C6992F
- 13: 5968D0B4198A0AAD3D0395018F, 781F22E2DA98F83398FCF911B2010057
- 14: 4E55B14432B601E3EF2EF567CB15, 8BF6E53D7657E56EA3DA1BFD9C9EC06E
- 15: 6ED89651CE19B3DD1EE5C8780B5015, 131CFD657D32D4E1B35140ADDCA0E13A
- 16: 2295A968B4D072D12757756247554850, F35FAC95C2AA4155450EAAA6E2E789B5
- 17: F9B2AA2AA502EA79BBA0C5EAD932B8E1EE, 0ED81AA40B9BF39A9AAEDDDB7A04BEA6
- 18: 385055F1C1C26C0472A504B4CD225DCA55FE, 24831680B56368231AC54227D737F582
- 19: 771529585C741A3F8B1C973709892F255A99EE, 2A132B4BF96FD5109DB04459103F5E84
- 20: E7A2197D9FAA8AB8B303B5EC71AE34AD5EC5DD66, CCAB6518371EC8E0A9E9EE4F7CA5878B
- 21: 279E54F755EAC6B57375B9EC4406E43DB3139D740C, 7B6F26F2C0ECC9F2DF4EDD7513E6E0B7
- 22: 27816AA94CBA2BF98E49E595AF5B3FAD12BF1D6F1AC6, D04876C5492D275F15C834E3CF794F0E
- 23: B5658DC148855F68B282211D879F688F3C142FE555CF81, 4539CDA8A65DB9047AAD76B421B81120
- 24: 72F0BD4F939C2C9B4FA734DCB0AE4FB9BD342BC8459ED2FE, CEA8469BC0457EBF3418C1114288C904
- 25: 70568245E6E6BD5D11AD0C74030D7AE08BA05057DEA0FBF4AD, 71554FDE6B87477A51EE4499D78783D2
- 26: 8702D35BE07D7ADF70684046CC6C72FBBBF821E0BBCCBC973601, 33CC6FBFDA15E306919E0C3BB2E22BB6
- 27: 0BA23F4A6174165D4A8BA80B7C875340B0F8B2A6967D34E106BC22, 00E6679496714236EECEC84B9AF3072E
- 28: B9E25ABA84C6BD95B5149E7616FE2E1D6FAACEAAD77A636C60279176, 8D8AD0B9D4C709E1DA370EE01611482A
- 29: 74759711F6D542581F9F83498FB616638D092732BA07109BF4B5BE045C, 71A40DC777BD09F75362F7B20E0B7576
- 30: ADBF7E98926484BA2C7F6CD7CD9734FC19265F68AF3BFCAEB025F6296E37, 8DF15B5F69B67F7DABE44E3666B55047
- 31: 2DC26D449379997D110309B2A0DC2760FCE8CADB4B14ED580F86C70F69C9BA, EFCB60EB2B25737E256BC76700B198EF
- 32: 2B1890EB9FC0B8293E45D42D2126F4072754AA54E220C853C5F20FBA86BE0795, 1A1B15BBC287372FB9AF035FB124B6A1
-
-EAX-safer-k64 (8 byte key)
- 0: , 9065118C8F6F7842
- 1: A1, 1926B3F5112C33BA
- 2: 2E9A, 5FA6078A0AA7B7C8
- 3: 56FCE2, 984E385F9441FEC8
- 4: C33ACE8A, 24AC1CBBCCD0D00A
- 5: 24307E196B, DD2D52EFCA571B68
- 6: 31471EAA5155, EB41C2B36FAAA774
- 7: 03D397F6CFFF62, 7DFBC8485C8B169B
- 8: 8FA39E282C21B5B2, 2C7EC769966B36D7
- 9: FEA5402D9A8BE34946, A058E165B5FFB556
- 10: 6CDEF76554CA845193F0, FED516001FFE039A
- 11: DC50D19E98463543D94820, 8F9CCF32394498A1
- 12: 42D8DC34F1974FB4EB2535D7, 77F648526BCBB5AF
- 13: B75F1299EF6211A6318F6A8EAA, C5086AEA1BE7640B
- 14: 1E28D68373330829DD1FFC5D083E, 33EDA06A7B5929A2
- 15: 85529CF87C4706751B0D47CC89CEA6, D031905D6141CBED
- 16: FE5CB61BAF93B30ED3C296EE85F51864, CC484888F0ABD922
-
-EAX-safer-sk64 (8 byte key)
- 0: , 5254AB3079CDCB78
- 1: 75, 798DCF14FEF8F4D1
- 2: 0300, D5FCA75DAC97849C
- 3: 520F98, 10E357957CE20898
- 4: 80E2764D, 5C7F46656C6A46EA
- 5: C48960CDAA, 3CCF44BD41F01CA8
- 6: E0E60BD9AA2C, EBB493983FCEE79D
- 7: D13D8804906A1B, 6EDDCA919978F0B6
- 8: B7AE14C37A343BFB, 2369E38A9B686747
- 9: 5DE326BBCC7D0D35E9, 041E5EE8568E941C
- 10: 13494F5B0635BA3D6E53, EAEEA8AFA55141DD
- 11: A9BB35B14C831FDA0D83F7, 4002A696F1363987
- 12: E242043A1C355409819FABFC, 63A085B8886C5FDC
- 13: 204598B889272C6FE694BDBB4D, 194A1530138EFECE
- 14: EE3F39E0823A82615679C664DEBF, 1EFF8134C8BEFB3A
- 15: 8579D87FD3B5E2780BC229665F1D1B, A832CD3E1C1C2289
- 16: 74D7290D72DA67C4A9EAD434AE3A0A85, 96BAA615A5253CB5
-
-EAX-safer-k128 (16 byte key)
- 0: , 7E32E3F943777EE7
- 1: D1, BA00336F561731A7
- 2: F6D7, 8E3862846CD1F482
- 3: 5323B5, BD1B8C27B061969B
- 4: A3EC3416, 170BBB9CE17D1D62
- 5: 0C74D66716, 7BD024B890C5CE01
- 6: 6158A630EB37, B5C5BD0652ACB712
- 7: 17F2D0E019947D, F9FF81E2638EC21C
- 8: 68E135CC154509C8, AA9EAEF8426886AA
- 9: EDB1ABE0B486749C21, 355C99E4651C0400
- 10: DB0C30E9367A72E8F5B2, 631B5671B8A1DB9A
- 11: D4E5453D9A4C9DB5170FCE, 75A2DF0042E14D82
- 12: 3F429CC9A550CBDA44107AA7, 2C2977EA13FEBD45
- 13: A7CA22A97C2361171B415E7083, BFE81185F31727A8
- 14: 170F79D8B0E3F77299C44208C5B1, D5ED9F9459DF9C22
- 15: 2E24312D2AE5D5F09D5410900A4BBA, 2FC865CA96EA5A7E
- 16: 8F3C49A316BA27067FF2C6D99EC8C846, 9D840F40CDB62E4B
-
-EAX-safer-sk128 (16 byte key)
- 0: , 22D90A75BBA5F298
- 1: 3F, 98C31AB2DE61DE82
- 2: 584D, F4701D4A1A09928C
- 3: B9DEAD, 6E221A98505153DA
- 4: 06D4A6EB, 0E57C51B96BA13B6
- 5: 7B58B441CA, E28CCF271F5D0A29
- 6: 7950E0D1EC24, 2ACDDE6E38180C07
- 7: 65A4F4E098D7C6, 7DC1C9E9602BACF2
- 8: FEBE4E72BAA0848F, C4607EA3F138BAD9
- 9: 9B7BD6D6D655985AA3, 8B2C58A9530EA6AC
- 10: 60C92F925D1478470203, 51E6F5F6DC996F84
- 11: 7B40769370E651F64AA654, 74F1F8A8D3F4B9AF
- 12: 7215832C2FB9C54DF7A9C686, 9BF9AEF14F9151D1
- 13: AD0F9C79008572AB8AE2466EFF, F375D0583D921B69
- 14: C05076E2C330A0D25D7CEC80597F, 843C12F84B00A8E0
- 15: D18F0563AB0278140B0CD9A9B07B34, 262B1688E16A171E
- 16: 650747091F5C532EE37D2D78EE1EC605, 1BAC36144F9A0E8D
-
-EAX-rc2 (8 byte key)
- 0: , D6CC8632EEE0F46B
- 1: 4C, EA19572CB8970CB4
- 2: 5537, 3EDD3253F6D0C1A8
- 3: 206FA6, 20FA88F03F240D31
- 4: 17EE8B40, 702E8194F1FCBFDE
- 5: 2A89287136, 31C5534786E15FB3
- 6: 3A6AEDC7066B, 3C663A4081E1D243
- 7: 8BC5203947A644, 6AAC806C92BFBD6E
- 8: 2E0274BBE14D21A3, CEB0E0CB73C3664C
- 9: 9C4B292B0CF17E3A29, F23CD535559023EC
- 10: 8E322734308F85662877, 46363D7EFC322821
- 11: C413C405767FF5F98E3667, E7BA35D8F3678E7E
- 12: D77806B7A218098B1569EADC, BA67C306E5C0181B
- 13: 4BE5EF74F9E9799A4D636FEA9F, 4C511C44ADBA4030
- 14: 7E19969170C2C8D8AEBA8C7FBC2C, 54CC6D466A2DF6DA
- 15: 2EF1CEDC1DD3403CF440FC5561BE33, 61C6FB277E93701F
- 16: DE052719153EBACE9D7B19F52AC4282F, 4AC2A96F2FA8634C
-
-EAX-des (8 byte key)
- 0: , 44048B7F240B6F5F
- 1: 0A, 37009B7D4E09953A
- 2: 03BA, BFD2FD7758961728
- 3: 37EE10, 16A6AF96DE888A19
- 4: 07F44290, 100CA84AA0EDAA1D
- 5: 389EF0023B, 9614FB800A533268
- 6: 3F4DBA8AA01C, EFA6B55B7ED5E40F
- 7: 8C7B837896EAE7, C113CE8F664CE3D4
- 8: 7011D993D8EDB0C7, B4C370A919F60497
- 9: 0DEB30A31351B13D7B, 00ABC82DC5F3A1AF
- 10: 8D3897B2CBE323D6EE1C, 7A2D15627CA1441B
- 11: DBC002C817DEBFB419F94B, D8EB87F86D6ACDEF
- 12: 17048E2976FA85AA849E9A80, 229FCD1C9D1E3B9C
- 13: 30B989EF646544885A478AC198, C1B7EB4F799105C8
- 14: 5C2E12A7F118A08D6FD585F9C839, C358679FEE6FE7D7
- 15: 8D1A1E888BBB8648E638C4E74E11B8, 685E006C441448B8
- 16: 93AE906B8BE4EAC8ED6D8F48F04A7AFF, 71DD7AF752FE28FB
-
-EAX-3des (24 byte key)
- 0: , 8914311BB990B725
- 1: D8, 2094EDC5D03E54B1
- 2: FEE5, 781CFB0EBE3895CA
- 3: DECF5E, 59918E8A5C4B459B
- 4: BD583AAD, 2013BEEBEEA795A1
- 5: 2BC01C6C78, 0B1134DBBEAB5D3F
- 6: 4D5EAF01A895, AB4D17516ECBA50A
- 7: AF229F90614480, D3113C0A9D133CD4
- 8: BCA6F375DF4568E0, 8E9EAEC8E77786BC
- 9: 575F34219E6DD8DB4C, B40C75139E5D1860
- 10: A199B8AC433B615EC96F, 774AF803698ADE3D
- 11: 718A2975DD9A872A68AE10, 3B9460F849CBA7FB
- 12: AB38E148180F6E2FFBB96F91, E3EE3B8FC50DADBC
- 13: EB10E0233507459D4A6C29EE80, 8D90B46BB1EAB27E
- 14: EB48559C320DFB056C37458E19B5, 9315F0C4AF8500EB
- 15: 9E8C73EADA105749B5D8D97392EDC3, 2E749EE66C1E6A16
- 16: 600FA4149AF252C87B828C780AEFF8BC, 33D7D11DCDC19936
-
-EAX-cast5 (8 byte key)
- 0: , 382FB8F7E9F69FDC
- 1: 99, 20DA959849B3F7AB
- 2: C54B, D05547C6AFA3484A
- 3: 579836, AAA92B2321FC50C5
- 4: FEB7AE55, 639EDF01C4FB965D
- 5: EA8A6023FA, 01274B3ED5CE102C
- 6: B7C4E995121F, 712BFE27CAFF6DDE
- 7: F44236660B0004, FAC51D1DF8EC7093
- 8: 01CD7E3D0BF29E8A, 049C47A45D868D0B
- 9: DAB170493DFD6E0365, 6F3AEDD9A3ECF4FD
- 10: 82C9EEC4803D9CD11FA8, 32683C0A9128C6EA
- 11: 324AC59E87B244ECE0F32F, F6B095AAB49353CF
- 12: DBDDAB11D02C9CA5843C406E, EA728FC46DDD3B04
- 13: D67376C2A4AD92E7DD80E39303, CAF72B7E7C237EB3
- 14: F2B9BBEF08036C2982C6DDD06918, 70A29D780C22752C
- 15: 96E3D9141F8EBF520540C2BC9A9C23, CEFC86A1CD48203D
- 16: 70CABBA983179106AE7FCD5F1F31D5C3, BF7F9168F4F82F56
-
-EAX-noekeon (16 byte key)
- 0: , 556805EEA595CFB9A30FAD196103D7FD
- 1: F5, 0A7DAEDFB656526CEF4DDBA8087A227A
- 2: 7B8C, 249895D79962D5B4D18FE07366281B72
- 3: ACFF15, DCC489D24832EB106F576AE6B6EB957A
- 4: 08ADE7DB, 0D3215999E9960EDAB29B78744C7F139
- 5: 66139213F6, 505E1E7141D043E903C26EE0959EEECD
- 6: 078B79F880A8, 35B7EB326A55E50332866EEDB682EC20
- 7: 2809E34D9667D4, FFDEC555F68524A09A6ABACA372077D9
- 8: 93D267DE1EC635D3, 4FF3561990A56E4B374618722EF850FF
- 9: F377A4D93FF32F4A51, 91D4070423A90FC54D305169C03F49ED
- 10: 6244B717E082993EB7A1, 2E3A8A354AFA9473667ED7FDD46BE9FC
- 11: E917559625D25E6E5F2EDA, 19295C37A70314CC9A1D11FDE8D23C92
- 12: 1E6DF2EE112A893AB14DFA92, 12C4A89D4CD65F8116A03A135AFD3701
- 13: 47B18CD762E011770E203CF605, 434909A97E118B20D3AEDC79AFE33A9E
- 14: 72D9A1A7DA6F33D5E0B927F9F32C, 779C23714FCAA2B2321EC7FB5B03E222
- 15: DA8B830FFCB3DB274807F780D33240, EDC2F1C8A401F328A53392597730B007
- 16: B53DD2BB840AD933D36A7B5FFDCCFBBB, 4EC0E6D1F916BF633869239B672B37A1
- 17: 42936BB9A936C30408660855F4F47F3314, F0DAA6DDA15585E1697ABBB4790B15B5
- 18: 00372E47F5BA016F1B2A1E680B76AB02052A, CDBF3D241BF7FF96D3DFBEDDB872E901
- 19: 8AA236B0C8BEF6F67A97C2DF90628F6E5838FF, 731DCD61F7F26004C03519F9500EA824
- 20: 55338647812FC9D86CBDDCED7120268A4D43F8BA, 0E61B3C835CAD95FD49FEF002C014E72
- 21: 435820B28E52154B47A04D5E635D8FE37FA47FC985, F6A96DCE4917E8D7C610923627E80970
- 22: 0D30C15B6FEB4A48B14DD15D41A4B25D442AA677B25C, 28E15CCB74AE992C68BDDC8D87802050
- 23: D9D701F9AD6B0E13D2CDDA15A5194E7CE8BD2C02137391, 2DB9A15884E9C996C3D6B5BDA44B9598
- 24: E2390AC5CE10CCFBC72106A52C7F180CB477E3C193CBACA8, 22D3F7DCD6947EA4E78DF57A8E1A9A59
- 25: ADEFB7D9500658D34996AF6BE6336CD78891064EA1DB8E9785, F239D67D039A15C620A7CD4BE4796B3F
- 26: 89964C90ABF54A6DF9F13C3681E70C702D80A17BE79F8160F30E, 6336F729ECE1ED7368669D75B7E2DCBA
- 27: 576B2813CECDA4F905BD5D58349EF070FF41B7EB6BB2B01B061B0B, 125324CBF2ACF1011A44A99A11EC8AFC
- 28: 430B957481748519A60494F0B5F698F34B1A8235B00AC0D1F0A4442E, 1E80A7FCEBBB8E1E12D6831906154485
- 29: E781BFE5FCDE0BFC056CC86C4A0B9DD3B815BE8CA678204CF47289B5B5, 190D5AAA9EC1CB4CC86FACE53BF1201B
- 30: 78BFAC07A9B7B2AE9329BF9F9BF18A1A49DD9587001EFCA00E9AD9752764, 4FB5ECBEEB0995C150EBC66508FA19C1
- 31: 7D6C20694109DE21F7955855A8FF832347518DD496C2A114DF142C68ACDEAA, B25D4BB34056DC091A7A3950D46C32EC
- 32: 3E1E4395DEC1AFEA9212B95F37E679B6E2D14DF23C5DE49018C2C8038CC4AD45, 9A6DE7BD41A21918AD504490EF4E581D
-
-EAX-skipjack (10 byte key)
- 0: , 85F74B6AFFB10ACD
- 1: 3F, 604DF8BDD98A0B3F
- 2: EA87, 792374FE07588BF9
- 3: 0169CA, 489AB8AF69DA3306
- 4: A7AC3EB1, 428DAF508E24B583
- 5: AA9028D5B3, C0A44EDA71FB2C86
- 6: DA97BA88A061, DA2EC34077F42585
- 7: 7E25FAA41CEBC8, 36D4987551E06D5B
- 8: F662DA6C9001CBFE, B7DEF76680C316A9
- 9: 6D3F73EC716E1DA897, 5F0F83BAE4D3513B
- 10: 2A300F585BEE9C889743, F4756C24DEB72A9C
- 11: 80518B010DD77C82D19106, 50FF5CAA365F4A70
- 12: 6E579A2173C861B6F37B4CD3, 81E3E5ABBA8F0292
- 13: 5B04829880A72C38871C7021F3, 6B26F463708A3294
- 14: 934177878E9A9A9FB4DEB3895922, EBC1C32F0A2A3E96
- 15: 07AF486D1C458AAB2DBF13C3243FAD, 87288E41A9E64089
- 16: 84059283DF9A2A8563E7AF69235F26DF, 351652A0DBCE9D6E
-
-EAX-anubis (16 byte key)
- 0: , 8E20F19D9BA22ABA09FB86FDE6B9EF38
- 1: 3B, F4201E546A9160F989191942EC8FD1D3
- 2: 9F38, 4E3CEAE3E1CB954E021A10E814B71732
- 3: 4F4769, 3E8F35A6A5B11200E9F1AA38590066CD
- 4: AB41F5FC, EC4C97A8892AAF5433106D4AC8A49843
- 5: 414F95D61B, BF831E34D1E3FECB973A8C730ECA2E6D
- 6: 4798322F06D1, 005BBC30BFEDBE6463536C4F80D1A071
- 7: F256B6CD1BF4F5, 468A28F0661884B846B191B530C8D064
- 8: 90906F27A633ADDE, 6D9200A37A7F6A456CB103673184C2E5
- 9: 16CD3C17C9B4EAB135, 6D716E23D7B35109F55B036EDFA7742E
- 10: 7AD1C22F1F06298DFB25, B076990F8193543C8F3185D3792BCE56
- 11: 0476F2ABCD057FE6FEE39D, BB2876DB18C00038FADBBD9B264ACC3C
- 12: B69EDE336407DBC2EE735857, AB63E5906116A8BE22C52B5DA31B1839
- 13: C3864C1354065A56470669E602, C72BFD3A0BC73BFF051C9AB2F0DFED93
- 14: 296D8F183A59020D33890420DD7B, C9D90B9EB42C32EDCF6223587D1598A6
- 15: 256ED8E9D982616680559979BDF2E9, 179FE4E7BA7E966050D35900317E9916
- 16: D4ED8F30FF9C0470D75B3B16750A3AE4, 5D50F05BB270A292DFF9F67A3BA84675
- 17: 40CDEB6388274143CA3C4F6020BD9A4875, B27C7DFB1BFBB3FCCEE0171852C7924E
- 18: 54EF262EC1801D505C7629D038654EBA0594, 9D2060FCD0A2C577511C7752ADE60BBE
- 19: F39EE54A37F16DD38B624D7AB8F0D9CBD4B981, BC056C7D2C09D813703CDD63C1C69F44
- 20: F4E7AD474FCA153ABD670E43081ED09EB2C4CC1A, F244BD4D630272F0D98FCA04226C04F1
- 21: 039ECC36A0A16273E7246CA1FF19D213AC87B53F29, 3056DB6916C925DF220B6C9980EE141A
- 22: 7DE1DCDEF01447CA2FE83375A48DD84E4A7CB7C01992, 79AFEA4816EAF8DAC8A5E93960F1594F
- 23: A886C4B914BF0983003272F226F9B2197EF2DC05ACDDE0, B59D85A0FDA5FA4422F7203C055B97A9
- 24: 00B3E1E91448E250AAFB695C0643A6577AB453EFECFABF53, 4A7EFF1CBC1AB535122A017203616D85
- 25: 85E972E774D66D0531E40B8FE9E264A77B50FA883AB0943080, B18E164BF89B7E7AB0DC256DFEC7C72F
- 26: 004849E39334969B392CB0CF3FDEFB3D792DCBBC15F8328C7EDC, 3C51295711F5F878DE8F0B2B5A26A227
- 27: A0BAD6C2264AB1578993BA49E59D4598822FFED20A57D88F756FF1, 2EB9D525697A419A10DB2A84AEEA5FBC
- 28: C34DD806EAB5AD823D78BCA78A7709A705FC94ECC521A367D76C9588, 3C57580C7903039D645C06DBAF07B477
- 29: C447EC77512938CF7862388C32AF22ACE6B5E4CBAA998BE4F5CBC4D215, 43425D09B7ACFD90371C08953946A955
- 30: 2C16993AAE624CBA4CDAF34FE3D368559E6BE548292B281439866375013B, 3B7360C3FA8FB1C15D19F567153CB46C
- 31: 538E5DFAF14854A786851E4165F2E01CDDA963E318FCE4FB58E31A6B5CFC33, 2F8EA13B7A6873FE556CA535ABA0968B
- 32: 5E29CDB7D9695A110043E9C260104BDF020A3A2A139D4112E918AB584BDD7EDA, 9133213AA7BCF062D2BD37F866683D3F
-
-EAX-khazad (16 byte key)
- 0: , 75968E54452F6781
- 1: 95, ADAF5949F09B5A22
- 2: 6B8F, A06B201947424A11
- 3: 5BE668, 3251416625DF347A
- 4: 5A92E82B, 33E25772427D9786
- 5: 62F9F2ABCC, DE714F5F5D17D6D0
- 6: 0E3CD825BD8D, A7991C8CB8975ED9
- 7: 4AD0D999503AAD, 53A827D7886F7227
- 8: BB08E6FAED1DAEE8, 91A118749B7AB9F3
- 9: 16E30CB12E20D18495, F8F8B8C1280158F9
- 10: 616DBCC6346959D89E4A, 506BF35A70297D53
- 11: F86B022D4B28FDB1F0B7D3, EA42220C805FD759
- 12: 9B8A3D9CDBADD9BBCCCD2B28, BB478D3CE9A229C9
- 13: CDC4AB4EF2D5B46E87827241F0, 658EDB9497A91823
- 14: 1A113D96B21B4AEBDB13E34C381A, 63AD0C4084AC84B0
- 15: 14DA751E5AF7E01F35B3CE74EE1ACF, 3C76AB64E1724DCE
- 16: A13BBC7E408D2C550634CBC64690B8FE, 3D4BBC0C76536730
-
diff --git a/doc/examples/ecdsa.cpp b/doc/examples/ecdsa.cpp
deleted file mode 100644
index df1e1b93a..000000000
--- a/doc/examples/ecdsa.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/botan.h>
-#include <botan/ecdsa.h>
-#include <botan/pubkey.h>
-
-#include <memory>
-#include <iostream>
-
-using namespace Botan;
-
-int main()
- {
- Botan::LibraryInitializer init;
-
- try
- {
- AutoSeeded_RNG rng;
-
- EC_Domain_Params params("1.3.132.0.8");
-
- ECDSA_PrivateKey ecdsa(rng, params);
-
- ECDSA_PublicKey ecdsa_pub = ecdsa;
-
- /*
- std::cout << params.get_curve().get_p() << "\n";
- std::cout << params.get_order() << "\n";
- std::cout << X509::PEM_encode(ecdsa);
- std::cout << PKCS8::PEM_encode(ecdsa);
- */
-
- PK_Signer signer(ecdsa, "EMSA1(SHA-256)");
-
- const char* message = "Hello World";
-
- signer.update((const byte*)message, strlen(message));
-
- SecureVector<byte> sig = signer.signature(rng);
-
- std::cout << sig.size() << "\n";
-
- PK_Verifier verifier(ecdsa_pub, "EMSA1(SHA-256)");
-
- verifier.update((const byte*)message, strlen(message));
-
- bool ok = verifier.check_signature(sig);
- if(ok)
- std::cout << "Signature valid\n";
- else
- std::cout << "Bad signature\n";
- }
- catch(std::exception& e)
- {
- std::cout << e.what() << "\n";
- }
- }
diff --git a/doc/examples/encrypt.cpp b/doc/examples/encrypt.cpp
deleted file mode 100644
index 28017d875..000000000
--- a/doc/examples/encrypt.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-/*
-Encrypt a file using a block cipher in CBC mode. Compresses the plaintext
-with Zlib, MACs with HMAC(SHA-1). Stores the block cipher used in the file,
-so you don't have to specify it when decrypting.
-
-What a real application would do (and what this example should do), is test for
-the presence of the Zlib module, and use it only if it's available. Then add
-some marker to the stream so the other side knows whether or not the plaintext
-was compressed. Bonus points for supporting multiple compression schemes.
-
-Another flaw is that is stores the entire ciphertext in memory, so if the file
-you're encrypting is 1 Gb... you better have a lot of RAM.
-*/
-
-#include <fstream>
-#include <iostream>
-#include <string>
-#include <vector>
-#include <cstring>
-#include <memory>
-
-#include <botan/botan.h>
-
-#if defined(BOTAN_HAS_COMPRESSOR_ZLIB)
- #include <botan/zlib.h>
-#endif
-
-using namespace Botan;
-
-std::string b64_encode(const SecureVector<byte>&);
-
-int main(int argc, char* argv[])
- {
- if(argc < 2)
- {
- std::cout << "Usage: " << argv[0] << " [-c algo] -p passphrase file\n"
- " -p : Use this passphrase to encrypt\n"
- " -c : Encrypt with block cipher 'algo' (default 3DES)\n";
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- std::string algo = "TripleDES";
- std::string filename, passphrase;
-
- // Holy hell, argument processing is a PITA
- for(int j = 1; argv[j] != 0; j++)
- {
- if(std::strcmp(argv[j], "-c") == 0)
- {
- if(argv[j+1])
- {
- algo = argv[j+1];
- j++;
- }
- else
- {
- std::cout << "No argument for -c option" << std::endl;
- return 1;
- }
- }
- else if(std::strcmp(argv[j], "-p") == 0)
- {
- if(argv[j+1])
- {
- passphrase = argv[j+1];
- j++;
- }
- else
- {
- std::cout << "No argument for -p option" << std::endl;
- return 1;
- }
- }
- else
- {
- if(filename != "")
- {
- std::cout << "You can only specify one file at a time\n";
- return 1;
- }
- filename = argv[j];
- }
- }
-
- if(passphrase == "")
- {
- std::cout << "You have to specify a passphrase!" << std::endl;
- return 1;
- }
-
- std::ifstream in(filename.c_str(), std::ios::binary);
- if(!in)
- {
- std::cout << "ERROR: couldn't open " << filename << std::endl;
- return 1;
- }
-
- std::string outfile = filename + ".enc";
- std::ofstream out(outfile.c_str());
- if(!out)
- {
- std::cout << "ERROR: couldn't open " << outfile << std::endl;
- return 1;
- }
-
- try
- {
- const BlockCipher* cipher_proto = global_state().algorithm_factory().prototype_block_cipher(algo);
-
- if(!cipher_proto)
- {
- std::cout << "Don't know about the block cipher \"" << algo << "\"\n";
- return 1;
- }
-
- const u32bit key_len = cipher_proto->maximum_keylength();
- const u32bit iv_len = cipher_proto->block_size();
-
- AutoSeeded_RNG rng;
-
- std::auto_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(SHA-1)"));
-
- SecureVector<byte> salt(8);
- rng.randomize(&salt[0], salt.size());
-
- const u32bit PBKDF2_ITERATIONS = 8192;
-
- SymmetricKey bc_key = pbkdf->derive_key(key_len, "BLK" + passphrase,
- &salt[0], salt.size(),
- PBKDF2_ITERATIONS);
-
- InitializationVector iv = pbkdf->derive_key(iv_len, "IVL" + passphrase,
- &salt[0], salt.size(),
- PBKDF2_ITERATIONS);
-
- SymmetricKey mac_key = pbkdf->derive_key(16, "MAC" + passphrase,
- &salt[0], salt.size(),
- PBKDF2_ITERATIONS);
-
- // Just to be all fancy we even write a (simple) header.
- out << "-------- ENCRYPTED FILE --------" << std::endl;
- out << algo << std::endl;
- out << b64_encode(salt) << std::endl;
-
- Pipe pipe(new Fork(
- new Chain(new MAC_Filter("HMAC(SHA-1)", mac_key),
- new Base64_Encoder
- ),
- new Chain(
-#ifdef BOTAN_HAS_COMPRESSOR_ZLIB
- new Zlib_Compression,
-#endif
- get_cipher(algo + "/CBC", bc_key, iv, ENCRYPTION),
- new Base64_Encoder(true)
- )
- )
- );
-
- pipe.start_msg();
- in >> pipe;
- pipe.end_msg();
-
- out << pipe.read_all_as_string(0) << std::endl;
- out << pipe.read_all_as_string(1);
-
- }
- catch(Algorithm_Not_Found)
- {
- std::cout << "Don't know about the block cipher \"" << algo << "\"\n";
- return 1;
- }
- catch(std::exception& e)
- {
- std::cout << "Exception caught: " << e.what() << std::endl;
- return 1;
- }
- return 0;
- }
-
-std::string b64_encode(const SecureVector<byte>& in)
- {
- Pipe pipe(new Base64_Encoder);
- pipe.process_msg(in);
- return pipe.read_all_as_string();
- }
diff --git a/doc/examples/encrypt2.cpp b/doc/examples/encrypt2.cpp
deleted file mode 100644
index 41f4fb478..000000000
--- a/doc/examples/encrypt2.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/botan.h>
-#include <botan/pbkdf2.h>
-#include <botan/hmac.h>
-#include <botan/sha160.h>
-
-#include <fstream>
-
-using namespace Botan;
-
-int main()
- {
- Botan::LibraryInitializer init;
-
- AutoSeeded_RNG rng;
-
- std::string passphrase = "secret";
-
- std::ifstream infile("readme.txt");
- std::ofstream outfile("readme.txt.enc");
-
- PKCS5_PBKDF2 pbkdf2(new HMAC(new SHA_160));
-
- const u32bit PBKDF2_ITERATIONS = 8192;
-
- SecureVector<byte> salt(8);
- rng.randomize(&salt[0], salt.size());
-
- SecureVector<byte> master_key = pbkdf2.derive_key(48, passphrase,
- &salt[0], salt.size(),
- PBKDF2_ITERATIONS).bits_of();
-
- KDF* kdf = get_kdf("KDF2(SHA-1)");
-
- SymmetricKey key = kdf->derive_key(20, master_key, "cipher key");
-
- SymmetricKey mac_key = kdf->derive_key(20, master_key, "hmac key");
-
- InitializationVector iv = kdf->derive_key(8, master_key, "cipher iv");
-
- Pipe pipe(new Fork(
- new Chain(
- get_cipher("Blowfish/CBC/PKCS7", key, iv, ENCRYPTION),
- new Base64_Encoder,
- new DataSink_Stream(outfile)
- ),
- new Chain(
- new MAC_Filter("HMAC(SHA-1)", mac_key),
- new Hex_Encoder)
- )
- );
-
- outfile.write((const char*)salt.begin(), salt.size());
-
- pipe.start_msg();
- infile >> pipe;
- pipe.end_msg();
-
- SecureVector<byte> hmac = pipe.read_all(1);
- outfile.write((const char*)hmac.begin(), hmac.size());
- }
diff --git a/doc/examples/factor.cpp b/doc/examples/factor.cpp
deleted file mode 100644
index 58b12d9a5..000000000
--- a/doc/examples/factor.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
-* (C) 2009-2010 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*
-* Factor integers using a combination of trial division by small
-* primes, and Pollard's Rho algorithm
-*/
-
-#include <botan/botan.h>
-#include <botan/reducer.h>
-#include <botan/numthry.h>
-using namespace Botan;
-
-#include <algorithm>
-#include <iostream>
-#include <iterator>
-
-namespace {
-
-/*
-* Pollard's Rho algorithm, as described in the MIT algorithms book. We
-* use (x^2+x) mod n instead of (x*2-1) mod n as the random function,
-* it _seems_ to lead to faster factorization for the values I tried.
-*/
-BigInt rho(const BigInt& n, RandomNumberGenerator& rng)
- {
- BigInt x = BigInt::random_integer(rng, 0, n-1);
- BigInt y = x;
- BigInt d = 0;
-
- Modular_Reducer mod_n(n);
-
- u32bit i = 1, k = 2;
- while(true)
- {
- i++;
-
- if(i == 0) // overflow, bail out
- break;
-
- x = mod_n.multiply((x + 1), x);
-
- d = gcd(y - x, n);
- if(d != 1 && d != n)
- return d;
-
- if(i == k)
- {
- y = x;
- k = 2*k;
- }
- }
- return 0;
- }
-
-// Remove (and return) any small (< 2^16) factors
-std::vector<BigInt> remove_small_factors(BigInt& n)
- {
- std::vector<BigInt> factors;
-
- while(n.is_even())
- {
- factors.push_back(2);
- n /= 2;
- }
-
- for(u32bit j = 0; j != PRIME_TABLE_SIZE; j++)
- {
- if(n < PRIMES[j])
- break;
-
- BigInt x = gcd(n, PRIMES[j]);
-
- if(x != 1)
- {
- n /= x;
-
- u32bit occurs = 0;
- while(x != 1)
- {
- x /= PRIMES[j];
- occurs++;
- }
-
- for(u32bit k = 0; k != occurs; k++)
- factors.push_back(PRIMES[j]);
- }
- }
-
- return factors;
- }
-
-std::vector<BigInt> factorize(const BigInt& n_in,
- RandomNumberGenerator& rng)
- {
- BigInt n = n_in;
- std::vector<BigInt> factors = remove_small_factors(n);
-
- while(n != 1)
- {
- if(check_prime(n, rng))
- {
- factors.push_back(n);
- break;
- }
-
- BigInt a_factor = 0;
- while(a_factor == 0)
- a_factor = rho(n, rng);
-
- std::vector<BigInt> rho_factored = factorize(a_factor, rng);
- for(u32bit j = 0; j != rho_factored.size(); j++)
- factors.push_back(rho_factored[j]);
-
- n /= a_factor;
- }
- return factors;
- }
-
-}
-
-int main(int argc, char* argv[])
- {
- if(argc != 2)
- {
- std::cerr << "Usage: " << argv[0] << " integer\n";
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- try
- {
- BigInt n(argv[1]);
-
- AutoSeeded_RNG rng;
-
- std::vector<BigInt> factors = factorize(n, rng);
- std::sort(factors.begin(), factors.end());
-
- std::cout << n << ": ";
- std::copy(factors.begin(),
- factors.end(),
- std::ostream_iterator<BigInt>(std::cout, " "));
- std::cout << "\n";
- }
- catch(std::exception& e)
- {
- std::cout << e.what() << std::endl;
- return 1;
- }
- return 0;
- }
diff --git a/doc/examples/fpe.cpp b/doc/examples/fpe.cpp
deleted file mode 100644
index 9b18d4879..000000000
--- a/doc/examples/fpe.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-/*
-* Encrypt credit cards numbers with valid checksums into other credit
-* card numbers with valid checksums using format preserving encryption.
-*/
-
-#include <botan/fpe.h>
-#include <botan/sha160.h>
-#include <botan/init.h>
-
-using namespace Botan;
-
-#include <iostream>
-#include <stdexcept>
-
-namespace {
-
-byte luhn_checksum(u64bit cc_number)
- {
- byte sum = 0;
-
- bool alt = false;
- while(cc_number)
- {
- byte digit = cc_number % 10;
- if(alt)
- {
- digit *= 2;
- if(digit > 9)
- digit -= 9;
- }
-
- sum += digit;
-
- cc_number /= 10;
- alt = !alt;
- }
-
- return (sum % 10);
- }
-
-bool luhn_check(u64bit cc_number)
- {
- return (luhn_checksum(cc_number) == 0);
- }
-
-u64bit cc_rank(u64bit cc_number)
- {
- // Remove Luhn checksum
- return cc_number / 10;
- }
-
-u64bit cc_derank(u64bit cc_number)
- {
- for(u32bit i = 0; i != 10; ++i)
- if(luhn_check(cc_number * 10 + i))
- return (cc_number * 10 + i);
- return 0;
- }
-
-/*
-* Use the SHA-1 hash of the account name or ID as a tweak
-*/
-SecureVector<byte> sha1(const std::string& acct_name)
- {
- SHA_160 hash;
- hash.update(acct_name);
- return hash.final();
- }
-
-u64bit encrypt_cc_number(u64bit cc_number,
- const SymmetricKey& key,
- const std::string& acct_name)
- {
- BigInt n = 1000000000000000;
-
- u64bit cc_ranked = cc_rank(cc_number);
-
- BigInt c = fpe_encrypt(n, cc_ranked, key, sha1(acct_name));
-
- if(c.bits() > 50)
- throw std::runtime_error("FPE produced a number too large");
-
- u64bit enc_cc = 0;
- for(u32bit i = 0; i != 7; ++i)
- enc_cc = (enc_cc << 8) | c.byte_at(6-i);
- return cc_derank(enc_cc);
- }
-
-u64bit decrypt_cc_number(u64bit enc_cc,
- const SymmetricKey& key,
- const std::string& acct_name)
- {
- BigInt n = 1000000000000000;
-
- u64bit cc_ranked = cc_rank(enc_cc);
-
- BigInt c = fpe_decrypt(n, cc_ranked, key, sha1(acct_name));
-
- if(c.bits() > 50)
- throw std::runtime_error("FPE produced a number too large");
-
- u64bit dec_cc = 0;
- for(u32bit i = 0; i != 7; ++i)
- dec_cc = (dec_cc << 8) | c.byte_at(6-i);
- return cc_derank(dec_cc);
- }
-
-}
-
-int main(int argc, char* argv[])
- {
- LibraryInitializer init;
-
- if(argc != 4)
- {
- std::cout << "Usage: " << argv[0] << " cc-number acct-name passwd\n";
- return 1;
- }
-
- u64bit cc_number = atoll(argv[1]);
- std::string acct_name = argv[2];
- std::string passwd = argv[3];
-
- std::cout << "Input was: " << cc_number << ' '
- << luhn_check(cc_number) << '\n';
-
- /**
- * In practice something like PBKDF2 with a salt and high iteration
- * count would be a good idea.
- */
- SymmetricKey key = sha1(passwd);
-
- u64bit enc_cc = encrypt_cc_number(cc_number, key, acct_name);
-
- std::cout << "Encrypted: " << enc_cc
- << ' ' << luhn_check(enc_cc) << '\n';
-
- u64bit dec_cc = decrypt_cc_number(enc_cc, key, acct_name);
-
- std::cout << "Decrypted: " << dec_cc
- << ' ' << luhn_check(dec_cc) << '\n';
-
- if(dec_cc != cc_number)
- std::cout << "Something went wrong :( Bad CC checksum?\n";
- }
diff --git a/doc/examples/gen_certs.cpp b/doc/examples/gen_certs.cpp
deleted file mode 100644
index f8c9fe124..000000000
--- a/doc/examples/gen_certs.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-/*
-* Generate a root CA plus httpd, dovecot, and postfix certs/keys
-*
-*/
-
-#include <botan/botan.h>
-#include <botan/rsa.h>
-#include <botan/time.h>
-#include <botan/x509self.h>
-#include <botan/x509_ca.h>
-
-using namespace Botan;
-
-#include <iostream>
-#include <fstream>
-
-namespace {
-
-void fill_commoninfo(X509_Cert_Options& opts)
- {
- opts.country = "US";
- opts.organization = "randombit.net";
- opts.email = "[email protected]";
- opts.locality = "Vermont";
- }
-
-X509_Certificate make_ca_cert(RandomNumberGenerator& rng,
- const Private_Key& priv_key,
- const X509_Time& now,
- const X509_Time& later)
- {
- X509_Cert_Options opts;
- fill_commoninfo(opts);
- opts.common_name = "randombit.net CA";
- opts.start = now;
- opts.end = later;
- opts.CA_key();
-
- return X509::create_self_signed_cert(opts, priv_key, "SHA-256", rng);
- }
-
-PKCS10_Request make_server_cert_req(const Private_Key& key,
- const std::string& hostname,
- RandomNumberGenerator& rng)
- {
- X509_Cert_Options opts;
- opts.common_name = hostname;
- fill_commoninfo(opts);
-
- opts.add_ex_constraint("PKIX.ServerAuth");
-
- return X509::create_cert_req(opts, key, "SHA-1", rng);
- }
-
-void save_pair(const std::string& name,
- const std::string& password,
- const X509_Certificate& cert,
- const Private_Key& key,
- RandomNumberGenerator& rng)
- {
- std::string cert_fsname = name + "_cert.pem";
- std::string key_fsname = name + "_key.pem";
-
- std::ofstream cert_out(cert_fsname.c_str());
- cert_out << cert.PEM_encode() << "\n";
- cert_out.close();
-
- std::ofstream key_out(key_fsname.c_str());
- if(password != "")
- key_out << PKCS8::PEM_encode(key, rng, password);
- else
- key_out << PKCS8::PEM_encode(key);
- key_out.close();
- }
-
-}
-
-int main()
- {
- const u32bit seconds_in_a_year = 31556926;
-
- const u32bit current_time = system_time();
-
- X509_Time now = X509_Time(current_time);
- X509_Time later = X509_Time(current_time + 4*seconds_in_a_year);
-
- LibraryInitializer init;
-
- AutoSeeded_RNG rng;
-
- RSA_PrivateKey ca_key(rng, 2048);
-
- X509_Certificate ca_cert = make_ca_cert(rng, ca_key, now, later);
-
- const std::string ca_password = "sekrit";
-
- save_pair("ca", ca_password, ca_cert, ca_key, rng);
-
- X509_CA ca(ca_cert, ca_key, "SHA-256");
-
- RSA_PrivateKey httpd_key(rng, 1536);
- X509_Certificate httpd_cert = ca.sign_request(
- make_server_cert_req(httpd_key, "www.randombit.net", rng),
- rng, now, later);
-
- save_pair("httpd", "", httpd_cert, httpd_key, rng);
-
- RSA_PrivateKey bugzilla_key(rng, 1536);
- X509_Certificate bugzilla_cert = ca.sign_request(
- make_server_cert_req(bugzilla_key, "bugs.randombit.net", rng),
- rng, now, later);
-
- save_pair("bugzilla", "", bugzilla_cert, bugzilla_key, rng);
-
- RSA_PrivateKey postfix_key(rng, 1536);
- X509_Certificate postfix_cert = ca.sign_request(
- make_server_cert_req(postfix_key, "mail.randombit.net", rng),
- rng, now, later);
-
- save_pair("postfix", "", postfix_cert, postfix_key, rng);
-
- RSA_PrivateKey dovecot_key(rng, 1536);
- X509_Certificate dovecot_cert = ca.sign_request(
- make_server_cert_req(dovecot_key, "imap.randombit.net", rng),
- rng, now, later);
-
- save_pair("dovecot", "", dovecot_cert, dovecot_key, rng);
- }
diff --git a/doc/examples/gtk/Makefile b/doc/examples/gtk/Makefile
deleted file mode 100644
index 10e069bb3..000000000
--- a/doc/examples/gtk/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-
-LIBS=$(shell botan-config --libs) $(shell pkg-config --libs gtk+-2.0)
-IFLAGS=$(shell botan-config --cflags) $(shell pkg-config --cflags gtk+-2.0)
-
-CXX = g++
-CXXFLAGS = -Wall -W $(IFLAGS)
-
-dsa: gtk_ui.o dsa.o
- $(CXX) $^ $(LIBS) -o $@
-
-gtk_ui.o: gtk_ui.cpp gtk_ui.h
- $(CXX) $(CXXFLAGS) -c $< -o $@
-
-dsa.o: dsa.cpp gtk_ui.h
- $(CXX) $(CXXFLAGS) -c $< -o $@
-
-clean:
- rm -f dsa *.o
diff --git a/doc/examples/gtk/dsa.cpp b/doc/examples/gtk/dsa.cpp
deleted file mode 100644
index 2cd91b0e8..000000000
--- a/doc/examples/gtk/dsa.cpp
+++ /dev/null
@@ -1,566 +0,0 @@
-/*
- This shows some of the details involved in a GUI application that uses
- Botan. Actually most of the code is just dealing with GTK+, but it shows how
- the password callback and pulse function stuff works. (See gtk_ui.cpp for the
- acutal password callback code.)
-
- The major points of interest (assuming what you care about is how to use
- Botan from a GUI, and not looking at my terrible GTK code) are gtk_ui.cpp
- and, in this file, GTK_Pulse, gen_key(), and get_key():
-
- gtk_ui.cpp and get_key() show how to get a passphrase from a user for
- decrypting (well, in theory, anything), but in this case, PKCS #8 private
- keys. Which is coincidentally the only thing Botan currently uses UI
- objects for, though that will probably change eventually. GTK_UI does
- double duty, for getting passphrases for encryption as well (in
- do_save_key).
-
- gen_key() and GTK_Pulse show how to do an activity meter while doing a
- long-term operation inside Botan. Since, typically, the only operations
- which take a long time and can't be broken up into smaller parts are prime
- generation/testing, that is currently where the pulse hooks are
- called. It's certainly not the most general callback method in the world,
- but it's general enough that it's usable without getting in the way too
- much. The callbacks will eventually be extended to other parts of the
- library (Pipe, maybe) where it's useful.
-
- This program is in the public domain.
-*/
-#include <fstream>
-#include <iostream>
-#include <memory>
-
-#include <botan/botan.h>
-#include <botan/libstate.h>
-#include <botan/look_pk.h>
-#include <botan/filters.h>
-#include <botan/pk_filts.h>
-#include <botan/dsa.h>
-
-// we don't have a 'using namespace' here, so it's easy to grep for code that
-// is actually dealing with the library (rather than messing around with GTK).
-
-#include <gtk/gtk.h>
-#include "gtk_ui.h"
-
-static Botan::RandomNumberGenerator* rng = 0;
-
-/*
-* Pop up an message box
-*/
-static void show_dialog(const std::string& about_message,
- const std::string& dialog_name)
- {
- GtkDialogFlags flags =
- (GtkDialogFlags)(GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL);
-
- GtkWidget* dialog = gtk_dialog_new_with_buttons(dialog_name.c_str(),
- NULL, flags,
- GTK_STOCK_OK,
- GTK_RESPONSE_NONE,
- NULL);
- GtkWidget* label = gtk_label_new(NULL);
- gtk_label_set_markup(GTK_LABEL(label), about_message.c_str());
- gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
-
- g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
- G_CALLBACK(gtk_widget_destroy),
- GTK_OBJECT(dialog));
-
- gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
- gtk_widget_show_all(dialog);
- }
-
-/*
-* Pop up an About box
-*/
-static void show_about()
- {
- const std::string about_message =
- "<big>DSA Utility</big>\n"
- "\n"
- "A simple application showing how to use Botan within a GUI.\n"
- "It lets you generate or load keys, and sign text files.\n"
- "\n"
- "Send comments/questions to <tt>[email protected]</tt>";
-
- show_dialog(about_message, "About");
- }
-
-/*
-* Pop up a help box
-*/
-static void show_help()
- {
- const std::string help_message =
- "<big>DSA Utility Help</big>\n"
- "\n"
- "Simply, this is a (very) simple text editor, with the added ability\n"
- "of being able to generate or read a DSA private key, and sign the\n"
- "text buffer using that key.\n"
- "\n"
- "You can load, edit, and save text files as you would normally. If a\n"
- "key is loaded (done using the commands in the Keys menu), you can\n"
- "also use the Sign command (in the Signing menu) to generate a\n"
- "signature for the current file. It will be displayed at the bottom\n"
- "of the screen (if it has been calculated for the current buffer\n"
- "contents), and can be saved using the \"Save Sig\" command.\n"
- "\n"
- "Signatures generated by this program can be verified using a the\n"
- "<tt>dsa_ver</tt> example included in the Botan distribution.\n";
-
- show_dialog(help_message, "Help");
- }
-
-/*
-* Get and return a filename from the user
-*/
-static std::string get_filename(const std::string& title)
- {
- GtkWidget* dialog = gtk_file_selection_new(title.c_str());
-
- /* Some window managers don't display the titles of transient windows,
- put a message elsewhere for those people.
- */
- GtkWidget* label = gtk_label_new(title.c_str());
- gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
-
- std::string fsname;
-
- gtk_widget_show(label); /* dialog_run won't show sub-widgets */
- if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
- fsname = gtk_file_selection_get_filename(GTK_FILE_SELECTION(dialog));
- gtk_widget_destroy(dialog);
-
- /* If it's a directory, that's no good */
- if(fsname.size() && fsname[fsname.size()-1] == '/')
- return "";
-
- return fsname;
- }
-
-/*
-* Global state
-*/
-static Botan::DSA_PrivateKey* key = 0; // our key
-static GtkTextBuffer* buffer = 0; // the text buffer
-static std::string buffer_source;
- // what file (if any) the buffer's data came from
-static GtkWidget* sig_view = 0; // the signature
-
-/*
-* Zap the currently set signature (if any)
-*/
-static void zap_sig()
- {
- gtk_editable_delete_text(GTK_EDITABLE(sig_view), 0, -1);
- }
-
-/*
-* Save the current key
-*/
-static void do_save_key(const std::string& title)
- {
- if(key == 0)
- return;
-
- std::string filename = get_filename(title.c_str());
-
- if(filename != "")
- {
- const std::string msg = "Select a passphrase to encrypt the key:";
-
- std::ofstream out_priv(filename.c_str());
-
- GTK_UI ui;
- Botan::User_Interface::UI_Result result;
- std::string passphrase = ui.get_passphrase(msg, result);
-
- if(result == Botan::User_Interface::OK)
- out_priv << Botan::PKCS8::PEM_encode(*key, *rng, passphrase);
- else
- out_priv << Botan::PKCS8::PEM_encode(*key);
-
- // for testing
- //std::cout << X509::PEM_encode(*key);
- }
- }
-
-/*
-* Generate a signature for the text buffer
-*/
-static void sign_buffer()
- {
- /* No key? Ignore request. */
- if(key == 0)
- return;
-
- /* same format as the text-mode dsa_sign example */
- Botan::Pipe pipe(new Botan::PK_Signer_Filter(
- Botan::get_pk_signer(*key, "EMSA1(SHA-1)"), *rng
- ),
- new Botan::Base64_Encoder
- );
-
- /* It would probably be smart to do this a little bit at a time */
- GtkTextIter start, end;
- gtk_text_buffer_get_bounds(buffer, &start, &end);
- gchar* bits = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
- size_t length = strlen(bits);
-
- pipe.start_msg();
- pipe.write((unsigned char*)bits, length);
- pipe.end_msg();
-
- std::string sig = pipe.read_all_as_string();
-
- zap_sig();
-
- gint position = 0;
- gtk_editable_insert_text(GTK_EDITABLE(sig_view), sig.c_str(), sig.length(),
- &position);
-
- g_free(bits);
- }
-
-#if 0
-/*
-* GTK+ pulse callback
-*/
-class GTK_Pulse : public Botan::Library_State::UI
- {
- public:
- void pulse(Botan::Pulse_Type);
- };
-
-void GTK_Pulse::pulse(Botan::Pulse_Type)
- {
- /* We need this to flush the updates, otherwise GTK+ will wait until we're
- done with the computation before doing any updates (generally the right
- thing, but not with a progress bar).
- */
-
- while(gtk_events_pending())
- gtk_main_iteration();
- }
-#endif
-
-/*
-* Actual do the pulse (as a GTK+ timeout func) *
-*/
-static gboolean gtk_pulse_timeout(void* pbar)
- {
- GtkWidget* progress_bar = (GtkWidget*)pbar;
- gtk_progress_bar_pulse(GTK_PROGRESS_BAR(progress_bar));
- return TRUE; /* keep calling us */
- }
-
-/*
-* Generate a new key
-*/
-static void gen_key()
- {
- /* This gives a nice smooth progress bar, though we do use up quite a bit of
- CPU for it. Keep in mind that if PULSE_INTERVAL is significantly less
- than the average time between pulses from the library, the progress bar
- will jerk around going slower or faster. Keep it at at least 50ms.
- */
- const double PROGRESS_PER_PULSE = .01; /* % of bar */
- const guint32 PULSE_INTERVAL = 30; /* ms */
-
- delete key;
-
- GtkDialogFlags flags =
- (GtkDialogFlags)(GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL);
-
- GtkWidget* dialog =
- gtk_dialog_new_with_buttons("Generating Key", NULL, flags, NULL);
-
- GtkWidget* label = gtk_label_new(" Generating new key, please wait... \n");
- gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
-
- GtkWidget* progress_bar = gtk_progress_bar_new();
- gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(progress_bar),
- PROGRESS_PER_PULSE);
- gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), progress_bar);
-
- guint timer_id = gtk_timeout_add(PULSE_INTERVAL, gtk_pulse_timeout,
- progress_bar);
-
- gtk_widget_show_all(dialog);
-
- while(gtk_events_pending())
- gtk_main_iteration();
-
- /* Register gtk_pulse so it will be called every so often when we embark
- on our prime generation quest...
- */
- /* this just updates the GUI; the GTK+ timeout function actually updates
- the progress bar. That's because the amount of time between pulses
- from the library is rather irregular, so the progress bar looks jerky.
- */
- //Botan::global_state().set_ui(new GTK_Pulse);
-
- /* Not generally recommended, since it's slow and there's not much point.
- However, *because* it's slow, we'll want to put up a progress bar or
- something, and part of this whole thing is to show how to do that and get
- the pulse functions to do the right thing.
- */
- Botan::DL_Group group(*rng, Botan::DL_Group::DSA_Kosherizer, 1024);
- key = new Botan::DSA_PrivateKey(*rng, group);
-
- gtk_timeout_remove(timer_id);
- //Botan::global_state().set_ui(0); // unset the pulse function
-
- gtk_widget_destroy(dialog);
-
- do_save_key("Save New Key");
-
- /* new key, any old sigs are no longer useful */
- zap_sig();
- }
-
-/*
-* Load up a key
-*/
-static void get_key()
- {
- std::string fsname = get_filename("Select a DSA Key");
-
- if(fsname != "")
- {
- try {
- delete key;
- key = 0;
- zap_sig();
-
- /*
- A GTK_UI is a subclass of User_Interface that pops up a dialog that
- asks the user for a passphrase. It actually works quite well,
- though the fixed upper limit on the passphrase size is not
- ideal. Feel free to use it as-is or modify it however you like
- (gtk_ui.* is public domain).
- */
- GTK_UI ui;
- Botan::PKCS8_PrivateKey* p8_key =
- Botan::PKCS8::load_key(fsname, *rng, ui);
-
- key = dynamic_cast<Botan::DSA_PrivateKey*>(p8_key);
- if(!key)
- show_dialog("The key in " + fsname + " is not a DSA key",
- "Failure");
- }
- catch(std::exception)
- {
- key = 0; // make sure it's not something random
- show_dialog("Loading the key from " + fsname + " failed.", "Failure");
- }
- }
- }
-
-static void really_sign_buffer()
- {
- /* No key? Ask the user for one. */
- if(key == 0)
- get_key();
- sign_buffer();
- }
-
-/*
-* Clear the text buffer
-*/
-static void new_buffer()
- {
- /*
- In theory, it would be nice to check if this was unsaved text and prompt
- to save it. However, this really isn't supposed to be a GTK+ example, so
- we won't.
- */
- gtk_text_buffer_set_text(buffer, "", -1);
- buffer_source = "";
- }
-
-/*
-* Put the contents of a file into the buffer
-*/
-static void open_buffer()
- {
- std::string filename = get_filename("Select File");
-
- if(filename == "")
- return;
-
- std::ifstream in(filename.c_str());
-
- new_buffer();
- buffer_source = filename;
-
- while(in.good())
- {
- char buf[1024] = { 0 };
-
- in.read(buf, 1024);
- size_t got = in.gcount();
-
- GtkTextIter iter;
- gtk_text_buffer_get_end_iter(buffer, &iter);
- gtk_text_buffer_insert(buffer, &iter, buf, got);
- }
- }
-
-/*
-* Save the signature to a file
-*/
-static void save_sig()
- {
- std::string sig_file = buffer_source;
-
- /* No sig, nothing to save */
- const gchar* sig = gtk_entry_get_text(GTK_ENTRY(sig_view));
- if(strlen(sig) == 0)
- return;
-
- if(sig_file == "")
- sig_file = get_filename("Select Signature Output File");
- else
- sig_file += ".sig";
-
- std::ofstream out(sig_file.c_str());
- out << sig << std::endl;
- }
-
-/*
-* Save the current key
-*/
-static void save_key()
- {
- do_save_key("Save Current Key");
- }
-
-/*
-* Common case of Save/Save As
-*/
-static void do_save(const std::string& filename)
- {
- std::ofstream out(filename.c_str());
-
- GtkTextIter start, end;
- gtk_text_buffer_get_bounds(buffer, &start, &end);
- gchar* bits = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
- out.write(bits, strlen(bits));
- g_free(bits);
- buffer_source = filename;
- }
-
-/*
-* Save the buffer
-*/
-static void save_buffer_as()
- {
- std::string filename = get_filename("Select Output File");
- if(filename != "")
- do_save(filename);
- }
-
-/*
-* Save the buffer
-*/
-static void save_buffer()
- {
- if(buffer_source != "")
- do_save(buffer_source);
- else
- save_buffer_as();
- }
-
-/*
-* Make a menubar for the app
-*/
-static GtkWidget* make_menubar(GtkWidget *window)
- {
- static GtkItemFactoryEntry menu_items[] = {
- { "/_File", NULL, NULL, 0, "<Branch>", NULL },
- { "/File/_New", "<control>N", new_buffer, 0, NULL, NULL },
- { "/File/_Open", "<control>O", open_buffer, 0, NULL, NULL },
- { "/File/_Save", "<control>S", save_buffer, 0, NULL, NULL },
- { "/File/Save _As", NULL, save_buffer_as, 0, NULL, NULL },
- { "/File/sep1", NULL, NULL, 0, "<Separator>", NULL },
- { "/File/Save Sig", NULL, save_sig, 0, NULL, NULL },
- { "/File/sep2", NULL, NULL, 0, "<Separator>", NULL },
- { "/File/_Quit", "<control>Q", gtk_main_quit, 0, NULL, NULL },
-
- { "/_Keys", NULL, NULL, 0, "<Branch>", NULL },
- { "/Keys/Open", NULL, get_key, 0, NULL, NULL },
- { "/Keys/_Generate", NULL, gen_key, 0, NULL, NULL },
- { "/Keys/Save Current", NULL, save_key, 0, NULL, NULL },
-
- { "/Signing", NULL, NULL, 0, "<Branch>", NULL },
- { "/Signing/Sign", NULL, really_sign_buffer, 0, NULL, NULL },
-
- { "/_Help", NULL, NULL, 0, "<LastBranch>", NULL },
- { "/Help/Help", NULL, show_help, 0, NULL, NULL },
- { "/Help/sep1", NULL, NULL, 0, "<Separator>", NULL },
- { "/Help/About", NULL, show_about, 0, NULL, NULL },
- };
-
- GtkAccelGroup* accel_group = gtk_accel_group_new();
- GtkItemFactory* item_factory =
- gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accel_group);
- const gint nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
- gtk_item_factory_create_items(item_factory, nmenu_items, menu_items, NULL);
- gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
- return gtk_item_factory_get_widget(item_factory, "<main>");
- }
-
-int main(int argc, char *argv[])
- {
- gtk_init(&argc, &argv);
-
- try {
- Botan::LibraryInitializer init;
-
- rng = new Botan::AutoSeeded_RNG;
-
- /* Create a new top-level window */
- GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title(GTK_WINDOW(window), "DSA Utility");
- gtk_signal_connect(GTK_OBJECT(window), "delete_event",
- gtk_main_quit, NULL);
-
- /* Create the vbox to hold our stuff */
- GtkWidget* vbox = gtk_vbox_new(FALSE, 0);
- gtk_container_border_width(GTK_CONTAINER(vbox), 1);
- gtk_container_add(GTK_CONTAINER(window), vbox);
-
- /* Create the menu bar */
- GtkWidget *menubar = make_menubar(window);
-
- /* Create the entry that holds the signature */
- sig_view = gtk_entry_new();
- gtk_editable_set_editable(GTK_EDITABLE(sig_view), FALSE);
-
- /* Create the text box */
- GtkWidget* view = gtk_text_view_new();
- buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
-
- gtk_widget_set_size_request(view, 640, 480);
- gtk_text_buffer_set_text(buffer, "Some initial contents.", -1);
-
- // Resign it on each change: fast enough, but probably not really useful
- //g_signal_connect(G_OBJECT(buffer), "changed", sign_buffer, 0);
- g_signal_connect(G_OBJECT(buffer), "changed", zap_sig, 0);
-
- gtk_container_add(GTK_CONTAINER(vbox), menubar);
- gtk_container_add(GTK_CONTAINER(vbox), view);
- gtk_container_add(GTK_CONTAINER(vbox), sig_view);
-
- gtk_widget_show_all(window);
-
- gtk_main();
- }
- catch(std::exception& e)
- {
- std::cout << e.what() << std::endl;
- }
- return 0;
- }
diff --git a/doc/examples/gtk/gtk_ui.cpp b/doc/examples/gtk/gtk_ui.cpp
deleted file mode 100644
index d4e9cd238..000000000
--- a/doc/examples/gtk/gtk_ui.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-* GTK+ User Interface Source File
-*/
-
-#include "gtk_ui.h"
-#include <cstring>
-
-/*
-* GTK+ Callback *
-*/
-void GTK_UI::callback(GtkWidget* entry, gpointer passphrase_ptr)
- {
- const gchar *entry_text = gtk_entry_get_text(GTK_ENTRY(entry));
- char* passphrase = (char*)passphrase_ptr;
- std::strcpy(passphrase, entry_text);
- }
-
-/*
-* Get a passphrase from the user
-*/
-std::string GTK_UI::get_passphrase(const std::string& what,
- const std::string& source,
- UI_Result& result) const
- {
- std::string msg = "A passphrase is needed to access the " + what;
- if(source != "") msg += "\nin " + source;
- return get_passphrase(msg, result);
- }
-
-/*
-* Get a passphrase from the user
-*/
-std::string GTK_UI::get_passphrase(const std::string& label_text,
- UI_Result& result) const
- {
- const int MAX_PASSPHRASE = 64;
-
- GtkDialogFlags flags =
- (GtkDialogFlags)(GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL);
-
- GtkWidget* dialog = gtk_dialog_new_with_buttons(
- "Enter Passphrase",
- NULL, flags,
- GTK_STOCK_OK, GTK_RESPONSE_OK,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- NULL);
-
- gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
-
- GtkWidget* label = gtk_label_new(label_text.c_str());
-
- GtkWidget* entry = gtk_entry_new();
- gtk_entry_set_visibility(GTK_ENTRY(entry), 0);
- gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
- gtk_entry_set_max_length(GTK_ENTRY(entry), MAX_PASSPHRASE);
-
- char passphrase_buf[MAX_PASSPHRASE + 1] = { 0 };
-
- gtk_signal_connect(GTK_OBJECT(entry), "activate",
- GTK_SIGNAL_FUNC(callback), passphrase_buf);
-
- GtkWidget* vbox = gtk_vbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 0);
-
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), vbox, TRUE, TRUE, 0);
- gtk_widget_show_all(vbox);
-
- /* Block until we get something back */
- result = CANCEL_ACTION;
- if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
- result = OK;
-
- gtk_widget_destroy(dialog);
-
- if(result == OK)
- return std::string(passphrase_buf);
- return "";
- }
diff --git a/doc/examples/gtk/gtk_ui.h b/doc/examples/gtk/gtk_ui.h
deleted file mode 100644
index 065a4f76b..000000000
--- a/doc/examples/gtk/gtk_ui.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
-* (C) 2006 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#ifndef BOTAN_EXT_GTK_UI__
-#define BOTAN_EXT_GTK_UI__
-
-#include <botan/ui.h>
-#include <gtk/gtk.h>
-
-/*
-* GTK+ Passphrase Callback Object
-*/
-class GTK_UI : public Botan::User_Interface
- {
- public:
- std::string get_passphrase(const std::string&, const std::string&,
- UI_Result&) const;
-
- std::string get_passphrase(const std::string&, UI_Result&) const;
-
- static void callback(GtkWidget*, gpointer);
- };
-
-#endif
diff --git a/doc/examples/gtk/readme.txt b/doc/examples/gtk/readme.txt
deleted file mode 100644
index 4f3691166..000000000
--- a/doc/examples/gtk/readme.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-
-This is an example of how to use Botan in a GUI. You need at least
-Botan 1.6.0.
-
-You'll also need GTK+ 2.x (tested with GTK+ 2.10; should work with
-most versions). Keep in mind that I was learning GTK as I was writing
-this code, so it is not exactly the best GTK code you're likely to
-see.
-
-dsa.cpp is the main GTK+ driver. It has some comments at the top which
-point out major areas of interest.
-
-gtk_ui.* implement a User_Interface object that opens up a GTK+ dialog
-box that asks the user for their passphrase. It works pretty well, the
-only major deficiency is a fixed upper limit on the size of the
-passphrase (currently 64). You may want to use this in your own code,
-assuming you use GTK. If not, it should at least provide an outline
-for writing a version for your favorite windowing system.
diff --git a/doc/examples/hash.cpp b/doc/examples/hash.cpp
deleted file mode 100644
index 1a4ca1b64..000000000
--- a/doc/examples/hash.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <iostream>
-#include <fstream>
-#include <botan/botan.h>
-
-int main(int argc, char* argv[])
- {
- if(argc < 3)
- {
- std::cout << "Usage: " << argv[0] << " digest <filenames>" << std::endl;
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- std::string hash = argv[1];
- /* a couple of special cases, kind of a crock */
- if(hash == "sha1") hash = "SHA-1";
- if(hash == "md5") hash = "MD5";
-
- try {
- if(!Botan::have_hash(hash))
- {
- std::cout << "Unknown hash \"" << argv[1] << "\"" << std::endl;
- return 1;
- }
-
- Botan::Pipe pipe(new Botan::Hash_Filter(hash),
- new Botan::Hex_Encoder);
-
- int skipped = 0;
- for(int j = 2; argv[j] != 0; j++)
- {
- std::ifstream file(argv[j], std::ios::binary);
- if(!file)
- {
- std::cout << "ERROR: could not open " << argv[j] << std::endl;
- skipped++;
- continue;
- }
- pipe.start_msg();
- file >> pipe;
- pipe.end_msg();
- pipe.set_default_msg(j-2-skipped);
- std::cout << pipe << " " << argv[j] << std::endl;
- }
- }
- catch(std::exception& e)
- {
- std::cout << "Exception caught: " << e.what() << std::endl;
- }
- return 0;
- }
diff --git a/doc/examples/hash_fd.cpp b/doc/examples/hash_fd.cpp
deleted file mode 100644
index 32acdbec3..000000000
--- a/doc/examples/hash_fd.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-/*
-This is just like the normal hash application, but uses the Unix I/O
-system calls instead of C++ iostreams. Previously, this version was
-much faster and smaller, but GCC 3.1's libstdc++ seems to have been
-improved enough that the difference is now fairly minimal.
-
-Nicely enough, doing the change required changing only about 3 lines
-of code.
-*/
-
-#include <iostream>
-#include <botan/botan.h>
-
-#if !defined(BOTAN_HAS_PIPE_UNIXFD_IO)
- #error "You didn't compile the pipe_unixfd module into Botan"
-#endif
-
-#include <fcntl.h>
-#include <unistd.h>
-
-int main(int argc, char* argv[])
- {
- if(argc < 3)
- {
- std::cout << "Usage: " << argv[0] << " digest <filenames>" << std::endl;
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- try
- {
- Botan::Pipe pipe(new Botan::Hash_Filter(argv[1]),
- new Botan::Hex_Encoder);
-
- int skipped = 0;
- for(int j = 2; argv[j] != 0; j++)
- {
- int file = open(argv[j], O_RDONLY);
- if(file == -1)
- {
- std::cout << "ERROR: could not open " << argv[j] << std::endl;
- skipped++;
- continue;
- }
- pipe.start_msg();
- file >> pipe;
- pipe.end_msg();
- close(file);
- pipe.set_default_msg(j-2-skipped);
- std::cout << pipe << " " << argv[j] << std::endl;
- }
- }
- catch(Botan::Algorithm_Not_Found)
- {
- std::cout << "Don't know about the hash function \"" << argv[1] << "\""
- << std::endl;
- }
- catch(std::exception& e)
- {
- std::cout << "Exception caught: " << e.what() << std::endl;
- }
- return 0;
- }
diff --git a/doc/examples/hash_quickly.cpp b/doc/examples/hash_quickly.cpp
deleted file mode 100644
index 005a6d719..000000000
--- a/doc/examples/hash_quickly.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-/*
-Try to find the fastest SHA-1 implementation and use it to hash
-files. In most programs this isn't worth the bother and
-overhead. However with large amount of input, it is worth it. On tests
-on a Core2 system with the SHA-1 SSE2 code enabled, over a few hundred
-Mb or so the overhead paid for itself.
-
-Of course you could also just do this once and save it as an
-application config, which is probably the smart thing to do.
-*/
-
-#include <botan/botan.h>
-#include <botan/benchmark.h>
-#include <botan/filters.h>
-
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <map>
-#include <cstdlib>
-
-namespace {
-
-void set_fastest_implementation(const std::string& algo,
- Botan::RandomNumberGenerator& rng,
- double ms = 30)
- {
- Botan::Algorithm_Factory& af = Botan::global_state().algorithm_factory();
-
- std::map<std::string, double> results =
- Botan::algorithm_benchmark(algo, af, rng, ms, 16*1024);
-
- std::string fastest_provider = "";
- double best_res = 0;
-
- for(std::map<std::string, double>::iterator r = results.begin();
- r != results.end(); ++r)
- {
- std::cout << r->first << " @ " << r->second << " MiB/sec\n";
-
- if(fastest_provider == "" || r->second > best_res)
- {
- fastest_provider = r->first;
- best_res = r->second;
- }
- }
-
- std::cout << "Using " << fastest_provider << "\n";
-
- af.set_preferred_provider(algo, fastest_provider);
- }
-
-}
-
-int main(int argc, char* argv[])
- {
- if(argc <= 1)
- {
- std::cout << "Usage: " << argv[0] << " <file> <file> ...\n";
- return 1;
- }
-
- Botan::LibraryInitializer init;
- Botan::AutoSeeded_RNG rng;
-
- const std::string hash = "SHA-1";
-
- set_fastest_implementation(hash, rng);
-
- // Here we intentionally use the 'old style' lookup interface
- // which will also respect the provider settings. Or can use:
- // global_state().algorithm_factory().make_hash_function(hash)
- Botan::Pipe pipe(
- new Botan::Hash_Filter(Botan::get_hash(hash)),
- new Botan::Hex_Encoder
- );
-
- for(size_t i = 1; argv[i]; ++i)
- {
- std::ifstream in(argv[i], std::ios::binary);
- if(!in)
- continue;
-
- pipe.start_msg();
- in >> pipe;
- pipe.end_msg();
-
- std::cout << argv[i] << " = "
- << pipe.read_all_as_string(Botan::Pipe::LAST_MESSAGE) << "\n";
-
- }
- }
diff --git a/doc/examples/hasher.cpp b/doc/examples/hasher.cpp
deleted file mode 100644
index e5c52ba55..000000000
--- a/doc/examples/hasher.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <fstream>
-#include <iostream>
-#include <string>
-#include <botan/botan.h>
-
-int main(int argc, char* argv[])
- {
- if(argc < 2)
- {
- std::cout << "Usage: " << argv[0] << " <filenames>" << std::endl;
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- const int COUNT = 3;
- std::string name[COUNT] = { "MD5", "SHA-1", "RIPEMD-160" };
-
- for(int j = 1; argv[j] != 0; j++)
- {
- Botan::Filter* hash[COUNT] = {
- new Botan::Chain(new Botan::Hash_Filter(name[0]),
- new Botan::Hex_Encoder),
- new Botan::Chain(new Botan::Hash_Filter(name[1]),
- new Botan::Hex_Encoder),
- new Botan::Chain(new Botan::Hash_Filter(name[2]),
- new Botan::Hex_Encoder)
- };
-
- Botan::Pipe pipe(new Botan::Fork(hash, COUNT));
-
- std::ifstream file(argv[j], std::ios::binary);
- if(!file)
- {
- std::cout << "ERROR: could not open " << argv[j] << std::endl;
- continue;
- }
- pipe.start_msg();
- file >> pipe;
- pipe.end_msg();
- file.close();
- for(int k = 0; k != COUNT; k++)
- {
- pipe.set_default_msg(k);
- std::cout << name[k] << "(" << argv[j] << ") = " << pipe << std::endl;
- }
- }
- return 0;
- }
diff --git a/doc/examples/hasher2.cpp b/doc/examples/hasher2.cpp
deleted file mode 100644
index b6303b644..000000000
--- a/doc/examples/hasher2.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-* (C) 2001 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-/*
-Identical to hasher.cpp, but uses Pipe in a different way.
-
-Note this tends to be much less efficient than hasher.cpp, because it
-does three passes over the file. For a small file, it doesn't really
-matter. But for a large file, or for something you can't re-read
-easily (socket, stdin, ...) this is a bad idea.
-*/
-
-#include <fstream>
-#include <iostream>
-#include <string>
-#include <botan/botan.h>
-
-int main(int argc, char* argv[])
- {
- if(argc < 2)
- {
- std::cout << "Usage: " << argv[0] << " <filenames>" << std::endl;
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- const int COUNT = 3;
- std::string name[COUNT] = { "MD5", "SHA-1", "RIPEMD-160" };
-
- Botan::Pipe pipe;
-
- int skipped = 0;
- for(int j = 1; argv[j] != 0; j++)
- {
- Botan::Filter* hash[COUNT] = {
- new Botan::Hash_Filter(name[0]),
- new Botan::Hash_Filter(name[1]),
- new Botan::Hash_Filter(name[2]),
- };
-
- std::ifstream file(argv[j], std::ios::binary);
- if(!file)
- {
- std::cout << "ERROR: could not open " << argv[j] << std::endl;
- skipped++;
- continue;
- }
- for(int k = 0; k != COUNT; k++)
- {
- pipe.reset();
- pipe.append(hash[k]);
- pipe.append(new Botan::Hex_Encoder);
- pipe.start_msg();
-
- // trickiness: the >> op reads until EOF, but seekg won't work
- // unless we're in the "good" state (which EOF is not).
- file.clear();
- file.seekg(0, std::ios::beg);
- file >> pipe;
- pipe.end_msg();
- }
- file.close();
- for(int k = 0; k != COUNT; k++)
- {
- std::string out = pipe.read_all_as_string(COUNT*(j-1-skipped) + k);
- std::cout << name[k] << "(" << argv[j] << ") = " << out << std::endl;
- }
- }
-
- return 0;
- }
diff --git a/doc/examples/keywrap.cpp b/doc/examples/keywrap.cpp
deleted file mode 100644
index 730bcb6c9..000000000
--- a/doc/examples/keywrap.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-* NIST keywrap example
-* (C) 2011 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/botan.h>
-#include <botan/rfc3394.h>
-#include <botan/hex.h>
-#include <iostream>
-
-int main()
- {
- using namespace Botan;
-
- LibraryInitializer init;
-
- AutoSeeded_RNG rng;
-
- // The key to encrypt
- SymmetricKey key(rng, 24);
-
- // The key encryption key
- SymmetricKey kek(rng, 32);
-
- std::cout << "Original: " << key.as_string() << "\n";
-
- Algorithm_Factory& af = global_state().algorithm_factory();
-
- SecureVector<byte> enc = rfc3394_keywrap(key.bits_of(), kek, af);
-
- std::cout << "Encrypted: " << hex_encode(enc) << "\n";
-
- SecureVector<byte> dec = rfc3394_keyunwrap(enc, kek, af);
-
- std::cout << "Decrypted: " << hex_encode(dec) << "\n";
- }
diff --git a/doc/examples/make_prime.cpp b/doc/examples/make_prime.cpp
deleted file mode 100644
index acaaac698..000000000
--- a/doc/examples/make_prime.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/numthry.h>
-#include <botan/auto_rng.h>
-#include <botan/botan.h>
-
-using namespace Botan;
-
-#include <set>
-#include <iostream>
-#include <iterator>
-#include <map>
-
-int main()
- {
- Botan::LibraryInitializer init;
- AutoSeeded_RNG rng;
-
- std::set<BigInt> primes;
-
- std::map<int, int> bit_count;
-
- int not_new = 0;
-
- while(primes.size() < 10000)
- {
- u32bit start_cnt = primes.size();
-
- u32bit bits = 18;
-
- if(rng.next_byte() % 128 == 0)
- bits -= rng.next_byte() % (bits-2);
-
- bit_count[bits]++;
-
- //std::cout << "random_prime(" << bits << ")\n";
-
- BigInt p = random_prime(rng, bits);
-
- if(p.bits() != bits)
- {
- std::cout << "Asked for " << bits << " got " << p
- << " " << p.bits() << " bits\n";
- return 1;
- }
-
- primes.insert(random_prime(rng, bits));
-
- if(primes.size() != start_cnt)
- std::cout << primes.size() << "\n";
- else
- not_new++;
-
- //std::cout << "miss: " << not_new << "\n";
-
- if(not_new % 100000 == 0)
- {
- for(std::map<int, int>::iterator i = bit_count.begin();
- i != bit_count.end(); ++i)
- std::cout << "bit_count[" << i->first << "] = "
- << i->second << "\n";
- std::copy(primes.begin(), primes.end(),
- std::ostream_iterator<BigInt>(std::cout, " "));
- }
- }
-
- std::cout << "Generated all? primes\n";
- /*
- for(u32bit j = 0; j != PRIME_TABLE_SIZE; ++j)
- {
- if(primes.count(PRIMES[j]) != 1)
- std::cout << "Missing " << PRIMES[j] << "\n";
- }
- */
- }
diff --git a/doc/examples/new_engine.cpp b/doc/examples/new_engine.cpp
deleted file mode 100644
index 42e5dbe33..000000000
--- a/doc/examples/new_engine.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
-* Adding an application specific engine
-* (C) 2004,2008 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/stream_cipher.h>
-#include <botan/engine.h>
-
-using namespace Botan;
-
-class XOR_Cipher : public StreamCipher
- {
- public:
- void clear() throw() { mask.clear(); mask_pos = 0; }
-
- // what we want to call this cipher
- std::string name() const { return "XOR"; }
-
- // return a new object of this type
- StreamCipher* clone() const { return new XOR_Cipher; }
-
- Key_Length_Specification key_spec() const
- {
- return Key_Length_Specification(1, 32);
- }
-
- XOR_Cipher() : mask_pos(0) {}
- private:
- void cipher(const byte in[], byte out[], size_t length)
- {
- for(size_t j = 0; j != length; j++)
- {
- out[j] = in[j] ^ mask[mask_pos];
- mask_pos = (mask_pos + 1) % mask.size();
- }
- }
-
- void key_schedule(const byte key[], size_t length)
- {
- mask.resize(length);
- copy_mem(&mask[0], key, length);
- }
-
- SecureVector<byte> mask;
- u32bit mask_pos;
- };
-
-class Application_Engine : public Engine
- {
- public:
- std::string provider_name() const { return "application"; }
-
- StreamCipher* find_stream_cipher(const SCAN_Name& request,
- Algorithm_Factory&) const
- {
- if(request.algo_name() == "XOR")
- return new XOR_Cipher;
- return 0;
- }
- };
-
-#include <botan/botan.h>
-#include <iostream>
-#include <string>
-
-int main()
- {
-
- Botan::LibraryInitializer init;
-
- global_state().algorithm_factory().add_engine(
- new Application_Engine);
-
- // a hex key value
- SymmetricKey key("010203040506070809101112AAFF");
-
- /*
- Since stream ciphers are typically additive, the encryption and
- decryption ops are the same, so this isn't terribly interesting.
-
- If this where a block cipher you would have to add a cipher mode and
- padding method, such as "/CBC/PKCS7".
- */
- Pipe enc(get_cipher("XOR", key, ENCRYPTION), new Hex_Encoder);
- Pipe dec(new Hex_Decoder, get_cipher("XOR", key, DECRYPTION));
-
- // I think the pigeons are actually asleep at midnight...
- std::string secret = "The pigeon flys at midnight.";
-
- std::cout << "The secret message is '" << secret << "'" << std::endl;
-
- enc.process_msg(secret);
- std::string cipher = enc.read_all_as_string();
-
- std::cout << "The encrypted secret message is " << cipher << std::endl;
-
- dec.process_msg(cipher);
- secret = dec.read_all_as_string();
-
- std::cout << "The decrypted secret message is '"
- << secret << "'" << std::endl;
-
- return 0;
- }
diff --git a/doc/examples/package.cpp b/doc/examples/package.cpp
deleted file mode 100644
index 02cf52816..000000000
--- a/doc/examples/package.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/botan.h>
-#include <botan/serpent.h>
-#include <botan/package.h>
-
-#include <iostream>
-#include <fstream>
-#include <vector>
-
-using namespace Botan;
-
-namespace {
-
-std::vector<byte> slurp_file(const std::string& filename)
- {
- std::ifstream in(filename.c_str(), std::ios::binary);
-
- std::vector<byte> out;
- byte buf[4096] = { 0 };
-
- while(in.good())
- {
- in.read((char*)buf, sizeof(buf));
- ssize_t got = in.gcount();
-
- out.insert(out.end(), buf, buf+got);
- }
-
- return out;
- }
-
-}
-
-int main(int argc, char* argv[])
- {
- if(argc != 2)
- {
- std::cout << "Usage: " << argv[0] << " filename\n";
- return 1;
- }
-
- LibraryInitializer init;
-
- AutoSeeded_RNG rng;
-
- BlockCipher* cipher = new Serpent;
-
- std::vector<byte> input = slurp_file(argv[1]);
- std::vector<byte> output(input.size() + cipher->block_size());
-
- aont_package(rng, new Serpent,
- &input[0], input.size(),
- &output[0]);
-
- std::vector<byte> unpackage_output(output.size() - cipher->block_size());
-
- aont_unpackage(new Serpent,
- &output[0], output.size(),
- &unpackage_output[0]);
-
- if(unpackage_output == input)
- std::cout << "Package/unpackage worked\n";
- else
- std::cout << "Something went wrong :(\n";
- }
diff --git a/doc/examples/passhash.cpp b/doc/examples/passhash.cpp
deleted file mode 100644
index 586c28c3f..000000000
--- a/doc/examples/passhash.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/botan.h>
-#include <botan/passhash9.h>
-#include <iostream>
-#include <memory>
-
-#include <stdio.h>
-
-int main(int argc, char* argv[])
- {
- if(argc != 2 && argc != 3)
- {
- std::cerr << "Usage: " << argv[0] << " password\n";
- std::cerr << "Usage: " << argv[0] << " password hash\n";
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- try
- {
-
- if(argc == 2)
- {
- Botan::AutoSeeded_RNG rng;
-
- std::cout << "H('" << argv[1] << "') = "
- << Botan::generate_passhash9(argv[1], rng) << '\n';
- }
- else
- {
- bool ok = Botan::check_passhash9(argv[1], argv[2]);
- if(ok)
- std::cout << "Password and hash match\n";
- else
- std::cout << "Password and hash do not match\n";
- }
- }
- catch(std::exception& e)
- {
- std::cerr << e.what() << '\n';
- return 1;
- }
- return 0;
- }
diff --git a/doc/examples/pkcs10.cpp b/doc/examples/pkcs10.cpp
deleted file mode 100644
index 3f5ec8e05..000000000
--- a/doc/examples/pkcs10.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
-* (C) 2003 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/init.h>
-#include <botan/auto_rng.h>
-#include <botan/x509self.h>
-#include <botan/rsa.h>
-#include <botan/dsa.h>
-using namespace Botan;
-
-#include <iostream>
-#include <fstream>
-#include <memory>
-
-int main(int argc, char* argv[])
- {
- if(argc != 6)
- {
- std::cout << "Usage: " << argv[0] <<
- " passphrase name country_code organization email" << std::endl;
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- try
- {
- AutoSeeded_RNG rng;
-
- RSA_PrivateKey priv_key(rng, 1024);
- // If you want a DSA key instead of RSA, comment out the above line and
- // uncomment this one:
- //DSA_PrivateKey priv_key(DL_Group("dsa/jce/1024"));
-
- std::ofstream key_file("private.pem");
- key_file << PKCS8::PEM_encode(priv_key, rng, argv[1]);
-
- X509_Cert_Options opts;
-
- opts.common_name = argv[2];
- opts.country = argv[3];
- opts.organization = argv[4];
- opts.email = argv[5];
-
- /* Some hard-coded options, just to give you an idea of what's there */
- opts.challenge = "a fixed challenge passphrase";
- opts.locality = "Baltimore";
- opts.state = "MD";
- opts.org_unit = "Testing";
- opts.add_ex_constraint("PKIX.ClientAuth");
- opts.add_ex_constraint("PKIX.IPsecUser");
- opts.add_ex_constraint("PKIX.EmailProtection");
-
- opts.xmpp = "[email protected]";
-
- PKCS10_Request req = X509::create_cert_req(opts, priv_key, "SHA-1", rng);
-
- std::ofstream req_file("req.pem");
- req_file << req.PEM_encode();
- }
- catch(std::exception& e)
- {
- std::cout << e.what() << std::endl;
- return 1;
- }
- return 0;
- }
diff --git a/doc/examples/pqg_gen.cpp b/doc/examples/pqg_gen.cpp
deleted file mode 100644
index c033dac3b..000000000
--- a/doc/examples/pqg_gen.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <vector>
-#include <map>
-#include <memory>
-
-#include <botan/botan.h>
-#include <botan/auto_rng.h>
-#include <botan/dsa.h>
-#include <botan/numthry.h>
-#include <botan/dl_group.h>
-using namespace Botan;
-
-bool check(RandomNumberGenerator& rng,
- std::map<std::string, std::string>);
-
-int main()
- {
- try {
- Botan::LibraryInitializer init("use_engines");
-
- AutoSeeded_RNG rng;
-
- std::ifstream in("PQGGen.rsp");
- if(!in)
- throw std::runtime_error("Can't open response file");
-
- std::map<std::string, std::string> inputs;
-
- while(in.good())
- {
- std::string line;
- std::getline(in, line);
-
- if(line == "" || line[0] == '[' || line[0] == '#')
- continue;
-
- std::vector<std::string> name_and_val = split_on(line, '=');
-
- if(name_and_val.size() != 2)
- throw std::runtime_error("Unexpected input: " + line);
-
- name_and_val[0].erase(name_and_val[0].size()-1);
- name_and_val[1].erase(0, 1);
-
- std::string name = name_and_val[0], value = name_and_val[1];
-
- inputs[name] = value;
-
- if(name == "H")
- {
- bool result = check(rng, inputs);
- std::cout << "." << std::flush;
- if(result == false)
- {
- std::cout << " Check failed\n";
-
- std::map<std::string, std::string>::const_iterator i;
-
- for(i = inputs.begin(); i != inputs.end(); i++)
- std::cout << i->first << " = " << i->second << "\n";
-
- std::cout << "\n";
- }
-
- inputs.clear();
- }
- }
- }
- catch(std::exception& e)
- {
- std::cout << e.what() << std::endl;
- return 1;
- }
- return 0;
- }
-
-bool check(RandomNumberGenerator& rng,
- std::map<std::string, std::string> inputs)
- {
- BigInt p("0x"+inputs["P"]),
- q("0x"+inputs["Q"]),
- g("0x"+inputs["G"]),
- h("0x"+inputs["H"]);
-
- if(h < 1 || h >= p-1) return false;
-
- //u32bit c = to_u32bit(inputs["c"]);
-
- Pipe pipe(new Hex_Decoder);
- pipe.process_msg(inputs["Seed"]);
- SecureVector<byte> seed = pipe.read_all();
-
- BigInt our_p, our_q;
-
- u32bit qbits = (p.bits() <= 1024) ? 160 : 256;
-
- Algorithm_Factory& af = global_state().algorithm_factory();
-
- bool found = generate_dsa_primes(rng, af, our_p, our_q,
- p.bits(), qbits, seed);
-
- if(!found) /* bad seed */
- return false;
-
- if(our_p != p) return false;
- if(our_q != q) return false;
-
- BigInt our_g = power_mod(h, (p-1)/q, p);
-
- if(our_g != g) return false;
-
- return true;
- }
diff --git a/doc/examples/read_ssh.cpp b/doc/examples/read_ssh.cpp
deleted file mode 100644
index f6299a29d..000000000
--- a/doc/examples/read_ssh.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-/*
-* Example of reading SSH2 format public keys (see RFC 4716)
-*/
-
-#include <fstream>
-#include <botan/x509_key.h>
-#include <botan/filters.h>
-#include <botan/loadstor.h>
-#include <botan/rsa.h>
-#include <botan/dsa.h>
-
-using namespace Botan;
-
-namespace {
-
-u32bit read_u32bit(Pipe& pipe)
- {
- byte out[4] = { 0 };
- pipe.read(out, 4);
- u32bit len = load_be<u32bit>(out, 0);
- if(len > 10000)
- throw Decoding_Error("Huge size in read_u32bit, something went wrong");
- return len;
- }
-
-std::string read_string(Pipe& pipe)
- {
- u32bit len = read_u32bit(pipe);
-
- std::string out(len, 'X');
- pipe.read(reinterpret_cast<byte*>(&out[0]), len);
- return out;
- }
-
-BigInt read_bigint(Pipe& pipe)
- {
- u32bit len = read_u32bit(pipe);
-
- SecureVector<byte> buf(len);
- pipe.read(&buf[0], len);
- return BigInt::decode(buf);
- }
-
-Public_Key* read_ssh_pubkey(const std::string& file)
- {
- std::ifstream in(file.c_str());
-
- const std::string ssh_header = "---- BEGIN SSH2 PUBLIC KEY ----";
- const std::string ssh_trailer = "---- END SSH2 PUBLIC KEY ----";
-
- std::string hex_bits;
-
- std::string line;
- std::getline(in, line);
-
- if(line != ssh_header)
- return 0;
-
- while(in.good())
- {
- std::getline(in, line);
-
- if(line.find("Comment: ") == 0)
- {
- while(line[line.size()-1] == '\\')
- std::getline(in, line);
- std::getline(in, line);
- }
-
- if(line == ssh_trailer)
- break;
-
- hex_bits += line;
- }
-
- Pipe pipe(new Base64_Decoder);
- pipe.process_msg(hex_bits);
-
- std::string key_type = read_string(pipe);
-
- if(key_type != "ssh-rsa" && key_type != "ssh-dss")
- return 0;
-
- if(key_type == "ssh-rsa")
- {
- BigInt e = read_bigint(pipe);
- BigInt n = read_bigint(pipe);
- return new RSA_PublicKey(n, e);
- }
- else if(key_type == "ssh-dss")
- {
- BigInt p = read_bigint(pipe);
- BigInt q = read_bigint(pipe);
- BigInt g = read_bigint(pipe);
- BigInt y = read_bigint(pipe);
-
- return new DSA_PublicKey(DL_Group(p, q, g), y);
- }
-
- return 0;
- }
-
-}
-
-#include <botan/init.h>
-#include <iostream>
-
-int main()
- {
- LibraryInitializer init;
-
- Public_Key* key = read_ssh_pubkey("dsa.ssh");
-
- if(key == 0)
- {
- std::cout << "Failed\n";
- return 1;
- }
-
- std::cout << X509::PEM_encode(*key);
-
- return 0;
- }
diff --git a/doc/examples/readme.txt b/doc/examples/readme.txt
deleted file mode 100644
index fb6a03ddf..000000000
--- a/doc/examples/readme.txt
+++ /dev/null
@@ -1,77 +0,0 @@
-This directory contains some simple example applications for the Botan crypto
-library. If you want to see something a bit more complicated, check out the
-stuff in the checks/ directory. Both it and the files in this directory are in
-the public domain, and you may do with them however you please.
-
-The makefile assumes that you built the library with g++; you'll have to change
-it if this assumption proves incorrect.
-
-Some of these examples will not build on all configurations of the library,
-particularly 'bzip', 'encrypt', 'decrypt', and 'hash_fd', as they require
-various extensions.
-
-The examples are fairly small (50-150 lines). And that's with argument
-processing, I/O, error checking, etc (which counts for 40% or more of most of
-them). This is partially to make them easy to understand, and partially because
-I'm lazy. For the most part, the examples cover the stuff a 'regular'
-application might need.
-
-Feel free to contribute new examples. You too can gain fame and fortune by
-writing example apps for obscure libraries!
-
-The examples are:
-
-* X.509 examples
---------
-ca: A (very) simple CA application
-
-x509info: Prints some information about an X.509 certificate
-
-pkcs10: Generates a PKCS #10 certificate request for a 1024 bit RSA key
-
-self_sig: Generates a self-signed X.509v3 certificate with a 1024 bit RSA key
---------
-
-* RSA examples (also uses X.509, PKCS #8, block ciphers, MACs, PBKDF algorithms)
---------
-rsa_kgen: Generate an RSA key, encrypt the private key with a passphrase,
- output the keys to a pair of files
-rsa_enc: Take a public key (generated by rsa_kgen) and encrypt a file
- using CAST-128, MAC it with HMAC(SHA-1)
-rsa_dec: Decrypt a file encrypted by rsa_enc
-
-* DSA examples (also uses X.509, PKCS #8)
---------
-dsa_kgen: Generates a DSA key, encrypts the private key with a passphrase
- and stores it in PKCS #8 format.
-dsa_sign: Produce a DSA signature for a file. Uses SHA-1
-dsa_ver: Verify a message signed with dsa_sign
-
-* Encryption examples
---------
-encrypt: Encrypt a file in CBC mode with a block cipher of your choice. Adds
- a MAC for authentication, and compresses the plaintext with Zlib.
-
-decrypt: Decrypt the result of 'encrypt'
-
-xor_ciph: Shows how to add a new algorithm from application code
-
-* Hash function examples (also shows different methods of using Pipe)
---------
-hash: Print digests of files, using any chosen hash function
-
-hash_fd: Same as hash, except that it uses Unix file I/O. Requires the
- pipe_unixfd extension
-
-hasher: Print MD5, SHA-1, and RIPEMD-160 digests of files
-
-hasher2: Same as hasher, just shows an alternate method
-
-stack: A demonstration of some more advanced Pipe functionality. Prints
- MD5 hashes
-
-* Misc examples
---------
-base64: Simple base64 encoding/decoding tool
-
-bzip: Bzip2 compression/decompression.
diff --git a/doc/examples/rng_test.cpp b/doc/examples/rng_test.cpp
deleted file mode 100644
index c0d24fd80..000000000
--- a/doc/examples/rng_test.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/botan.h>
-#include <botan/x931_rng.h>
-#include <botan/hex.h>
-#include <botan/lookup.h>
-
-#include <iostream>
-#include <fstream>
-#include <deque>
-#include <stdexcept>
-
-using namespace Botan;
-
-namespace {
-
-class Fixed_Output_RNG : public RandomNumberGenerator
- {
- public:
- bool is_seeded() const { return !buf.empty(); }
-
- byte random()
- {
- if(buf.empty())
- throw std::runtime_error("Out of bytes");
-
- byte out = buf.front();
- buf.pop_front();
- return out;
- }
-
- void randomize(byte out[], size_t len) throw()
- {
- for(size_t j = 0; j != len; j++)
- out[j] = random();
- }
-
- std::string name() const { return "Fixed_Output_RNG"; }
-
- void reseed(size_t) {}
-
- void clear() throw() {}
-
- void add_entropy(const byte in[], size_t len)
- {
- buf.insert(buf.end(), in, in + len);
- }
-
- void add_entropy_source(EntropySource* es) { delete es; }
-
- Fixed_Output_RNG() {}
- private:
- std::deque<byte> buf;
- };
-
-void x931_tests(std::vector<std::pair<std::string, std::string> > vecs,
- const std::string& cipher)
- {
- for(size_t j = 0; j != vecs.size(); ++j)
- {
- const std::string result = vecs[j].first;
- const std::string input = vecs[j].second;
-
- ANSI_X931_RNG prng(get_block_cipher(cipher),
- new Fixed_Output_RNG);
-
- SecureVector<byte> x = hex_decode(input);
- prng.add_entropy(x.begin(), x.size());
-
- SecureVector<byte> output(result.size() / 2);
- prng.randomize(output, output.size());
-
- if(hex_decode(result) != output)
- std::cout << "FAIL";
- else
- std::cout << "PASS";
-
- std::cout << " Seed " << input << " "
- << "Got " << hex_encode(output) << " "
- << "Exp " << result << "\n";
- }
-
- }
-
-std::vector<std::pair<std::string, std::string> >
-read_file(const std::string& fsname)
- {
- std::ifstream in(fsname.c_str());
-
- std::vector<std::pair<std::string, std::string> > out;
-
- while(in.good())
- {
- std::string line;
- std::getline(in, line);
-
- if(line == "")
- break;
-
- std::vector<std::string> l = split_on(line, ':');
-
- if(l.size() != 2)
- throw std::runtime_error("Bad line " + line);
-
- out.push_back(std::make_pair(l[0], l[1]));
- }
-
- return out;
- }
-
-}
-
-int main()
- {
- Botan::LibraryInitializer init;
-
- x931_tests(read_file("ANSI931_AES128VST.txt.vst"), "AES-128");
- x931_tests(read_file("ANSI931_AES192VST.txt.vst"), "AES-192");
- x931_tests(read_file("ANSI931_AES256VST.txt.vst"), "AES-256");
- x931_tests(read_file("ANSI931_TDES2VST.txt.vst"), "TripleDES");
- x931_tests(read_file("ANSI931_TDES3VST.txt.vst"), "TripleDES");
- }
diff --git a/doc/examples/row_encryptor.cpp b/doc/examples/row_encryptor.cpp
deleted file mode 100644
index 685850945..000000000
--- a/doc/examples/row_encryptor.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <string>
-#include <memory>
-#include <sstream>
-#include <iostream>
-#include <stdexcept>
-
-#include <botan/botan.h>
-#include <botan/filters.h>
-#include <botan/eax.h>
-
-using namespace Botan;
-
-/*
-* Encrypt and decrypt small rows
-*/
-class Row_Encryptor
- {
- public:
- Row_Encryptor(const std::string& passphrase,
- RandomNumberGenerator& rng);
-
- Row_Encryptor(const std::string& passphrase,
- const MemoryRegion<byte>& salt);
-
- std::string encrypt(const std::string& input,
- const MemoryRegion<byte>& salt);
-
- std::string decrypt(const std::string& input,
- const MemoryRegion<byte>& salt);
-
- SecureVector<byte> get_pbkdf_salt() const { return pbkdf_salt; }
- private:
- void init(const std::string& passphrase);
-
- Row_Encryptor(const Row_Encryptor&) {}
- Row_Encryptor& operator=(const Row_Encryptor&) { return (*this); }
-
- SecureVector<byte> pbkdf_salt;
- Pipe enc_pipe, dec_pipe;
- EAX_Encryption* eax_enc; // owned by enc_pipe
- EAX_Decryption* eax_dec; // owned by dec_pipe;
- };
-
-Row_Encryptor::Row_Encryptor(const std::string& passphrase,
- RandomNumberGenerator& rng)
- {
- pbkdf_salt.resize(10); // 80 bits
- rng.randomize(&pbkdf_salt[0], pbkdf_salt.size());
- init(passphrase);
- }
-
-Row_Encryptor::Row_Encryptor(const std::string& passphrase,
- const MemoryRegion<byte>& salt)
- {
- pbkdf_salt = salt;
- init(passphrase);
- }
-
-void Row_Encryptor::init(const std::string& passphrase)
- {
- std::auto_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(SHA-160)"));
-
- SecureVector<byte> key = pbkdf->derive_key(32, passphrase,
- &pbkdf_salt[0], pbkdf_salt.size(),
- 10000).bits_of();
-
- /*
- Save pointers to the EAX objects so we can change the IV as needed
- */
-
- Algorithm_Factory& af = global_state().algorithm_factory();
-
- const BlockCipher* proto = af.prototype_block_cipher("Serpent");
-
- if(!proto)
- throw std::runtime_error("Could not get a Serpent proto object");
-
- enc_pipe.append(eax_enc = new EAX_Encryption(proto->clone()));
- dec_pipe.append(eax_dec = new EAX_Decryption(proto->clone()));
-
- eax_enc->set_key(key);
- eax_dec->set_key(key);
- }
-
-std::string Row_Encryptor::encrypt(const std::string& input,
- const MemoryRegion<byte>& salt)
- {
- eax_enc->set_iv(salt);
- enc_pipe.process_msg(input);
- return enc_pipe.read_all_as_string(Pipe::LAST_MESSAGE);
- }
-
-std::string Row_Encryptor::decrypt(const std::string& input,
- const MemoryRegion<byte>& salt)
- {
- eax_dec->set_iv(salt);
- dec_pipe.process_msg(input);
- return dec_pipe.read_all_as_string(Pipe::LAST_MESSAGE);
- }
-
-/*
-* Test code follows:
-*/
-
-int main()
- {
- Botan::LibraryInitializer init;
-
- AutoSeeded_RNG rng;
-
- const std::string secret_passphrase = "secret passphrase";
-
- Row_Encryptor encryptor("secret passphrase", rng);
-
- std::vector<std::string> original_inputs;
-
- for(u32bit i = 0; i != 50000; ++i)
- {
- std::ostringstream out;
-
- u32bit output_bytes = rng.next_byte();
-
- for(u32bit j = 0; j != output_bytes; ++j)
- out << std::hex << (int)rng.next_byte();
-
- original_inputs.push_back(out.str());
- }
-
- std::vector<std::string> encrypted_values;
- MemoryVector<byte> salt(4); // keep out of loop to avoid excessive dynamic allocation
-
- for(u32bit i = 0; i != original_inputs.size(); ++i)
- {
- std::string input = original_inputs[i];
-
- for(u32bit j = 0; j != 4; ++j)
- salt[j] = (i >> 8) & 0xFF;
-
- encrypted_values.push_back(encryptor.encrypt(input, salt));
- }
-
- for(u32bit i = 0; i != encrypted_values.size(); ++i)
- {
- std::string ciphertext = encrypted_values[i];
-
- // NOTE: same salt value as previous loop (index value)
- for(u32bit j = 0; j != 4; ++j)
- salt[j] = (i >> 8) & 0xFF;
-
- std::string output = encryptor.decrypt(ciphertext, salt);
-
- if(output != original_inputs[i])
- std::cout << "BOOM " << i << "\n";
- }
-
- Row_Encryptor test_pbkdf_salt_copy(secret_passphrase,
- encryptor.get_pbkdf_salt());
-
- zeroise(salt);
- std::string test = test_pbkdf_salt_copy.decrypt(encrypted_values[0], salt);
- if(test != original_inputs[0])
- std::cout << "PBKDF salt copy failed to decrypt properly\n";
-
- return 0;
- }
diff --git a/doc/examples/rsa_dec.cpp b/doc/examples/rsa_dec.cpp
deleted file mode 100644
index 81592328c..000000000
--- a/doc/examples/rsa_dec.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
-* (C) 2002-2010 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-/*
-Decrypt an encrypted RSA private key. Then use that key to decrypt a
-message. This program can decrypt messages generated by rsa_enc, and uses the
-same key format as that generated by rsa_kgen.
-*/
-
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <memory>
-
-#include <botan/botan.h>
-#include <botan/pubkey.h>
-#include <botan/rsa.h>
-using namespace Botan;
-
-SecureVector<byte> b64_decode(const std::string&);
-SymmetricKey derive_key(const std::string&, const SymmetricKey&, u32bit);
-
-const std::string SUFFIX = ".enc";
-
-int main(int argc, char* argv[])
- {
- if(argc != 4)
- {
- std::cout << "Usage: " << argv[0] << " keyfile messagefile passphrase"
- << std::endl;
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- try
- {
- AutoSeeded_RNG rng;
-
- std::auto_ptr<PKCS8_PrivateKey> key(
- PKCS8::load_key(argv[1], rng, argv[3]));
-
- RSA_PrivateKey* rsakey = dynamic_cast<RSA_PrivateKey*>(key.get());
- if(!rsakey)
- {
- std::cout << "The loaded key is not a RSA key!\n";
- return 1;
- }
-
- std::ifstream message(argv[2]);
- if(!message)
- {
- std::cout << "Couldn't read the message file." << std::endl;
- return 1;
- }
-
- std::string outfile(argv[2]);
- outfile = outfile.replace(outfile.find(SUFFIX), SUFFIX.length(), "");
-
- std::ofstream plaintext(outfile.c_str(), std::ios::binary);
- if(!plaintext)
- {
- std::cout << "Couldn't write the plaintext to "
- << outfile << std::endl;
- return 1;
- }
-
- std::string enc_masterkey_str;
- std::getline(message, enc_masterkey_str);
- std::string mac_str;
- std::getline(message, mac_str);
-
- SecureVector<byte> enc_masterkey = b64_decode(enc_masterkey_str);
-
- PK_Decryptor_EME decryptor(*rsakey, "EME1(SHA-1)");
-
- SecureVector<byte> masterkey = decryptor.decrypt(enc_masterkey);
-
- SymmetricKey cast_key = derive_key("CAST", masterkey, 16);
- InitializationVector iv = derive_key("IV", masterkey, 8);
- SymmetricKey mac_key = derive_key("MAC", masterkey, 16);
-
- Pipe pipe(new Base64_Decoder,
- get_cipher("CAST-128/CBC/PKCS7", cast_key, iv, DECRYPTION),
- new Fork(
- 0,
- new Chain(
- new MAC_Filter("HMAC(SHA-1)", mac_key, 12),
- new Base64_Encoder
- )
- )
- );
-
- pipe.start_msg();
- message >> pipe;
- pipe.end_msg();
-
- std::string our_mac = pipe.read_all_as_string(1);
-
- if(our_mac != mac_str)
- std::cout << "WARNING: MAC in message failed to verify\n";
-
- plaintext << pipe.read_all_as_string(0);
- }
- catch(std::exception& e)
- {
- std::cout << "Exception caught: " << e.what() << std::endl;
- return 1;
- }
- return 0;
- }
-
-SecureVector<byte> b64_decode(const std::string& in)
- {
- Pipe pipe(new Base64_Decoder);
- pipe.process_msg(in);
- return pipe.read_all();
- }
-
-SymmetricKey derive_key(const std::string& param,
- const SymmetricKey& masterkey,
- u32bit outputlength)
- {
- std::auto_ptr<KDF> kdf(get_kdf("KDF2(SHA-1)"));
- return kdf->derive_key(outputlength, masterkey.bits_of(), param);
- }
diff --git a/doc/examples/rsa_enc.cpp b/doc/examples/rsa_enc.cpp
deleted file mode 100644
index ac609c4b3..000000000
--- a/doc/examples/rsa_enc.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
-* (C) 2002 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-/*
- Grab an RSA public key from the file given as an argument, grab a message
- from another file, and encrypt the message.
-
- Algorithms used:
- RSA with EME1(SHA-1) padding to encrypt the master key
- CAST-128 in CBC mode with PKCS#7 padding to encrypt the message.
- HMAC with SHA-1 is used to authenticate the message
-
- The keys+IV used are derived from the master key (the thing that's encrypted
- with RSA) using KDF2(SHA-1). The 3 outputs of KDF2 are parameterized by P,
- where P is "CAST", "IV" or "MAC", in order to make each key/IV unique.
-
- The format is:
- 1) First line is the master key, encrypted with the recipients public key
- using EME1(SHA-1), and then base64 encoded.
- 2) Second line is the first 96 bits (12 bytes) of the HMAC(SHA-1) of
- the _plaintext_
- 3) Following lines are base64 encoded ciphertext (CAST-128 as described),
- each broken after ~72 characters.
-*/
-
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <memory>
-
-#include <botan/botan.h>
-#include <botan/pubkey.h>
-#include <botan/rsa.h>
-using namespace Botan;
-
-std::string b64_encode(const SecureVector<byte>&);
-SymmetricKey derive_key(const std::string&, const SymmetricKey&, u32bit);
-
-int main(int argc, char* argv[])
- {
- if(argc != 3)
- {
- std::cout << "Usage: " << argv[0] << " keyfile messagefile" << std::endl;
- return 1;
- }
-
- std::ifstream message(argv[2], std::ios::binary);
- if(!message)
- {
- std::cout << "Couldn't read the message file." << std::endl;
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- std::string output_name(argv[2]);
- output_name += ".enc";
- std::ofstream ciphertext(output_name.c_str());
- if(!ciphertext)
- {
- std::cout << "Couldn't write the ciphertext to " << output_name
- << std::endl;
- return 1;
- }
-
- try {
- std::auto_ptr<X509_PublicKey> key(X509::load_key(argv[1]));
- RSA_PublicKey* rsakey = dynamic_cast<RSA_PublicKey*>(key.get());
- if(!rsakey)
- {
- std::cout << "The loaded key is not a RSA key!\n";
- return 1;
- }
-
- AutoSeeded_RNG rng;
-
- PK_Encryptor_EME encryptor(*rsakey, "EME1(SHA-1)");
-
- /* Generate the master key (the other keys are derived from this)
-
- Basically, make the key as large as can be encrypted by this key, up
- to a limit of 256 bits. For 512 bit keys, the master key will be >160
- bits. A >600 bit key will use the full 256 bit master key.
-
- In theory, this is not enough, because we derive 16+16+8=40 bytes of
- secrets (if you include the IV) using the master key, so they are not
- statistically indepedent. Practically speaking I don't think this is
- a problem.
- */
- SymmetricKey masterkey(rng,
- std::min<size_t>(32,
- encryptor.maximum_input_size()));
-
- SymmetricKey cast_key = derive_key("CAST", masterkey, 16);
- SymmetricKey mac_key = derive_key("MAC", masterkey, 16);
- SymmetricKey iv = derive_key("IV", masterkey, 8);
-
- SecureVector<byte> encrypted_key =
- encryptor.encrypt(masterkey.bits_of(), rng);
-
- ciphertext << b64_encode(encrypted_key) << std::endl;
-
- Pipe pipe(new Fork(
- new Chain(
- get_cipher("CAST-128/CBC/PKCS7", cast_key, iv,
- ENCRYPTION),
- new Base64_Encoder(true) // true == do linebreaking
- ),
- new Chain(
- new MAC_Filter("HMAC(SHA-1)", mac_key, 12),
- new Base64_Encoder
- )
- )
- );
-
- pipe.start_msg();
- message >> pipe;
- pipe.end_msg();
-
- /* Write the MAC as the second line. That way we can pull it off right
- from the start, and feed the rest of the file right into a pipe on the
- decrypting end.
- */
-
- ciphertext << pipe.read_all_as_string(1) << std::endl;
- ciphertext << pipe.read_all_as_string(0);
- }
- catch(std::exception& e)
- {
- std::cout << "Exception: " << e.what() << std::endl;
- }
- return 0;
- }
-
-std::string b64_encode(const SecureVector<byte>& in)
- {
- Pipe pipe(new Base64_Encoder);
- pipe.process_msg(in);
- return pipe.read_all_as_string();
- }
-
-SymmetricKey derive_key(const std::string& param,
- const SymmetricKey& masterkey,
- u32bit outputlength)
- {
- std::auto_ptr<KDF> kdf(get_kdf("KDF2(SHA-1)"));
- return kdf->derive_key(outputlength, masterkey.bits_of(), param);
- }
diff --git a/doc/examples/rsa_kgen.cpp b/doc/examples/rsa_kgen.cpp
deleted file mode 100644
index f4566263b..000000000
--- a/doc/examples/rsa_kgen.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
-* (C) 2002 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-/*
-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).
-*/
-
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <cstdlib>
-#include <memory>
-
-#include <botan/botan.h>
-#include <botan/rsa.h>
-using namespace Botan;
-
-int main(int argc, char* argv[])
- {
- if(argc != 2 && argc != 3)
- {
- std::cout << "Usage: " << argv[0] << " bitsize [passphrase]"
- << std::endl;
- return 1;
- }
-
- u32bit bits = std::atoi(argv[1]);
- if(bits < 1024 || bits > 16384)
- {
- std::cout << "Invalid argument for bitsize" << std::endl;
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- std::ofstream pub("rsapub.pem");
- std::ofstream priv("rsapriv.pem");
- if(!priv || !pub)
- {
- std::cout << "Couldn't write output files" << std::endl;
- return 1;
- }
-
- try
- {
- AutoSeeded_RNG rng;
-
- RSA_PrivateKey key(rng, bits);
- pub << X509::PEM_encode(key);
-
- if(argc == 2)
- priv << PKCS8::PEM_encode(key);
- else
- priv << PKCS8::PEM_encode(key, rng, argv[2]);
- }
- catch(std::exception& e)
- {
- std::cout << "Exception caught: " << e.what() << std::endl;
- }
- return 0;
- }
diff --git a/doc/examples/rsa_manykey.cpp b/doc/examples/rsa_manykey.cpp
deleted file mode 100644
index e6a511753..000000000
--- a/doc/examples/rsa_manykey.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-/*
-Generate a whole sequence of keys (for benchmarking)
-*/
-
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <cstdlib>
-#include <memory>
-
-#include <botan/botan.h>
-#include <botan/rsa.h>
-#include <botan/parsing.h>
-using namespace Botan;
-
-int main()
- {
- Botan::LibraryInitializer init;
-
- AutoSeeded_RNG rng;
-
- for(u32bit j = 512; j <= 8192; j += 256)
- {
- std::cout << j << "...";
-
- RSA_PrivateKey key(rng, j);
-
- std::ofstream priv(("rsa/" + to_string(j) + ".pem").c_str());
- priv << PKCS8::PEM_encode(key);
- priv.close();
-
- std::cout << " done" << std::endl;
- }
-
- return 0;
- }
diff --git a/doc/examples/self_sig.cpp b/doc/examples/self_sig.cpp
deleted file mode 100644
index 6710cfb51..000000000
--- a/doc/examples/self_sig.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
-* (C) 2003 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-/*
-Generate a 1024 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.
-*/
-
-#include <botan/botan.h>
-#include <botan/x509self.h>
-#include <botan/rsa.h>
-#include <botan/dsa.h>
-using namespace Botan;
-
-#include <iostream>
-#include <fstream>
-#include <memory>
-
-int main(int argc, char* argv[])
- {
- if(argc != 7)
- {
- std::cout << "Usage: " << argv[0]
- << " passphrase [CA|user] name country_code organization email"
- << std::endl;
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- std::string CA_flag = argv[2];
- bool do_CA = false;
-
- if(CA_flag == "CA") do_CA = true;
- else if(CA_flag == "user") do_CA = false;
- else
- {
- std::cout << "Bad flag for CA/user switch: " << CA_flag << std::endl;
- return 1;
- }
-
- try
- {
- AutoSeeded_RNG rng;
-
- RSA_PrivateKey key(rng, 1024);
-
- std::ofstream priv_key("private.pem");
- priv_key << PKCS8::PEM_encode(key, rng, argv[1]);
-
- X509_Cert_Options opts;
-
- opts.common_name = argv[3];
- opts.country = argv[4];
- opts.organization = argv[5];
- opts.email = argv[6];
- /* Fill in other values of opts here */
-
- //opts.xmpp = "[email protected]";
-
- if(do_CA)
- opts.CA_key();
-
- X509_Certificate cert =
- X509::create_self_signed_cert(opts, key, "SHA-256", rng);
-
- std::ofstream cert_file("cert.pem");
- cert_file << cert.PEM_encode();
- }
- catch(std::exception& e)
- {
- std::cout << "Exception: " << e.what() << std::endl;
- return 1;
- }
-
- return 0;
- }
diff --git a/doc/examples/sig_gen.cpp b/doc/examples/sig_gen.cpp
deleted file mode 100644
index cf273216a..000000000
--- a/doc/examples/sig_gen.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <vector>
-#include <map>
-#include <memory>
-
-#include <botan/botan.h>
-#include <botan/dsa.h>
-#include <botan/pubkey.h>
-using namespace Botan;
-
-bool check(std::map<std::string, std::string>);
-
-int main()
- {
- try {
- Botan::LibraryInitializer init;
-
- std::ifstream in("SigGen.rsp");
- if(!in)
- throw Exception("Can't open response file");
-
- std::map<std::string, std::string> inputs;
-
- while(in.good())
- {
- std::string line;
- std::getline(in, line);
-
- if(line == "" || line[0] == '[' || line[0] == '#')
- continue;
-
- std::vector<std::string> name_and_val = split_on(line, '=');
-
- if(name_and_val.size() != 2)
- throw Decoding_Error("Unexpected input: " + line);
-
- name_and_val[0].erase(name_and_val[0].size()-1);
- name_and_val[1].erase(0, 1);
-
- std::string name = name_and_val[0], value = name_and_val[1];
-
- inputs[name] = value;
-
- if(name == "S")
- {
- bool result = check(inputs);
- if(result == false)
- {
- std::cout << " Check failed\n";
-
- std::map<std::string, std::string>::const_iterator i;
-
- for(i = inputs.begin(); i != inputs.end(); i++)
- std::cout << i->first << " = " << i->second << "\n";
- }
- inputs["Msg"] = inputs["R"] = inputs["S"] = "";
- }
- }
- }
- catch(std::exception& e)
- {
- std::cout << e.what() << std::endl;
- return 1;
- }
- return 0;
- }
-
-bool check(std::map<std::string, std::string> inputs)
- {
- BigInt p("0x"+inputs["P"]),
- q("0x"+inputs["Q"]),
- g("0x"+inputs["G"]),
- y("0x"+inputs["Y"]);
-
- DSA_PublicKey key(DL_Group(p, q, g), y);
-
- Pipe pipe(new Hex_Decoder);
-
- pipe.process_msg(inputs["Msg"]);
- pipe.start_msg();
- pipe.write(inputs["R"]);
- pipe.write(inputs["S"] );
- pipe.end_msg();
-
- PK_Verifier verifier(key, "EMSA1(SHA-1)");
-
- return verifier.verify_message(pipe.read_all(0), pipe.read_all(1));
- }
diff --git a/doc/examples/stack.cpp b/doc/examples/stack.cpp
deleted file mode 100644
index 0c00ed183..000000000
--- a/doc/examples/stack.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-* (C) 2002 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-/*
-An Botan example application showing how to use the pop and prepend
-functions of Pipe. Based on the md5 example. It's output should always
-be identical to such.
-*/
-
-#include <iostream>
-#include <fstream>
-#include <botan/botan.h>
-
-int main(int argc, char* argv[])
- {
- if(argc < 2)
- {
- std::cout << "Usage: " << argv[0] << " <filenames>" << std::endl;
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- // this is a pretty vacuous example, but it's useful as a test
- Botan::Pipe pipe;
-
- // CPS == Current Pipe Status, ie what Filters are set up
-
- pipe.prepend(new Botan::Hash_Filter("MD5"));
- // CPS: MD5
-
- pipe.prepend(new Botan::Hash_Filter("RIPEMD-160"));
- // CPS: RIPEMD-160 | MD5
-
- pipe.prepend(new Botan::Chain(
- new Botan::Hash_Filter("RIPEMD-160"),
- new Botan::Hash_Filter("RIPEMD-160")));
- // CPS: (RIPEMD-160 | RIPEMD-160) | RIPEMD-160 | MD5
-
- pipe.pop(); // will pop everything inside the Chain as well as Chain itself
- // CPS: RIPEMD-160 | MD5
-
- pipe.pop(); // will get rid of the RIPEMD-160 Hash_Filter
- // CPS: MD5
-
- pipe.prepend(new Botan::Hash_Filter("SHA-1"));
- // CPS: SHA-1 | MD5
-
- pipe.append(new Botan::Hex_Encoder);
- // CPS: SHA-1 | MD5 | Hex_Encoder
-
- pipe.prepend(new Botan::Hash_Filter("SHA-1"));
- // CPS: SHA-1 | SHA-1 | MD5 | Hex_Encoder
-
- pipe.pop(); // Get rid of the Hash_Filter(SHA-1)
- pipe.pop(); // Get rid of the other Hash_Filter(SHA-1)
- // CPS: MD5 | Hex_Encoder
- // The Hex_Encoder is safe because it is at the end of the Pipe,
- // and pop() pulls off the Filter that is at the start.
-
- pipe.prepend(new Botan::Hash_Filter("RIPEMD-160"));
- // CPS: RIPEMD-160 | MD5 | Hex_Encoder
-
- pipe.pop(); // Get rid of that last prepended Hash_Filter(RIPEMD-160)
- // CPS: MD5 | Hex_Encoder
-
- int skipped = 0;
- for(int j = 1; argv[j] != 0; j++)
- {
- std::ifstream file(argv[j], std::ios::binary);
- if(!file)
- {
- std::cout << "ERROR: could not open " << argv[j] << std::endl;
- skipped++;
- continue;
- }
- pipe.start_msg();
- file >> pipe;
- pipe.end_msg();
- file.close();
- pipe.set_default_msg(j-1-skipped);
- std::cout << pipe << " " << argv[j] << std::endl;
- }
- return 0;
- }
diff --git a/doc/examples/tls_client.cpp b/doc/examples/tls_client.cpp
deleted file mode 100644
index 10ead20cc..000000000
--- a/doc/examples/tls_client.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-* (C) 2008 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/init.h>
-#include <botan/tls_client.h>
-#include <botan/unx_sock.h>
-
-using namespace Botan;
-
-#include <stdio.h>
-#include <string>
-#include <iostream>
-#include <memory>
-
-class Client_TLS_Policy : public TLS_Policy
- {
- public:
- bool check_cert(const std::vector<X509_Certificate>& certs) const
- {
- for(size_t i = 0; i != certs.size(); ++i)
- {
- std::cout << certs[i].to_string();
- }
-
- std::cout << "Warning: not checking cert signatures\n";
-
- return true;
- }
- };
-
-int main(int argc, char* argv[])
- {
- if(argc != 2 && argc != 3)
- {
- printf("Usage: %s host [port]\n", argv[0]);
- return 1;
- }
-
- try
- {
- LibraryInitializer init;
-
- std::string host = argv[1];
- u32bit port = argc == 3 ? Botan::to_u32bit(argv[2]) : 443;
-
- printf("Connecting to %s:%d...\n", host.c_str(), port);
-
- Unix_Socket sock(argv[1], port);
-
- std::auto_ptr<Botan::RandomNumberGenerator> rng(
- Botan::RandomNumberGenerator::make_rng());
-
- Client_TLS_Policy policy;
-
- TLS_Client tls(std::tr1::bind(&Socket::read, std::tr1::ref(sock), _1, _2),
- std::tr1::bind(&Socket::write, std::tr1::ref(sock), _1, _2),
- policy, *rng);
-
- printf("Handshake extablished...\n");
-
-#if 0
- std::string http_command = "GET / HTTP/1.1\r\n"
- "Server: " + host + ':' + to_string(port) + "\r\n\r\n";
-#else
- std::string http_command = "GET / HTTP/1.0\r\n\r\n";
-#endif
-
- tls.write((const byte*)http_command.c_str(), http_command.length());
-
- u32bit total_got = 0;
-
- while(true)
- {
- if(tls.is_closed())
- break;
-
- byte buf[16+1] = { 0 };
- u32bit got = tls.read(buf, sizeof(buf)-1);
- printf("%s", buf);
- fflush(0);
-
- total_got += got;
- }
-
- printf("\nRetrieved %d bytes total\n", total_got);
- }
- catch(std::exception& e)
- {
- printf("%s\n", e.what());
- return 1;
- }
- return 0;
- }
diff --git a/doc/examples/tls_server.cpp b/doc/examples/tls_server.cpp
deleted file mode 100644
index da13953f8..000000000
--- a/doc/examples/tls_server.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
-* (C) 2008-2010 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/botan.h>
-#include <botan/tls_server.h>
-#include <botan/unx_sock.h>
-
-#include <botan/rsa.h>
-#include <botan/dsa.h>
-#include <botan/x509self.h>
-
-using namespace Botan;
-
-#include <stdio.h>
-#include <string>
-#include <iostream>
-#include <memory>
-
-class Server_TLS_Policy : public TLS_Policy
- {
- public:
- bool check_cert(const std::vector<X509_Certificate>& certs) const
- {
- for(size_t i = 0; i != certs.size(); ++i)
- {
- std::cout << certs[i].to_string();
- }
-
- std::cout << "Warning: not checking cert signatures\n";
-
- return true;
- }
- };
-int main(int argc, char* argv[])
- {
-
- int port = 4433;
-
- if(argc == 2)
- port = to_u32bit(argv[1]);
-
- try
- {
- LibraryInitializer init;
-
- AutoSeeded_RNG rng;
-
- //RSA_PrivateKey key(rng, 1024);
- DSA_PrivateKey key(rng, DL_Group("dsa/jce/1024"));
-
- X509_Cert_Options options(
- "localhost/US/Syn Ack Labs/Mathematical Munitions Dept");
-
- X509_Certificate cert =
- X509::create_self_signed_cert(options, key, "SHA-1", rng);
-
- Unix_Server_Socket listener(port);
-
- Server_TLS_Policy policy;
-
- while(true)
- {
- try {
- printf("Listening for new connection on port %d\n", port);
-
- Socket* sock = listener.accept();
-
- printf("Got new connection\n");
-
- TLS_Server tls(
- std::tr1::bind(&Socket::read, std::tr1::ref(sock), _1, _2),
- std::tr1::bind(&Socket::write, std::tr1::ref(sock), _1, _2),
- policy,
- rng,
- cert,
- key);
-
- std::string hostname = tls.requested_hostname();
-
- if(hostname != "")
- printf("Client requested host '%s'\n", hostname.c_str());
-
- printf("Writing some text\n");
-
- char msg[] = "Foo\nBar\nBaz\nQuux\n";
- tls.write((const byte*)msg, strlen(msg));
-
- printf("Now trying a read...\n");
-
- char buf[1024] = { 0 };
- u32bit got = tls.read((byte*)buf, sizeof(buf)-1);
- printf("%d: '%s'\n", got, buf);
-
- tls.close();
- }
- catch(std::exception& e) { printf("%s\n", e.what()); }
- }
- }
- catch(std::exception& e)
- {
- printf("%s\n", e.what());
- return 1;
- }
- return 0;
- }
diff --git a/doc/examples/toolbox.cpp b/doc/examples/toolbox.cpp
deleted file mode 100644
index 622a1f56f..000000000
--- a/doc/examples/toolbox.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/botan.h>
-
-#if defined(BOTAN_HAS_COMPRESSOR_BZIP2)
- #include <botan/bzip2.h>
-#endif
-
-#if defined(BOTAN_HAS_COMPRESSOR_ZLIB)
- #include <botan/zlib.h>
-#endif
-
-#include <iostream>
-#include <fstream>
-
-using namespace Botan;
-
-#include "../../checks/getopt.h"
-
-class Encoder_Decoder
- {
- public:
- Encoder_Decoder(const std::string& command,
- bool decode,
- const std::vector<std::string>& args) :
- type(command),
- args(args),
- decode(decode)
- { }
-
- void run(std::istream& in, std::ostream& out)
- {
- Filter* filt = decode ? decoder(type) : encoder(type);
-
- DataSource_Stream src(in);
- Pipe pipe(filt, new DataSink_Stream(out));
- pipe.process_msg(src);
- }
-
- Filter* encoder(const std::string& type) const
- {
- if(type == "hex") return new Hex_Encoder;
- if(type == "base64") return new Base64_Encoder;
-
-#if defined(BOTAN_HAS_COMPRESSOR_BZIP2)
- if(type == "bzip2") return new Bzip_Compression;
-#endif
-
-#if defined(BOTAN_HAS_COMPRESSOR_ZLIB)
- if(type == "zlib") return new Zlib_Compression;
-#endif
- return 0;
- }
-
- Filter* decoder(const std::string& type) const
- {
- if(type == "hex") return new Hex_Decoder;
- if(type == "base64") return new Base64_Decoder;
-
-#if defined(BOTAN_HAS_COMPRESSOR_BZIP2)
- if(type == "bzip2") return new Bzip_Decompression;
-#endif
-
-#if defined(BOTAN_HAS_COMPRESSOR_ZLIB)
- if(type == "zlib") return new Zlib_Decompression;
-#endif
-
- return 0;
- }
-
- private:
- std::string type;
- std::vector<std::string> args;
- bool decode;
- };
-
-void run_command(const std::string& command,
- const std::vector<std::string>& arguments,
- const OptionParser& opts)
- {
- if(command == "hex" ||
- command == "base64" ||
- command == "bzip2" ||
- command == "zlib")
- {
- bool decode = opts.is_set("decode");
-
- std::string output = opts.value_or_else("output", "-");
- std::string input = opts.value_or_else("input", "-");
-
- Encoder_Decoder enc_dec(command, decode, arguments);
-
- try
- {
- if(output == "-")
- {
- if(input == "-")
- enc_dec.run(std::cin, std::cout);
- else
- {
- std::ifstream in(input.c_str());
- enc_dec.run(in, std::cout);
- }
- }
- else // output != "-"
- {
- std::ofstream out(output.c_str());
-
- if(input == "-")
- enc_dec.run(std::cin, out);
- else
- {
- std::ifstream in(input.c_str());
- enc_dec.run(in, out);
- }
- }
- }
- catch(Botan::Stream_IO_Error& e)
- {
- std::cout << "I/O failure - " << e.what() << '\n';
- }
- }
- else if(command == "hash" ||
- command == "sha1" ||
- command == "md5")
- {
- std::string hash;
-
- if(command == "md5")
- hash = "MD5";
- if(command == "sha1")
- hash = "SHA-160";
- else
- hash = opts.value_or_else("hash", "SHA-160"); // sha1 is default
-
- Pipe pipe(new Hash_Filter(get_hash(hash)),
- new Hex_Encoder(false, 0, Hex_Encoder::Lowercase));
-
- for(size_t i = 0; i != arguments.size(); ++i)
- {
- std::string file_name = arguments[i];
-
- u32bit previously = pipe.message_count();
-
- if(file_name == "-")
- {
- pipe.start_msg();
- std::cin >> pipe;
- pipe.end_msg();
- }
- else
- {
- std::ifstream in(file_name.c_str());
- if(in)
- {
- pipe.start_msg();
- in >> pipe;
- pipe.end_msg();
- }
- else
- std::cerr << "Could not read " << file_name << '\n';
- }
-
- if(pipe.message_count() > previously)
- std::cout << pipe.read_all_as_string(Pipe::LAST_MESSAGE) << " "
- << file_name << '\n';
- }
-
- }
- else
- {
- std::cerr << "Command " << command << " not known\n";
- }
- }
-
-int main(int argc, char* argv[])
- {
- LibraryInitializer init;
-
- OptionParser opts("help|version|seconds=|"
- "input=|output=|decode|"
- "hash=|key=");
-
- try
- {
- opts.parse(argv);
- }
- catch(std::runtime_error& e)
- {
- std::cout << "Command line problem: " << e.what() << '\n';
- return 2;
- }
-
- if(opts.is_set("version") || argc <= 1)
- {
- std::cerr << "Botan Toolbox v" << version_string() << '\n';
- std::cerr << "Commands: hash hex base64 ";
-#if defined(BOTAN_HAS_COMPRESSOR_BZIP2)
- std::cerr << "bzip2 ";
-#endif
-
-#if defined(BOTAN_HAS_COMPRESSOR_ZLIB)
- std::cerr << "zlib ";
-#endif
-
- std::cerr << "\n";
-
- return 0;
- }
-
- if(opts.is_set("help"))
- {
- std::vector<std::string> what = opts.leftovers();
-
- for(size_t i = 0; i != what.size(); ++i)
- std::cerr << what[i] << "? Never heard of it\n";
- return 0;
- }
-
- std::vector<std::string> args = opts.leftovers();
-
- if(args.size() == 0)
- return 0;
-
- std::string command = args[0];
- args.erase(args.begin());
-
- run_command(command, args, opts);
-
- return 0;
- }
diff --git a/doc/examples/tss.cpp b/doc/examples/tss.cpp
deleted file mode 100644
index 03d7699bf..000000000
--- a/doc/examples/tss.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/botan.h>
-#include <botan/tss.h>
-#include <iostream>
-#include <stdio.h>
-
-namespace {
-
-void print(const Botan::SecureVector<Botan::byte>& r)
- {
- for(Botan::u32bit i = 0; i != r.size(); ++i)
- printf("%02X", r[i]);
- printf("\n");
- }
-
-}
-
-int main()
- {
- using namespace Botan;
-
- LibraryInitializer init;
-
- AutoSeeded_RNG rng;
-
- byte id[16];
- for(int i = 0; i != 16; ++i)
- id[i] = i;
-
- const byte S2[] = { 0xDE, 0xAD, 0xCA, 0xFE, 0xBA, 0xBE, 0xBE, 0xEF };
-
- std::vector<RTSS_Share> shares =
- RTSS_Share::split(4, 6, S2, sizeof(S2), id, rng);
-
- for(size_t i = 0; i != shares.size(); ++i)
- std::cout << i << " = " << shares[i].to_string() << "\n";
-
- print(RTSS_Share::reconstruct(shares));
- }
diff --git a/doc/examples/x509info.cpp b/doc/examples/x509info.cpp
deleted file mode 100644
index b22b4ebd8..000000000
--- a/doc/examples/x509info.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-* Read an X.509 certificate, and print various things about it
-* (C) 2003 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/botan.h>
-#include <botan/x509cert.h>
-using namespace Botan;
-
-#include <iostream>
-
-int main(int argc, char* argv[])
- {
- if(argc != 2)
- {
- std::cout << "Usage: " << argv[0] << " <x509cert>\n";
- return 1;
- }
-
- Botan::LibraryInitializer init;
-
- try {
- X509_Certificate cert(argv[1]);
-
- std::cout << cert.to_string();
- }
- catch(std::exception& e)
- {
- std::cout << e.what() << std::endl;
- return 1;
- }
- return 0;
- }
diff --git a/doc/filters.txt b/doc/filters.txt
new file mode 100644
index 000000000..8ce396371
--- /dev/null
+++ b/doc/filters.txt
@@ -0,0 +1,782 @@
+
+Information Flow: Pipes and Filters
+========================================
+
+Many common uses of cryptography involve processing one or more
+streams of data. Botan provides services that make setting up data
+flows through various operations, such as compression, encryption, and
+base64 encoding. Each of these operations is implemented in what are
+called *filters* in Botan. A set of filters are created and placed into
+a *pipe*, and information "flows" through the pipe until it reaches
+the end, where the output is collected for retrieval. If you're
+familiar with the Unix shell environment, this design will sound quite
+familiar.
+
+Here is an example that uses a pipe to base64 encode some strings::
+
+ Pipe pipe(new Base64_Encoder); // pipe owns the pointer
+ pipe.start_msg();
+ pipe.write("message 1");
+ pipe.end_msg(); // flushes buffers, increments message number
+
+ // process_msg(x) is start_msg() && write(x) && end_msg()
+ pipe.process_msg("message2");
+
+ std::string m1 = pipe.read_all_as_string(0); // "message1"
+ std::string m2 = pipe.read_all_as_string(1); // "message2"
+
+Bytestreams in the pipe are grouped into messages; blocks of data that
+are processed in an identical fashion (ie, with the same sequence of
+filter operations). Messages are delimited by calls to ``start_msg``
+and ``end_msg``. Each message in a pipe has its own identifier, which
+currently is an integer that increments up from zero.
+
+The ``Base64_Encoder`` was allocated using ``new``; but where was it
+deallocated? When a filter object is passed to a ``Pipe``, the pipe
+takes ownership of the object, and will deallocate it when it is no
+longer needed.
+
+There are two different ways to make use of messages. One is to send
+several messages through a ``Pipe`` without changing the ``Pipe``
+configuration, so you end up with a sequence of messages; one use of
+this would be to send a sequence of identically encrypted UDP packets,
+for example (note that the *data* need not be identical; it is just
+that each is encrypted, encoded, signed, etc in an identical
+fashion). Another is to change the filters that are used in the
+``Pipe`` between each message, by adding or removing filters;
+functions that let you do this are documented in the Pipe API section.
+
+Botan has about 40 filters that perform different operations on data.
+Here's code that uses one of them to encrypt a string with AES::
+
+ AutoSeeded_RNG rng,
+ SymmetricKey key(rng, 16); // a random 128-bit key
+ InitializationVector iv(rng, 16); // a random 128-bit IV
+
+ // The algorithm we want is specified by a string
+ Pipe pipe(get_cipher("AES-128/CBC", key, iv, ENCRYPTION));
+
+ pipe.process_msg("secrets");
+ pipe.process_msg("more secrets");
+
+ MemoryVector<byte> c1 = pipe.read_all(0);
+
+ byte c2[4096] = { 0 };
+ size_t got_out = pipe.read(c2, sizeof(c2), 1);
+ // use c2[0...got_out]
+
+Note the use of ``AutoSeeded_RNG``, which is a random number
+generator. If you want to, you can explicitly set up the random number
+generators and entropy sources you want to, however for 99% of cases
+``AutoSeeded_RNG`` is preferable.
+
+``Pipe`` also has convenience methods for dealing with
+``std::iostream``s. Here is an example of those, using the
+``Bzip_Compression`` filter (included as a module; if you have bzlib
+available, check the build instructions for how to enable it) to
+compress a file::
+
+ std::ifstream in("data.bin", std::ios::binary)
+ std::ofstream out("data.bin.bz2", std::ios::binary)
+
+ Pipe pipe(new Bzip_Compression);
+
+ pipe.start_msg();
+ in >> pipe;
+ pipe.end_msg();
+ out << pipe;
+
+However there is a hitch to the code above; the complete contents of
+the compressed data will be held in memory until the entire message
+has been compressed, at which time the statement ``out << pipe`` is
+executed, and the data is freed as it is read from the pipe and
+written to the file. But if the file is very large, we might not have
+enough physical memory (or even enough virtual memory!) for that to be
+practical. So instead of storing the compressed data in the pipe for
+reading it out later, we divert it directly to the file::
+
+ std::ifstream in("data.bin", std::ios::binary)
+ std::ofstream out("data.bin.bz2", std::ios::binary)
+
+ Pipe pipe(new Bzip_Compression, new DataSink_Stream(out));
+
+ pipe.start_msg();
+ in >> pipe;
+ pipe.end_msg();
+
+This is the first code we've seen so far that uses more than one
+filter in a pipe. The output of the compressor is sent to the
+``DataSink_Stream``. Anything written to a ``DataSink_Stream`` is
+written to a file; the filter produces no output. As soon as the
+compression algorithm finishes up a block of data, it will send it
+along, at which point it will immediately be written to disk; if you
+were to call ``pipe.read_all()`` after ``pipe.end_msg()``, you'd get
+an empty vector out.
+
+Here's an example using two computational filters::
+
+ AutoSeeded_RNG rng,
+ SymmetricKey key(rng, 32);
+ InitializationVector iv(rng, 16);
+
+ Pipe encryptor(get_cipher("AES/CBC/PKCS7", key, iv, ENCRYPTION),
+ new Base64_Encoder);
+
+ encryptor.start_msg();
+ file >> encryptor;
+ encryptor.end_msg(); // flush buffers, complete computations
+ std::cout << encryptor;
+
+Fork
+---------------------------------
+
+It is common that you might receive some data and want to perform more
+than one operation on it (ie, encrypt it with Serpent and calculate
+the SHA-256 hash of the plaintext at the same time). That's where
+``Fork`` comes in. ``Fork`` is a filter that takes input and passes it
+on to *one or more* filters that are attached to it. ``Fork`` changes
+the nature of the pipe system completely: instead of being a linked
+list, it becomes a tree or acyclic graph.
+
+Each filter in the fork is given its own output buffer, and thus its
+own message. For example, if you had previously written two messages
+into a pipe, then you start a new one with a fork that has three
+paths of filter's inside it, you add three new messages to the
+pipe. The data you put into the pipe is duplicated and sent
+into each set of filter and the eventual output is placed into a
+dedicated message slot in the pipe.
+
+Messages in the pipe are allocated in a depth-first manner. This is only
+interesting if you are using more than one fork in a single pipe.
+As an example, consider the following::
+
+ Pipe pipe(new Fork(
+ new Fork(
+ new Base64_Encoder,
+ new Fork(
+ NULL,
+ new Base64_Encoder
+ )
+ ),
+ new Hex_Encoder
+ )
+ );
+
+In this case, message 0 will be the output of the first
+``Base64_Encoder``, message 1 will be a copy of the input (see below
+for how fork interprets NULL pointers), message 2 will be the output
+of the second ``Base64_Encoder``, and message 3 will be the output of
+the ``Hex_Encoder``. This results in message numbers being allocated
+in a top to bottom fashion, when looked at on the screen. However,
+note that there could be potential for bugs if this is not
+anticipated. For example, if your code is passed a filter, and you
+assume it is a "normal" one that only uses one message, your message
+offsets would be wrong, leading to some confusion during output.
+
+If Fork's first argument is a null pointer, but a later argument is
+not, then Fork will feed a copy of its input directly through. Here's
+a case where that is useful::
+
+ // have std::string ciphertext, auth_code, key, iv, mac_key;
+
+ Pipe pipe(new Base64_Decoder,
+ get_cipher(``AES-128'', key, iv, DECRYPTION),
+ new Fork(
+ 0
+ new MAC_Filter(``HMAC(SHA-1)'', mac_key)
+ )
+ );
+
+ pipe.process_msg(ciphertext);
+ std::string plaintext = pipe.read_all_as_string(0);
+ SecureVector<byte> mac = pipe.read_all(1);
+
+ if(mac != auth_code)
+ error();
+
+Here we wanted to not only decrypt the message, but send the decrypted
+text through an additional computation, in order to compute the
+authentication code.
+
+Any filters that are attached to the pipe after the fork are
+implicitly attached onto the first branch created by the fork. For
+example, let's say you created this pipe::
+
+ Pipe pipe(new Fork(new Hash_Filter("MD5"), new Hash_Filter("SHA-1")),
+ new Hex_Encoder);
+
+And then called ``start_msg``, inserted some data, then
+``end_msg``. Then ``pipe`` would contain two messages. The
+first one (message number 0) would contain the MD5 sum of the input in
+hex encoded form, and the other would contain the SHA-1 sum of the
+input in raw binary. However, it's much better to use a ``Chain``
+instead.
+
+Chain
+---------------------------------
+
+A ``Chain`` filter creates a chain of filters and encapsulates them
+inside a single filter (itself). This allows a sequence of filters to
+become a single filter, to be passed into or out of a function, or to
+a ``Fork`` constructor.
+
+You can call ``Chain``'s constructor with up to four ``Filter``
+pointers (they will be added in order), or with an array of filter
+pointers and a ``size_t`` that tells ``Chain`` how many filters are in
+the array (again, they will be attached in order). Here's the example
+from the last section, using chain instead of relying on the implicit
+passthrough the other version used::
+
+ Pipe pipe(new Fork(
+ new Chain(new Hash_Filter("MD5"), new Hex_Encoder),
+ new Hash_Filter("SHA-1")
+ )
+ );
+
+Sources and Sinks
+----------------------------------------
+
+Data Sources
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A ``DataSource`` is a simple abstraction for a thing that stores bytes. This
+type is used heavily in the areas of the API related to ASN.1
+encoding/decoding. The following types are ``DataSource``s: ``Pipe``,
+``SecureQueue``, and a couple of special purpose ones:
+``DataSource_Memory`` and ``DataSource_Stream``.
+
+You can create a ``DataSource_Memory`` with an array of bytes and a length
+field. The object will make a copy of the data, so you don't have to worry
+about keeping that memory allocated. This is mostly for internal use, but if it
+comes in handy, feel free to use it.
+
+A ``DataSource_Stream`` is probably more useful than the memory based
+one. Its constructors take either a ``std::istream`` or a
+``std::string``. If it's a stream, the data source will use the
+``istream`` to satisfy read requests (this is particularly useful to use
+with ``std::cin``). If the string version is used, it will attempt to open
+up a file with that name and read from it.
+
+Data Sinks
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A ``DataSink`` (in ``data_snk.h``) is a ``Filter`` that
+takes arbitrary amounts of input, and produces no output. This means
+it's doing something with the data outside the realm of what
+``Filter``/``Pipe`` can handle, for example, writing it to a
+file (which is what the ``DataSink_Stream`` does). There is no
+need for ``DataSink``s that write to a ``std::string`` or memory
+buffer, because ``Pipe`` can handle that by itself.
+
+Here's a quick example of using a ``DataSink``, which encrypts
+``in.txt`` and sends the output to ``out.txt``. There is
+no explicit output operation; the writing of ``out.txt`` is
+implicit::
+
+ DataSource_Stream in("in.txt");
+ Pipe pipe(new CBC_Encryption("AES-128", "PKCS7", key, iv),
+ new DataSink_Stream("out.txt"));
+ pipe.process_msg(in);
+
+A real advantage of this is that even if "in.txt" is large, only as
+much memory is needed for internal I/O buffers will be used.
+
+The Pipe API
+---------------------------------
+
+Initializing Pipe
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+By default, ``Pipe`` will do nothing at all; any input placed into the
+``Pipe`` will be read back unchanged. Obviously, this has limited
+utility, and presumably you want to use one or more filters to somehow
+process the data. First, you can choose a set of filters to initialize
+the ``Pipe`` via the constructor. You can pass it either a set of up
+to four filter pointers, or a pre-defined array and a length::
+
+ Pipe pipe1(new Filter1(/*args*/), new Filter2(/*args*/),
+ new Filter3(/*args*/), new Filter4(/*args*/));
+ Pipe pipe2(new Filter1(/*args*/), new Filter2(/*args*/));
+
+ Filter* filters[5] = {
+ new Filter1(/*args*/), new Filter2(/*args*/), new Filter3(/*args*/),
+ new Filter4(/*args*/), new Filter5(/*args*/) /* more if desired... */
+ };
+ Pipe pipe3(filters, 5);
+
+This is by far the most common way to initialize a ``Pipe``. However,
+occasionally a more flexible initialization strategy is necessary;
+this is supported by 4 member functions. These functions may only be
+used while the pipe in question is not in use; that is, either before
+calling ``start_msg``, or after ``end_msg`` has been called (and no
+new calls to ``start_msg`` have been made yet).
+
+.. cpp:function:: void Pipe::prepend(Filter* filter)
+
+ Calling ``prepend`` will put the passed filter first in the list of
+ transformations. For example, if you prepend a filter implementing
+ encryption, and the pipe already had a filter that hex encoded the
+ input, then the next message processed would be first encrypted,
+ and *then* hex encoded.
+
+.. cpp:function:: void Pipe::append(Filter* filter)
+
+ Like ``prepend``, but places the filter at the end of the message
+ flow. This doesn't always do what you expect if there is a fork.
+
+.. cpp:function:: void Pipe::pop()
+
+ Removes the first filter in the flow.
+
+.. cpp:function:: void Pipe::reset()
+
+ Removes all the filters that the pipe currently holds - it is reset
+ to an empty/no-op state. Any data that is being retained by the
+ pipe is retained after a ``reset``, and ``reset`` does not affect
+ message numbers (discussed later).
+
+Giving Data to a Pipe
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Input to a ``Pipe`` is delimited into messages, which can be read from
+independently (ie, you can read 5 bytes from one message, and then all of
+another message, without either read affecting any other messages).
+
+.. cpp:function:: void Pipe::start_msg()
+
+ Starts a new message; if a message was already running, an exception is
+ thrown. After this function returns, you can call ``write``.
+
+.. cpp:function:: void Pipe::write(const byte* input, size_t length)
+
+.. cpp:function:: void Pipe::write(const MemoryRegion<byte>& input)
+
+.. cpp:function:: void Pipe::write(const std::string& input)
+
+.. cpp:function:: void Pipe::write(DataSource& input)
+
+.. cpp:function:: void Pipe::write(byte input)
+
+ All versions of ``write`` write the input into the filter sequence.
+ If a message is not currently active, an exception is thrown.
+
+.. cpp:function:: void Pipe::end_msg()
+
+ End the currently active message
+
+Sometimes, you may want to do only a single write per message. In this
+case, you can use the ``process_msg`` series of functions, which start
+a message, write their argument into the pipe, and then end the
+message. In this case you would not make any explicit calls to
+``start_msg``/``end_msg``.
+
+Pipes can also be used with the ``>>`` operator, and will accept a
+``std::istream``, or on Unix systems with the ``fd_unix`` module, a
+Unix file descriptor. In either case, the entire contents of the file
+will be read into the pipe.
+
+Getting Output from a Pipe
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Retrieving the processed data from a pipe is a bit more complicated,
+for various reasons. The pipe will separate each message into a
+separate buffer, and you have to retrieve data from each message
+independently. Each of the reader functions has a final parameter that
+specifies what message to read from. If this parameter is set to
+``Pipe::DEFAULT_MESSAGE``, it will read the current default message
+(``DEFAULT_MESSAGE`` is also the default value of this parameter).
+
+Functions in ``Pipe`` related to reading include:
+
+.. cpp:function:: size_t Pipe::read(byte* out, size_t len)
+
+ Reads up to ``len`` bytes into ``out``, and returns the number of
+ bytes actually read.
+
+.. cpp:function:: size_t Pipe::peek(byte* out, size_t len)
+
+ Acts exactly like `read`, except the data is not actually read; the
+ next read will return the same data.
+
+.. cpp:function:: SecureVector<byte> Pipe::read_all()
+
+ Reads the entire message into a buffer and returns it
+
+.. cpp:function:: std::string Pipe::read_all_as_string()
+
+ Like ``read_all``, but it returns the data as a ``std::string``.
+ No encoding is done; if the message contains raw binary, so will
+ the string.
+
+.. cpp:function:: size_t Pipe::remaining()
+
+ Returns how many bytes are left in the message
+
+.. cpp:function:: Pipe::message_id default_msg()
+
+ Returns the current default message number
+
+.. cpp:function:: Pipe::message_id Pipe::message_count()
+
+ Returns the total number of messages currently in the pipe
+
+.. cpp:function:: Pipe::set_default_msg(Pipe::message_id msgno)
+
+ Sets the default message number (which must be a valid message
+ number for that pipe). The ability to set the default message number
+ is particularly important in the case of using the file output
+ operations (``<<`` with a ``std::ostream`` or Unix file descriptor),
+ because there is no way to specify the message explicitly when using
+ the output operator.
+
+Pipe I/O for Unix File Descriptors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This is a minor feature, but it comes in handy sometimes. In all
+installations of the library, Botan's ``Pipe`` object overloads the
+``<<`` and ``>>`` operators for C++ iostream objects,
+which is usually more than sufficient for doing I/O.
+
+However, there are cases where the iostream hierarchy does not map well to
+local 'file types', so there is also the ability to do I/O directly with Unix
+file descriptors. This is most useful when you want to read from or write to
+something like a TCP or Unix-domain socket, or a pipe, since for simple file
+access it's usually easier to just use C++'s file streams.
+
+If ``BOTAN_EXT_PIPE_UNIXFD_IO`` is defined, then you can use the
+overloaded I/O operators with Unix file descriptors. For an example of this,
+check out the ``hash_fd`` example, included in the Botan distribution.
+
+A Filter Example
+---------------------------------
+
+Here is some code that takes one or more filenames in ``argv`` and
+calculates the result of several hash functions for each file. The complete
+program can be found as ``hasher.cpp`` in the Botan distribution. For
+brevity, error checking has been removed::
+
+ string name[3] = { "MD5", "SHA-1", "RIPEMD-160" };
+ Filter* hash[3] = {
+ new Chain(new Hash_Filter(name[0]),
+ new Hex_Encoder),
+ new Chain(new Hash_Filter(name[1]),
+ new Hex_Encoder),
+ new Chain(new Hash_Filter(name[2]),
+ new Hex_Encoder) };
+
+ Pipe pipe(new Fork(hash, COUNT));
+
+ for(size_t j = 1; argv[j] != 0; j++)
+ {
+ ifstream file(argv[j]);
+ pipe.start_msg();
+ file >> pipe;
+ pipe.end_msg();
+ file.close();
+ for(size_t k = 0; k != 3; k++)
+ {
+ pipe.set_default_msg(3*(j-1)+k);
+ cout << name[k] << "(" << argv[j] << ") = " << pipe << endl;
+ }
+ }
+
+
+Filter Catalog
+---------------------------------
+
+This section documents most of the useful filters included in the
+library.
+
+Keyed Filters
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A few sections ago, it was mentioned that ``Pipe`` can process
+multiple messages, treating each of them the same. Well, that was a
+bit of a lie. There are some algorithms (in particular, block ciphers
+not in ECB mode, and all stream ciphers) that change their state as
+data is put through them.
+
+Naturally, you might well want to reset the keys or (in the case of
+block cipher modes) IVs used by such filters, so multiple messages can
+be processed using completely different keys, or new IVs, or new keys
+and IVs, or whatever. And in fact, even for a MAC or an ECB block
+cipher, you might well want to change the key used from message to
+message.
+
+Enter ``Keyed_Filter``, which acts as an abstract interface for any
+filter that is uses keys: block cipher modes, stream ciphers, MACs,
+and so on. It has two functions, ``set_key`` and ``set_iv``. Calling
+``set_key`` will set (or reset) the key used by the algorithm. Setting
+the IV only makes sense in certain algorithms -- a call to ``set_iv``
+on an object that doesn't support IVs will cause an exception. You
+must call ``set_key`` *before* calling ``set_iv``.
+
+Here's a example::
+
+ Keyed_Filter *cast, *hmac;
+ Pipe pipe(new Base64_Decoder,
+ // Note the assignments to the cast and hmac variables
+ cast = new CBC_Decryption("CAST-128", "PKCS7", cast_key, iv),
+ new Fork(
+ 0, // Read the section 'Fork' to understand this
+ new Chain(
+ hmac = new MAC_Filter("HMAC(SHA-1)", mac_key, 12),
+ new Base64_Encoder
+ )
+ )
+ );
+ pipe.start_msg();
+ // use pipe for a while, decrypt some stuff, derive new keys and IVs
+ pipe.end_msg();
+
+ cast->set_key(cast_key2);
+ cast->set_iv(iv2);
+ hmac->set_key(mac_key2);
+
+ pipe.start_msg();
+ // use pipe for some other things
+ pipe.end_msg();
+
+There are some requirements to using ``Keyed_Filter`` that you must
+follow. If you call ``set_key`` or ``set_iv`` on a filter that
+is owned by a ``Pipe``, you must do so while the ``Pipe`` is
+"unlocked". This refers to the times when no messages are being processed by
+``Pipe`` -- either before ``Pipe``'s ``start_msg`` is called, or
+after ``end_msg`` is called (and no new call to ``start_msg``
+has happened yet). Doing otherwise will result in undefined behavior, probably
+silently getting invalid output.
+
+And remember: if you're resetting both values, reset the key *first*.
+
+Cipher Filters
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Getting a hold of a ``Filter`` implementing a cipher is very
+easy. Make sure you're including the header ``lookup.h``, and
+then call ``get_cipher``. You will pass the return value
+directly into a ``Pipe``. There are a couple different functions
+which do varying levels of initialization:
+
+.. cpp:function:: Keyed_Filter* get_cipher(std::string cipher_spec, SymmetricKey key, InitializationVector iv, Cipher_Dir dir)
+
+.. cpp:function:: Keyed_Filter* get_cipher(std::string cipher_spec, SymmetricKey key, Cipher_Dir dir)
+
+The version that doesn't take an IV is useful for things that don't
+use them, like block ciphers in ECB mode, or most stream ciphers. If
+you specify a cipher spec that does want a IV, and you use the version
+that doesn't take one, an exception will be thrown. The ``dir``
+argument can be either ``ENCRYPTION`` or ``DECRYPTION``.
+
+The cipher_spec is a string that specifies what cipher is to be
+used. The general syntax for "cipher_spec" is "STREAM_CIPHER",
+"BLOCK_CIPHER/MODE", or "BLOCK_CIPHER/MODE/PADDING". In the case of
+stream ciphers, no mode is necessary, so just the name is
+sufficient. A block cipher requires a mode of some sort, which can be
+"ECB", "CBC", "CFB(n)", "OFB", "CTR-BE", or "EAX(n)". The argument to
+CFB mode is how many bits of feedback should be used. If you just use
+"CFB" with no argument, it will default to using a feedback equal to
+the block size of the cipher. EAX mode also takes an optional bit
+argument, which tells EAX how large a tag size to use~--~generally
+this is the size of the block size of the cipher, which is the default
+if you don't specify any argument.
+
+In the case of the ECB and CBC modes, a padding method can also be
+specified. If it is not supplied, ECB defaults to not padding, and CBC
+defaults to using PKCS #5/#7 compatible padding. The padding methods
+currently available are "NoPadding", "PKCS7", "OneAndZeros", and
+"CTS". CTS padding is currently only available for CBC mode, but the
+others can also be used in ECB mode.
+
+Some example "cipher_spec arguments are: "AES-128/CBC",
+"Blowfish/CTR-BE", "Serpent/XTS", and "AES-256/EAX".
+
+"CTR-BE" refers to counter mode where the counter is incremented as if
+it were a big-endian encoded integer. This is compatible with most
+other implementations, but it is possible some will use the
+incompatible little endian convention. This version would be denoted
+as "CTR-LE" if it were supported.
+
+"EAX" is a new cipher mode designed by Wagner, Rogaway, and
+Bellare. It is an authenticated cipher mode (that is, no separate
+authentication is needed), has provable security, and is free from
+patent entanglements. It runs about half as fast as most of the other
+cipher modes (like CBC, OFB, or CTR), which is not bad considering you
+don't need to use an authentication code.
+
+Hashes and MACs
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Hash functions and MACs don't need anything special when it comes to
+filters. Both just take their input and produce no output until
+``end_msg`` is called, at which time they complete the hash or MAC and
+send that as output.
+
+These filters take a string naming the type to be used. If for some
+reason you name something that doesn't exist, an exception will be thrown.
+
+.. cpp:function:: Hash_Filter::Hash_Filter(std::string hash, size_t outlen = 0)
+
+ This constructor creates a filter that hashes its input with
+ ``hash``. When ``end_msg`` is called on the owning pipe, the hash is
+ completed and the digest is sent on to the next filter in the
+ pipeline. The parameter ``outlen`` specifies how many bytes of the
+ hash output will be passed along to the next filter when ``end_msg``
+ is called. By default, it will pass the entire hash.
+
+ Examples of names for ``Hash_Filter`` are "SHA-1" and "Whirlpool".
+
+.. cpp:function:: MAC_Filter::MAC_Filter(std::string mac, SymmetricKey key, size_t outlen = 0)
+
+ This constructor takes a name for a mac, such as "HMAC(SHA-1)" or
+ "CMAC(AES-128)", along with a key to use. The optional ``outlen``
+ works the same as in ``Hash_Filter``.
+
+PK Filters
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+There are four classes in this category, ``PK_Encryptor_Filter``,
+``PK_Decryptor_Filter``, ``PK_Signer_Filter``, and
+``PK_Verifier_Filter``. Each takes a pointer to an object of the
+appropriate type (``PK_Encryptor``, ``PK_Decryptor``, etc) that is
+deleted by the destructor. These classes are found in ``pk_filts.h``.
+
+Three of these, for encryption, decryption, and signing are much the
+same in terms of dataflow - ach of them buffers its input until the
+end of the message is marked with a call to the ``end_msg``
+function. Then they encrypt, decrypt, or sign the entire input as a
+single blob and send the output (the ciphertext, the plaintext, or the
+signature) into the next filter.
+
+Signature verification works a little differently, because it needs to
+know what the signature is in order to check it. You can either pass
+this in along with the constructor, or call the function
+``set_signature`` -- with this second method, you need to keep
+a pointer to the filter around so you can send it this command. In
+either case, after ``end_msg`` is called, it will try to
+verify the signature (if the signature has not been set by either
+method, an exception will be thrown here). It will then send a single
+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`.
+
+Encoders
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Often you want your data to be in some form of text (for sending over
+channels that aren't 8-bit clean, printing it, etc). The filters
+``Hex_Encoder`` and ``Base64_Encoder`` will convert arbitrary binary
+data into hex or base64 formats. Not surprisingly, you can use
+``Hex_Decoder`` and ``Base64_Decoder`` to convert it back into its
+original form.
+
+Both of the encoders can take a few options about how the data should
+be formatted (all of which have defaults). The first is a ``bool``
+which says if the encoder should insert line breaks. This defaults to
+false. Line breaks don't matter either way to the decoder, but it
+makes the output a bit more appealing to the human eye, and a few
+transport mechanisms (notably some email systems) limit the maximum
+line length.
+
+The second encoder option is an integer specifying how long such lines
+will be (obviously this will be ignored if line-breaking isn't being
+used). The default tends to be in the range of 60-80 characters, but
+is not specified. If you want a specific value, set it. Otherwise the
+default should be fine.
+
+Lastly, ``Hex_Encoder`` takes an argument of type ``Case``, which can
+be ``Uppercase`` or ``Lowercase`` (default is ``Uppercase``). This
+specifies what case the characters A-F should be output as. The base64
+encoder has no such option, because it uses both upper and lower case
+letters for its output.
+
+You can find the declarations for these types in ``hex_filt.h`` and
+``b64_filt.h``.
+
+Compressors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+There are two compression algorithms supported by Botan, zlib and
+bzip2. Only lossless compression algorithms are currently supported by
+Botan, because they tend to be the most useful for
+cryptography. However, it is very reasonable to consider supporting
+something like GSM speech encoding (which is lossy), for use in
+encrypted voice applications.
+
+You should always compress *before* you encrypt, because encryption seeks
+to hide the redundancy that compression is supposed to try to find and remove.
+
+To test for Bzip2, check to see if ``BOTAN_HAS_COMPRESSOR_BZIP2`` is
+defined. If so, you can include ``botan/bzip2.h``, which will declare
+a pair of ``Filter`` objects: ``Bzip2_Compression`` and
+``Bzip2_Decompression``.
+
+You should be prepared to take an exception when using the
+decompressing filter, for if the input is not valid bzip2 data, that
+is what you will receive. You can specify the desired level of
+compression to ``Bzip2_Compression``'s constructor as an integer
+between 1 and 9, 1 meaning worst compression, and 9 meaning the
+best. The default is to use 9, since small values take the same amount
+of time, just use a little less memory.
+
+Zlib compression works much like Bzip2 compression. The only
+differences in this case are that the macro is
+``BOTAN_HAS_COMPRESSOR_ZLIB``, the header you need to include is
+called ``botan/zlib.h`` (remember that you shouldn't just ``#include
+<zlib.h>``, or you'll get the regular zlib API, which is not what you
+want). The Botan classes for zlib compression/decompression are called
+``Zlib_Compression`` and ``Zlib_Decompression``.
+
+Like Bzip2, a ``Zlib_Decompression`` object will throw an exception if
+invalid (in the sense of not being in the Zlib format) data is passed
+into it.
+
+While the zlib compression library uses the same compression algorithm
+as the gzip and zip programs, the format is different. The zlib format
+is defined in RFC 1950.
+
+Writing New Filters
+---------------------------------
+
+The system of filters and pipes was designed in an attempt to make it
+as simple as possible to write new filter types. There are four
+functions that need to be implemented by a class deriving from
+``Filter``:
+
+.. cpp:function:: void Filter::write(const byte* input, size_t length)
+
+ This function is what is called when a filter receives input for it
+ to process. The filter is not required to process the data right
+ away; many filters buffer their input before producing any output. A
+ filter will usually have ``write`` called many times during its
+ lifetime.
+
+.. cpp:function:: void Filter::send(byte* output, size_t length)
+
+ Eventually, a filter will want to produce some output to send along
+ to the next filter in the pipeline. It does so by calling ``send``
+ with whatever it wants to send along to the next filter. There is
+ also a version of ``send`` taking a single byte argument, as a
+ convenience.
+
+.. cpp:function:: void Filter::start_msg()
+
+ Implementing this function is optional. Implement it if your filter
+ would like to do some processing or setup at the start of each
+ message, such as allocating a data structure.
+
+.. cpp:function:: void Filter::end_msg()
+
+ Implementing this function is optional. It is called when it has
+ been requested that filters finish up their computations. The filter
+ should finish up with whatever computation it is working on (for
+ example, a compressing filter would flush the compressor and
+ ``send`` the final block), and empty any buffers in preparation for
+ processing a fresh new set of input.
+
+Additionally, if necessary, filters can define a constructor that
+takes any needed arguments, and a destructor to deal with deallocating
+memory, closing files, etc.
+
diff --git a/doc/fips140.tex b/doc/fips140.tex
deleted file mode 100644
index 8b2004508..000000000
--- a/doc/fips140.tex
+++ /dev/null
@@ -1,156 +0,0 @@
-\documentclass{article}
-
-\setlength{\textwidth}{6.5in}
-\setlength{\textheight}{9in}
-
-\setlength{\headheight}{0in}
-\setlength{\topmargin}{0in}
-\setlength{\headsep}{0in}
-
-\setlength{\oddsidemargin}{0in}
-\setlength{\evensidemargin}{0in}
-
-\title{\textbf{Botan FIPS 140-2 Security Policy}}
-\author{Jack Lloyd \\
- \texttt{[email protected]}}
-\date{}
-
-\newcommand{\filename}[1]{\texttt{#1}}
-\newcommand{\module}[1]{\texttt{#1}}
-
-\newcommand{\type}[1]{\texttt{#1}}
-\newcommand{\function}[1]{\textbf{#1}}
-\newcommand{\macro}[1]{\texttt{#1}}
-
-\begin{document}
-
-\maketitle
-
-\tableofcontents
-
-\parskip=5pt
-%\baselineskip=15pt
-
-\pagebreak
-
-\section{Introduction}
-
-\emph{Note that this is a draft, and almost certainly does not comply with what
-FIPS 140-2 wants (also it's incomplete). In any case, there is no way for me to
-afford paying the validation lab, so this is all theoretical.}
-
-\emph{I would welcome comments from people who are familiar with the FIPS 140
-process. I am currently basing this off a few dozen other security policies and
-the FIPS itself.}
-
-\subsection{Purpose}
-
-This document is a security policy for the Botan C++ crypto library for use in
-a FIPS 140-2 Level 1 validation process. It describes how to configure and use
-the library to comply with the requirements of FIPS 140-2.
-
-This document is non-proprietary, and may be freely reproduced and distributed
-in unmodified form.
-
-\subsection{Product Description}
-
-The Botan C++ crypto library (hereafter ``Botan'' or ``the library'') is an
-open source C++ class library providing a general-purpose interface to a wide
-variety of cryptographic algorithms and formats (such as X.509v3 and PKCS
-\#10). It runs on most Win32 and POSIX-like systems, including Windows
-NT/2000/XP, MacOS X, Linux, Solaris, FreeBSD, and QNX. However, only versions
-running on \emph{(goal:)} Windows XP, Linux, and Solaris have been validated by
-FIPS 140-2 at this time.
-
-\subsection{Algorithms}
-
-The library contains the following FIPS Approved algorithms: RSA, DSA, DES,
-TripleDES, Skipjack, AES, SHA-1, HMAC, the X9.19 DES MAC, and the FIPS 186-2
-SHA-1 RNG. Other (non-Approved) algorithms, such as MD5 and Diffie-Hellman, are
-also included.
-
-\section{Initialization}
-
-Certain tests are only performed if the flag ``fips140'' is passed as part of
-the initialization process to the library (the argument to
-\type{LibraryInitializer} or \function{Init::initialize}). Known answer tests
-and key generation self-checks for RSA and DSA are always performed, regardless
-of this setting. This flag must be passed by any application which desires
-using the FIPS 140 mode of operation.
-
-\section{Roles and Services}
-
-Botan supports two roles, the User and the Crypto Officer. Authentication is
-not performed by the module; all authentication is implicitly done by the
-operating system.
-
-\subsection{User Role}
-
-The user has the ability to access the services of the module. This role is
-implicitly selected whenever the module's services are accessed.
-
-\subsection{Crypto Officer Role}
-
-The crypto officer has all of the powers of the user, and in addition has the
-power to install and uninstall the module and to configure the operating
-system. This role is implicitly selected whenever these actions are performed.
-
-\section{Key Management}
-
-\subsection{Key Import/Export}
-
-Symmetric keys can be imported and exported in either unencrypted, encrypted,
-or split-knowledge forms, as the application desires. Private keys for
-asymmetric algorithms can be imported and exported as either encrypted or
-unencrypted PKCS \#8 structures. The library natively supports PKCS \#5
-encryption with TripleDES for encrypting private keys.
-
-\subsection{Key Storage}
-
-In no case does the library itself import or export keys from/to an external
-storage device; all such operations are done explicitly by the application. It
-is the responsibly of the operator to ensure than any such operations comply
-with the requirements of FIPS 140-2 Level 1.
-
-\subsection{Key Generation}
-
-Keys for symmetric algorithms (such as DES, AES, and HMAC) are generated by an
-Approved RNG, by generating a random byte string of the appropriate size, and
-using it as a key.
-
-DSA keys are generated as specified in FIPS 186-2 (or not?). RSA keys are
-generated as specified in ANSI X9.31 (\emph{I think...}). Diffie-Hellman keys
-are generated in a manner compatible with ANSI X9.42. All newly created DSA and
-RSA keys are checked with a pairwise consistency test before being returned to
-the caller. A pairwise consistency check can be performed on any RSA, DSA, or
-Diffie-Hellman key by calling the \function{check\_key} member function with
-an argument of \type{true}.
-
-\subsection{Key Establishment}
-
-Botan supports using RSA or Diffie-Hellman to establish keys. RSA can be used
-with PKCS \#1 v1.5 or OAEP padding. None of these methods are FIPS Approved,
-but Annex D of FIPS 140-2 allows for their use until such time as a FIPS
-Approved asymmetric key establishment method is established.
-
-\subsection{Key Protection / Zeroization}
-
-Keys are protected against external access by the operating system's memory and
-process protection mechanisms. If the library is used by multiple processes at
-once, the OS virtual memory mechanisms ensure that each version will have it's
-own data space (and thus, keys are not shared among multiple processes).
-
-All keys and other sensitive materials are zeroed in memory before being
-released to the system.
-
-On Windows systems the \function{VirtualLock} system call is used to notify the
-operating system that the memory containing potentially sensitive keying
-material is not swapped to disk, preventing an attacker from applying disk
-forenistics techniques to recovery data.
-
-On Unix systems, Botan allocates memory from file-backed memory mappings, which
-are thoroughly erased when the memory is freed.
-
-\section{References}
-
-\end{document}
diff --git a/doc/indent.el b/doc/indent.el
index 9811bf848..7fa2540b0 100644
--- a/doc/indent.el
+++ b/doc/indent.el
@@ -2,19 +2,14 @@
; get everything perfectly correct, but it's pretty close. Copy this code into
; your .emacs file, or use M-x eval-buffer. Make sure to also set
; indent-tabs-mode to nil so spaces are inserted instead.
-
+;
; This style is basically Whitesmiths style with 3 space indents (the Emacs
; "whitesmith" style seems more like a weird Whitesmiths/Allman mutant style).
-
+;
; To activate using this style, open the file you want to edit and run this:
-; M-x c-set-style <RET> and then enter "botan". Alternately, put something
-; like this in your .emacs file to make it the default style:
+; M-x c-set-style <RET> and then enter "botan".
-; (add-hook 'c++-mode-common-hook
-; (function (lambda()
-; (c-add-style "botan" botan t))))
-
-(setq botan '(
+(setq botan-style '(
(c-basic-offset . 3)
(c-comment-only-line-offset . 0)
(c-offsets-alist
@@ -55,3 +50,6 @@
(label . 0)
)
))
+
+(add-hook 'c++-mode-common-hook
+ (function (lambda () (c-add-style "botan" botan-style nil))))
diff --git a/doc/index.txt b/doc/index.txt
new file mode 100644
index 000000000..1dfa6abcc
--- /dev/null
+++ b/doc/index.txt
@@ -0,0 +1,27 @@
+
+Botan Reference Manual
+=================================
+
+Contents:
+
+.. toctree::
+ :maxdepth: 2
+
+ intro
+ building
+ filters
+ pubkey
+ x509
+ lowlevel
+ bigint
+ algos
+ pgpkeys
+ license
+ credits
+ log
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`search`
diff --git a/doc/internals.tex b/doc/internals.tex
deleted file mode 100644
index 5b1650f6e..000000000
--- a/doc/internals.tex
+++ /dev/null
@@ -1,179 +0,0 @@
-\documentclass{article}
-
-\setlength{\textwidth}{6.75in} % 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{Botan Internals}
-\author{Jack Lloyd ([email protected])}
-\date{August 20, 2006}
-
-\newcommand{\filename}[1]{\texttt{#1}}
-\newcommand{\manpage}[2]{\texttt{#1}(#2)}
-
-\newcommand{\function}[1]{\textbf{#1}}
-\newcommand{\type}[1]{\texttt{#1}}
-\renewcommand{\arg}[1]{\textsl{#1}}
-
-\begin{document}
-
-\maketitle
-
-\tableofcontents
-
-\parskip=5pt
-
-\section{Introduction}
-
-This document is intended to document some of the trickier and/or more
-complicated parts of Botan. This is not going to be terribly useful if
-you just want to use the library, but for people wishing to understand
-how it works, or contribute new code to it, it will hopefully prove
-helpful.
-
-I've realized that a lot of things Botan does internally are pretty
-hard to understand, and that a lot of things are only inside my head,
-which is a bad place for them to be (things tend to get lost in there,
-not to mention the possibility that I'll get hit by a truck next
-week).
-
-This document is currently very incomplete. I'll be working on it as I
-have time.
-
-\pagebreak
-
-\section{Filter}
-
-\type{Filter} is one of the core abstractions of the library. It is
-used to represent any sort of transformation. Nearly all
-\type{Filter}s are linear; they take input from a single source and
-send their output (if any) to another single \type{Filter}. The one
-exception is \type{Fanout\_Filter}, which uses friend access to
-\type{Filter} in order to allow for multiple \type{Filter}s to attach
-to its output. This special access is used by the Chain and Fork
-filters; Chain encapsulates one or more \type{Filter}s into a single
-Filter, and Fork sends its input to a set of several \type{Filter}
-objects.
-
-The majority of the relations between filters is maintained by the
-\type{Pipe} object which ``owns'' the \type{Filter}s.
-
-\section{Pipe}
-
-\type{Pipe} is, conceptually, a tree structure of \type{Filter}
-objects. There is a single unique top, and an arbitrary number of
-leaves (which are \type{SecureQueue} objects). \type{SecureQueue} is a
-simple \type{Filter} that buffers its input.
-
-Writing into the pipe writes into the top of the tree. The filter at
-the top of the tree writes its output into the next \type{Filter}, and
-so on until eventually data trickles down into the bottommost
-\type{Filter}s, where the data is stored for later retrieval.
-
-When a new message is started, \type{Pipe} searches through the tree
-of \type{Filter}s and finds places where the \arg{next} field of the
-\type{Filter} is NULL. This implies that it was the lowest layer of
-the \type{Filter} tree that the user added. It then adds
-\type{SecureQueue} objects onto these \type{Filter}s. These queues are
-also stored in an deque; this is so \type{Pipe} can read from them
-later without doing a tree traversal each time.
-
-\type{Pipe} will, if asked, destroy the existing tree structure, in
-order to create a new one. However, the queue objects are not deleted,
-because \type{Pipe} might be asked to read from them later (while
-\type{Pipe} could delete all the messages in this case, the principle
-of least astonishment suggested keeping them).
-
-What I wrote about \type{Pipe} keeing the queues in a deque is a
-lie. Sort of. It keeps them in an object called
-\type{Output\_Buffers}, which keeps them in a
-deque. \type{Output\_Buffers} is intended to abstract away how message
-queues are stored from \type{Pipe}. After a queue has been added to
-the output buffers object, \type{Pipe} keeps no references to it
-whatsoever; all access is mediated by the \type{Output\_Buffers}.
-This allows queues which have been read to be deleted, rather than
-leaving empty queue objects all over the place.
-
-\section{Library Initialization}
-
-WRITEME
-
-\section{Lookup Mechanism}
-
-Most objects know their name, and they know how to create a new copy
-of themselves. We build mapping tables that map from an algorithm name
-into a single instance of that algorithm. The tables themselves can be
-found in \filename{src/lookup.cpp}.
-
-There are a set of functions named \function{add\_algorithm} that can
-be used to populate the tables. We get something out of the table with
-\function{retrieve\_x}, where x is the name of a type
-(\texttt{block\_cipher}, \texttt{hash}, etc). This returns a const
-pointer to the single unique instance of the algorithm that the lookup
-tables know about. If it doesn't know about it, it falls back on
-calling a function called \function{try\_to\_get\_x}. These functions
-live in \filename{src/algolist.cpp}. They are mostly used to handle
-algorithms which need (or at least can have) arguments passed to them,
-like \type{HMAC} and \type{SAFER\_SK}. It will return NULL if it can't
-find the algorithm at all.
-
-When it's asked for an algorithm it doesn't know about (ie, isn't in
-the mapping tables), the retrieval functions will ask the try-to-get
-functions if \emph{they} know about it. If they do, then the object
-returned will be stored into the table for later retrieval.
-
-The functions \function{get\_x} call the retrieval functions. If we
-get back NULL, an exception is thrown. Otherwise it will call the
-\function{clone} method to get a new copy of the algorithm, which it
-returns.
-
-The various functions like \function{output\_length\_of} call the
-retrieval function for each type of object that the parameter in
-question (in this case, \texttt{OUTPUT\_LENGTH}) might be meaningful
-for. If it manages to get back an object, it will return (in this
-case) the \texttt{OUTPUT\_LENGTH} field of the object. No allocations
-are required to call this function: all of its operations work
-directly on the copies living in the lookup tables.
-
-\section{Allocators}
-
-A big (slow) mess.
-
-\section{BigInt}
-
-Read ``Handbook of Applied Cryptography''.
-
-\section{PEM/BER Identification}
-
-We have a specific algorithm for figuring out if something is PEM or
-BER. Previous versions (everything before 1.3.0) requried that the
-caller specify which one it was, and they had to be right. Now we use
-a hueristic (aka, an algorithm that sometimes doesn't work right) to
-figure it out. If the first character is not 0x30 (equal to ASCII
-'0'), then it can't possibly be BER (because everything we care about
-is enclosed in an ASN.1 SEQUENCE, which for BER/DER is encoded as
-beginning with 0x30). Roughly 99.9% of PEM blocks \emph{won't} have a
-random 0 character in front of them, so we are mostly safe (unless
-someone does it on purpose, in which case, please hit them for me).
-But to be sure, if there is a 0, then we search the first \emph{N}
-bytes of the block for the string ``-----BEGIN ``, which marks the
-typical start of a PEM block. The specific \emph{N} depends on the
-variable ``base/pem\_search'', which defaults to 4 kilobytes.
-
-So, you can actually fool it either way: that a PEM file is really
-BER, or that a BER file is actually PEM. To fool it that a BER file is
-PEM, just have the string ``-----BEGIN `` somewhere (I can't imagine
-this string shows up in certificates or CRLs too often, so if it is
-there it means somebody is being a jerk). If a file starts with 0 and
-has at least ``base/pem\_search'' byte more junk in the way, it won't
-notice that its PEM at all. In either case, of course, the loading
-will fail, and you'll get a nice exception saying that the decoding
-failed.
-
-\end{document}
diff --git a/doc/intro.txt b/doc/intro.txt
new file mode 100644
index 000000000..c9a153563
--- /dev/null
+++ b/doc/intro.txt
@@ -0,0 +1,169 @@
+
+Introduction
+=================================
+
+Botan is a C++ library that attempts to provide the most common
+cryptographic algorithms and operations in an easy to use, efficient,
+and portable way. It runs on a wide variety of systems, and can be
+used with most modern C++ compilers.
+
+It is released under the 2 clause BSD license and can be used by
+commercial and open source software; see :ref:`license` for the
+specifics.
+
+The base library is written in ISO C++, so it can be ported with
+minimal fuss, but a modules system is also used. This system exposes
+system dependent code to the library through portable interfaces,
+extending the set of services available to users.
+
+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 are also capable of using Botan.
+
+The design makes it quite easy to remove unused algorithms in such a
+way that applications do not need to be recompiled to work, even
+applications that use the algorithm in question. They can ask the
+library if the algorithm exists, and if so, retrieve an object
+implementing that algorithm.
+
+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/)
+
+Getting Help
+----------------------------------------
+
+Questions or problems you have with Botan can be directed to the
+`development mailing list
+<http://lists.randombit.net/mailman/listinfo/botan-devel/>`_.
+"Philosophical" bug reports, announcements of programs using Botan,
+and anything else having to do with Botan are also welcome.
+
+If you find what you believe to be a bug, please file a ticket in
+`Bugzilla <http://bugs.randombit.net/>`_.
+
+Getting Started
+---------------------------------
+
+All declarations in the library are contained within the namespace
+``Botan``, so you need to either prefix types with ``Botan::`` or add
+a ``using`` declaration in your code. All examples will assume a
+``using`` declaration.
+
+All library headers are included like so::
+
+ #include <botan/botan.h>
+
+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::
+
+ Botan::LibraryInitializer init;
+
+at the start of your ``main``.
+
+The constructor takes an optional string that specifies arguments.
+Currently the only possible argument is "thread_safe", which must have
+an boolean argument (for instance "thread_safe=false" or
+"thread_safe=true"). If "thread_safe" is specified as true the library
+will attempt to register a mutex type to properly guard access to
+shared resources. However these locks do not protect individual Botan
+objects: explicit locking must be used if you wish to share a single
+object between threads.
+
+If you do not create a ``LibraryInitializer`` object, all library
+operations will fail, because it will be unable to do basic things
+like allocate memory or get random bits. You should never create more
+than one ``LibraryInitializer``.
+
+Pitfalls
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+There are a few things to watch out for to prevent problems when using
+the library.
+
+Never allocate any kind of Botan object globally. The problem with
+doing this is that the constructor for such an object will be called
+before the library is initialized. Many Botan objects will, in their
+constructor, make one or more calls into the library global state
+object. Access to this object is checked, so an exception should be
+thrown (rather than a memory access violation or undetected
+uninitialized object access). A rough equivalent that will work is to
+keep a global pointer to the object, initializing it after creating
+your ``LibraryInitializer``. Merely making the
+``LibraryInitializer`` also global will probably not help, because
+C++ does not make very strong guarantees about the order that such
+objects will be created.
+
+The same rule applies for making sure the destructors of all your
+Botan objects are called before the ``LibraryInitializer`` is
+destroyed. This implies you can't have static variables that are Botan
+objects inside functions or classes; in many C++ runtimes, these
+objects will be destroyed after main has returned.
+
+The memory object classes (``MemoryRegion``, ``MemoryVector``,
+``SecureVector``) are extremely primitive, and meant only for
+secure storage of potentially sensitive data like keys. They do not
+meet the requirements for an STL container object and you should not
+try to use them with STL algorithms. For a general-purpose container,
+use ``std::vector``.
+
+Use a ``try``/``catch`` block inside your ``main`` function, and catch
+any ``std::exception`` throws (remember to catch by reference, as
+``std::exception::what`` is polymorphic)::
+
+ int main()
+ {
+ try
+ {
+ LibraryInitializer init;
+
+ // ...
+ }
+ catch(std::exception& e)
+ {
+ std::cerr << e.what() << "\n";
+ }
+ }
+
+This is not strictly required, but if you don't, and Botan throws an
+exception, the runtime will call ``std::terminate``, which usually
+calls ``abort`` or something like it, leaving you (or worse, a user of
+your application) wondering what went wrong.
diff --git a/doc/license.txt b/doc/license.txt
index f1b261eab..33b2f5982 100644
--- a/doc/license.txt
+++ b/doc/license.txt
@@ -1,42 +1,48 @@
-Botan (http://botan.randombit.net/) is distributed under these terms:
-
-Copyright (C) 1999-2011 Jack Lloyd
- 2001 Peter J Jones
- 2004-2007 Justin Karneges
- 2004 Vaclav Ovsik
- 2005 Matthew Gregan
- 2005-2006 Matt Johnston
- 2006 Luca Piccarreta
- 2007 Yves Jerschow
- 2007-2008 FlexSecure GmbH
- 2007-2008 Technische Universitat Darmstadt
- 2007-2008 Falko Strenzke
- 2007-2008 Martin Doering
- 2007 Manuel Hartl
- 2007 Christoph Ludwig
- 2007 Patrick Sona
- 2010 Olivier de Gaalon
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-1. Redistributions of source code must retain the above copyright
-notice, this list of conditions, and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions, and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+.. _license:
+
+License
+========================================
+
+Botan (http://botan.randombit.net/) is distributed under these terms::
+
+ Copyright (C) 1999-2011 Jack Lloyd
+ 2001 Peter J Jones
+ 2004-2007 Justin Karneges
+ 2004 Vaclav Ovsik
+ 2005 Matthew Gregan
+ 2005-2006 Matt Johnston
+ 2006 Luca Piccarreta
+ 2007 Yves Jerschow
+ 2007-2008 FlexSecure GmbH
+ 2007-2008 Technische Universitat Darmstadt
+ 2007-2008 Falko Strenzke
+ 2007-2008 Martin Doering
+ 2007 Manuel Hartl
+ 2007 Christoph Ludwig
+ 2007 Patrick Sona
+ 2010 Olivier de Gaalon
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions, and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/doc/log.txt b/doc/log.txt
index 8ceb13a60..d4dd96430 100644
--- a/doc/log.txt
+++ b/doc/log.txt
@@ -1,1545 +1,1884 @@
-* 1.9.16-dev, ????-??-??
- - Second release candidate for 1.10.0
- - Disable the by-default 'strong' checking of private keys that are
- loaded from storage. You can always request key material sanity
- checking using check_key.
- - Bring back removed functions min_keylength_of, max_keylength_of,
- keylength_multiple_of in lookup.h to avoid breaking applications.
-
-* 1.9.15, 2011-03-21
- - First release candidate for 1.10.0
- - Modify how message expansion is done in SHA-256 and SHA-512.
- Instead of expanding the entire message at the start, compute them
- in the minimum number of registers. Values are computed 15 rounds
- before they are needed. On a Core i7-860, GCC 4.5.2, went from
- 143 to 157 MiB/s in SHA-256, and 211 to 256 MiB/s in SHA-512.
- - Pipe will delete empty output queues as soon as they are no longer
- needed, even if earlier messages still have data unread. However an
- (empty) entry in a deque of pointers will remain until all prior
- messages are completely emptied.
- - Avoid reading the SPARC %tick register on OpenBSD as unlike Linux
- the kernel will not trap and emulate it for us, causing a illegal
- instruction crash.
- - Improve detection and autoconfiguration for ARM processors.
-
-* 1.9.14, 2011-03-01
- - Add support for bcrypt, OpenBSD's password hashing scheme
- - Add support for NIST's AES key wrapping algorithm
- - Fix an infinite loop in zlib filters introduced in 1.9.11 (PR 142)
-
-* 1.9.13, 2011-02-19
- - Update Keccak to the round 3 variant
- - Fix ordering in GOST 34.10 signatures to match DNSSEC specifications
- - Use size_t instead of u32bit for small integers in DER/BER codecs
- - Add new build option --distribution-info
- - Fix problems in the amalgamation build
- - Fix building under Clang 2.9 and Sun Studio 12
-
-* 1.9.12, 2010-12-13
- - Add the Keccak hash function
- - Fix compilation problems in Python wrappers
- - Fix compilation problem in OpenSSL engine
- - Update SQLite3 database encryption codec
-
-* 1.9.11, 2010-11-29
- - Many SSL/TLS APIs have changed. This API is still unstable.
- - The SSL interface requires TR1 (uses std::tr1::function)
- - Fix SSL handshake failures when using RC4 ciphersuites
- - Fix a number of CRL encoding and decoding bugs
- - Counter mode now always encrypts 256 blocks in parallel
- - Code where u32bit was used to represent a length now uses size_t
- - Use small tables in the first round of AES
- - Removed AES class: app must choose AES-128, AES-192, or AES-256
- - Add hex encoding/decoding functions that can be used without a Pipe
- - Add base64 encoding functions that can be used without a Pipe
- - Add to_string function to X509_Certificate
- - Add support for dynamic engine loading on Windows
- - Replace BlockCipher::BLOCK_SIZE attribute with function block_size()
- - Replace HashFunction::HASH_BLOCK_SIZE attribute with hash_block_size()
- - Changed semantics of MemoryRegion::resize and clear to match STL
- - Removed MemoryRegion::append, replaced by push_back and operator+=
- - Move PBKDF lookup to engine system
- - The IDEA key schedule has been changed to run in constant time
- - Avoid a possible timing vulnerability in Montgomery reduction
- - Add Algorithm and Key_Length_Specification classes
- - Switch default PKCS #8 encryption algorithm from AES-128 to AES-256
- - Update Skein-512 to match the v1.3 specification
- - Allow using PBKDF2 with empty passphrases
- - Add compile-time deprecation warnings for GCC, Clang, and MSVC
- - Support use of HMAC(SHA-256) and CMAC(Blowfish) in passhash9
- - Improve support for Intel Atom processors
- - Fix compilation problems under Sun Studio and Clang
-
-* 1.8.11, 2010-11-02
- - Fix a number of CRL encoding and decoding bugs
- - When building a debug library under VC++, use the debug runtime
- - Fix compilation under Sun Studio on Linux and Solaris
- - Add several functions for compatability with 1.9
- - In the examples, read most input files as binary
- - The Perl build script has been removed in this release
-
-* 1.8.10, 2010-08-31
- - Switch default PKCS #8 encryption algorithm from 3DES to AES-256
- - Increase default hash iterations from 2048 to 10000 in PBES1 and PBES2
- - Use small tables in the first round of AES
- - Add PBKDF typedef and get_pbkdf for better compatability with 1.9
- - Add version of S2K::derive_key taking salt and iteration count
- - Enable the /proc-walking entropy source on NetBSD
- - Fix the doxygen makefile target
-
-* 1.9.10, 2010-08-12
- - Add a constant time AES implementation using SSSE3
- - Add support for loading new Engines at runtime
- - Use GCC byteswap intrinsics where possible
- - Drop support for building with Python 2.4
- - Fix benchmarking of block ciphers in ECB mode
- - Consolidate the two x86 assembly engines
- - Rename S2K to PBKDF
-
-* 1.9.9, 2010-06-28
- - Add new X509::BER_encode and PKCS8::BER_encode
- - Give all Filter objects a name() function
- - Add Keyed_Filter::valid_iv_length
- - Increase default iteration counts for private key encryption
- - Fix compilation of mp_asm64 on 64-bit MIPS with GCC 4.4 and later
- - Fix compilation under Apple's GCC 4.2
- - Expand and update the Doxygen documentation
-
-* 1.8.9, 2010-06-16
- - Use constant time multiplication in IDEA
- - Avoid possible timing attack against OAEP decoding
- - Add new X509::BER_encode and PKCS8::BER_encode
- - Enable DLL builds under Windows
- - Add Win32 installer support
- - Add support for the Clang compiler
- - Fix problem in semcem.h preventing build under Clang or GCC 3.4
- - Fix bug that prevented creation of DSA groups under 1024 bits
- - Fix crash in GMP_Engine if library is shutdown and reinitialized
- - Work around problem with recent binutils in x86-64 SHA-1
- - The Perl build script is no longer supported and refuses to run by default
-
-* 1.9.8, 2010-06-14
- - Add support for wide multiplications on 64-bit Windows
- - Use constant time multiplication in IDEA
- - Avoid possible timing attack against OAEP decoding
- - Removed FORK-256; rarely used and it has been broken
- - Rename --use-boost-python to --with-boost-python
- - Skip building shared libraries on MinGW/Cygwin
- - Fix creation of 512 and 768 bit DL groups using the DSA kosherizer
- - Fix compilation on GCC versions before 4.3 (missing cpuid.h)
- - Fix compilation under the Clang compiler
-
-* 1.9.7, 2010-04-27
- - TLS: Support reading SSLv2 client hellos
- - TLS: Add support for SEED ciphersuites (RFC 4162)
- - Add Comb4P hash combiner function
- - Fix checking of EMSA_Raw signatures with leading 0 bytes
-
-* 1.9.6, 2010-04-09
- - TLS: Add support for TLS v1.1
- - TLS: Support server name indicator extension
- - TLS: Fix server handshake
- - TLS: Fix server using DSA certificates
- - TLS: Avoid timing channel between CBC padding check and MAC verification
-
-* 1.9.5, 2010-03-29
- - Numerous ECC optimizations
- - Fix GOST 34.10-2001 X.509 key loading
- - Allow PK_Signer's fault protection checks to be toggled off
- - Avoid using pool-based locking allocator if we can't mlock
- - Remove all runtime options
- - New BER_Decoder::{decode_and_check, decode_octet_string_bigint}
- - Remove SecureBuffer in favor of SecureVector length parameter
- - HMAC_RNG: Perform a poll along with user-supplied entropy
- - Fix crash in MemoryRegion if Allocator::get failed
- - Fix small compilation problem on FreeBSD
-
-* 1.9.4, 2010-03-09
- - Add the Ajisai SSLv3/TLSv1.0 implementation
- - Add GOST 34.10-2001 public key signature scheme
- - Add SIMD implementation of Noekeon
- - Add SSE2 implementation of IDEA
- - Extend Salsa20 to support longer IVs (XSalsa20)
- - Perform XTS encryption and decryption in parallel where possible
- - Perform CBC decryption in parallel where possible
- - Add SQLite3 db encryption codec, contributed by Olivier de Gaalon
- - Add a block cipher cascade construction
- - Add support for password hashing for authentication (passhash9.h)
- - Add support for Win32 high resolution system timers
- - Major refactoring and API changes in the public key code
- - Use consistency checking (anti-fault attack) for all signature schemes
- - Changed S2K interface: derive_key now takes salt, iteration count
- - Remove dependency on TR1 for ECC and CVC code
- - Renamed ECKAEG to its more usual name, ECDH
- - Fix crash in GMP_Engine if library is shutdown and reinitialized
- - Fix an invalid memory read in MD4
- - Fix Visual C++ static builds
- - Remove Timer class entirely
- - Switch default PKCS #8 encryption algorithm from 3DES to AES-128
- - New option --gen-amalgamation for creating a SQLite-style amalgamation
- - Many headers are now explicitly internal-use-only and are not installed
- - Greatly improve the Win32 installer
- - Several fixes for Visual C++ debug builds
-
-* 1.9.3, 2009-11-19
- - Add new AES implementation using Intel's AES instruction intrinsics
- - Add an implementation of format preserving encryption
- - Allow use of any hash function in X.509 certificate creation
- - Optimizations for MARS, Skipjack, and AES
- - Set macros for available SIMD instructions in build.h
- - Add support for using InnoSetup to package Windows builds
- - By default build a DLL on Windows
-
-* 1.9.2, 2009-11-03
- - Add SIMD version of XTEA
- - Support both SSE2 and AltiVec SIMD for Serpent and XTEA
- - Optimizations for SHA-1 and SHA-2
- - Add AltiVec runtime detection
- - Fix x86 CPU identification with Intel C++ and Visual C++
-
-* 1.8.8, 2009-11-03
- - Alter Skein-512 to match the tweaked 1.2 specification
- - Fix use of inline asm for access to x86 bswap function
- - Allow building the library without AES enabled
- - Add 'powerpc64' alias to ppc64 arch for Gentoo ebuild
-
-* 1.9.1, 2009-10-23
- - Better support for Python and Perl wrappers
- - Add an implementation of Blue Midnight Wish (Round 2 tweak version)
- - Modify Skein-512 to match the tweaked 1.2 specification
- - Add threshold secret sharing (draft-mcgrew-tss-02)
- - Add runtime cpu feature detection for x86/x86-64
- - Add code for general runtime self testing for hashes, MACs, and ciphers
- - Optimize XTEA; twice as fast as before on Core2 and Opteron
- - Convert CTR_BE and OFB from filters to stream ciphers
- - New parsing code for SCAN algorithm names
- - Enable SSE2 optimizations under Visual C++
- - Remove all use of C++ exception specifications
- - Add support for GNU/Hurd and Clang/LLVM
-
-* 1.9.0, 2009-09-09
- - Add support for parallel invocation of block ciphers where possible
- - Add SSE2 implementation of Serpent
- - Add Rivest's package transform (an all or nothing transform)
- - Minor speedups to the Turing key schedule
- - Fix processing multiple messages in XTS mode
- - Add --no-autoload option to configure.py, for minimized builds
- - The previously used configure.pl script is no longer supported
-
-* 1.8.7, 2009-09-09
- - Fix processing multiple messages in XTS mode
- - Add --no-autoload option to configure.py, for minimized builds
-
-* 1.8.6, 2009-08-13
- - Add Cryptobox, a set of simple password-based encryption routines
- - Only read world-readable files when walking /proc for entropy
- - Fix building with TR1 disabled
- - Fix x86 bswap support for Visual C++
- - Fixes for compilation under Sun C++
- - Add support for Dragonfly BSD (contributed by Patrick Georgi)
- - Add support for the Open64 C++ compiler
- - Build fixes for MIPS systems running Linux
- - Minor changes to license, now equivalent to the FreeBSD/NetBSD license
-
-* 1.8.5, 2009-07-23
- - Change configure.py to work on stock Python 2.4
- - Avoid a crash in Skein_512::add_data processing a zero-length input
- - Small build fixes for SPARC, ARM, and HP-PA processors
- - The test suite now returns an error code from main() if any tests failed
-
-* 1.8.4, 2009-07-12
- - Fix a bug in nonce generation in the Miller-Rabin test
-
-* 1.8.3, 2009-07-11
- - Add a new Python configuration script
- - Add the Skein-512 SHA-3 candidate hash function
- - Add the XTS block cipher mode from IEEE P1619
- - Fix random_prime when generating a prime of less than 7 bits
- - Improve handling of low-entropy situations during PRNG seeding
- - Change random device polling to prefer /dev/urandom over /dev/random
- - Use an input insensitive implementation of same_mem instead of memcmp
- - Correct DataSource::discard_next to return the number of discarded bytes
- - Provide a default value for AutoSeeded_RNG::reseed
- - Fix Gentoo bug 272242
-
-* 1.8.2, 2009-04-07
- - Make entropy polling more flexible and in most cases faster
- - GOST 28147 now supports multiple sbox parameters
- - Added the GOST 34.11 hash function
- - Fix botan-config problems on MacOS X
-
-* 1.8.1, 2009-01-20
- - Avoid a valgrind warning in es_unix.cpp on 32-bit Linux
- - Fix memory leak in PKCS8 load_key and encrypt_key
- - Relicense api.tex from CC-By-SA 2.5 to BSD
- - Fix botan-config on MacOS X, Solaris
-
-* 1.8.0, 2008-12-08
- - Fix compilation on Solaris with GCC
-
-* 1.7.24, 2008-12-01
- - Fix a compatibility problem with SHA-512/EMSA3 signature padding
- - Fix bug preventing EGD/PRNGD entropy poller from working
- - Fix integer overflow in Pooling_Allocator::get_more_core (bug id #27)
- - Add EMSA3_Raw, a variant of EMSA3 called CKM_RSA_PKCS in PKCS #11
- - Add support for SHA-224 in EMSA2 and EMSA3 PK signature padding schemes
- - Add many more test vectors for RSA with EMSA2, EMSA3, and EMSA4
- - Wrap private structs in SSE2 SHA-1 code in anonymous namespace
- - Change configure.pl's CPU autodetection output to be more consistent
- - Disable using OpenSSL's AES due to crashes of unknown cause
- - Fix warning in /proc walking entropy poller
- - Fix compilation with IBM XLC for Cell 0.9-200709
-
-* 1.7.23, 2008-11-23
- - Change to use TR1 (thus enabling ECDSA) with GCC and ICC
- - Optimize almost all hash functions, especially MD4 and Tiger
- - Add configure.pl options --{with,without}-{bzip2,zlib,openssl,gnump}
- - Change Timer to be pure virtual, and add ANSI_Clock_Timer
- - Cache socket descriptors in the EGD entropy source
- - Avoid bogging down startup in /proc walking entropy source
- - Remove Buffered_EntropySource helper class
- - Add a Default_Benchmark_Timer typedef in benchmark.h
- - Add examples using benchmark.h and Algorithm_Factory
- - Add ECC tests from InSiTo
- - Minor documentation updates
-
-* 1.7.22, 2008-11-17
- - Add provider preferences to Algorithm_Factory
- - Fix memory leaks in PBE_PKCS5v20 and get_pbe introduced in 1.7.21
- - Optimize AES encryption and decryption (about 10% faster)
- - Enable SSE2 optimized SHA-1 implementation on Intel Prescott CPUs
- - Fix nanoseconds overflow in benchmark code
- - Remove Engine::add_engine
-
-* 1.7.21, 2008-11-11
- - Make algorithm lookup much more configuable
- - Add facilities for runtime performance testing of algorithms
- - Drop use of entropy estimation in the PRNGs
- - Increase intervals between HMAC_RNG automatic reseeding
- - Drop InitializerOptions class, all options but thread safety
-
-* 1.7.20, 2008-11-09
- - Namespace pkg-config file by major and minor versions
- - Cache device descriptors in Device_EntropySource
- - Split base.h into {block_cipher,stream_cipher,mac,hash}.h
- - Removed get_mgf function from lookup.h
-
-* 1.7.19, 2008-11-06
- - Add HMAC_RNG, based on a design by Hugo Krawczyk
- - Optimized the Turing stream cipher (about 20% faster on x86-64)
- - Modify Randpool's reseeding algorithm to poll more sources
- - Add a new AutoSeeded_RNG in auto_rng.h
- - OpenPGP_S2K changed to take hash object instead of name
- - Add automatic identification for Intel's Prescott processors
-
-* 1.7.18, 2008-10-22
- - Add Doxygen comments from InSiTo
- - Add ECDSA and ECKAEG benchmarks
- - Add configure.pl switch --with-tr1-implementation
- - Fix configure.pl's --with-endian and --with-unaligned-mem options
- - Added support for pkg-config
- - Optimize byteswap with x86 inline asm for Visual C++ by Yves Jerschow
- - Use const references to avoid copying overhead in CurveGFp, GFpModulus
-
-* 1.7.17, 2008-10-12
- - Add missing ECDSA object identifiers
- - Fix error in x86 and x86-64 assembler affecting GF(p) math
- - Remove Boost dependency from GF(p) math
- - Modify botan-config to not print -L/usr/lib or -L/usr/local/lib
- - Add BOTAN_DLL macro to over 30 classes missing it
- - Rename the two SHA-2 base classes for consistency
-
-* 1.7.16, 2008-10-09
- - Add several missing pieces needed for ECDSA and ECKAEG
- - Add Card Verifiable Certificates from InSiTo
- - Add SHA-224 from InSiTo
- - Add BSI variant of EMSA1 from InSiTo
- - Add GF(p) and ECDSA tests from InSiTo
- - Split ECDSA and ECKAEG into distinct modules
- - Allow OpenSSL and GNU MP engines to be built with public key algos disabled
- - Rename sha256.h to sha2_32.h and sha_64.h to sha2_64.h
-
-* 1.7.15, 2008-10-07
- - Add GF(p) arithmetic from InSiTo
- - Add ECDSA and ECKAEG implementations from InSiTo
- - Minimize internal dependencies, allowing for smaller build configurations
- - Add new User Manual and Architecture Guide from FlexSecure GmbH
- - Alter configure.pl options for better autotools compatibility
- - Update build instructions for recent changes to configure.pl
- - Fix CPU detection using /proc/cpuinfo
-
-* 1.7.14, 2008-09-30
- - Split library into parts allowing modular builds
- - Add (very preliminary) CMS support to the main library
- - Some constructors now require object pointers instead of names
- - Support multiple implementations of the same algorithm
- - Build support for Pentium-M processors, from Derek Scherger
- - Build support for MinGW/MSYS, from Zbigniew Zagorski
- - Use inline assembly for bswap on 32-bit x86
-
-* 1.7.13, 2008-09-27
- - Add SSLv3 MAC, SSLv3 PRF, and TLS v1.0 PRF from Ajisai
- - Allow all examples to compile even if compression not enabled
- - Make CMAC's polynomial doubling operation a public class method
- - Use the -m64 flag when compiling with Sun Forte on x86-64
- - Clean up and slightly optimize CMAC::final_result
-
-* 1.7.12, 2008-09-18
- - Add x86 assembly for Visual Studio C++, by Luca Piccarreta
- - Add a Perl XS module, by Vaclav Ovsik
- - Add SWIG-based wrapper for Botan
- - Add SSE2 implementation of SHA-1, by Dean Gaudet
- - Remove the BigInt::sig_words cache due to bugs
- - Combined the 4 Blowfish sboxes, suggested by Yves Jerschow
- - Changed BigInt::grow_by and BigInt::grow_to to be non-const
- - Add private assignment operators to classes that don't support assignment
- - Benchmark RSA encryption and signatures
- - Added test programs for random_prime and ressol
- - Add high resolution timers for IA-64, HP-PA, S390x
- - Reduce use of the RNG during benchmarks
- - Fix builds on STI Cell PPU
- - Add support for IBM's XLC compiler
- - Add IETF 8192 bit MODP group
-
-* 1.7.11, 2008-09-11
- - Added the Salsa20 stream cipher
- - Optimized Montgomery reduction, Karatsuba squaring
- - Added 16x16->32 word Comba multiplication and squaring
- - Use a much larger Karatsuba cutoff point
- - Remove bigint_mul_add_words
- - Inlined several BigInt functions
- - Add useful information to the generated build.h
- - Rename alg_{ia32,amd64} modules to asm_{ia32,amd64}
- - Fix the Windows build
-
-* 1.7.10, 2008-09-05
- - Public key benchmarks run using a selection of random keys
- - New benchmark timer options are clock_gettime, gettimeofday, times, clock
- - Including reinterpret_cast optimization for xor_buf in default header
- - Split byte swapping and word rotation functions into distinct headers
- - Add IETF modp 6144 group and 2048 and 3072 bit DSS groups
- - Optimizes BigInt right shift
- - Add aliases in DL_Group::Format enum
- - BigInt now caches the significant word count
-
-* 1.7.9, 2008-08-27
- - Make clear() in most algorithm base classes a pure virtual
- - Add noexec stack marker for GNU linker in assembly code
- - Avoid string operations in ressol
- - Compilation fixes for MinGW and Visual Studio C++ 2008
- - Some autoconfiguration fixes for Windows
-
-* 1.6.5, 2008-08-27
- - Add noexec stack marker for GNU linker in assembly code
- - Fix autoconfiguration problem on x86 with GCC 4.2 and 4.3
-
-* 1.7.8, 2008-07-15
- - Added the block cipher Noekeon
- - Remove global deref_alias function
- - X509_Store takes timeout options as constructor arguments
- - Add Shanks-Tonelli algorithm, contributed by FlexSecure GmbH
- - Extend random_prime() for generating primes of any bit length
- - Remove Config class
- - Allow adding new entropy via base RNG interface
- - Reseeding a X9.31 PRNG also reseeds the underlying PRNG
-
-* 1.7.7, 2008-06-28
- - Remove the global PRNG object
- - The PK filter objects were removed
- - Add a test suite for the ANSI X9.31 PRNG
- - Much cleaner and (mostly) thread-safe reimplementation of es_ftw
- - Remove both default arguments to ANSI_X931_RNG's constructor
- - Remove the randomizing version of OctetString::change
- - Make the cipher and MAC to use in Randpool configurable
- - Move RandomNumberGenerator declaration to rng.h
- - RSA_PrivateKey will not generate keys smaller than 1024 bits
- - Fix an error decoding BER UNIVERSAL types with special taggings
-
-* 1.7.6, 2008-05-05
- - Initial support for Windows DLLs, from Joel Low
- - Reset the position pointer when a new block is generated in X9.32 PRNG
- - Timer objects are now treated as entropy sources
- - Moved several ASN.1-related enums from enums.h to an appropriate header
- - Removed the AEP module, due to inability to test
- - Removed Global_RNG and rng.h
- - Removed system_clock
- - Removed Library_State::UI and the pulse callback logic
-
-* 1.7.5, 2008-04-12
- - The API of X509_CA::sign_request was altered to avoid race conditions
- - New type Pipe::message_id to represent the Pipe message number
- - Remove the Named_Mutex_Holder for a small performance gain
- - Removed several unused or rarely used functions from Config
- - Ignore spaces inside of a decimal string in BigInt::decode
- - Allow using a std::istream to initialize a DataSource_Stream object
- - Fix compilation problem in zlib compression module
- - The chunk sized used by Pooling_Allocator is now a compile time setting
- - The size of random blinding factors is now a compile time setting
- - The install target no longer tries to set a particular owner/group
-
-* 1.7.4, 2008-03-10
- - Use unaligned memory read/writes on systems that allow it, for performance
- - Assembly for x86-64 for accessing the bswap instruction
- - Use larger buffers in ARC4 and WiderWAKE for significant throughput increase
- - Unroll loops in SHA-160 for a few percent increase in performance
- - Fix compilation with GCC 3.2 in es_ftw and es_unix
- - Build fix for NetBSD systems
- - Prevent es_dev from being built except on Unix systems
-
-* 1.6.4, 2008-03-08
- - Fix a compilation problem with Visual Studio C++ 2003
-
-* 1.7.3, 2008-01-23
- - New invocation syntax for configure.pl with several new options
- - Support for IPv4 addresses in a subject alternative name
- - New fast poll for the generic Unix entropy source (es_unix)
- - The es_file entropy source has been replaced by the es_dev module
- - The malloc allocator does not inherit from Pooling_Allocator anymore
- - The path that es_unix will search in are now fully user-configurable
- - Truncate X9.42 PRF output rather than allow counter overflow
- - PowerPC is now assumed to be big-endian
-
-* 1.7.2, 2007-10-13
- - Initialize the global library state lazily
- - Add plain CBC-MAC for backwards compatibility with old systems
- - Clean up some of the self test code
- - Throw a sensible exception if a DL_Group is not found
- - Truncate KDF2 output rather than allowing counter overflow
- - Add newly assigned OIDs for SHA-2 and DSA with SHA-224/256
- - Fix a Visual Studio compilation problem in x509stat.cpp
-
-* 1.7.1, 2007-07-23
- - Fix a race condition in the algorithm object cache
- - HMAC key schedule optimization
- - The build header sets a macro defining endianness, if known
- - New word load/store abstraction allowing further optimization
- - Modify most of the library to avoid use the C-style casts
- - Use higher resolution timers in symmetric benchmarks
-
-* 1.6.3, 2007-07-23
- - Fix a race condition in the algorithm lookup cache
- - Fix problems building the memory pool on some versions of Visual C++
-
-* 1.7.0, 2007-05-19
- - DSA parameter generation now follows FIPS 186-3
- - Added OIDs for Rabin-Williams and Nyberg-Rueppel
- - Somewhat better support for out of tree builds
- - Minor optimizations for RC2 and Tiger
- - Documentation updates
- - Update the todo list
-
-* 1.6.2, 2007-03-24
- - Fix autodection on Athlon64s running Linux
- - Fix builds on QNX and compilers using STLport
- - Remove a call to abort() that crept into production
-
-* 1.6.1, 2007-01-20
- - Fix some base64 decoder bugs
- - Add a new option to base64 encoding, to always append a newline
- - Fix some build problems under Visual Studio with debug enabled
- - Fix a bug in BER_Decoder that was triggered under some compilers
-
-* 1.6.0, 2006-12-17
- - Minor cleanups versus 1.5.13
-
-* 1.5.13, 2006-12-10
- - Compilation fixes for the bzip2, zlib, and GNU MP modules
- - Better support for Intel C++ and EKOpath C++ on x86-64
-
-* 1.5.12, 2006-10-27
- - Cleanups in the initialization routines
- - Add some x86-64 assembly for multiply-add
- - Fix problems generating very small (below 384 bit) RSA keys
- - Support out of tree builds
- - Bring some of the documentation up to date
- - More improvements to the Python bindings
-
-* 1.5.11, 2006-09-10
- - Removed the Algorithm base class
- - Various cleanups in the public key inheritance hierarchy
- - Major overhaul of the configure/build setup
- - Added x86 assembler implementations of Serpent and low-level MPI code
- - Optimizations for the SHA-1 x86 assembler
- - Various improvements to the Python wrappers
- - Work around a Visual Studio compiler bug
-
-* 1.5.10, 2006-08-13
- - Add x86 assembler versions of MD4, MD5, and SHA-1
- - Expand InitializerOptions' language to support on/off switches
- - Fix definition of OID 2.5.4.8; was accidentally changed in 1.5.9
- - Fix possible resource leaks in the mmap allocator
- - Slightly optimized buffering in MDx_HashFunction
- - Initialization failures are dealt with somewhat better
- - Add an example implementing Pollard's Rho algorithm
- - Better option handling in the test/benchmark tool
- - Expand the xor_ciph example to support longer keys
- - Some updates to the documentation
-
-* 1.5.9, 2006-07-12
- - Fixed bitrot in the AEP engine
- - Fix support for marking certificate/CRL extensions as critical
- - Significant cleanups in the library state / initialization code
- - LibraryInitializer takes an explicit InitializerOptions object
- - Make Mutex_Factory an abstract class, add Default_Mutex_Factory
- - Change configuration access to using global_state()
- - Add support for global named mutexes throughout the library
- - Add some STL wrappers for the delete operator
- - Change how certificates are created to be more flexible and general
-
-* 1.5.8, 2006-06-23
- - Many internal cleanups to the X.509 cert/CRL code
- - Allow for application code to support new X.509 extensions
- - Change the return type of X509_Certificate::{subject,issuer}_info
- - Allow for alternate character set handling mechanisms
- - Fix a bug that was slowing squaring performance somewhat
- - Fix a very hard to hit overflow bug in the C version of word3_muladd
- - Minor cleanups to the assembler modules
- - Disable es_unix module on FreeBSD due to build problem on FreeBSD 6.1
- - Support for GCC 2.95.x has been dropped in this release
-
-* 1.5.7, 2006-05-28
- - Further, major changes to the BER/DER coding system
- - Updated the Qt mutex module to use Mutex_Factory
- - Moved the library global state object into an anonymous namespace
- - Drop the Visual C++ x86 assembly module due to bugs
-
-* 1.5.6, 2006-03-01
- - The low-level DER/BER coding system was redesigned and rewritten
- - Portions of the certificate code were cleaned up internally
- - Use macros to substantially clean up the GCC assembly code
- - Added 32-bit x86 assembly for Visual C++ (by Luca Piccarreta)
- - Avoid a couple of spurious warnings under Visual C++
- - Some slight cleanups in X509_PublicKey::key_id
-
-* 1.5.5, 2006-02-04
- - Fixed a potential infinite loop in the memory pool code (Matt Johnston)
- - Made Pooling_Allocator::Memory_Block an actual class of sorts
- - Some small optimizations to the division and modulo computations
- - Cleaned up the implementation of some of the BigInt operators
- - Reduced use of dynamic memory allocation in low-level BigInt functions
- - A few simplifications in the Randpool mixing function
- - Removed power(), as it was not particularly useful (or fast)
- - Fixed some annoying bugs in the benchmark code
- - Added a real credits file
-
-* 1.5.4, 2006-01-29
- - Integrated x86 and amd64 assembly code, contributed by Luca Piccarreta
- - Fixed a memory access off-by-one in the Karatsuba code
- - Changed Pooling_Allocator's free list search to a log(N) algorithm
- - Merged ModularReducer with its only subclass, Barrett_Reducer
- - Fixed sign-handling bugs in some of the division and modulo code
- - Renamed the module description files to modinfo.txt
- - Further cleanups in the initialization code
- - Removed BigInt::add and BigInt::sub
- - Merged all the division-related functions into just divide()
- - Modified the <mp_asmi.h> functions to allow for better optimizations
- - Made the number of bits polled from an EntropySource user configurable
- - Avoid including <algorithm> in <botan/secmem.h>
- - Fixed some build problems with Sun Forte
- - Removed some dead code from bigint_modop
- - Fix the definition of same_mem
-
-* 1.5.3, 2006-01-24
- - Many optimizations in the low-level multiple precision integer code
- - Added hooks for assembly implementations of the MPI code
- - Support for the X.509 issuer alternative name extension in new certs
- - Fixed a bug in the decompression modules; found and patched by Matt Johnston
- - New Windows mutex module (mux_win32), by Luca Piccarreta
- - Changed the Windows timer module to use QueryPerformanceCounter
- - mem_pool.cpp was using std::set iterators instead of std::multiset ones
- - Fixed a bug in X509_CA preventing users from disabling particular extensions
- - Fixed the mp_asm64 module, which was entirely broken in 1.5.2
- - Fixed some module build problems on FreeBSD and Tru64
-
-* 1.5.2, 2006-01-15
- - Fixed an off-by-one memory read in MISTY1::key()
- - Fixed a nasty memory leak in Output_Buffers::retire()
- - Reimplemented the memory allocator from scratch
- - Improved memory caching in Montgomery exponentiation
- - Optimizations for multiple precision addition and subtraction
- - Fixed a build problem in the hardware timer module on 64-bit PowerPC
- - Changed default Karatsuba cutoff to 12 words (was 14)
- - Removed MemoryRegion::bits(), which was unused and incorrect
- - Changed maximum HMAC keylength to 1024 bits
- - Various minor Makefile and build system changes
- - Avoid using std::min in <secmem.h> to bypass Windows libc macro pollution
- - Switched checks/clock.cpp back to using clock() by default
- - Enabled the symmetric algorithm tests, which were accidentally off in 1.5.1
- - Removed the Default_Mutex's unused clone() member function
-
-* 1.4.12, 2006-01-15
- - Fixed an off-by-one memory read in MISTY1::key()
- - Fixed a nasty memory leak in Output_Buffers::retire()
- - Changed maximum HMAC keylength to 1024 bits
- - Fixed a build problem in the hardware timer module on 64-bit PowerPC
-
-* 1.5.1, 2006-01-08
- - Implemented Montgomery exponentiation
- - Implemented generalized Karatsuba multiplication and squaring
- - Implemented Comba squaring for 4, 6, and 8 word inputs
- - Added new Modular_Exponentiator and Power_Mod classes
- - Removed FixedBase_Exp and FixedExponent_Exp
- - Fixed a performance regression in get_allocator introduced in 1.5.0
- - Engines can now offer S2K algorithms and block cipher padding methods
- - Merged the remaining global 'algolist' code into Default_Engine
- - The low-level MPI code is linked as C again
- - Replaced BigInt's get_nibble with the more general get_substring
- - Some documentation updates
-
-* 1.5.0, 2006-01-01
- - Moved all global/shared library state into a single object
- - Mutex objects are created through mutex factories instead of a global
- - Removed ::get_mutex(), ::initialize_mutex(), and Mutex::clone()
- - Removed the RNG_Quality enum entirely
- - There is now only a single global-use PRNG
- - Removed the no_aliases and no_oids options for LibraryInitializer
- - Removed the deprecated algorithms SEAL, ISAAC, and HAVAL
- - Change es_ftw to use unbuffered I/O
-
-* 1.4.11, 2005-12-31
- - Changed Whirlpool diffusion matrix to match updated algorithm spec
- - Fixed several engine module build errors introduced in 1.4.10
- - Fixed two build problems in es_capi; reported by Matthew Gregan
- - Added a constructor to DataSource_Memory taking a std::string
- - Placing the same Filter in multiple Pipes triggers an exception
- - The configure script accepts --docdir and --libdir
- - Merged doc/rngs.txt into the main API document
- - Thanks to Joel Low for several bug reports on early tarballs of 1.4.11
-
-* 1.4.10, 2005-12-18
- - Added an implementation of KASUMI, the block cipher used in 3G phones
- - Refactored Pipe; output queues are now managed by a distinct class
- - Made certain Filter facilities only available to subclasses of Fanout_Filter
- - There is no longer any overhead in Pipe for a message that has been read out
- - It is now possible to generate RSA keys as small as 128 bits
- - Changed some of the core classes to derive from Algorithm as a virtual base
- - Changed Randpool to use HMAC instead of a plain hash as the mixing function
- - Fixed a bug in the allocators; found and fixed by Matthew Gregan
- - Enabled the use of binary file I/O, when requested by the application
- - The OpenSSL engine's block cipher code was missing some deallocation calls
- - Disabled the es_ftw module on NetBSD, due to header problems there
- - Fixed a problem preventing tm_hard from building on MacOS X on PowerPC
- - Some cleanups for the modules that use inline assembler
- - config.h is now stored in build/ instead of build/include/botan/
- - The header util.h was split into bit_ops.h, parsing.h, and util.h
- - Cleaned up some redundant include directives
-
-* 1.4.9, 2005-11-06
- - Added the IBM-created AES candidate algorithm MARS
- - Added the South Korean block cipher SEED
- - Added the stream cipher Turing
- - Added the new hash function FORK-256
- - Deprecated the ISAAC stream cipher
- - Twofish and RC6 are significantly faster with GCC
- - Much better support for 64-bit PowerPC
- - Added support for high-resolution PowerPC timers
- - Fixed a bug in the configure script causing problems on FreeBSD
- - Changed ANSI X9.31 to support arbitrary block ciphers
- - Make the configure script a bit less noisy
- - Added more test vectors for some algorithms, including all the AES finalists
- - Various cosmetic source code cleanups
-
-* 1.4.8, 2005-10-16
- - Resolved a bad performance problem in the allocators; fix by Matt Johnston
- - Worked around a Visual Studio 2003 compilation problem introduced in 1.4.7
- - Renamed OMAC to CMAC to match the official NIST naming
- - Added single byte versions of update() to PK_Signer and PK_Verifier
- - Removed the unused reverse_bits and reverse_bytes functions
-
-* 1.4.7, 2005-09-25
- - Fixed major performance problems with recent versions of GNU C++
- - Added an implementation of the X9.31 PRNG
- - Removed the X9.17 and FIPS 186-2 PRNG algorithms
- - Changed defaults to use X9.31 PRNGs as global PRNG objects
- - Documentation updates to reflect the PRNG changes
- - Some cleanups related to the engine code
- - Removed two useless headers, base_eng.h and secalloc.h
- - Removed PK_Verifier::valid_signature
- - Fixed configure/build system bugs affecting MacOS X builds
- - Added support for the EKOPath x86-64 compiler
- - Added missing destructor for BlockCipherModePaddingMethod
- - Fix some build problems with Visual C++ 2005 beta
- - Fix some build problems with Visual C++ 2003 Workshop
-
-* 1.4.6, 2005-03-13
- - Fix an error in the shutdown code introduced in 1.4.5
- - Setting base/pkcs8_tries to 0 disables the builtin fail-out
- - Support for XMPP identifiers in X.509 certificates
- - Duplicate entries in X.509 DNs are removed
- - More fixes for Borland C++, from Friedemann Kleint
- - Add a workaround for buggy iostreams
-
-* 1.4.5, 2005-02-26
- - Add support for AES encryption of private keys
- - Minor fixes for PBES2 parameter decoding
- - Internal cleanups for global state variables
- - GCC 3.x version detection was broken in non-English locales
- - Work around a Sun Forte bug affecting mem_pool.h
- - Several fixes for Borland C++ 5.5, from Friedemann Kleint
- - Removed inclusion of init.h into base.h
- - Fixed a major bug in reading from certificate stores
- - Cleaned up a couple of mutex leaks
- - Removed some left-over debugging code
- - Removed SSL3_MAC, SSL3_PRF, and TLS_PRF
-
-* 1.4.4, 2004-12-02
- - Further tweaks to the pooling allocator
- - Modified EMSA3 to support SSL/TLS signatures
- - Changes to support Qt/QCA, from Justin Karneges
- - Moved mux_qt module code into mod_qt
- - Fixes for HP-UX from Mike Desjardins
-
-* 1.4.3, 2004-11-06
- - Split up SecureAllocator into Allocator and Pooling_Allocator
- - Memory locking allocators are more likely to be used
- - Fixed the placement of includes in some modules
- - Fixed broken installation procedure
- - Fixes in configure script to support alternate install programs
- - Modules can specify the minimum version they support
-
-* 1.4.2, 2004-10-31
- - Fixed a major CRL handling bug
- - Cipher and hash operations can be offloaded to engines
- - Added support for cipher and hash offload in OpenSSL engine
- - Improvements for 64-bit CPUs without a widening multiply instruction
- - Support for SHA2-* and Whirlpool with EMSA2
- - Fixed a long-standing build problem with conflicting include files
- - Fixed some examples that hadn't been updated for 1.4.x
- - Portability fixes for Solaris, *BSD, HP-UX, and others
- - Lots of fixes and cleanups in the configure script
- - Updated the Gentoo ebuild file
-
-* 1.4.1, 2004-10-10
- - Fixed major errors in the X.509 and PKCS #8 copy_key functions
- - Added a LAST_MESSAGE meta-message number for Pipe
- - Added new aliases (3DES and DES-EDE) for Triple-DES
- - Added some new functions to PK_Verifier
- - Cleaned up the KDF interface
- - Disabled tm_posix on *BSD due to header issues
- - Fixed a build problem on PowerPC with GNU C++ pre-3.4
-
-* 1.4.0, 2004-06-26
- - Added the FIPS 186 RNG back
- - Added copy_key functions for X.509 public keys and PKCS #8 private keys
- - Fixed PKCS #1 signatures with RIPEMD-128
- - Moved some code around to avoid warnings with Sun ONE compiler
- - Fixed a bug in botan-config affecting OpenBSD
- - Fixed some build problems on Tru64, HP-UX
- - Fixed compile problems with Intel C++, Compaq C++
-
-* 1.3.14, 2004-06-12
- - Added support for AEP's AEP1000/AEP2000 crypto cards
- - Added a Mutex module using Qt, from Justin Karneges
- - Added support for engine loading in LibraryInitializer
- - Tweaked SecureAllocator, giving 20% better performance under heavy load
- - Added timer and memory locking modules for Win32 (tm_win32, ml_win32)
- - Renamed PK_Engine to Engine_Core
- - Improved the Karatsuba cutoff points
- - Fixes for compiling with GCC 3.4 and Sun C++ 5.5
- - Fixes for Linux/s390, OpenBSD, and Solaris
- - Added support for Linux/s390x
- - The configure script was totally broken for 'generic' OS
- - Removed Montgomery reduction due to bugs
- - Removed an unused header, pkcs8alg.h
- - check --validate returns an error code if any tests failed
- - Removed duplicate entry in Unix command list for es_unix
- - Moved the Cert_Usage enumeration into X509_Store
- - Added new timing methods for PK benchmarks, clock_gettime and RDTSC
- - Fixed a few minor bugs in the configure script
- - Removed some deprecated functions from x509cert.h and pkcs10.h
- - Removed the 'minimal' module, has to be updated for Engine support
- - Changed MP_WORD_BITS macro to BOTAN_MP_WORD_BITS to clean up namespace
- - Documentation updates
-
-* 1.3.13, 2004-05-15
- - Major fixes for Cygwin builds
- - Minor MacOS X install fixes
- - The configure script is a little better at picking the right modules
- - Removed ml_unix from the 'unix' module set for Cygwin compatibility
- - Fixed a stupid compile problem in pkcs10.h
-
-* 1.3.12, 2004-05-02
- - Added ability to remove old entries from CRLs
- - Swapped the first two arguments of X509_CA::update_crl()
- - Added an < operator for MemoryRegion, so it can be used as a std::map key
- - Changed X.509 searching by DNS name from substring to full string compares
- - Renamed a few X509_Certificate and PKCS10_Request member functions
- - Fixed a problem when decoding some PKCS #10 requests
- - Hex_Decoder would not check inputs, reported by Vaclav Ovsik
- - Changed default CRL expire time from 30 days to 7 days
- - X509_CRL's default PEM header is now "X509 CRL", for OpenSSL compatibility
- - Corrected errors in the API doc, fixes from Ken Perano
- - More documentation about the Pipe/Filter code
-
-* 1.3.11, 2004-04-01
- - Fixed two show-stopping bugs in PKCS10_Request
- - Added some sanity checks in Pipe/Filter
- - The DNS and URI entries would get swapped in subjectAlternativeNames
- - MAC_Filter is now willing to not take a key at creation time
- - Setting the expiration times of certs and CRLs is more flexible
- - Fixed problems building on AIX with GCC
- - Fixed some problems in the tutorial pointed out by Dominik Vogt
- - Documentation updates
-
-* 1.3.10, 2004-03-27
- - Added support for OpenPGP's ASCII armor format
- - Cleaned up the RNG system; seeding is much more flexible
- - Added simple autoconfiguration abilities to configure.pl
- - Fixed a GCC 2.95.x compile problem
- - Updated the example configuration file
- - Documentation updates
-
-* 1.3.9, 2004-03-07
- - Added an engine using OpenSSL (requires 0.9.7 or later)
- - X509_Certificate would lose email addresses stored in the DN
- - Fixed a missing initialization in a BigInt constructor
- - Fixed several Visual C++ compile problems
- - Fixed some BeOS build problems
- - Fixed the WiderWake benchmark
-
-* 1.3.8, 2003-12-30
- - Internal changes to PK algorithms to divide data and algorithms
- - DSA/DH/NR/ElGamal constructors accept taking just the private key again
- - ElGamal keys now support being imported/exported as ASN.1 objects
- - Much more consistent and complete error checking in PK algorithms
- - Support for arbitrary backends (engines) for PK operations
- - Added Montgomery reductions
- - Added an engine that uses GNU MP (requires 4.1 or later)
- - Removed the obsolete mp_gmp module
- - Moved several initialization/shutdown functions to init.h
- - Major refactoring of the memory containers
- - New non-locking container, MemoryVector
- - Fixed 64-bit problems in BigInt::set_bit/clear_bit
- - Renamed PK_Key::check_params() to check_key()
- - Some incompatible changes to OctetString
- - Added version checking macros in version.h
- - Removed the fips140 module pending rewrite
- - Added some functions and hooks to help GUIs
- - Moved more shared code into MDx_HashFunction
- - Added a policy hook for specifying the encoding of X.509 strings
-
-* 1.3.7, 2003-12-12
- - Fixed a big security problem in es_unix
- - Fixed several stability problems in es_unix
- - Expanded the list of programs es_unix will try to use
- - SecureAllocator now only preallocates blocks in special cases
- - Added a special case in Global_RNG::seed for forcing a full poll
- - Removed the FIPS 186 RNG added in 1.3.5 pending further testing
- - Configure updates for PowerPC CPUs
- - Removed the (never tested) VAX support
- - Added support for S/390 Linux
-
-* 1.3.6, 2003-12-07
- - Added a new module 'minimal', which disables most algorithms
- - SecureAllocator allocates a few blocks at startup
- - A few minor MPI cleanups
- - RPM spec file cleanups and fixes
-
-* 1.3.5, 2003-11-30
- - Major improvements in ASN.1 string handling
- - Added partial support for ASN.1 UTF8 STRINGs and BMP STRINGs
- - Added partial support for the X.509v3 certificate policies extension
- - Centralized the handling of character set information
- - Added FIPS 140-2 startup self tests
- - Added a module (fips140) for doing extra FIPS 140-2 tests
- - Added FIPS 186-2 RNG
- - Improved ASN.1 BIT STRING handling
- - Removed a memory leak in PKCS10_Request
- - The encoding of DirectoryString now follows PKIX guidelines
- - Fixed some of the character set dependencies
- - Fixed a DER encoding error for tags greater than 30
- - The BER decoder can now handle tags larger than 30
- - Fixed tm_hard.cpp to recognize SPARC on more systems
- - Workarounds for a GCC 2.95.x bug in x509find.cpp
- - RPM changed to install into /usr instead of /usr/local
- - Added support for QNX
-
-* 1.2.8, 2003-11-21
- - Merged several important bug fixes from 1.3.x
-
-* 1.3.4, 2003-11-21
- - Added a module that does certain MPI operations using GNU MP
- - Added the X9.42 Diffie-Hellman PRF
- - The Zlib and Bzip2 objects now use custom allocators
- - Added member functions for directly hashing/MACing SecureVectors
- - Minor optimizations to the MPI addition and subtraction algorithms
- - Some cleanups in the low-level MPI code
- - Created separate AES-{128,192,256} objects
-
-* 1.3.3, 2003-11-17
- - The library can now be repeatedly initialized and shutdown without crashing
- - Fixed an off-by-one error in the CTS code
- - Fixed an error in the EMSA4 verification code
- - Fixed a memory leak in mutex.cpp (pointed out by James Widener)
- - Fixed a memory leak in Pthread_Mutex
- - Fixed several memory leaks in the testing code
- - Bulletproofed the EMSA/EME/KDF/MGF retrieval functions
- - Minor cleanups in SecureAllocator
- - Removed a needless mutex guarding the (stateless) global timer
- - Fixed a piece of bash-specific code in botan-config
- - X.509 objects report more information about decoding errors
- - Cleaned up some of the exception handling
- - Updated the example config file with new OIDSs
- - Moved the build instructions into a separate document, building.tex
-
-* 1.3.2, 2003-11-13
- - Fixed a bug preventing DSA signatures from verifying on X.509 objects
- - Made the X509_Store search routines more efficient and flexible
- - Added a function to X509_PublicKey to do easy public/private key matching
- - Added support for decoding indefinite length BER data
- - Changed Pipe's peek() to take an offset
- - Removed Filter::set_owns in favor of the new incr_owns function
- - Removed BigInt::zero() and BigInt::one()
- - Renamed the PEM related options from base/pem_* to pem/*
- - Added an option to specify the line width when encoding PEM
- - Removed the "rng/safe_longterm" option; it's always on now
- - Changed the cipher used for RNG super-encryption from ARC4 to WiderWake4+1
- - Cleaned up the base64/hex encoders and decoders
- - Added an ASN.1/BER decoder as an example
- - AES had its internals marked 'public' in previous versions
- - Changed the value of the ASN.1 NO_OBJECT enum
- - Various new hacks in the configure script
- - Removed the already nominal support for SunOS
-
-* 1.3.1, 2003-11-04
- - Generalized a few pieces of the DER encoder
- - PKCS8::load_key would fail if handed an unencrypted key
- - Added a failsafe so PKCS #8 key decoding can't go into an infinite loop
-
-* 1.3.0, 2003-11-02
- - Major redesign of the PKCS #8 private key import/export system
- - Added a small amount of UI interface code for getting passphrases
- - Added heuristics that tell if a key, cert, etc is stored as PEM or BER
- - Removed CS-Cipher, SHARK, ThreeWay, MD5-MAC, and EMAC
- - Removed certain deprecated constructors of RSA, DSA, DH, RW, NR
- - Made PEM decoding more forgiving of extra text before the header
-
-* 1.2.7, 2003-10-31
- - Added support for reading configuration files
- - Added constructors so NR and RW keys can be imported easily
- - Fixed mp_asm64, which was completely broken in 1.2.6
- - Removed tm_hw_ia32 module; replaced by tm_hard
- - Added support for loading certain oddly formed RSA certificates
- - Fixed spelling of NON_REPUDIATION enum
- - Renamed the option default_to_ca to v1_assume_ca
- - Fixed a minor bug in X.509 certificate generation
- - Fixed a latent bug in the OID lookup code
- - Updated the RPM spec file
- - Added to the tutorial
-
-* 1.2.6, 2003-07-04
- - Major performance increase for PK algorithms on most 64-bit systems
- - Cleanups in the low-level MPI code to support asm implementations
- - Fixed build problems with some versions of Compaq's C++ compiler
- - Removed useless constructors for NR public and private keys
- - Removed support for the patch_file directive in module files
- - Removed several deprecated functions
-
-* 1.2.5, 2003-06-22
- - Fixed a tricky and long-standing memory leak in Pipe
- - Major cleanups and fixes in the memory allocation system
- - Removed alloc_mlock, which has been superseded by the ml_unix module
- - Removed a denial of service vulnerability in X509_Store
- - Fixed compilation problems with VS .NET 2003 and Codewarrior 8
- - Added another variant of PKCS8::load_key, taking a memory buffer
- - Fixed various minor/obscure bugs which occurred when MP_WORD_BITS != 32
- - BigInt::operator%=(word) was a no-op if the input was a power of 2
- - Fixed portability problems in BigInt::to_u32bit
- - Fixed major bugs in SSL3-MAC
- - Cleaned up some messes in the PK algorithms
- - Cleanups and extensions for OMAC and EAX
- - Made changes to the entropy estimation function
- - Added a 'beos' module set for use on BeOS
- - Officially deprecated a few X509:: and PKCS8:: functions
- - Moved the contents of primes.h to numthry.h
- - Moved the contents of x509opt.h to x509self.h
- - Removed the (empty) desx.h header
- - Documentation updates
-
-* 1.2.4, 2003-05-29
- - Fixed a bug in EMSA1 affecting NR signature verification
- - Fixed a few latent bugs in BigInt related to word size
- - Removed an unused function, mp_add2_nc, from the MPI implementation
- - Reorganized the core MPI files
-
-* 1.2.3, 2003-05-20
- - Fixed a bug that prevented DSA/NR key generation
- - Fixed a bug that prevented importing some root CA certs
- - Fixed a bug in the BER decoder when handing optional bit or byte strings
- - Fixed the encoding of authorityKeyIdentifier in X509_CA
- - Added a sanity check in PBKDF2 for zero length passphrases
- - Added versions of X509::load_key and PKCS8::load_key that take a file name
- - X509_CA generates 128 bit serial numbers now
- - Added tests to check PK key generation
- - Added a simplistic X.509 CA example
- - Cleaned up some of the examples
-
-* 1.2.2, 2003-05-13
- - Add checks to prevent any BigInt bugs from revealing an RSA or RW key
- - Changed the interface of Global_RNG::seed
- - Major improvements for the es_unix module
- - Added another Win32 entropy source, es_win32
- - The Win32 CryptoAPI entropy source can now poll multiple providers
- - Improved the BeOS entropy source
- - Renamed pipe_unixfd module to fd_unix
- - Fixed a file descriptor leak in the EGD module
- - Fixed a few locking bugs
-
-* 1.2.1, 2003-05-06
- - Added ANSI X9.23 compatible CBC padding
- - Added an entropy source using Win32 CryptoAPI
- - Removed the Pipe I/O operators taking a FILE*
- - Moved the BigInt encoding/decoding functions into the BigInt class
- - Integrated several fixes for VC++ 7 (from Hany Greiss)
- - Fixed the configure.pl script for Windows builds
-
-* 1.2.0, 2003-04-28
- - Tweaked the Karatsuba cut-off points
- - Increased the allowed keylength of HMAC and Blowfish
- - Removed the 'mpi_ia32' module, pending rewrite
- - Workaround a GCC 2.95.x bug in eme1.cpp
-
-* 1.1.13, 2003-04-22
- - Added OMAC
- - Added EAX authenticated cipher mode
- - Diffie-Hellman would not do blinding in some cases
- - Optimized the OFB and CTR modes
- - Corrected Skipjack's word ordering, as per NIST clarification
- - Support for all subject/issuer attribute types required by RFC 3280
- - The removeFromCRL CRL reason code is now handled correctly
- - Increased the flexibility of the allocators
- - Renamed Rijndael to AES, created aes.h, deleted rijndael.h
- - Removed support for the 'no_timer' LibraryInitializer option
- - Removed 'es_pthr' module, pending further testing
- - Cleaned up get_ciph.cpp
-
-* 1.1.12, 2003-04-15
- - Fixed a ASN.1 string encoding bug
- - Fixed a pair of X509_DN encoding problems
- - Base64_Decoder and Hex_Decoder can now validate input
- - Removed support for the LibraryInitializer option 'egd_path'
- - Added tests for DSA X.509 and PKCS #8 key formats
- - Removed a long deprecated feature of DH_PrivateKey's constructor
- - Updated the RPM .spec file
- - Major documentation updates
-
-* 1.1.11, 2003-04-07
- - Added PKCS #10 certificate requests
- - Changed X509_Store searching interface to be more flexible
- - Added a generic Certificate_Store interface
- - Added a function for generating self-signed X.509 certs
- - Cleanups and changes to X509_CA
- - New examples for PKCS #10 and self-signed certificates
- - Some documentation updates
-
-* 1.1.10, 2003-04-03
- - X509_CA can now generate new X.509 CRLs
- - Added blinding for RSA, RW, DH, and ElGamal to prevent timing attacks
- - More certificate and CRL extensions/attributes are supported
- - Better DN handling in X.509 certificates/CRLs
- - Added a DataSink hierarchy (suggested by Jim Darby)
- - Consolidated SecureAllocator and ManagedAllocator
- - Many cleanups and generalizations
- - Added a (slow) pthreads based EntropySource
- - Fixed some threading bugs
-
-* 1.1.9, 2003-02-25
- - Added support for using X.509v2 CRLs
- - Fixed several bugs in the path validation algorithm
- - Certificates can be verified for a particular usage
- - Algorithm for comparing distinguished names now follows X.509
- - Cleaned up the code for the es_beos, es_ftw, es_unix modules
- - Documentation updates
-
-* 1.1.8, 2003-01-29
- - Fixes for the certificate path validation algorithm in X509_Store
- - Fixed a bug affecting X509_Certificate::is_ca_cert()
- - Added a general configuration interface for policy issues
- - Cleanups and API changes in the X.509 CA, cert, and store code
- - Made various options available for X509_CA users
- - Changed X509_Time's interface to work around time_t problems
- - Fixed a theoretical weakness in Randpool's entropy mixing function
- - Fixed problems compiling with GCC 2.95.3 and GCC 2.96
- - Fixed a configure bug (reported by Jon Wilson) affecting MinGW
-
-* 1.1.7, 2003-01-12
- - Fixed an obscure but dangerous bug in SecureVector::swap
- - Consolidated SHA-384 and SHA-512 to save code space
- - Added SSL3-MAC and SSL3-PRF
- - Documentation updates, including a new tutorial
-
-* 1.0.2, 2003-01-12
- - Fixed an obscure SEGFAULT causing bug in Pipe
- - Fixed an obscure but dangerous bug in SecureVector::swap
-
-* 1.1.6, 2002-12-10
- - Initial support for X.509v3 certificates and CAs
- - Major redesign/rewrite of the ASN.1 encoding/decoding code
- - Added handling for DSA/NR signatures encoded as DER SEQUENCEs
- - Documented the generic cipher lookup interface
- - Added an (untested) entropy source for BeOS
- - Various cleanups and bug fixes
-
-* 1.1.5, 2002-11-17
- - Added the discrete logarithm integrated encryption system (DLIES)
- - Various optimizations for BigInt
- - Added support for assembler optimizations in modules
- - Added BigInt x86 optimizations module (mpi_ia32)
-
-* 1.1.4, 2002-11-10
- - Speedup of 15-30% for PK algorithms
- - Implemented the PBES2 encryption scheme
- - Fixed a potential bug in decoding RSA and RW private keys
- - Changed the DL_Group class interface to handle different formats better
- - Added support for PKCS #3 encoded DH parameters
- - X9.42 DH parameters use a PEM label of 'X942 DH PARAMETERS'
- - Added key pair consistency checking
- - Fixed a compatibility problem with gcc 2.96 (pointed out by Hany Greiss)
- - A botan-config script is generated at configure time
- - Documentation updates
-
-* 1.1.3, 2002-11-03
- - Added a generic public/private key loading interface
- - Fixed a small encoding bug in RSA, RW, and DH
- - Changed the PK encryption/decryption interface classes
- - ECB supports using padding methods
- - Added a function-based interface for library initialization
- - Added support for RIPEMD-128 and Tiger PKCS#1 v1.5 signatures
- - The cipher mode benchmarks now use 128-bit AES instead of DES
- - Removed some obsolete typedefs
- - Removed OpenCL support (opencl.h, the OPENCL_* macros, etc)
- - Added tests for PKCS #8 encoding/decoding
- - Added more tests for ECB and CBC
-
-* 1.1.2, 2002-10-21
- - Support for PKCS #8 encoded RSA, DSA, and DH private keys
- - Support for Diffie-Hellman X.509 public keys
- - Major reorganization of how X.509 keys are handled
- - Added PKCS #5 v2.0's PBES1 encryption scheme
- - Added a generic cipher lookup interface
- - Added the WiderWake4+1 stream cipher
- - Added support for sync-able stream ciphers
- - Added a 'paranoia level' option for the LibraryInitializer
- - More security for RNG output meant for long term keys
- - Added documentation for some of the new 1.1.x features
- - CFB's feedback argument is now specified in bits
- - Renamed CTR class to CTR_BE
- - Updated the RSA and DSA examples to use X.509 and PKCS #8 key formats
-
-* 1.1.1, 2002-10-15
- - Added the Korean hash function HAS-160
- - Partial support for RSA and DSA X.509 public keys
- - Added a mostly functional BER encoder/decoder
- - Added support for non-deterministic MAC functions
- - Initial support for PEM encoding/decoding
- - Internal cleanups in the PK algorithms
- - Several new convenience functions in Pipe
- - Fixed two nasty bugs in Pipe
- - Messed with the entropy sources for es_unix
- - Discrete logarithm groups are checked for safety more closely now
- - For compatibility with GnuPG, ElGamal now supports DSA-style groups
-
-* 1.1.0, 2002-09-14
- - Added entropy estimation to the RNGs
- - Improved the overall design of both Randpool and ANSI_X917_RNG
- - Added a separate RNG for nonce generation
- - Added window exponentiation support in power_mod
- - Added a get_s2k function and the PKCS #5 S2K algorithms
- - Added the TLSv1 PRF
- - Replaced BlockCipherModeIV typedef with InitializationVector class
- - Renamed PK_Key_Agreement_Scheme to PK_Key_Agreement
- - Renamed SHA1 -> SHA_160 and SHA2_x -> SHA_x
- - Added support for RIPEMD-160 PKCS#1 v1.5 signatures
- - Changed the key agreement scheme interface
- - Changed the S2K and KDF interfaces
- - Better SCAN compatibility for HAVAL, Tiger, MISTY1, SEAL, RC5, SAFER-SK
- - Added support for variable-pass Tiger
- - Major speedup for Rabin-Williams key generation
-
-* 1.0.1, 2002-09-14
- - Fixed a minor bug in Randpool::random()
- - Added some new aliases and typedefs for 1.1.x compatibility
- - The 4096-bit RSA benchmark key was decimal instead of hex
- - EMAC was returning an incorrect name
-
-* 1.0.0, 2002-08-26
- - Octal I/O of BigInt is now supported
- - Fixed portability problems in the es_egd module
- - Generalized IV handling in the block cipher modes
- - Added Karatsuba multiplication and k-ary exponentiation
- - Fixed a problem in the multiplication routines
-
-* 0.9.2, 2002-08-18
- - DH_PrivateKey::public_value() was returning the wrong value
- - Various BigInt optimizations
- - The filters.h header now includes hex.h and base64.h
- - Moved Counter mode to ctr.h
- - Fixed a couple minor problems with VC++ 7
- - Fixed problems with the RPM spec file
-
-* 0.9.1, 2002-08-10
- - Grand rename from OpenCL to Botan
- - Major optimizations for the PK algorithms
- - Added ElGamal encryption
- - Added Whirlpool
- - Tweaked memory allocation parameters
- - Improved the method of seeding the global RNG
- - Moved pkcs1.h to eme_pkcs.h
- - Added more test vectors for some algorithms
- - Fixed error reporting in the BigInt tests
- - Removed Default_Timer, it was pointless
- - Added some new example applications
- - Removed some old examples that weren't that interesting
- - Documented the compression modules
-
-* 0.9.0, 2002-08-03
- - EMSA4 supports variable salt size
- - PK_* can take a string naming the encoding method to use
- - Started writing some internals documentation
-
-* 0.8.7, 2002-07-30
- - Fixed bugs in EME1 and EMSA4
- - Fixed a potential crash at shutdown
- - Cipher modes returned an ill-formed name
- - Removed various deprecated types and headers
- - Cleaned up the Pipe interface a bit
- - Minor additions to the documentation
- - First stab at a Visual C++ makefile (doc/Makefile.vc7)
-
-* 0.8.6, 2002-07-25
- - Added EMSA4 (aka PSS)
- - Brought the manual up to date; many corrections and additions
- - Added a parallel hash function construction
- - Lookup supports all available algorithms now
- - Lazy initialization of the lookup tables
- - Made more discrete logarithm groups available through get_dl_group()
- - StreamCipher_Filter supports seeking (if the underlying cipher does)
- - Minor optimization for GCD calculations
- - Renamed SAFER_SK128 to SAFER_SK
- - Removed many previously deprecated functions
- - Some now-obsolete functions, headers, and types have been deprecated
- - Fixed some bugs in DSA prime generation
- - DL_Group had a constructor for DSA-style prime gen but it wasn't defined
- - Reversed the ordering of the two arguments to SEAL's constructor
- - Fixed a threading problem in the PK algorithms
- - Fixed a minor memory leak in lookup.cpp
- - Fixed pk_types.h (it was broken in 0.8.5)
- - Made validation tests more verbose
- - Updated the check and example applications
-
-* 0.8.5, 2002-07-21
- - Major changes to constructors for DL-based cryptosystems (DSA, NR, DH)
- - Added a DL_Group class
- - Reworking of the pubkey internals
- - Support in lookup for aliases and PK algorithms
- - Renamed CAST5 to CAST_128 and CAST256 to CAST_256
- - Added EMSA1
- - Reorganization of header files
- - LibraryInitializer will install new allocator types if requested
- - Fixed a bug in Diffie-Hellman key generation
- - Did a workaround in pipe.cpp for GCC 2.95.x on Linux
- - Removed some debugging code from init.cpp that made FTW ES useless
- - Better checking for invalid arguments in the PK algorithms
- - Reduced Base64 and Hex default line length (if line breaking is used)
- - Fixes for HP's aCC compiler
- - Cleanups in BigInt
-
-* 0.8.4, 2002-07-14
- - Added Nyberg-Rueppel signatures
- - Added Diffie-Hellman key exchange (kex interface is subject to change)
- - Added KDF2
- - Enhancements to the lookup API
- - Many things formerly taking pointers to algorithms now take names
- - Speedups for prime generation
- - LibraryInitializer has support for seeding the global RNG
- - Reduced SAFER-SK128 memory consumption
- - Reversed the ordering of public and private key values in DSA constructor
- - Fixed serious bugs in MemoryMapping_Allocator
- - Fixed memory leak in Lion
- - FTW_EntropySource was not closing the files it read
- - Fixed line breaking problem in Hex_Encoder
-
-* 0.8.3, 2002-06-09
- - Added DSA and Rabin-Williams signature schemes
- - Added EMSA3
- - Added PKCS#1 v1.5 encryption padding
- - Added Filters for PK algorithms
- - Added a Keyed_Filter class
- - LibraryInitializer processes arguments now
- - Major revamp of the PK interface classes
- - Changed almost all of the Filters for non-template operation
- - Changed HMAC, Lion, Luby-Rackoff to non-template classes
- - Some fairly minor BigInt optimizations
- - Added simple benchmarking for PK algorithms
- - Added hooks for fixed base and fixed exponent modular exponentiation
- - Added some examples for using RSA
- - Numerous bugfixes and cleanups
- - Documentation updates
-
-* 0.8.2, 2002-05-18
- - Added an (experimental) algorithm lookup interface
- - Added code for directly testing BigInt
- - Added SHA2-384
- - Optimized SHA2-512
- - Major optimization for Adler32 (thanks to Dan Nicolaescu)
- - Various minor optimizations in BigInt and related areas
- - Fixed two bugs in X9.19 MAC, both reported by Darren Starsmore
- - Fixed a bug in BufferingFilter
- - Made a few fixes for MacOS X
- - Added a workaround in configure.pl for GCC 2.95.x
- - Better support for PowerPC, ARM, and Alpha
- - Some more cleanups
-
-* 0.8.1, 2002-05-06
- - Major code cleanup (check doc/deprecated.txt)
- - Various bugs fixed, including several portability problems
- - Renamed MessageAuthCode to MessageAuthenticationCode
- - A replacement for X917 is in x917_rng.h
- - Changed EMAC to non-template class
- - Added ANSI X9.19 compatible CBC-MAC
- - TripleDES now supports 128 bit keys
-
-* 0.8.0, 2002-04-24
- - Merged BigInt: many bugfixes and optimizations since alpha2
- - Added RSA (rsa.h)
- - Added EMSA2 (emsa2.h)
- - Lots of new interface code for public key algorithms (pk_base.h, pubkey.h)
- - Changed some interfaces, including SymmetricKey, to support the global rng
- - Fixed a serious bug in ManagedAllocator
- - Renamed RIPEMD128 to RIPEMD_128 and RIPEMD160 to RIPEMD_160
- - Removed some deprecated stuff
- - Added a global random number generator (rng.h)
- - Added clone functions to most of the basic algorithms
- - Added a library initializer class (init.h)
- - Version macros in version.h
- - Moved the base classes from opencl.h to base.h
- - Renamed the bzip2 module to comp_bzip2 and zlib to comp_zlib
- - Documentation updates for the new stuff (still incomplete)
- - Many new deprecated things: check doc/deprecated.txt
-
-* 0.7.10, 2002-04-07
- - Added EGD_EntropySource module (es_egd)
- - Added a file tree walking EntropySource (es_ftw)
- - Added MemoryLocking_Allocator module (alloc_mlock)
- - Renamed the pthr_mux, unix_rnd, and mmap_mem modules
- - Changed timer mechanism; the clock method can be switched on the fly.
- - Renamed MmapDisk_Allocator to MemoryMapping_Allocator
- - Renamed ent_file.h to es_file.h (ent_file.h is around, but deprecated)
- - Fixed several bugs in MemoryMapping_Allocator
- - Added more default sources for Unix_EntropySource
- - Changed SecureBuffer to use same allocation methods as SecureVector
- - Added bigint_divcore into mp_core to support BigInt alpha2 release
- - Removed some Pipe functions deprecated since 0.7.8
- - Some fixes for the configure program
-
-* 0.7.9, 2002-03-19
- - Memory allocation substantially revamped
- - Added memory allocation method based on mmap(2) in the mmap_mem module
- - Added ECB and CTS block cipher modes (ecb.h, cts.h)
- - Added a Mutex interface (mutex.h)
- - Added module pthr_mux, implementing the Mutex interface
- - Added Threaded Filter interface (thr_filt.h)
- - All algorithms can now by keyed with SymmetricKey objects
- - More testing occurs with --validate (expected failures)
- - Fixed two bugs reported by Hany Greiss, in Luby-Rackoff and RC6
- - Fixed a buffering bug in Bzip_Decompress and Zlib_Decompress
- - Made X917 safer (and about 1/3 as fast)
- - Documentation updates
-
-* 0.7.8, 2002-02-28
- - More capabilities for Pipe, inspired by SysV STREAMS, including peeking,
- better buffering, and stack ops. NOT BACKWARDS COMPATIBLE: SEE DOCUMENTATION
- - Added a BufferingFilter class
- - Added popen() based EntropySource for generic Unix systems (unix_rnd)
- - Moved 'devrand' module into main distribution (ent_file.h), renamed to
- File_EntropySource, and changed interface somewhat.
- - Made Randpool somewhat more conservative and also 25% faster
- - Minor fixes and updates for the configure script
- - Added some tweaks for memory allocation
- - Documentation updates for the new Pipe interface
- - Fixed various minor bugs
- - Added a couple of new example programs (stack and hasher2)
-
-* 0.7.7, 2001-11-24
- - Filter::send now works in the constructor of a Filter subclass
- - You may now have to include <opencl/pipe.h> explicitly in some code
- - Added preliminary PK infrastructure classes in pubkey.h and pkbase.h
- - Enhancements to SecureVector (append, destroy functions)
- - New infrastructure for secure memory allocation
- - Added IEEE P1363 primitives MGF1, EME1, KDF1
- - Rijndael optimizations and cleanups
- - Changed CipherMode<B> to BlockCipherMode(B*)
- - Fixed a nasty bug in pipe_unixfd
- - Added portions of the BigInt code into the main library
- - Support for VAX, SH, POWER, PowerPC-64, Intel C++
-
-* 0.7.6, 2001-10-14
- - Fixed several serious bugs in SecureVector created in 0.7.5
- - Square optimizations
- - Fixed shared objects on MacOS X and HP-UX
- - Fixed static libs for KCC 4.0; works with KCC 3.4g as well
- - Full support for Athlon and K6 processors using GCC
- - Added a table of prime numbers < 2**16 (primes.h)
- - Some minor documentation updates
-
-* 0.7.5, 2001-08-19
- - Split checksum.h into adler32.h, crc24.h, and crc32.h
- - Split modes.h into cbc.h, cfb.h, and ofb.h
- - CBC_wPadding* has been replaced by CBC_Encryption and CBC_Decryption
- - Added OneAndZeros and NoPadding methods for CBC
- - Added Lion, a very fast block cipher construction
- - Added an S2K base class (s2k.h) and an OpenPGP_S2K class (pgp_s2k.h)
- - Basic types (ciphers, hashes, etc) know their names now (call name())
- - Changed the EntropySource type somewhat
- - Big speed-ups for ISAAC, Adler32, CRC24, and CRC32
- - Optimized CAST-256, DES, SAFER-SK, Serpent, SEAL, MD2, and RIPEMD-160
- - Some semantics of SecureVector have changed slightly
- - The mlock module has been removed for the time being
- - Added string handling functions for hashes and MACs
- - Various non-user-visible cleanups
- - Shared library soname is now set to the full version number
-
-* 0.7.4, 2001-07-15
- - New modules: Zlib, gettimeofday and x86 RTC timers, Unix I/O for Pipe
- - Fixed a vast number of errors in the config script/makefile/specfile
- - Pipe now has a stdio(3) interface as well as C++ iostreams
- - ARC4 supports skipping the first N bytes of the cipher stream (ala MARK4)
- - Bzip2 supports decompressing multiple concatenated streams, and flushing
- - Added a simple 'overall average' score to the benchmarks
- - Fixed a small bug in the POSIX timer module
- - Removed a very-unlikely-to-occur bug in most of the hash functions
- - filtbase.h now includes <iosfwd>, not <iostream>
- - Minor documentation updates
-
-* 0.7.3, 2001-06-08
- - Fix build problems on Solaris/SPARC
- - Fix build problems with Perl versions < 5.6
- - Fixed some stupid code that broke on a few compilers
- - Added string handling functions to Pipe
- - MISTY1 optimizations
-
-* 0.7.2, 2001-06-03
- - Build system supports modules
- - Added modules for mlock, a /dev/random EntropySource, POSIX1.b timers
- - Added Bzip2 compression filter, contributed by Peter Jones
- - GNU make no longer required (tested with 4.4BSD pmake and Solaris make)
- - Fixed minor bug in several of the hash functions
- - Various other minor fixes and changes
- - Updates to the documentation
-
-* 0.7.1, 2001-05-16
- - Rewrote configure script: more consistent and complete
- - Made it easier to find out parameters of types at run time (opencl.h)
- - New functions for finding the version being used (version.h)
- - New SymmetricKey interface for Filters (symkey.h)
- - InvalidKeyLength now records what the invalid key length was
- - Optimized DES, CS-Cipher, MISTY1, Skipjack, XTEA
- - Changed GOST to use correct S-box ordering (incompatible change)
- - Benchmark code was almost totally rewritten
- - Many more entries in the test vector file
- - Fixed minor and idiotic bug in check.cpp
-
-* 0.7.0, 2001-03-01
- - First public release
+Release Notes
+========================================
+
+2011
+----------------------------------------
+
+1.9.16-dev, ????-??-??
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Second release candidate for 1.10.0
+ * The documenation, previously written in LaTeX, is now in
+ reStructuredText suitable for processing by Sphinx, which can
+ generate HTML, PDFs, or man pages.
+ * Disable the by-default 'strong' checking of private keys that are
+ loaded from storage. You can always request key material sanity
+ checking using check_key.
+ * Bring back removed functions min_keylength_of, max_keylength_of,
+ keylength_multiple_of in lookup.h to avoid breaking applications.
+
+1.9.15, 2011-03-21
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * First release candidate for 1.10.0
+ * Modify how message expansion is done in SHA-256 and SHA-512.
+ Instead of expanding the entire message at the start, compute them
+ in the minimum number of registers. Values are computed 15 rounds
+ before they are needed. On a Core i7-860, GCC 4.5.2, went from
+ 143 to 157 MiB/s in SHA-256, and 211 to 256 MiB/s in SHA-512.
+ * Pipe will delete empty output queues as soon as they are no longer
+ needed, even if earlier messages still have data unread. However an
+ (empty) entry in a deque of pointers will remain until all prior
+ messages are completely emptied.
+ * Avoid reading the SPARC %tick register on OpenBSD as unlike Linux
+ the kernel will not trap and emulate it for us, causing a illegal
+ instruction crash.
+ * Improve detection and autoconfiguration for ARM processors.
+
+1.9.14, 2011-03-01
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add support for bcrypt, OpenBSD's password hashing scheme
+ * Add support for NIST's AES key wrapping algorithm
+ * Fix an infinite loop in zlib filters introduced in 1.9.11 (PR 142)
+
+1.9.13, 2011-02-19
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Update Keccak to the round 3 variant
+ * Fix ordering in GOST 34.10 signatures to match DNSSEC specifications
+ * Use size_t instead of u32bit for small integers in DER/BER codecs
+ * Add new build option --distribution-info
+ * Fix problems in the amalgamation build
+ * Fix building under Clang 2.9 and Sun Studio 12
+
+2010
+----------------------------------------
+
+1.9.12, 2010-12-13
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add the Keccak hash function
+ * Fix compilation problems in Python wrappers
+ * Fix compilation problem in OpenSSL engine
+ * Update SQLite3 database encryption codec
+
+1.9.11, 2010-11-29
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Many SSL/TLS APIs have changed. This API is still unstable.
+ * The SSL interface requires TR1 (uses std::tr1::function)
+ * Fix SSL handshake failures when using RC4 ciphersuites
+ * Fix a number of CRL encoding and decoding bugs
+ * Counter mode now always encrypts 256 blocks in parallel
+ * Code where u32bit was used to represent a length now uses size_t
+ * Use small tables in the first round of AES
+ * Removed AES class: app must choose AES-128, AES-192, or AES-256
+ * Add hex encoding/decoding functions that can be used without a Pipe
+ * Add base64 encoding functions that can be used without a Pipe
+ * Add to_string function to X509_Certificate
+ * Add support for dynamic engine loading on Windows
+ * Replace BlockCipher::BLOCK_SIZE attribute with function block_size()
+ * Replace HashFunction::HASH_BLOCK_SIZE attribute with hash_block_size()
+ * Changed semantics of MemoryRegion::resize and clear to match STL
+ * Removed MemoryRegion::append, replaced by push_back and operator+=
+ * Move PBKDF lookup to engine system
+ * The IDEA key schedule has been changed to run in constant time
+ * Avoid a possible timing vulnerability in Montgomery reduction
+ * Add Algorithm and Key_Length_Specification classes
+ * Switch default PKCS #8 encryption algorithm from AES-128 to AES-256
+ * Update Skein-512 to match the v1.3 specification
+ * Allow using PBKDF2 with empty passphrases
+ * Add compile-time deprecation warnings for GCC, Clang, and MSVC
+ * Support use of HMAC(SHA-256) and CMAC(Blowfish) in passhash9
+ * Improve support for Intel Atom processors
+ * Fix compilation problems under Sun Studio and Clang
+
+1.8.11, 2010-11-02
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fix a number of CRL encoding and decoding bugs
+ * When building a debug library under VC++, use the debug runtime
+ * Fix compilation under Sun Studio on Linux and Solaris
+ * Add several functions for compatability with 1.9
+ * In the examples, read most input files as binary
+ * The Perl build script has been removed in this release
+
+1.8.10, 2010-08-31
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Switch default PKCS #8 encryption algorithm from 3DES to AES-256
+ * Increase default hash iterations from 2048 to 10000 in PBES1 and PBES2
+ * Use small tables in the first round of AES
+ * Add PBKDF typedef and get_pbkdf for better compatability with 1.9
+ * Add version of S2K::derive_key taking salt and iteration count
+ * Enable the /proc-walking entropy source on NetBSD
+ * Fix the doxygen makefile target
+
+1.9.10, 2010-08-12
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add a constant time AES implementation using SSSE3
+ * Add support for loading new Engines at runtime
+ * Use GCC byteswap intrinsics where possible
+ * Drop support for building with Python 2.4
+ * Fix benchmarking of block ciphers in ECB mode
+ * Consolidate the two x86 assembly engines
+ * Rename S2K to PBKDF
+
+1.9.9, 2010-06-28
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add new X509::BER_encode and PKCS8::BER_encode
+ * Give all Filter objects a name() function
+ * Add Keyed_Filter::valid_iv_length
+ * Increase default iteration counts for private key encryption
+ * Fix compilation of mp_asm64 on 64-bit MIPS with GCC 4.4 and later
+ * Fix compilation under Apple's GCC 4.2
+ * Expand and update the Doxygen documentation
+
+1.8.9, 2010-06-16
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Use constant time multiplication in IDEA
+ * Avoid possible timing attack against OAEP decoding
+ * Add new X509::BER_encode and PKCS8::BER_encode
+ * Enable DLL builds under Windows
+ * Add Win32 installer support
+ * Add support for the Clang compiler
+ * Fix problem in semcem.h preventing build under Clang or GCC 3.4
+ * Fix bug that prevented creation of DSA groups under 1024 bits
+ * Fix crash in GMP_Engine if library is shutdown and reinitialized
+ * Work around problem with recent binutils in x86-64 SHA-1
+ * The Perl build script is no longer supported and refuses to run by default
+
+1.9.8, 2010-06-14
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add support for wide multiplications on 64-bit Windows
+ * Use constant time multiplication in IDEA
+ * Avoid possible timing attack against OAEP decoding
+ * Removed FORK-256; rarely used and it has been broken
+ * Rename --use-boost-python to --with-boost-python
+ * Skip building shared libraries on MinGW/Cygwin
+ * Fix creation of 512 and 768 bit DL groups using the DSA kosherizer
+ * Fix compilation on GCC versions before 4.3 (missing cpuid.h)
+ * Fix compilation under the Clang compiler
+
+1.9.7, 2010-04-27
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * TLS: Support reading SSLv2 client hellos
+ * TLS: Add support for SEED ciphersuites (RFC 4162)
+ * Add Comb4P hash combiner function
+ * Fix checking of EMSA_Raw signatures with leading 0 bytes
+
+1.9.6, 2010-04-09
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * TLS: Add support for TLS v1.1
+ * TLS: Support server name indicator extension
+ * TLS: Fix server handshake
+ * TLS: Fix server using DSA certificates
+ * TLS: Avoid timing channel between CBC padding check and MAC verification
+
+1.9.5, 2010-03-29
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Numerous ECC optimizations
+ * Fix GOST 34.10-2001 X.509 key loading
+ * Allow PK_Signer's fault protection checks to be toggled off
+ * Avoid using pool-based locking allocator if we can't mlock
+ * Remove all runtime options
+ * New BER_Decoder::{decode_and_check, decode_octet_string_bigint}
+ * Remove SecureBuffer in favor of SecureVector length parameter
+ * HMAC_RNG: Perform a poll along with user-supplied entropy
+ * Fix crash in MemoryRegion if Allocator::get failed
+ * Fix small compilation problem on FreeBSD
+
+1.9.4, 2010-03-09
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add the Ajisai SSLv3/TLSv1.0 implementation
+ * Add GOST 34.10-2001 public key signature scheme
+ * Add SIMD implementation of Noekeon
+ * Add SSE2 implementation of IDEA
+ * Extend Salsa20 to support longer IVs (XSalsa20)
+ * Perform XTS encryption and decryption in parallel where possible
+ * Perform CBC decryption in parallel where possible
+ * Add SQLite3 db encryption codec, contributed by Olivier de Gaalon
+ * Add a block cipher cascade construction
+ * Add support for password hashing for authentication (passhash9.h)
+ * Add support for Win32 high resolution system timers
+ * Major refactoring and API changes in the public key code
+ * Use consistency checking (anti-fault attack) for all signature schemes
+ * Changed S2K interface: derive_key now takes salt, iteration count
+ * Remove dependency on TR1 for ECC and CVC code
+ * Renamed ECKAEG to its more usual name, ECDH
+ * Fix crash in GMP_Engine if library is shutdown and reinitialized
+ * Fix an invalid memory read in MD4
+ * Fix Visual C++ static builds
+ * Remove Timer class entirely
+ * Switch default PKCS #8 encryption algorithm from 3DES to AES-128
+ * New option --gen-amalgamation for creating a SQLite-style amalgamation
+ * Many headers are now explicitly internal-use-only and are not installed
+ * Greatly improve the Win32 installer
+ * Several fixes for Visual C++ debug builds
+
+2009
+----------------------------------------
+
+1.9.3, 2009-11-19
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add new AES implementation using Intel's AES instruction intrinsics
+ * Add an implementation of format preserving encryption
+ * Allow use of any hash function in X.509 certificate creation
+ * Optimizations for MARS, Skipjack, and AES
+ * Set macros for available SIMD instructions in build.h
+ * Add support for using InnoSetup to package Windows builds
+ * By default build a DLL on Windows
+
+1.9.2, 2009-11-03
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add SIMD version of XTEA
+ * Support both SSE2 and AltiVec SIMD for Serpent and XTEA
+ * Optimizations for SHA-1 and SHA-2
+ * Add AltiVec runtime detection
+ * Fix x86 CPU identification with Intel C++ and Visual C++
+
+1.8.8, 2009-11-03
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Alter Skein-512 to match the tweaked 1.2 specification
+ * Fix use of inline asm for access to x86 bswap function
+ * Allow building the library without AES enabled
+ * Add 'powerpc64' alias to ppc64 arch for Gentoo ebuild
+
+1.9.1, 2009-10-23
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Better support for Python and Perl wrappers
+ * Add an implementation of Blue Midnight Wish (Round 2 tweak version)
+ * Modify Skein-512 to match the tweaked 1.2 specification
+ * Add threshold secret sharing (draft-mcgrew-tss-02)
+ * Add runtime cpu feature detection for x86/x86-64
+ * Add code for general runtime self testing for hashes, MACs, and ciphers
+ * Optimize XTEA; twice as fast as before on Core2 and Opteron
+ * Convert CTR_BE and OFB from filters to stream ciphers
+ * New parsing code for SCAN algorithm names
+ * Enable SSE2 optimizations under Visual C++
+ * Remove all use of C++ exception specifications
+ * Add support for GNU/Hurd and Clang/LLVM
+
+1.9.0, 2009-09-09
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add support for parallel invocation of block ciphers where possible
+ * Add SSE2 implementation of Serpent
+ * Add Rivest's package transform (an all or nothing transform)
+ * Minor speedups to the Turing key schedule
+ * Fix processing multiple messages in XTS mode
+ * Add --no-autoload option to configure.py, for minimized builds
+ * The previously used configure.pl script is no longer supported
+
+1.8.7, 2009-09-09
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fix processing multiple messages in XTS mode
+ * Add --no-autoload option to configure.py, for minimized builds
+
+1.8.6, 2009-08-13
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add Cryptobox, a set of simple password-based encryption routines
+ * Only read world-readable files when walking /proc for entropy
+ * Fix building with TR1 disabled
+ * Fix x86 bswap support for Visual C++
+ * Fixes for compilation under Sun C++
+ * Add support for Dragonfly BSD (contributed by Patrick Georgi)
+ * Add support for the Open64 C++ compiler
+ * Build fixes for MIPS systems running Linux
+ * Minor changes to license, now equivalent to the FreeBSD/NetBSD license
+
+1.8.5, 2009-07-23
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Change configure.py to work on stock Python 2.4
+ * Avoid a crash in Skein_512::add_data processing a zero-length input
+ * Small build fixes for SPARC, ARM, and HP-PA processors
+ * The test suite now returns an error code from main() if any tests failed
+
+1.8.4, 2009-07-12
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fix a bug in nonce generation in the Miller-Rabin test
+
+1.8.3, 2009-07-11
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add a new Python configuration script
+ * Add the Skein-512 SHA-3 candidate hash function
+ * Add the XTS block cipher mode from IEEE P1619
+ * Fix random_prime when generating a prime of less than 7 bits
+ * Improve handling of low-entropy situations during PRNG seeding
+ * Change random device polling to prefer /dev/urandom over /dev/random
+ * Use an input insensitive implementation of same_mem instead of memcmp
+ * Correct DataSource::discard_next to return the number of discarded bytes
+ * Provide a default value for AutoSeeded_RNG::reseed
+ * Fix Gentoo bug 272242
+
+1.8.2, 2009-04-07
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Make entropy polling more flexible and in most cases faster
+ * GOST 28147 now supports multiple sbox parameters
+ * Added the GOST 34.11 hash function
+ * Fix botan-config problems on MacOS X
+
+1.8.1, 2009-01-20
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Avoid a valgrind warning in es_unix.cpp on 32-bit Linux
+ * Fix memory leak in PKCS8 load_key and encrypt_key
+ * Relicense api.tex from CC-By-SA 2.5 to BSD
+ * Fix botan-config on MacOS X, Solaris
+
+2008
+----------------------------------------
+
+1.8.0, 2008-12-08
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fix compilation on Solaris with GCC
+
+1.7.24, 2008-12-01
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fix a compatibility problem with SHA-512/EMSA3 signature padding
+ * Fix bug preventing EGD/PRNGD entropy poller from working
+ * Fix integer overflow in Pooling_Allocator::get_more_core (bug id #27)
+ * Add EMSA3_Raw, a variant of EMSA3 called CKM_RSA_PKCS in PKCS #11
+ * Add support for SHA-224 in EMSA2 and EMSA3 PK signature padding schemes
+ * Add many more test vectors for RSA with EMSA2, EMSA3, and EMSA4
+ * Wrap private structs in SSE2 SHA-1 code in anonymous namespace
+ * Change configure.pl's CPU autodetection output to be more consistent
+ * Disable using OpenSSL's AES due to crashes of unknown cause
+ * Fix warning in /proc walking entropy poller
+ * Fix compilation with IBM XLC for Cell 0.9-200709
+
+1.7.23, 2008-11-23
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Change to use TR1 (thus enabling ECDSA) with GCC and ICC
+ * Optimize almost all hash functions, especially MD4 and Tiger
+ * Add configure.pl options --{with,without}-{bzip2,zlib,openssl,gnump}
+ * Change Timer to be pure virtual, and add ANSI_Clock_Timer
+ * Cache socket descriptors in the EGD entropy source
+ * Avoid bogging down startup in /proc walking entropy source
+ * Remove Buffered_EntropySource helper class
+ * Add a Default_Benchmark_Timer typedef in benchmark.h
+ * Add examples using benchmark.h and Algorithm_Factory
+ * Add ECC tests from InSiTo
+ * Minor documentation updates
+
+1.7.22, 2008-11-17
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add provider preferences to Algorithm_Factory
+ * Fix memory leaks in PBE_PKCS5v20 and get_pbe introduced in 1.7.21
+ * Optimize AES encryption and decryption (about 10% faster)
+ * Enable SSE2 optimized SHA-1 implementation on Intel Prescott CPUs
+ * Fix nanoseconds overflow in benchmark code
+ * Remove Engine::add_engine
+
+1.7.21, 2008-11-11
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Make algorithm lookup much more configuable
+ * Add facilities for runtime performance testing of algorithms
+ * Drop use of entropy estimation in the PRNGs
+ * Increase intervals between HMAC_RNG automatic reseeding
+ * Drop InitializerOptions class, all options but thread safety
+
+1.7.20, 2008-11-09
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Namespace pkg-config file by major and minor versions
+ * Cache device descriptors in Device_EntropySource
+ * Split base.h into {block_cipher,stream_cipher,mac,hash}.h
+ * Removed get_mgf function from lookup.h
+
+1.7.19, 2008-11-06
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add HMAC_RNG, based on a design by Hugo Krawczyk
+ * Optimized the Turing stream cipher (about 20% faster on x86-64)
+ * Modify Randpool's reseeding algorithm to poll more sources
+ * Add a new AutoSeeded_RNG in auto_rng.h
+ * OpenPGP_S2K changed to take hash object instead of name
+ * Add automatic identification for Intel's Prescott processors
+
+1.7.18, 2008-10-22
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add Doxygen comments from InSiTo
+ * Add ECDSA and ECKAEG benchmarks
+ * Add configure.pl switch --with-tr1-implementation
+ * Fix configure.pl's --with-endian and --with-unaligned-mem options
+ * Added support for pkg-config
+ * Optimize byteswap with x86 inline asm for Visual C++ by Yves Jerschow
+ * Use const references to avoid copying overhead in CurveGFp, GFpModulus
+
+1.7.17, 2008-10-12
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add missing ECDSA object identifiers
+ * Fix error in x86 and x86-64 assembler affecting GF(p) math
+ * Remove Boost dependency from GF(p) math
+ * Modify botan-config to not print -L/usr/lib or -L/usr/local/lib
+ * Add BOTAN_DLL macro to over 30 classes missing it
+ * Rename the two SHA-2 base classes for consistency
+
+1.7.16, 2008-10-09
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add several missing pieces needed for ECDSA and ECKAEG
+ * Add Card Verifiable Certificates from InSiTo
+ * Add SHA-224 from InSiTo
+ * Add BSI variant of EMSA1 from InSiTo
+ * Add GF(p) and ECDSA tests from InSiTo
+ * Split ECDSA and ECKAEG into distinct modules
+ * Allow OpenSSL and GNU MP engines to be built with public key algos disabled
+ * Rename sha256.h to sha2_32.h and sha_64.h to sha2_64.h
+
+1.7.15, 2008-10-07
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add GF(p) arithmetic from InSiTo
+ * Add ECDSA and ECKAEG implementations from InSiTo
+ * Minimize internal dependencies, allowing for smaller build configurations
+ * Add new User Manual and Architecture Guide from FlexSecure GmbH
+ * Alter configure.pl options for better autotools compatibility
+ * Update build instructions for recent changes to configure.pl
+ * Fix CPU detection using /proc/cpuinfo
+
+1.7.14, 2008-09-30
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Split library into parts allowing modular builds
+ * Add (very preliminary) CMS support to the main library
+ * Some constructors now require object pointers instead of names
+ * Support multiple implementations of the same algorithm
+ * Build support for Pentium-M processors, from Derek Scherger
+ * Build support for MinGW/MSYS, from Zbigniew Zagorski
+ * Use inline assembly for bswap on 32-bit x86
+
+1.7.13, 2008-09-27
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add SSLv3 MAC, SSLv3 PRF, and TLS v1.0 PRF from Ajisai
+ * Allow all examples to compile even if compression not enabled
+ * Make CMAC's polynomial doubling operation a public class method
+ * Use the -m64 flag when compiling with Sun Forte on x86-64
+ * Clean up and slightly optimize CMAC::final_result
+
+1.7.12, 2008-09-18
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add x86 assembly for Visual Studio C++, by Luca Piccarreta
+ * Add a Perl XS module, by Vaclav Ovsik
+ * Add SWIG-based wrapper for Botan
+ * Add SSE2 implementation of SHA-1, by Dean Gaudet
+ * Remove the BigInt::sig_words cache due to bugs
+ * Combined the 4 Blowfish sboxes, suggested by Yves Jerschow
+ * Changed BigInt::grow_by and BigInt::grow_to to be non-const
+ * Add private assignment operators to classes that don't support assignment
+ * Benchmark RSA encryption and signatures
+ * Added test programs for random_prime and ressol
+ * Add high resolution timers for IA-64, HP-PA, S390x
+ * Reduce use of the RNG during benchmarks
+ * Fix builds on STI Cell PPU
+ * Add support for IBM's XLC compiler
+ * Add IETF 8192 bit MODP group
+
+1.7.11, 2008-09-11
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added the Salsa20 stream cipher
+ * Optimized Montgomery reduction, Karatsuba squaring
+ * Added 16x16->32 word Comba multiplication and squaring
+ * Use a much larger Karatsuba cutoff point
+ * Remove bigint_mul_add_words
+ * Inlined several BigInt functions
+ * Add useful information to the generated build.h
+ * Rename alg_{ia32,amd64} modules to asm_{ia32,amd64}
+ * Fix the Windows build
+
+1.7.10, 2008-09-05
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Public key benchmarks run using a selection of random keys
+ * New benchmark timer options are clock_gettime, gettimeofday, times, clock
+ * Including reinterpret_cast optimization for xor_buf in default header
+ * Split byte swapping and word rotation functions into distinct headers
+ * Add IETF modp 6144 group and 2048 and 3072 bit DSS groups
+ * Optimizes BigInt right shift
+ * Add aliases in DL_Group::Format enum
+ * BigInt now caches the significant word count
+
+1.7.9, 2008-08-27
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Make clear() in most algorithm base classes a pure virtual
+ * Add noexec stack marker for GNU linker in assembly code
+ * Avoid string operations in ressol
+ * Compilation fixes for MinGW and Visual Studio C++ 2008
+ * Some autoconfiguration fixes for Windows
+
+1.6.5, 2008-08-27
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add noexec stack marker for GNU linker in assembly code
+ * Fix autoconfiguration problem on x86 with GCC 4.2 and 4.3
+
+1.7.8, 2008-07-15
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added the block cipher Noekeon
+ * Remove global deref_alias function
+ * X509_Store takes timeout options as constructor arguments
+ * Add Shanks-Tonelli algorithm, contributed by FlexSecure GmbH
+ * Extend random_prime() for generating primes of any bit length
+ * Remove Config class
+ * Allow adding new entropy via base RNG interface
+ * Reseeding a X9.31 PRNG also reseeds the underlying PRNG
+
+1.7.7, 2008-06-28
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Remove the global PRNG object
+ * The PK filter objects were removed
+ * Add a test suite for the ANSI X9.31 PRNG
+ * Much cleaner and (mostly) thread-safe reimplementation of es_ftw
+ * Remove both default arguments to ANSI_X931_RNG's constructor
+ * Remove the randomizing version of OctetString::change
+ * Make the cipher and MAC to use in Randpool configurable
+ * Move RandomNumberGenerator declaration to rng.h
+ * RSA_PrivateKey will not generate keys smaller than 1024 bits
+ * Fix an error decoding BER UNIVERSAL types with special taggings
+
+1.7.6, 2008-05-05
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Initial support for Windows DLLs, from Joel Low
+ * Reset the position pointer when a new block is generated in X9.32 PRNG
+ * Timer objects are now treated as entropy sources
+ * Moved several ASN.1-related enums from enums.h to an appropriate header
+ * Removed the AEP module, due to inability to test
+ * Removed Global_RNG and rng.h
+ * Removed system_clock
+ * Removed Library_State::UI and the pulse callback logic
+
+1.7.5, 2008-04-12
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * The API of X509_CA::sign_request was altered to avoid race conditions
+ * New type Pipe::message_id to represent the Pipe message number
+ * Remove the Named_Mutex_Holder for a small performance gain
+ * Removed several unused or rarely used functions from Config
+ * Ignore spaces inside of a decimal string in BigInt::decode
+ * Allow using a std::istream to initialize a DataSource_Stream object
+ * Fix compilation problem in zlib compression module
+ * The chunk sized used by Pooling_Allocator is now a compile time setting
+ * The size of random blinding factors is now a compile time setting
+ * The install target no longer tries to set a particular owner/group
+
+1.7.4, 2008-03-10
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Use unaligned memory read/writes on systems that allow it, for performance
+ * Assembly for x86-64 for accessing the bswap instruction
+ * Use larger buffers in ARC4 and WiderWAKE for significant throughput increase
+ * Unroll loops in SHA-160 for a few percent increase in performance
+ * Fix compilation with GCC 3.2 in es_ftw and es_unix
+ * Build fix for NetBSD systems
+ * Prevent es_dev from being built except on Unix systems
+
+1.6.4, 2008-03-08
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fix a compilation problem with Visual Studio C++ 2003
+
+1.7.3, 2008-01-23
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * New invocation syntax for configure.pl with several new options
+ * Support for IPv4 addresses in a subject alternative name
+ * New fast poll for the generic Unix entropy source (es_unix)
+ * The es_file entropy source has been replaced by the es_dev module
+ * The malloc allocator does not inherit from Pooling_Allocator anymore
+ * The path that es_unix will search in are now fully user-configurable
+ * Truncate X9.42 PRF output rather than allow counter overflow
+ * PowerPC is now assumed to be big-endian
+
+2007
+----------------------------------------
+
+1.7.2, 2007-10-13
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Initialize the global library state lazily
+ * Add plain CBC-MAC for backwards compatibility with old systems
+ * Clean up some of the self test code
+ * Throw a sensible exception if a DL_Group is not found
+ * Truncate KDF2 output rather than allowing counter overflow
+ * Add newly assigned OIDs for SHA-2 and DSA with SHA-224/256
+ * Fix a Visual Studio compilation problem in x509stat.cpp
+
+1.7.1, 2007-07-23
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fix a race condition in the algorithm object cache
+ * HMAC key schedule optimization
+ * The build header sets a macro defining endianness, if known
+ * New word load/store abstraction allowing further optimization
+ * Modify most of the library to avoid use the C-style casts
+ * Use higher resolution timers in symmetric benchmarks
+
+1.6.3, 2007-07-23
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fix a race condition in the algorithm lookup cache
+ * Fix problems building the memory pool on some versions of Visual C++
+
+1.7.0, 2007-05-19
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * DSA parameter generation now follows FIPS 186-3
+ * Added OIDs for Rabin-Williams and Nyberg-Rueppel
+ * Somewhat better support for out of tree builds
+ * Minor optimizations for RC2 and Tiger
+ * Documentation updates
+ * Update the todo list
+
+1.6.2, 2007-03-24
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fix autodection on Athlon64s running Linux
+ * Fix builds on QNX and compilers using STLport
+ * Remove a call to abort() that crept into production
+
+1.6.1, 2007-01-20
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fix some base64 decoder bugs
+ * Add a new option to base64 encoding, to always append a newline
+ * Fix some build problems under Visual Studio with debug enabled
+ * Fix a bug in BER_Decoder that was triggered under some compilers
+
+2006
+----------------------------------------
+
+1.6.0, 2006-12-17
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Minor cleanups versus 1.5.13
+
+1.5.13, 2006-12-10
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Compilation fixes for the bzip2, zlib, and GNU MP modules
+ * Better support for Intel C++ and EKOpath C++ on x86-64
+
+1.5.12, 2006-10-27
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Cleanups in the initialization routines
+ * Add some x86-64 assembly for multiply-add
+ * Fix problems generating very small (below 384 bit) RSA keys
+ * Support out of tree builds
+ * Bring some of the documentation up to date
+ * More improvements to the Python bindings
+
+1.5.11, 2006-09-10
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Removed the Algorithm base class
+ * Various cleanups in the public key inheritance hierarchy
+ * Major overhaul of the configure/build setup
+ * Added x86 assembler implementations of Serpent and low-level MPI code
+ * Optimizations for the SHA-1 x86 assembler
+ * Various improvements to the Python wrappers
+ * Work around a Visual Studio compiler bug
+
+1.5.10, 2006-08-13
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add x86 assembler versions of MD4, MD5, and SHA-1
+ * Expand InitializerOptions' language to support on/off switches
+ * Fix definition of OID 2.5.4.8; was accidentally changed in 1.5.9
+ * Fix possible resource leaks in the mmap allocator
+ * Slightly optimized buffering in MDx_HashFunction
+ * Initialization failures are dealt with somewhat better
+ * Add an example implementing Pollard's Rho algorithm
+ * Better option handling in the test/benchmark tool
+ * Expand the xor_ciph example to support longer keys
+ * Some updates to the documentation
+
+1.5.9, 2006-07-12
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fixed bitrot in the AEP engine
+ * Fix support for marking certificate/CRL extensions as critical
+ * Significant cleanups in the library state / initialization code
+ * LibraryInitializer takes an explicit InitializerOptions object
+ * Make Mutex_Factory an abstract class, add Default_Mutex_Factory
+ * Change configuration access to using global_state()
+ * Add support for global named mutexes throughout the library
+ * Add some STL wrappers for the delete operator
+ * Change how certificates are created to be more flexible and general
+
+1.5.8, 2006-06-23
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Many internal cleanups to the X.509 cert/CRL code
+ * Allow for application code to support new X.509 extensions
+ * Change the return type of X509_Certificate::{subject,issuer}_info
+ * Allow for alternate character set handling mechanisms
+ * Fix a bug that was slowing squaring performance somewhat
+ * Fix a very hard to hit overflow bug in the C version of word3_muladd
+ * Minor cleanups to the assembler modules
+ * Disable es_unix module on FreeBSD due to build problem on FreeBSD 6.1
+ * Support for GCC 2.95.x has been dropped in this release
+
+1.5.7, 2006-05-28
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Further, major changes to the BER/DER coding system
+ * Updated the Qt mutex module to use Mutex_Factory
+ * Moved the library global state object into an anonymous namespace
+ * Drop the Visual C++ x86 assembly module due to bugs
+
+1.5.6, 2006-03-01
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * The low-level DER/BER coding system was redesigned and rewritten
+ * Portions of the certificate code were cleaned up internally
+ * Use macros to substantially clean up the GCC assembly code
+ * Added 32-bit x86 assembly for Visual C++ (by Luca Piccarreta)
+ * Avoid a couple of spurious warnings under Visual C++
+ * Some slight cleanups in X509_PublicKey::key_id
+
+1.5.5, 2006-02-04
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fixed a potential infinite loop in the memory pool code (Matt Johnston)
+ * Made Pooling_Allocator::Memory_Block an actual class of sorts
+ * Some small optimizations to the division and modulo computations
+ * Cleaned up the implementation of some of the BigInt operators
+ * Reduced use of dynamic memory allocation in low-level BigInt functions
+ * A few simplifications in the Randpool mixing function
+ * Removed power(), as it was not particularly useful (or fast)
+ * Fixed some annoying bugs in the benchmark code
+ * Added a real credits file
+
+1.5.4, 2006-01-29
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Integrated x86 and amd64 assembly code, contributed by Luca Piccarreta
+ * Fixed a memory access off-by-one in the Karatsuba code
+ * Changed Pooling_Allocator's free list search to a log(N) algorithm
+ * Merged ModularReducer with its only subclass, Barrett_Reducer
+ * Fixed sign-handling bugs in some of the division and modulo code
+ * Renamed the module description files to modinfo.txt
+ * Further cleanups in the initialization code
+ * Removed BigInt::add and BigInt::sub
+ * Merged all the division-related functions into just divide()
+ * Modified the <mp_asmi.h> functions to allow for better optimizations
+ * Made the number of bits polled from an EntropySource user configurable
+ * Avoid including <algorithm> in <botan/secmem.h>
+ * Fixed some build problems with Sun Forte
+ * Removed some dead code from bigint_modop
+ * Fix the definition of same_mem
+
+1.5.3, 2006-01-24
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Many optimizations in the low-level multiple precision integer code
+ * Added hooks for assembly implementations of the MPI code
+ * Support for the X.509 issuer alternative name extension in new certs
+ * Fixed a bug in the decompression modules; found and patched by Matt Johnston
+ * New Windows mutex module (mux_win32), by Luca Piccarreta
+ * Changed the Windows timer module to use QueryPerformanceCounter
+ * mem_pool.cpp was using std::set iterators instead of std::multiset ones
+ * Fixed a bug in X509_CA preventing users from disabling particular extensions
+ * Fixed the mp_asm64 module, which was entirely broken in 1.5.2
+ * Fixed some module build problems on FreeBSD and Tru64
+
+1.5.2, 2006-01-15
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fixed an off-by-one memory read in MISTY1::key()
+ * Fixed a nasty memory leak in Output_Buffers::retire()
+ * Reimplemented the memory allocator from scratch
+ * Improved memory caching in Montgomery exponentiation
+ * Optimizations for multiple precision addition and subtraction
+ * Fixed a build problem in the hardware timer module on 64-bit PowerPC
+ * Changed default Karatsuba cutoff to 12 words (was 14)
+ * Removed MemoryRegion::bits(), which was unused and incorrect
+ * Changed maximum HMAC keylength to 1024 bits
+ * Various minor Makefile and build system changes
+ * Avoid using std::min in <secmem.h> to bypass Windows libc macro pollution
+ * Switched checks/clock.cpp back to using clock() by default
+ * Enabled the symmetric algorithm tests, which were accidentally off in 1.5.1
+ * Removed the Default_Mutex's unused clone() member function
+
+1.4.12, 2006-01-15
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fixed an off-by-one memory read in MISTY1::key()
+ * Fixed a nasty memory leak in Output_Buffers::retire()
+ * Changed maximum HMAC keylength to 1024 bits
+ * Fixed a build problem in the hardware timer module on 64-bit PowerPC
+
+1.5.1, 2006-01-08
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Implemented Montgomery exponentiation
+ * Implemented generalized Karatsuba multiplication and squaring
+ * Implemented Comba squaring for 4, 6, and 8 word inputs
+ * Added new Modular_Exponentiator and Power_Mod classes
+ * Removed FixedBase_Exp and FixedExponent_Exp
+ * Fixed a performance regression in get_allocator introduced in 1.5.0
+ * Engines can now offer S2K algorithms and block cipher padding methods
+ * Merged the remaining global 'algolist' code into Default_Engine
+ * The low-level MPI code is linked as C again
+ * Replaced BigInt's get_nibble with the more general get_substring
+ * Some documentation updates
+
+1.5.0, 2006-01-01
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Moved all global/shared library state into a single object
+ * Mutex objects are created through mutex factories instead of a global
+ * Removed ::get_mutex(), ::initialize_mutex(), and Mutex::clone()
+ * Removed the RNG_Quality enum entirely
+ * There is now only a single global-use PRNG
+ * Removed the no_aliases and no_oids options for LibraryInitializer
+ * Removed the deprecated algorithms SEAL, ISAAC, and HAVAL
+ * Change es_ftw to use unbuffered I/O
+
+2005
+----------------------------------------
+
+1.4.11, 2005-12-31
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Changed Whirlpool diffusion matrix to match updated algorithm spec
+ * Fixed several engine module build errors introduced in 1.4.10
+ * Fixed two build problems in es_capi; reported by Matthew Gregan
+ * Added a constructor to DataSource_Memory taking a std::string
+ * Placing the same Filter in multiple Pipes triggers an exception
+ * The configure script accepts --docdir and --libdir
+ * Merged doc/rngs.txt into the main API document
+ * Thanks to Joel Low for several bug reports on early tarballs of 1.4.11
+
+1.4.10, 2005-12-18
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added an implementation of KASUMI, the block cipher used in 3G phones
+ * Refactored Pipe; output queues are now managed by a distinct class
+ * Made certain Filter facilities only available to subclasses of Fanout_Filter
+ * There is no longer any overhead in Pipe for a message that has been read out
+ * It is now possible to generate RSA keys as small as 128 bits
+ * Changed some of the core classes to derive from Algorithm as a virtual base
+ * Changed Randpool to use HMAC instead of a plain hash as the mixing function
+ * Fixed a bug in the allocators; found and fixed by Matthew Gregan
+ * Enabled the use of binary file I/O, when requested by the application
+ * The OpenSSL engine's block cipher code was missing some deallocation calls
+ * Disabled the es_ftw module on NetBSD, due to header problems there
+ * Fixed a problem preventing tm_hard from building on MacOS X on PowerPC
+ * Some cleanups for the modules that use inline assembler
+ * config.h is now stored in build/ instead of build/include/botan/
+ * The header util.h was split into bit_ops.h, parsing.h, and util.h
+ * Cleaned up some redundant include directives
+
+1.4.9, 2005-11-06
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added the IBM-created AES candidate algorithm MARS
+ * Added the South Korean block cipher SEED
+ * Added the stream cipher Turing
+ * Added the new hash function FORK-256
+ * Deprecated the ISAAC stream cipher
+ * Twofish and RC6 are significantly faster with GCC
+ * Much better support for 64-bit PowerPC
+ * Added support for high-resolution PowerPC timers
+ * Fixed a bug in the configure script causing problems on FreeBSD
+ * Changed ANSI X9.31 to support arbitrary block ciphers
+ * Make the configure script a bit less noisy
+ * Added more test vectors for some algorithms, including all the AES finalists
+ * Various cosmetic source code cleanups
+
+1.4.8, 2005-10-16
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Resolved a bad performance problem in the allocators; fix by Matt Johnston
+ * Worked around a Visual Studio 2003 compilation problem introduced in 1.4.7
+ * Renamed OMAC to CMAC to match the official NIST naming
+ * Added single byte versions of update() to PK_Signer and PK_Verifier
+ * Removed the unused reverse_bits and reverse_bytes functions
+
+1.4.7, 2005-09-25
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fixed major performance problems with recent versions of GNU C++
+ * Added an implementation of the X9.31 PRNG
+ * Removed the X9.17 and FIPS 186-2 PRNG algorithms
+ * Changed defaults to use X9.31 PRNGs as global PRNG objects
+ * Documentation updates to reflect the PRNG changes
+ * Some cleanups related to the engine code
+ * Removed two useless headers, base_eng.h and secalloc.h
+ * Removed PK_Verifier::valid_signature
+ * Fixed configure/build system bugs affecting MacOS X builds
+ * Added support for the EKOPath x86-64 compiler
+ * Added missing destructor for BlockCipherModePaddingMethod
+ * Fix some build problems with Visual C++ 2005 beta
+ * Fix some build problems with Visual C++ 2003 Workshop
+
+1.4.6, 2005-03-13
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fix an error in the shutdown code introduced in 1.4.5
+ * Setting base/pkcs8_tries to 0 disables the builtin fail-out
+ * Support for XMPP identifiers in X.509 certificates
+ * Duplicate entries in X.509 DNs are removed
+ * More fixes for Borland C++, from Friedemann Kleint
+ * Add a workaround for buggy iostreams
+
+1.4.5, 2005-02-26
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add support for AES encryption of private keys
+ * Minor fixes for PBES2 parameter decoding
+ * Internal cleanups for global state variables
+ * GCC 3.x version detection was broken in non-English locales
+ * Work around a Sun Forte bug affecting mem_pool.h
+ * Several fixes for Borland C++ 5.5, from Friedemann Kleint
+ * Removed inclusion of init.h into base.h
+ * Fixed a major bug in reading from certificate stores
+ * Cleaned up a couple of mutex leaks
+ * Removed some left-over debugging code
+ * Removed SSL3_MAC, SSL3_PRF, and TLS_PRF
+
+2004
+----------------------------------------
+
+1.4.4, 2004-12-02
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Further tweaks to the pooling allocator
+ * Modified EMSA3 to support SSL/TLS signatures
+ * Changes to support Qt/QCA, from Justin Karneges
+ * Moved mux_qt module code into mod_qt
+ * Fixes for HP-UX from Mike Desjardins
+
+1.4.3, 2004-11-06
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Split up SecureAllocator into Allocator and Pooling_Allocator
+ * Memory locking allocators are more likely to be used
+ * Fixed the placement of includes in some modules
+ * Fixed broken installation procedure
+ * Fixes in configure script to support alternate install programs
+ * Modules can specify the minimum version they support
+
+1.4.2, 2004-10-31
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fixed a major CRL handling bug
+ * Cipher and hash operations can be offloaded to engines
+ * Added support for cipher and hash offload in OpenSSL engine
+ * Improvements for 64-bit CPUs without a widening multiply instruction
+ * Support for SHA2-* and Whirlpool with EMSA2
+ * Fixed a long-standing build problem with conflicting include files
+ * Fixed some examples that hadn't been updated for 1.4.x
+ * Portability fixes for Solaris, BSD, HP-UX, and others
+ * Lots of fixes and cleanups in the configure script
+ * Updated the Gentoo ebuild file
+
+1.4.1, 2004-10-10
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fixed major errors in the X.509 and PKCS #8 copy_key functions
+ * Added a LAST_MESSAGE meta-message number for Pipe
+ * Added new aliases (3DES and DES-EDE) for Triple-DES
+ * Added some new functions to PK_Verifier
+ * Cleaned up the KDF interface
+ * Disabled tm_posix on BSD due to header issues
+ * Fixed a build problem on PowerPC with GNU C++ pre-3.4
+
+1.4.0, 2004-06-26
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added the FIPS 186 RNG back
+ * Added copy_key functions for X.509 public keys and PKCS #8 private keys
+ * Fixed PKCS #1 signatures with RIPEMD-128
+ * Moved some code around to avoid warnings with Sun ONE compiler
+ * Fixed a bug in botan-config affecting OpenBSD
+ * Fixed some build problems on Tru64, HP-UX
+ * Fixed compile problems with Intel C++, Compaq C++
+
+1.3.14, 2004-06-12
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added support for AEP's AEP1000/AEP2000 crypto cards
+ * Added a Mutex module using Qt, from Justin Karneges
+ * Added support for engine loading in LibraryInitializer
+ * Tweaked SecureAllocator, giving 20% better performance under heavy load
+ * Added timer and memory locking modules for Win32 (tm_win32, ml_win32)
+ * Renamed PK_Engine to Engine_Core
+ * Improved the Karatsuba cutoff points
+ * Fixes for compiling with GCC 3.4 and Sun C++ 5.5
+ * Fixes for Linux/s390, OpenBSD, and Solaris
+ * Added support for Linux/s390x
+ * The configure script was totally broken for 'generic' OS
+ * Removed Montgomery reduction due to bugs
+ * Removed an unused header, pkcs8alg.h
+ * check --validate returns an error code if any tests failed
+ * Removed duplicate entry in Unix command list for es_unix
+ * Moved the Cert_Usage enumeration into X509_Store
+ * Added new timing methods for PK benchmarks, clock_gettime and RDTSC
+ * Fixed a few minor bugs in the configure script
+ * Removed some deprecated functions from x509cert.h and pkcs10.h
+ * Removed the 'minimal' module, has to be updated for Engine support
+ * Changed MP_WORD_BITS macro to BOTAN_MP_WORD_BITS to clean up namespace
+ * Documentation updates
+
+1.3.13, 2004-05-15
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Major fixes for Cygwin builds
+ * Minor MacOS X install fixes
+ * The configure script is a little better at picking the right modules
+ * Removed ml_unix from the 'unix' module set for Cygwin compatibility
+ * Fixed a stupid compile problem in pkcs10.h
+
+1.3.12, 2004-05-02
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added ability to remove old entries from CRLs
+ * Swapped the first two arguments of X509_CA::update_crl()
+ * Added an < operator for MemoryRegion, so it can be used as a std::map key
+ * Changed X.509 searching by DNS name from substring to full string compares
+ * Renamed a few X509_Certificate and PKCS10_Request member functions
+ * Fixed a problem when decoding some PKCS #10 requests
+ * Hex_Decoder would not check inputs, reported by Vaclav Ovsik
+ * Changed default CRL expire time from 30 days to 7 days
+ * X509_CRL's default PEM header is now "X509 CRL", for OpenSSL compatibility
+ * Corrected errors in the API doc, fixes from Ken Perano
+ * More documentation about the Pipe/Filter code
+
+1.3.11, 2004-04-01
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fixed two show-stopping bugs in PKCS10_Request
+ * Added some sanity checks in Pipe/Filter
+ * The DNS and URI entries would get swapped in subjectAlternativeNames
+ * MAC_Filter is now willing to not take a key at creation time
+ * Setting the expiration times of certs and CRLs is more flexible
+ * Fixed problems building on AIX with GCC
+ * Fixed some problems in the tutorial pointed out by Dominik Vogt
+ * Documentation updates
+
+1.3.10, 2004-03-27
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added support for OpenPGP's ASCII armor format
+ * Cleaned up the RNG system; seeding is much more flexible
+ * Added simple autoconfiguration abilities to configure.pl
+ * Fixed a GCC 2.95.x compile problem
+ * Updated the example configuration file
+ * Documentation updates
+
+1.3.9, 2004-03-07
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added an engine using OpenSSL (requires 0.9.7 or later)
+ * X509_Certificate would lose email addresses stored in the DN
+ * Fixed a missing initialization in a BigInt constructor
+ * Fixed several Visual C++ compile problems
+ * Fixed some BeOS build problems
+ * Fixed the WiderWake benchmark
+
+2003
+----------------------------------------
+
+1.3.8, 2003-12-30
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Internal changes to PK algorithms to divide data and algorithms
+ * DSA/DH/NR/ElGamal constructors accept taking just the private key again
+ * ElGamal keys now support being imported/exported as ASN.1 objects
+ * Much more consistent and complete error checking in PK algorithms
+ * Support for arbitrary backends (engines) for PK operations
+ * Added Montgomery reductions
+ * Added an engine that uses GNU MP (requires 4.1 or later)
+ * Removed the obsolete mp_gmp module
+ * Moved several initialization/shutdown functions to init.h
+ * Major refactoring of the memory containers
+ * New non-locking container, MemoryVector
+ * Fixed 64-bit problems in BigInt::set_bit/clear_bit
+ * Renamed PK_Key::check_params() to check_key()
+ * Some incompatible changes to OctetString
+ * Added version checking macros in version.h
+ * Removed the fips140 module pending rewrite
+ * Added some functions and hooks to help GUIs
+ * Moved more shared code into MDx_HashFunction
+ * Added a policy hook for specifying the encoding of X.509 strings
+
+1.3.7, 2003-12-12
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fixed a big security problem in es_unix
+ * Fixed several stability problems in es_unix
+ * Expanded the list of programs es_unix will try to use
+ * SecureAllocator now only preallocates blocks in special cases
+ * Added a special case in Global_RNG::seed for forcing a full poll
+ * Removed the FIPS 186 RNG added in 1.3.5 pending further testing
+ * Configure updates for PowerPC CPUs
+ * Removed the (never tested) VAX support
+ * Added support for S/390 Linux
+
+1.3.6, 2003-12-07
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added a new module 'minimal', which disables most algorithms
+ * SecureAllocator allocates a few blocks at startup
+ * A few minor MPI cleanups
+ * RPM spec file cleanups and fixes
+
+1.3.5, 2003-11-30
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Major improvements in ASN.1 string handling
+ * Added partial support for ASN.1 UTF8 STRINGs and BMP STRINGs
+ * Added partial support for the X.509v3 certificate policies extension
+ * Centralized the handling of character set information
+ * Added FIPS 140-2 startup self tests
+ * Added a module (fips140) for doing extra FIPS 140-2 tests
+ * Added FIPS 186-2 RNG
+ * Improved ASN.1 BIT STRING handling
+ * Removed a memory leak in PKCS10_Request
+ * The encoding of DirectoryString now follows PKIX guidelines
+ * Fixed some of the character set dependencies
+ * Fixed a DER encoding error for tags greater than 30
+ * The BER decoder can now handle tags larger than 30
+ * Fixed tm_hard.cpp to recognize SPARC on more systems
+ * Workarounds for a GCC 2.95.x bug in x509find.cpp
+ * RPM changed to install into /usr instead of /usr/local
+ * Added support for QNX
+
+1.2.8, 2003-11-21
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Merged several important bug fixes from 1.3.x
+
+1.3.4, 2003-11-21
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added a module that does certain MPI operations using GNU MP
+ * Added the X9.42 Diffie-Hellman PRF
+ * The Zlib and Bzip2 objects now use custom allocators
+ * Added member functions for directly hashing/MACing SecureVectors
+ * Minor optimizations to the MPI addition and subtraction algorithms
+ * Some cleanups in the low-level MPI code
+ * Created separate AES-{128,192,256} objects
+
+1.3.3, 2003-11-17
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * The library can now be repeatedly initialized and shutdown without crashing
+ * Fixed an off-by-one error in the CTS code
+ * Fixed an error in the EMSA4 verification code
+ * Fixed a memory leak in mutex.cpp (pointed out by James Widener)
+ * Fixed a memory leak in Pthread_Mutex
+ * Fixed several memory leaks in the testing code
+ * Bulletproofed the EMSA/EME/KDF/MGF retrieval functions
+ * Minor cleanups in SecureAllocator
+ * Removed a needless mutex guarding the (stateless) global timer
+ * Fixed a piece of bash-specific code in botan-config
+ * X.509 objects report more information about decoding errors
+ * Cleaned up some of the exception handling
+ * Updated the example config file with new OIDSs
+ * Moved the build instructions into a separate document, building.tex
+
+1.3.2, 2003-11-13
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fixed a bug preventing DSA signatures from verifying on X.509 objects
+ * Made the X509_Store search routines more efficient and flexible
+ * Added a function to X509_PublicKey to do easy public/private key matching
+ * Added support for decoding indefinite length BER data
+ * Changed Pipe's peek() to take an offset
+ * Removed Filter::set_owns in favor of the new incr_owns function
+ * Removed BigInt::zero() and BigInt::one()
+ * Renamed the PEM related options from base/pem_* to pem/*
+ * Added an option to specify the line width when encoding PEM
+ * Removed the "rng/safe_longterm" option; it's always on now
+ * Changed the cipher used for RNG super-encryption from ARC4 to WiderWake4+1
+ * Cleaned up the base64/hex encoders and decoders
+ * Added an ASN.1/BER decoder as an example
+ * AES had its internals marked 'public' in previous versions
+ * Changed the value of the ASN.1 NO_OBJECT enum
+ * Various new hacks in the configure script
+ * Removed the already nominal support for SunOS
+
+1.3.1, 2003-11-04
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Generalized a few pieces of the DER encoder
+ * PKCS8::load_key would fail if handed an unencrypted key
+ * Added a failsafe so PKCS #8 key decoding can't go into an infinite loop
+
+1.3.0, 2003-11-02
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Major redesign of the PKCS #8 private key import/export system
+ * Added a small amount of UI interface code for getting passphrases
+ * Added heuristics that tell if a key, cert, etc is stored as PEM or BER
+ * Removed CS-Cipher, SHARK, ThreeWay, MD5-MAC, and EMAC
+ * Removed certain deprecated constructors of RSA, DSA, DH, RW, NR
+ * Made PEM decoding more forgiving of extra text before the header
+
+1.2.7, 2003-10-31
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added support for reading configuration files
+ * Added constructors so NR and RW keys can be imported easily
+ * Fixed mp_asm64, which was completely broken in 1.2.6
+ * Removed tm_hw_ia32 module; replaced by tm_hard
+ * Added support for loading certain oddly formed RSA certificates
+ * Fixed spelling of NON_REPUDIATION enum
+ * Renamed the option default_to_ca to v1_assume_ca
+ * Fixed a minor bug in X.509 certificate generation
+ * Fixed a latent bug in the OID lookup code
+ * Updated the RPM spec file
+ * Added to the tutorial
+
+1.2.6, 2003-07-04
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Major performance increase for PK algorithms on most 64-bit systems
+ * Cleanups in the low-level MPI code to support asm implementations
+ * Fixed build problems with some versions of Compaq's C++ compiler
+ * Removed useless constructors for NR public and private keys
+ * Removed support for the patch_file directive in module files
+ * Removed several deprecated functions
+
+1.2.5, 2003-06-22
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fixed a tricky and long-standing memory leak in Pipe
+ * Major cleanups and fixes in the memory allocation system
+ * Removed alloc_mlock, which has been superseded by the ml_unix module
+ * Removed a denial of service vulnerability in X509_Store
+ * Fixed compilation problems with VS .NET 2003 and Codewarrior 8
+ * Added another variant of PKCS8::load_key, taking a memory buffer
+ * Fixed various minor/obscure bugs which occurred when MP_WORD_BITS != 32
+ * BigInt::operator%=(word) was a no-op if the input was a power of 2
+ * Fixed portability problems in BigInt::to_u32bit
+ * Fixed major bugs in SSL3-MAC
+ * Cleaned up some messes in the PK algorithms
+ * Cleanups and extensions for OMAC and EAX
+ * Made changes to the entropy estimation function
+ * Added a 'beos' module set for use on BeOS
+ * Officially deprecated a few X509:: and PKCS8:: functions
+ * Moved the contents of primes.h to numthry.h
+ * Moved the contents of x509opt.h to x509self.h
+ * Removed the (empty) desx.h header
+ * Documentation updates
+
+1.2.4, 2003-05-29
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fixed a bug in EMSA1 affecting NR signature verification
+ * Fixed a few latent bugs in BigInt related to word size
+ * Removed an unused function, mp_add2_nc, from the MPI implementation
+ * Reorganized the core MPI files
+
+1.2.3, 2003-05-20
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fixed a bug that prevented DSA/NR key generation
+ * Fixed a bug that prevented importing some root CA certs
+ * Fixed a bug in the BER decoder when handing optional bit or byte strings
+ * Fixed the encoding of authorityKeyIdentifier in X509_CA
+ * Added a sanity check in PBKDF2 for zero length passphrases
+ * Added versions of X509::load_key and PKCS8::load_key that take a file name
+ * X509_CA generates 128 bit serial numbers now
+ * Added tests to check PK key generation
+ * Added a simplistic X.509 CA example
+ * Cleaned up some of the examples
+
+1.2.2, 2003-05-13
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Add checks to prevent any BigInt bugs from revealing an RSA or RW key
+ * Changed the interface of Global_RNG::seed
+ * Major improvements for the es_unix module
+ * Added another Win32 entropy source, es_win32
+ * The Win32 CryptoAPI entropy source can now poll multiple providers
+ * Improved the BeOS entropy source
+ * Renamed pipe_unixfd module to fd_unix
+ * Fixed a file descriptor leak in the EGD module
+ * Fixed a few locking bugs
+
+1.2.1, 2003-05-06
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added ANSI X9.23 compatible CBC padding
+ * Added an entropy source using Win32 CryptoAPI
+ * Removed the Pipe I/O operators taking a FILE*
+ * Moved the BigInt encoding/decoding functions into the BigInt class
+ * Integrated several fixes for VC++ 7 (from Hany Greiss)
+ * Fixed the configure.pl script for Windows builds
+
+1.2.0, 2003-04-28
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Tweaked the Karatsuba cut-off points
+ * Increased the allowed keylength of HMAC and Blowfish
+ * Removed the 'mpi_ia32' module, pending rewrite
+ * Workaround a GCC 2.95.x bug in eme1.cpp
+
+1.1.13, 2003-04-22
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added OMAC
+ * Added EAX authenticated cipher mode
+ * Diffie-Hellman would not do blinding in some cases
+ * Optimized the OFB and CTR modes
+ * Corrected Skipjack's word ordering, as per NIST clarification
+ * Support for all subject/issuer attribute types required by RFC 3280
+ * The removeFromCRL CRL reason code is now handled correctly
+ * Increased the flexibility of the allocators
+ * Renamed Rijndael to AES, created aes.h, deleted rijndael.h
+ * Removed support for the 'no_timer' LibraryInitializer option
+ * Removed 'es_pthr' module, pending further testing
+ * Cleaned up get_ciph.cpp
+
+1.1.12, 2003-04-15
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fixed a ASN.1 string encoding bug
+ * Fixed a pair of X509_DN encoding problems
+ * Base64_Decoder and Hex_Decoder can now validate input
+ * Removed support for the LibraryInitializer option 'egd_path'
+ * Added tests for DSA X.509 and PKCS #8 key formats
+ * Removed a long deprecated feature of DH_PrivateKey's constructor
+ * Updated the RPM .spec file
+ * Major documentation updates
+
+1.1.11, 2003-04-07
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added PKCS #10 certificate requests
+ * Changed X509_Store searching interface to be more flexible
+ * Added a generic Certificate_Store interface
+ * Added a function for generating self-signed X.509 certs
+ * Cleanups and changes to X509_CA
+ * New examples for PKCS #10 and self-signed certificates
+ * Some documentation updates
+
+1.1.10, 2003-04-03
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * X509_CA can now generate new X.509 CRLs
+ * Added blinding for RSA, RW, DH, and ElGamal to prevent timing attacks
+ * More certificate and CRL extensions/attributes are supported
+ * Better DN handling in X.509 certificates/CRLs
+ * Added a DataSink hierarchy (suggested by Jim Darby)
+ * Consolidated SecureAllocator and ManagedAllocator
+ * Many cleanups and generalizations
+ * Added a (slow) pthreads based EntropySource
+ * Fixed some threading bugs
+
+1.1.9, 2003-02-25
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added support for using X.509v2 CRLs
+ * Fixed several bugs in the path validation algorithm
+ * Certificates can be verified for a particular usage
+ * Algorithm for comparing distinguished names now follows X.509
+ * Cleaned up the code for the es_beos, es_ftw, es_unix modules
+ * Documentation updates
+
+1.1.8, 2003-01-29
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fixes for the certificate path validation algorithm in X509_Store
+ * Fixed a bug affecting X509_Certificate::is_ca_cert()
+ * Added a general configuration interface for policy issues
+ * Cleanups and API changes in the X.509 CA, cert, and store code
+ * Made various options available for X509_CA users
+ * Changed X509_Time's interface to work around time_t problems
+ * Fixed a theoretical weakness in Randpool's entropy mixing function
+ * Fixed problems compiling with GCC 2.95.3 and GCC 2.96
+ * Fixed a configure bug (reported by Jon Wilson) affecting MinGW
+
+1.1.7, 2003-01-12
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fixed an obscure but dangerous bug in SecureVector::swap
+ * Consolidated SHA-384 and SHA-512 to save code space
+ * Added SSL3-MAC and SSL3-PRF
+ * Documentation updates, including a new tutorial
+
+1.0.2, 2003-01-12
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fixed an obscure SEGFAULT causing bug in Pipe
+ * Fixed an obscure but dangerous bug in SecureVector::swap
+
+2002
+----------------------------------------
+
+1.1.6, 2002-12-10
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Initial support for X.509v3 certificates and CAs
+ * Major redesign/rewrite of the ASN.1 encoding/decoding code
+ * Added handling for DSA/NR signatures encoded as DER SEQUENCEs
+ * Documented the generic cipher lookup interface
+ * Added an (untested) entropy source for BeOS
+ * Various cleanups and bug fixes
+
+1.1.5, 2002-11-17
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added the discrete logarithm integrated encryption system (DLIES)
+ * Various optimizations for BigInt
+ * Added support for assembler optimizations in modules
+ * Added BigInt x86 optimizations module (mpi_ia32)
+
+1.1.4, 2002-11-10
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Speedup of 15-30% for PK algorithms
+ * Implemented the PBES2 encryption scheme
+ * Fixed a potential bug in decoding RSA and RW private keys
+ * Changed the DL_Group class interface to handle different formats better
+ * Added support for PKCS #3 encoded DH parameters
+ * X9.42 DH parameters use a PEM label of 'X942 DH PARAMETERS'
+ * Added key pair consistency checking
+ * Fixed a compatibility problem with gcc 2.96 (pointed out by Hany Greiss)
+ * A botan-config script is generated at configure time
+ * Documentation updates
+
+1.1.3, 2002-11-03
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added a generic public/private key loading interface
+ * Fixed a small encoding bug in RSA, RW, and DH
+ * Changed the PK encryption/decryption interface classes
+ * ECB supports using padding methods
+ * Added a function-based interface for library initialization
+ * Added support for RIPEMD-128 and Tiger PKCS#1 v1.5 signatures
+ * The cipher mode benchmarks now use 128-bit AES instead of DES
+ * Removed some obsolete typedefs
+ * Removed OpenCL support (opencl.h, the OPENCL_* macros, etc)
+ * Added tests for PKCS #8 encoding/decoding
+ * Added more tests for ECB and CBC
+
+1.1.2, 2002-10-21
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Support for PKCS #8 encoded RSA, DSA, and DH private keys
+ * Support for Diffie-Hellman X.509 public keys
+ * Major reorganization of how X.509 keys are handled
+ * Added PKCS #5 v2.0's PBES1 encryption scheme
+ * Added a generic cipher lookup interface
+ * Added the WiderWake4+1 stream cipher
+ * Added support for sync-able stream ciphers
+ * Added a 'paranoia level' option for the LibraryInitializer
+ * More security for RNG output meant for long term keys
+ * Added documentation for some of the new 1.1.x features
+ * CFB's feedback argument is now specified in bits
+ * Renamed CTR class to CTR_BE
+ * Updated the RSA and DSA examples to use X.509 and PKCS #8 key formats
+
+1.1.1, 2002-10-15
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added the Korean hash function HAS-160
+ * Partial support for RSA and DSA X.509 public keys
+ * Added a mostly functional BER encoder/decoder
+ * Added support for non-deterministic MAC functions
+ * Initial support for PEM encoding/decoding
+ * Internal cleanups in the PK algorithms
+ * Several new convenience functions in Pipe
+ * Fixed two nasty bugs in Pipe
+ * Messed with the entropy sources for es_unix
+ * Discrete logarithm groups are checked for safety more closely now
+ * For compatibility with GnuPG, ElGamal now supports DSA-style groups
+
+1.1.0, 2002-09-14
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added entropy estimation to the RNGs
+ * Improved the overall design of both Randpool and ANSI_X917_RNG
+ * Added a separate RNG for nonce generation
+ * Added window exponentiation support in power_mod
+ * Added a get_s2k function and the PKCS #5 S2K algorithms
+ * Added the TLSv1 PRF
+ * Replaced BlockCipherModeIV typedef with InitializationVector class
+ * Renamed PK_Key_Agreement_Scheme to PK_Key_Agreement
+ * Renamed SHA1 -> SHA_160 and SHA2_x -> SHA_x
+ * Added support for RIPEMD-160 PKCS#1 v1.5 signatures
+ * Changed the key agreement scheme interface
+ * Changed the S2K and KDF interfaces
+ * Better SCAN compatibility for HAVAL, Tiger, MISTY1, SEAL, RC5, SAFER-SK
+ * Added support for variable-pass Tiger
+ * Major speedup for Rabin-Williams key generation
+
+1.0.1, 2002-09-14
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fixed a minor bug in Randpool::random()
+ * Added some new aliases and typedefs for 1.1.x compatibility
+ * The 4096-bit RSA benchmark key was decimal instead of hex
+ * EMAC was returning an incorrect name
+
+1.0.0, 2002-08-26
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Octal I/O of BigInt is now supported
+ * Fixed portability problems in the es_egd module
+ * Generalized IV handling in the block cipher modes
+ * Added Karatsuba multiplication and k-ary exponentiation
+ * Fixed a problem in the multiplication routines
+
+0.9.2, 2002-08-18
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * DH_PrivateKey::public_value() was returning the wrong value
+ * Various BigInt optimizations
+ * The filters.h header now includes hex.h and base64.h
+ * Moved Counter mode to ctr.h
+ * Fixed a couple minor problems with VC++ 7
+ * Fixed problems with the RPM spec file
+
+0.9.1, 2002-08-10
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Grand rename from OpenCL to Botan
+ * Major optimizations for the PK algorithms
+ * Added ElGamal encryption
+ * Added Whirlpool
+ * Tweaked memory allocation parameters
+ * Improved the method of seeding the global RNG
+ * Moved pkcs1.h to eme_pkcs.h
+ * Added more test vectors for some algorithms
+ * Fixed error reporting in the BigInt tests
+ * Removed Default_Timer, it was pointless
+ * Added some new example applications
+ * Removed some old examples that weren't that interesting
+ * Documented the compression modules
+
+0.9.0, 2002-08-03
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * EMSA4 supports variable salt size
+ * PK_* can take a string naming the encoding method to use
+ * Started writing some internals documentation
+
+0.8.7, 2002-07-30
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fixed bugs in EME1 and EMSA4
+ * Fixed a potential crash at shutdown
+ * Cipher modes returned an ill-formed name
+ * Removed various deprecated types and headers
+ * Cleaned up the Pipe interface a bit
+ * Minor additions to the documentation
+ * First stab at a Visual C++ makefile (doc/Makefile.vc7)
+
+0.8.6, 2002-07-25
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added EMSA4 (aka PSS)
+ * Brought the manual up to date; many corrections and additions
+ * Added a parallel hash function construction
+ * Lookup supports all available algorithms now
+ * Lazy initialization of the lookup tables
+ * Made more discrete logarithm groups available through get_dl_group()
+ * StreamCipher_Filter supports seeking (if the underlying cipher does)
+ * Minor optimization for GCD calculations
+ * Renamed SAFER_SK128 to SAFER_SK
+ * Removed many previously deprecated functions
+ * Some now-obsolete functions, headers, and types have been deprecated
+ * Fixed some bugs in DSA prime generation
+ * DL_Group had a constructor for DSA-style prime gen but it wasn't defined
+ * Reversed the ordering of the two arguments to SEAL's constructor
+ * Fixed a threading problem in the PK algorithms
+ * Fixed a minor memory leak in lookup.cpp
+ * Fixed pk_types.h (it was broken in 0.8.5)
+ * Made validation tests more verbose
+ * Updated the check and example applications
+
+0.8.5, 2002-07-21
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Major changes to constructors for DL-based cryptosystems (DSA, NR, DH)
+ * Added a DL_Group class
+ * Reworking of the pubkey internals
+ * Support in lookup for aliases and PK algorithms
+ * Renamed CAST5 to CAST_128 and CAST256 to CAST_256
+ * Added EMSA1
+ * Reorganization of header files
+ * LibraryInitializer will install new allocator types if requested
+ * Fixed a bug in Diffie-Hellman key generation
+ * Did a workaround in pipe.cpp for GCC 2.95.x on Linux
+ * Removed some debugging code from init.cpp that made FTW ES useless
+ * Better checking for invalid arguments in the PK algorithms
+ * Reduced Base64 and Hex default line length (if line breaking is used)
+ * Fixes for HP's aCC compiler
+ * Cleanups in BigInt
+
+0.8.4, 2002-07-14
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added Nyberg-Rueppel signatures
+ * Added Diffie-Hellman key exchange (kex interface is subject to change)
+ * Added KDF2
+ * Enhancements to the lookup API
+ * Many things formerly taking pointers to algorithms now take names
+ * Speedups for prime generation
+ * LibraryInitializer has support for seeding the global RNG
+ * Reduced SAFER-SK128 memory consumption
+ * Reversed the ordering of public and private key values in DSA constructor
+ * Fixed serious bugs in MemoryMapping_Allocator
+ * Fixed memory leak in Lion
+ * FTW_EntropySource was not closing the files it read
+ * Fixed line breaking problem in Hex_Encoder
+
+0.8.3, 2002-06-09
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added DSA and Rabin-Williams signature schemes
+ * Added EMSA3
+ * Added PKCS#1 v1.5 encryption padding
+ * Added Filters for PK algorithms
+ * Added a Keyed_Filter class
+ * LibraryInitializer processes arguments now
+ * Major revamp of the PK interface classes
+ * Changed almost all of the Filters for non-template operation
+ * Changed HMAC, Lion, Luby-Rackoff to non-template classes
+ * Some fairly minor BigInt optimizations
+ * Added simple benchmarking for PK algorithms
+ * Added hooks for fixed base and fixed exponent modular exponentiation
+ * Added some examples for using RSA
+ * Numerous bugfixes and cleanups
+ * Documentation updates
+
+0.8.2, 2002-05-18
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added an (experimental) algorithm lookup interface
+ * Added code for directly testing BigInt
+ * Added SHA2-384
+ * Optimized SHA2-512
+ * Major optimization for Adler32 (thanks to Dan Nicolaescu)
+ * Various minor optimizations in BigInt and related areas
+ * Fixed two bugs in X9.19 MAC, both reported by Darren Starsmore
+ * Fixed a bug in BufferingFilter
+ * Made a few fixes for MacOS X
+ * Added a workaround in configure.pl for GCC 2.95.x
+ * Better support for PowerPC, ARM, and Alpha
+ * Some more cleanups
+
+0.8.1, 2002-05-06
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Major code cleanup (check doc/deprecated.txt)
+ * Various bugs fixed, including several portability problems
+ * Renamed MessageAuthCode to MessageAuthenticationCode
+ * A replacement for X917 is in x917_rng.h
+ * Changed EMAC to non-template class
+ * Added ANSI X9.19 compatible CBC-MAC
+ * TripleDES now supports 128 bit keys
+
+0.8.0, 2002-04-24
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Merged BigInt: many bugfixes and optimizations since alpha2
+ * Added RSA (rsa.h)
+ * Added EMSA2 (emsa2.h)
+ * Lots of new interface code for public key algorithms (pk_base.h, pubkey.h)
+ * Changed some interfaces, including SymmetricKey, to support the global rng
+ * Fixed a serious bug in ManagedAllocator
+ * Renamed RIPEMD128 to RIPEMD_128 and RIPEMD160 to RIPEMD_160
+ * Removed some deprecated stuff
+ * Added a global random number generator (rng.h)
+ * Added clone functions to most of the basic algorithms
+ * Added a library initializer class (init.h)
+ * Version macros in version.h
+ * Moved the base classes from opencl.h to base.h
+ * Renamed the bzip2 module to comp_bzip2 and zlib to comp_zlib
+ * Documentation updates for the new stuff (still incomplete)
+ * Many new deprecated things: check doc/deprecated.txt
+
+0.7.10, 2002-04-07
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Added EGD_EntropySource module (es_egd)
+ * Added a file tree walking EntropySource (es_ftw)
+ * Added MemoryLocking_Allocator module (alloc_mlock)
+ * Renamed the pthr_mux, unix_rnd, and mmap_mem modules
+ * Changed timer mechanism; the clock method can be switched on the fly.
+ * Renamed MmapDisk_Allocator to MemoryMapping_Allocator
+ * Renamed ent_file.h to es_file.h (ent_file.h is around, but deprecated)
+ * Fixed several bugs in MemoryMapping_Allocator
+ * Added more default sources for Unix_EntropySource
+ * Changed SecureBuffer to use same allocation methods as SecureVector
+ * Added bigint_divcore into mp_core to support BigInt alpha2 release
+ * Removed some Pipe functions deprecated since 0.7.8
+ * Some fixes for the configure program
+
+0.7.9, 2002-03-19
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Memory allocation substantially revamped
+ * Added memory allocation method based on mmap(2) in the mmap_mem module
+ * Added ECB and CTS block cipher modes (ecb.h, cts.h)
+ * Added a Mutex interface (mutex.h)
+ * Added module pthr_mux, implementing the Mutex interface
+ * Added Threaded Filter interface (thr_filt.h)
+ * All algorithms can now by keyed with SymmetricKey objects
+ * More testing occurs with --validate (expected failures)
+ * Fixed two bugs reported by Hany Greiss, in Luby-Rackoff and RC6
+ * Fixed a buffering bug in Bzip_Decompress and Zlib_Decompress
+ * Made X917 safer (and about 1/3 as fast)
+ * Documentation updates
+
+0.7.8, 2002-02-28
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * More capabilities for Pipe, inspired by SysV STREAMS, including peeking,
+ better buffering, and stack ops. NOT BACKWARDS COMPATIBLE: SEE DOCUMENTATION
+ * Added a BufferingFilter class
+ * Added popen() based EntropySource for generic Unix systems (unix_rnd)
+ * Moved 'devrand' module into main distribution (ent_file.h), renamed to
+ File_EntropySource, and changed interface somewhat.
+ * Made Randpool somewhat more conservative and also 25% faster
+ * Minor fixes and updates for the configure script
+ * Added some tweaks for memory allocation
+ * Documentation updates for the new Pipe interface
+ * Fixed various minor bugs
+ * Added a couple of new example programs (stack and hasher2)
+
+2001
+----------------------------------------
+
+0.7.7, 2001-11-24
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Filter::send now works in the constructor of a Filter subclass
+ * You may now have to include <opencl/pipe.h> explicitly in some code
+ * Added preliminary PK infrastructure classes in pubkey.h and pkbase.h
+ * Enhancements to SecureVector (append, destroy functions)
+ * New infrastructure for secure memory allocation
+ * Added IEEE P1363 primitives MGF1, EME1, KDF1
+ * Rijndael optimizations and cleanups
+ * Changed CipherMode<B> to BlockCipherMode(B*)
+ * Fixed a nasty bug in pipe_unixfd
+ * Added portions of the BigInt code into the main library
+ * Support for VAX, SH, POWER, PowerPC-64, Intel C++
+
+0.7.6, 2001-10-14
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fixed several serious bugs in SecureVector created in 0.7.5
+ * Square optimizations
+ * Fixed shared objects on MacOS X and HP-UX
+ * Fixed static libs for KCC 4.0; works with KCC 3.4g as well
+ * Full support for Athlon and K6 processors using GCC
+ * Added a table of prime numbers < 2**16 (primes.h)
+ * Some minor documentation updates
+
+0.7.5, 2001-08-19
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Split checksum.h into adler32.h, crc24.h, and crc32.h
+ * Split modes.h into cbc.h, cfb.h, and ofb.h
+ * CBC_wPadding* has been replaced by CBC_Encryption and CBC_Decryption
+ * Added OneAndZeros and NoPadding methods for CBC
+ * Added Lion, a very fast block cipher construction
+ * Added an S2K base class (s2k.h) and an OpenPGP_S2K class (pgp_s2k.h)
+ * Basic types (ciphers, hashes, etc) know their names now (call name())
+ * Changed the EntropySource type somewhat
+ * Big speed-ups for ISAAC, Adler32, CRC24, and CRC32
+ * Optimized CAST-256, DES, SAFER-SK, Serpent, SEAL, MD2, and RIPEMD-160
+ * Some semantics of SecureVector have changed slightly
+ * The mlock module has been removed for the time being
+ * Added string handling functions for hashes and MACs
+ * Various non-user-visible cleanups
+ * Shared library soname is now set to the full version number
+
+0.7.4, 2001-07-15
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * New modules: Zlib, gettimeofday and x86 RTC timers, Unix I/O for Pipe
+ * Fixed a vast number of errors in the config script/makefile/specfile
+ * Pipe now has a stdio(3) interface as well as C++ iostreams
+ * ARC4 supports skipping the first N bytes of the cipher stream (ala MARK4)
+ * Bzip2 supports decompressing multiple concatenated streams, and flushing
+ * Added a simple 'overall average' score to the benchmarks
+ * Fixed a small bug in the POSIX timer module
+ * Removed a very-unlikely-to-occur bug in most of the hash functions
+ * filtbase.h now includes <iosfwd>, not <iostream>
+ * Minor documentation updates
+
+0.7.3, 2001-06-08
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Fix build problems on Solaris/SPARC
+ * Fix build problems with Perl versions < 5.6
+ * Fixed some stupid code that broke on a few compilers
+ * Added string handling functions to Pipe
+ * MISTY1 optimizations
+
+0.7.2, 2001-06-03
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Build system supports modules
+ * Added modules for mlock, a /dev/random EntropySource, POSIX1.b timers
+ * Added Bzip2 compression filter, contributed by Peter Jones
+ * GNU make no longer required (tested with 4.4BSD pmake and Solaris make)
+ * Fixed minor bug in several of the hash functions
+ * Various other minor fixes and changes
+ * Updates to the documentation
+
+0.7.1, 2001-05-16
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Rewrote configure script: more consistent and complete
+ * Made it easier to find out parameters of types at run time (opencl.h)
+ * New functions for finding the version being used (version.h)
+ * New SymmetricKey interface for Filters (symkey.h)
+ * InvalidKeyLength now records what the invalid key length was
+ * Optimized DES, CS-Cipher, MISTY1, Skipjack, XTEA
+ * Changed GOST to use correct S-box ordering (incompatible change)
+ * Benchmark code was almost totally rewritten
+ * Many more entries in the test vector file
+ * Fixed minor and idiotic bug in check.cpp
+
+0.7.0, 2001-03-01
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * First public release
diff --git a/doc/lowlevel.txt b/doc/lowlevel.txt
new file mode 100644
index 000000000..4f63948da
--- /dev/null
+++ b/doc/lowlevel.txt
@@ -0,0 +1,641 @@
+
+The Low-Level Interface
+=================================
+
+Botan has two different interfaces. The one documented in this section is meant
+more for implementing higher-level types (see the section on filters, earlier in
+this manual) than for use by applications. Using it safely requires a solid
+knowledge of encryption techniques and best practices, so unless you know, for
+example, what CBC mode and nonces are, and why PKCS #1 padding is important,
+you should avoid this interface in favor of something working at a higher level
+(such as the CMS interface).
+
+Basic Algorithm Abilities
+---------------------------------
+
+There are a small handful of functions implemented by most of Botan's
+algorithm objects. Among these are:
+
+.. cpp:function:: std::string name()
+
+Returns a human-readable string of the name of this
+algorithm. Examples of names returned are "AES-128" and
+"HMAC(SHA-512)". You can turn names back into algorithm objects using
+the functions in ``lookup.h``.
+
+.. cpp:function:: void clear()
+
+Clear out the algorithm's internal state. A block cipher object will
+"forget" its key, a hash function will "forget" any data put into it,
+etc. The object will look and behave as it did when you initially
+allocated it.
+
+.. cpp:function:: T* clone()
+
+This function is central to Botan's name-based interface. The
+``clone`` has many different return types, such as ``BlockCipher``\*
+and ``HashFunction``\*, depending on what kind of object it is called
+on. Note that unlike Java's clone, this returns a new object in a
+"pristine" state; that is, operations done on the initial object
+before calling ``clone`` do not affect the initial state of the new
+clone.
+
+Cloned objects can (and should) be deallocated with the C++ ``delete``
+operator.
+
+Keys and IVs
+---------------------------------
+
+Both symmetric keys and initialization values can be considered byte
+(or octet) strings. These are represented by the classes
+``SymmetricKey`` and ``InitializationVector``, which are
+subclasses of ``OctetString``.
+
+Since often it's hard to distinguish between a key and IV, many things
+(such as key derivation mechanisms) return ``OctetString`` instead of
+``SymmetricKey`` to allow its use as a key or an IV.
+
+.. cpp:function:: OctetString::OctetString(RandomNumberGenerator& rng, size_t length)
+
+ This constructor creates a new random key ``length`` bytes long
+ using the random number generator.
+
+.. cpp:function:: OctetString::OctetString(std::string str)
+
+ The argument ``str`` is assumed to be a hex string; it is converted
+ to binary and stored. Whitespace is ignored.
+
+.. cpp:function:: OctetString::OctetString(const byte* input, size_t length)
+
+ This constructor copies its input.
+
+Symmetrically Keyed Algorithms
+---------------------------------
+
+Block ciphers, stream ciphers, and MACs are all keyed operations; to
+be useful, they have to be set to use a particular key, which is a
+randomly chosen string of bits of a specified length. The length
+required by any particular algorithm may vary, depending on both the
+algorithm specification and the implementation. You can query any
+botan object to find out what key length(s) it supports.
+
+To make this similarity in terms of keying explicit, all algorithms of
+those types are derived from the ``SymmetricAlgorithm`` base
+class. This type provides functions for setting the key, and querying
+restrictions on the size of the key:
+
+.. cpp:function:: void set_key(const byte* key, size_t length)
+
+ This sets the key to the value specified. Most algorithms only
+ accept keys of certain lengths. If you attempt to call ``set_key``
+ with a key length that is not supported, the exception
+ ``Invalid_Key_Length`` will be thrown. There is also another version
+ of ``set_key`` that takes a ``SymmetricKey`` as an argument.
+
+ In all cases, ``set_key`` must be called on an object before any
+ data processing (encryption, decryption, etc) is done by that
+ object. If this is not done, the results are undefined, but probably
+ will not be good.
+
+.. cpp:function:: bool valid_keylength(size_t length) const
+
+ This function returns true if and only if ``length`` is a valid keylength
+ for the algorithm.
+
+.. cpp:function:: size_t minimum_keylength() const
+
+ Return the smallest key length (in bytes) that is acceptible for the
+ algorithm.
+
+.. cpp:function:: size_t maximum_keylength() const
+
+ Return the largest key length (in bytes) that is acceptible for the
+ algorithm
+
+Block Ciphers
+---------------------------------
+
+Block ciphers implement the interface ``BlockCipher``, found in
+``block_cipher.h``, as well as the ``SymmetricAlgorithm`` interface.
+
+.. cpp:function:: size_t block_size() const
+
+ Returns the block size of the cipher in bytes
+
+.. cpp:function:: void encrypt_n(const byte* in, byte* out, size_t blocks) const
+
+ Encrypt ``blocks`` blocks of data, taking the input from ``in`` and
+ placing the ciphertext in ``out``. The two pointers may be
+ identical, but should not overlap ranges.
+
+.. cpp:function:: void encrypt(const byte* in, byte* out) const
+
+ Encrypt a single block, taking the input from ``in`` and placing it
+ in ``out``.
+
+.. cpp:function:: void encrypt(byte* block) const
+
+ Identical to ``encrypt(block, block)``.
+
+.. cpp:function:: void decrypt_n(const byte* in, byte* out, size_t blocks) const
+
+ Decrypt ``blocks`` blocks of data, taking the input from ``in`` and
+ placing the plaintext in ``out``. The two pointers may be identical,
+ but should not overlap ranges.
+
+.. cpp:function:: void decrypt(const byte* in, byte* out) const
+
+ Decrypt a single block, taking the input from ``in`` and placing it
+ in ``out``.
+
+.. cpp:function:: void decrypt(byte* block) const
+
+ Identical to ``decrypt(block, block)``.
+
+
+Stream Ciphers
+---------------------------------
+
+Stream ciphers are somewhat different from block ciphers, in that
+encrypting data results in changing the internal state of the
+cipher. Also, you may encrypt any length of data in one go (in byte
+amounts).
+
+.. cpp:function:: void encrypt(const byte* in, byte* out, size_t length)
+
+.. cpp:function:: void encrypt(byte* data, size_t length)
+
+Stream ciphers implement the ``SymmetricAlgorithm`` interface.
+
+Hash Functions / Message Authentication Codes
+----------------------------------------------
+
+Hash functions take their input without producing any output, only producing
+anything when all input has already taken place. MACs are very similar, but are
+additionally keyed. Both of these are derived from the base class
+``BufferedComputation``, which has the following functions.
+
+.. cpp:function:: size_t output_length()
+
+Return the size of the output of this function.
+
+.. cpp:function:: void update(const byte* input, size_t length)
+
+.. cpp:function:: void update(byte input)
+
+.. cpp:function:: void update(const std::string& input)
+
+Updates the hash/mac calculation with ``input``.
+
+.. cpp:function:: void final(byte* out)
+
+.. cpp:function:: SecureVector<byte> final()
+
+Complete the hash/MAC calculation and place the result into ``out``.
+For the argument taking an array, exactly ``output_length`` bytes will
+be written. After you call ``final``, the hash function is reset to
+its initial state, so it may be reused immediately.
+
+The second method of using final is to call it with no arguments at
+all, as shown in the second prototype. It will return the hash/mac
+value in a memory buffer.
+
+There is also a pair of functions called ``process``. They are
+a combination of a single ``update``, and ``final``.
+Both versions return the final value, rather than placing it an
+array. Calling ``process`` with a single byte value isn't
+available, mostly because it would rarely be useful.
+
+A MAC can be viewed (in most cases) as a keyed hash function, so
+classes that are derived from ``MessageAuthenticationCode`` have
+``update`` and ``final`` classes just like a
+``HashFunction`` (and like a ``HashFunction``, after
+``final`` is called, it can be used to make a new MAC right
+away; the key is kept around).
+
+A MAC has the ``SymmetricAlgorithm`` interface in addition to the
+``BufferedComputation`` interface.
+
+Random Number Generators
+---------------------------------
+
+The random number generators provided in Botan are meant for creating
+keys, IVs, padding, nonces, and anything else that requires 'random'
+data. It is important to remember that the output of these classes
+will vary, even if they are supplied with ethe same seed (ie, two
+``Randpool`` objects with similar initial states will not produce
+the same output, because the value of high resolution timers is added
+to the state at various points).
+
+To ensure good quality output, a PRNG needs to be seeded with truly
+random data (such as that produced by a hardware RNG). Typically, you
+will use an ``EntropySource`` (see below). To add some (typically
+application specific) entropy to a PRNG, you can use
+
+.. cpp:function:: void add_entropy(const byte* data, size_t length)
+
+Once a PRNG has been initialized, you can get a single byte of random
+data by
+
+.. cpp:function:: byte random()
+
+or get a large block by calling
+
+.. cpp:function:: void randomize(byte* data, size_t length)
+
+Randpool
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+``Randpool`` is the primary PRNG within Botan. In recent versions all
+uses of it have been wrapped by an implementation of the X9.31 PRNG
+(see below). If for some reason you should have cause to create a PRNG
+instead of using the "global" one owned by the library, it would be
+wise to consider the same on the grounds of general caution; while
+``Randpool`` is designed with known attacks and PRNG weaknesses in
+mind, it is not an standard/official PRNG. The remainder of this
+section is a (fairly technical, though high-level) description of the
+algorithms used in this PRNG. Unless you have a specific interest in
+this subject, the rest of this section might prove somewhat
+uninteresting.
+
+``Randpool`` has an internal state called pool, which is 512 bytes
+long. This is where entropy is mixed into and extracted from. There is also a
+small output buffer (called buffer), which holds the data which has already
+been generated but has just not been output yet.
+
+It is based around a MAC and a block cipher (which are currently
+HMAC(SHA-256) and AES-256). Where a specific size is mentioned, it
+should be taken as a multiple of the cipher's block size. For example,
+if a 256-bit block cipher were used instead of AES, all the sizes
+internally would double. Every time some new output is needed, we
+compute the MAC of a counter and a high resolution timer. The
+resulting MAC is XORed into the output buffer (wrapping as needed),
+and the output buffer is then encrypted with AES, producing 16 bytes
+of output.
+
+After 8 blocks (or 128 bytes) have been produced, we mix the pool. To
+do this, we first rekey both the MAC and the cipher; the new MAC key
+is the MAC of the current pool under the old MAC key, while the new
+cipher key is the MAC of the current pool under the just-chosen MAC
+key. We then encrypt the entire pool in CBC mode, using the current
+(unused) output buffer as the IV. We then generate a new output
+buffer, using the mechanism described in the previous paragraph.
+
+To add randomness to the PRNG, we compute the MAC of the input and XOR
+the output into the start of the pool. Then we remix the pool and
+produce a new output buffer. The initial MAC operation should make it
+very hard for chosen inputs to harm the security of ``Randpool``, and
+as HMAC should be able to hold roughly 256 bits of state, it is
+unlikely that we are wasting much input entropy (or, if we are, it
+doesn't matter, because we have a very abundant supply).
+
+ANSI X9.31
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+``ANSI_X931_PRNG`` is the standard issue X9.31 Appendix A.2.4 PRNG,
+though using AES-256 instead of 3DES as the block cipher. This PRNG
+implementation has been checked against official X9.31 test vectors.
+
+Internally, the PRNG holds a pointer to another PRNG (typically
+Randpool). This internal PRNG generates the key and seed used by the
+X9.31 algorithm, as well as the date/time vectors. Each time an X9.31
+PRNG object receives entropy, it passes it along to the PRNG it is
+holding, and then pulls out some random bits to generate a new key and
+seed. This PRNG considers itself seeded as soon as the internal PRNG
+is seeded.
+
+
+Entropy Sources
+---------------------------------
+
+An ``EntropySource`` is an abstract representation of some method of
+gather "real" entropy. This tends to be very system dependent. The
+*only* way you should use an ``EntropySource`` is to pass it to a PRNG
+that will extract entropy from it -- never use the output directly for
+any kind of key or nonce generation!
+
+``EntropySource`` has a pair of functions for getting entropy from
+some external source, called ``fast_poll`` and ``slow_poll``. These
+pass a buffer of bytes to be written; the functions then return how
+many bytes of entropy were gathered.
+
+Note for writers of ``EntropySource`` subclasses: it isn't necessary
+to use any kind of cryptographic hash on your output. The data
+produced by an EntropySource is only used by an application after it
+has been hashed by the ``RandomNumberGenerator`` that asked for the
+entropy, thus any hashing you do will be wasteful of both CPU cycles
+and entropy.
+
+User Interfaces
+---------------------------------
+
+Botan has recently changed some infrastructure to better accommodate
+more complex user interfaces, in particular ones that are based on
+event loops. Primary among these was the fact that when doing
+something like loading a PKCS #8 encoded private key, a passphrase
+might be needed, but then again it might not (a PKCS #8 key doesn't
+have to be encrypted). Asking for a passphrase to decrypt an
+unencrypted key is rather pointless. Not only that, but the way to
+handle the user typing the wrong passphrase was complicated,
+undocumented, and inefficient.
+
+So now Botan has an object called ``User_Interface``, which provides a
+simple interface for the aspects of user interaction the library has
+to be concerned with. Currently, this means getting a passphrase from
+the user, and that's it (``User_Interface`` will probably be extended
+in the future to support other operations as they are needed). The
+base ``User_Interface`` class is very stupid, because the library
+can't directly assume anything about the environment that it's running
+under (for example, if there will be someone sitting at the terminal,
+if the application is even *attached* to a terminal, and so on). But
+since you can subclass ``User_Interface`` to use whatever method
+happens to be appropriate for your application, this isn't a big deal:
+
+.. 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 when writing a
+ ``User_Interface`` subclass.
+
+ 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).
+
+There is an example ``User_Interface`` that uses GTK+ available on the
+web site. The ``GTK_UI`` code is cleanly separated from the rest of
+the example, so if you happen to be using GTK+, you can copy (and/or
+adapt) that code for your application. If you write a
+``User_Interface`` object for another windowing system (Win32, Qt,
+wxWidgets, FOX, etc), and would like to make it available to users in
+general (ideally under a permissive license such as public domain or
+MIT/BSD), feel free to send in a copy.
+
+PBKDF Algorithms
+---------------------------------
+
+There are various procedures (usually ad-hoc) for turning a
+passphrase into a (mostly) arbitrary length key for a symmetric
+cipher. A general interface for such algorithms is presented in
+``pbkdf.h``. The main function is ``derive_key``, which
+takes a passphrase, a salt, an iteration count, and the desired length
+of the output key, and returns a key of that length, deterministically
+produced from the passphrase and salt. If an algorithm can't produce a
+key of that size, it will throw an exception (most notably, PKCS #5's
+PBKDF1 can only produce strings between 1 and $n$ bytes, where $n$ is
+the output size of the underlying hash function).
+
+The purpose of the iteration count is to make the algorithm take
+longer to compute the final key (reducing the speed of brute-force
+attacks of various kinds). Most standards recommend an iteration count
+of at least 10000. Currently defined PBKDF algorithms are
+"PBKDF1(digest)", "PBKDF2(digest)", and "OpenPGP-S2K(digest)"; you can
+retrieve any of these using the ``get_pbkdf``, found in
+``lookup.h``. As of this writing, "PBKDF2(SHA-256)" with 10000
+iterations and a 16 byte salt is recommend for new applications.
+
+OpenPGP S2K
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+There are some oddities about OpenPGP's S2K algorithms that are
+documented here. For one thing, it uses the iteration count in a
+strange manner; instead of specifying how many times to iterate the
+hash, it tells how many *bytes* should be hashed in total
+(including the salt). So the exact iteration count will depend on the
+size of the salt (which is fixed at 8 bytes by the OpenPGP standard,
+though the implementation will allow any salt size) and the size of
+the passphrase.
+
+To get what OpenPGP calls "Simple S2K", set iterations to 0, and do
+not specify a salt. To get "Salted S2K", again leave the iteration
+count at 0, but give an 8-byte salt. "Salted and Iterated S2K"
+requires an 8-byte salt and some iteration count (this should be
+significantly larger than the size of the longest passphrase that
+might reasonably be used; somewhere from 1024 to 65536 would probably
+be about right). Using both a reasonably sized salt and a large
+iteration count is highly recommended to prevent password guessing
+attempts.
+
+Password Hashing
+---------------------------------
+
+Storing passwords for user authentication purposes in plaintext is the
+simplest but least secure method; when an attacker compromises the
+database in which the passwords are stored, they immediately gain
+access to all of them. Often passwords are reused among multiple
+services or machines, meaning once a password to a single service is
+known an attacker has a substantial head start on attacking other
+machines.
+
+The general approach is to store, instead of the password, the output
+of a one way function of the password. Upon receiving an
+authentication request, the authenticator can recompute the one way
+function and compare the value just computed with the one that was
+stored. If they match, then the authentication request succeeds. But
+when an attacker gains access to the database, they only have the
+output of the one way function, not the original password.
+
+Common hash functions such as SHA-256 are one way, but used alone they
+have problems for this purpose. What an attacker can do, upon gaining
+access to such a stored password database, is hash common dictionary
+words and other possible passwords, storing them in a list. Then he
+can search through his list; if a stored hash and an entry in his list
+match, then he has found the password. Even worse, this can happen
+*offline*: an attacker can begin hashing common passwords days,
+months, or years before ever gaining access to the database. In
+addition, if two users choose the same password, the one way function
+output will be the same for both of them, which will be visible upon
+inspection of the database.
+
+There are two solutions to these problems: salting and
+iteration. Salting refers to including, along with the password, a
+randomly chosen value which perturbs the one way function. Salting can
+reduce the effectivness of offline dictionary generation (because for
+each potential password, an attacker would have to compute the one way
+function output for all possible salts - with a large enough salt,
+this can make the problem quite difficult). It also prevents the same
+password from producing the same output, as long as the salts do not
+collide. With a large salt (say 80 to 128 bits) this will be quite
+unlikely. Iteration refers to the general technique of forcing
+multiple one way function evaluations when computing the output, to
+slow down the operation. For instance if hashing a single password
+requires running SHA-256 100,000 times instead of just once, that will
+slow down user authentication by a factor of 100,000, but user
+authentication happens quite rarely, and usually there are more
+expensive operations that need to occur anyway (network and database
+I/O, etc). On the other hand, an attacker who is attempting to break a
+database full of stolen password hashes will be seriously
+inconvenienced by a factor of 100,000 slowdown; they will be able to
+only test at a rate of .0001% of what they would without iterations
+(or, equivalently, will require 100,000 times as many zombie botnet
+hosts).
+
+There are many different ways of doing this password hashing
+operation, with common ones including Unix's crypt (which is based on
+DES) and OpenBSD's bcrypt (based on Blowfish). Other variants using
+MD5 or SHA-256 are also in use on various systems.
+
+Botan provides two techniques, passhash9 and bcrypt
+
+Passhash9
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Botan provides a password hashing technique called passhash9, in
+``passhash9.h``, which is based on PBKDF2. A usage example can be
+found in ``doc/examples/passhash.cpp``. Three functions are provided
+in this header:
+
+.. cpp:function:: std::string generate_passhash9(const std::string& password, RandomNumberGenerator& rng, u16bit work_factor = 10)
+
+ Takes the password to hash, a rng, and a work factor, which tells
+ how many iterations to compute. The default work factor is 10
+ (which means 100,000 iterations), but any non-zero value is
+ accepted.
+
+.. cpp:function:: std::string generate_passhash9(const std::string& password, byte alg_id, RandomNumberGenerator& rng, u16bit work_factor = 10)
+
+ Like the other ``generate_passhash9``, but taking a parameter that
+ specifies which PRF to use. Currently defined values are 0
+ ("HMAC(SHA-1)"), 1 ("HMAC(SHA-256)"), and 2 ("CMAC(Blowfish)").
+
+.. cpp:function:: bool check_passhash9(const std::string& password, const std::string& hash)
+
+ Takes a password and a passhash9 output and checks if the password
+ is the same as the one that was used to generate the passhash9
+ output, returning a boolean true (same) or false (not same).
+
+Bcrypt
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Bcrypt is a password hashing scheme originally designed for use in
+OpenBSD, but numerous other implementations exist. It is made
+available by including ``bcrypt.h``, and provides the functions
+
+.. cpp:function:: std::string generate_bcrypt(const std::string& password, RandomNumberGenerator& rng, u16bit work_factor = 10)
+
+and
+
+.. cpp:function:: bool check_bcrypt(const std::string& password, const std::string& hash)
+
+These work in exactly the same way as the passhash9 password hashing
+functions.
+
+Checksums
+---------------------------------
+
+Checksums are very similar to hash functions, and in fact share the same
+interface. But there are some significant differences, the major ones being
+that the output size is very small (usually in the range of 2 to 4 bytes), and
+is not cryptographically secure. But for their intended purpose (error
+checking), they perform very well. Some examples of checksums included in Botan
+are the Adler32 and CRC32 checksums.
+
+Threads and Mutexes
+---------------------------------
+
+Botan includes a mutex system, which is used internally to lock some shared
+data structures that must be kept shared for efficiency reasons (mostly, these
+are in the allocation systems~--~handing out 1000 separate allocators hurts
+performance and makes caching memory blocks useless). This system is supported
+by the ``mux_pthr`` module, implementing the ``Mutex`` interface for
+systems that have POSIX threads.
+
+If your application is using threads, you *must* add the option
+"thread_safe" to the options string when you create the
+``LibraryInitializer`` object. If you specify this option and no mutex
+type is available, an exception is thrown, since otherwise you would
+probably be facing a nasty crash.
+
+Secure Memory
+---------------------------------
+
+A major concern with mixing modern multiuser OSes and cryptographic
+code is that at any time the code (including secret keys) could be
+swapped to disk, where it can later be read by an attacker. Botan
+stores almost everything (and especially anything sensitive) in memory
+buffers that a) clear out their contents when their destructors are
+called, and b) have easy plugins for various memory locking functions,
+such as the ``mlock`` call on many Unix systems.
+
+Two of the allocation method used ("malloc" and "mmap") don't
+require any extra privileges on Unix, but locking memory does. At
+startup, each allocator type will attempt to allocate a few blocks
+(typically totaling 128k), so if you want, you can run your
+application ``setuid`` ``root``, and then drop privileges
+immediately after creating your ``LibraryInitializer``. If you end
+up using more than what's been allocated, some of your sensitive data
+might end up being swappable, but that beats running as ``root``
+all the time.
+
+These classes should also be used within your own code for storing
+sensitive data. They are only meant for primitive data types (int,
+long, etc): if you want a container of higher level Botan objects, you
+can just use a ``std::vector``, since these objects know how to clear
+themselves when they are destroyed. You cannot, however, have a
+``std::vector`` (or any other container) of ``Pipe`` objects or
+filters, because these types have pointers to other filters, and
+implementing copy constructors for these types would be both hard and
+quite expensive (vectors of pointers to such objects is fine, though).
+
+These types are not described in any great detail: for more information,
+consult the definitive sources~--~the header files ``secmem.h`` and
+``allocate.h``.
+
+``SecureBuffer`` is a simple array type, whose size is specified at compile
+time. It will automatically convert to a pointer of the appropriate type, and
+has a number of useful functions, including ``clear()``, and
+``size_t`` ``size()``, which returns the length of the array. It is a
+template that takes as parameters a type, and a constant integer which is how
+long the array is (for example: ``SecureBuffer<byte, 8> key;``).
+
+``SecureVector`` is a variable length array. Its size can be increased or
+decreased as need be, and it has a wide variety of functions useful for copying
+data into its buffer. Like ``SecureBuffer``, it implements ``clear``
+and ``size``.
+
+Allocators
+---------------------------------
+
+The containers described above get their memory from allocators. As a
+user of the library, you can add new allocator methods at run time for
+containers, including the ones used internally by the library, to
+use. The interface to this is in ``allocate.h``. Code needing
+to allocate or deallocate memory calls ``get_allocator``,
+which returns a pointer to an allocator object. This pointer should
+not be freed: the caller does not own the allocator (it is shared
+among multiple allocatore users, and uses a mutex to serialize access
+internally if necessary). It is possible to call
+``get_allocator`` with a specific name to request a particular
+type of allocator, otherwise, a default allocator type is returned.
+
+At start time, the only allocator known is a ``Default_Allocator``,
+which just allocates memory using ``malloc``, and zeroizes it when the
+memory is released. It is known by the name "malloc". If you ask for
+another type of allocator ("locking" and "mmap" are currently used),
+and it is not available, some other allocator will be returned.
+
+You can add in a new allocator type using ``add_allocator_type``. This
+function takes a string and a pointer to an allocator. The string gives this
+allocator type a name to which it can be referred when one is requesting it
+with ``get_allocator``. If an error occurs (such as the name being
+already registered), this function returns false. It will return true if the
+allocator was successfully registered. If you ask it to,
+``LibraryInitializer`` will do this for you.
+
+Finally, you can set the default allocator type that will be returned
+using the policy setting "default_alloc" to the name of any previously
+registered allocator.
+
diff --git a/doc/architecture.pdf b/doc/old/architecture.pdf
index f0edc3fc1..f0edc3fc1 100644
--- a/doc/architecture.pdf
+++ b/doc/old/architecture.pdf
Binary files differ
diff --git a/doc/insito_manual.pdf b/doc/old/insito_manual.pdf
index b07146992..b07146992 100644
--- a/doc/insito_manual.pdf
+++ b/doc/old/insito_manual.pdf
Binary files differ
diff --git a/doc/tutorial.tex b/doc/old/tutorial.tex
index f220d765a..f220d765a 100644
--- a/doc/tutorial.tex
+++ b/doc/old/tutorial.tex
diff --git a/doc/tutorial2.tex b/doc/old/tutorial2.tex
index 840679d10..840679d10 100644
--- a/doc/tutorial2.tex
+++ b/doc/old/tutorial2.tex
diff --git a/doc/pgpkeys.txt b/doc/pgpkeys.txt
index 8da1d1d05..1d2f3debc 100644
--- a/doc/pgpkeys.txt
+++ b/doc/pgpkeys.txt
@@ -1,36 +1,41 @@
-pub 2048R/EFBADFBC 2004-10-30
- Key fingerprint = 621D AF64 11E1 851C 4CF9 A2E1 6211 EBF1 EFBA DFBC
-uid Botan Distribution Key
+PGP Code Signing Key
+========================================
------BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v2.0.17 (GNU/Linux)
+The following PGP key is used to sign all releases::
-mQELBEGD1j0BCADHxPJkPcjJE+4Dlisx2hVc0Dj6JI1MSLrkM8R+2bOhVUSferxP
-T1EMPhfrAdOHTAloyvRThJztnZsNKqfLL49GGcBLdEGAVNks1pG37Teze5Lx1XIu
-zJFrozL2sqBy5C6nHpFgd1tcD68Rah2wp0u2cR9owXf1IqKdEfuo661+MTv7wTB1
-4hKV75nB7ZO6676SEZRILYM+7RJwKAKEmEPJc6hEf94VXn9ecNzaTlHgYkjhz9db
-LOd3od9XvuUw+LMR1dwBqMxbvR90MiXjbedDEkbArcZB9YOAIvEX/lC3qaW4XJt4
-iwHWl/YVZEfALcvQywe2CDrH5hO794wd9MpBAAYptBZCb3RhbiBEaXN0cmlidXRp
-b24gS2V5iQEqBBMBAgAUAhsDAh4BAheABQJKfFpnBBUKCQgACgkQYhHr8e+637xk
-PQf/aOi78XenwwvFrwXOVIVTdZIf8rK1zJksf26h09UD8uVV6z5iiTcpn86+eN9p
-6Ar8IH3tD+JuFnPSwZ/r9MNC2XZwenYo4Gb14jqM6/9hBe328vmeM4Y1G7bD4HrL
-kgV5WEyokqm3zbp3FBLr3Vh68TAC5JB9aHevra+cCA2u3vBNI3YUM5z4TdO150P3
-J00whkqImQEUni8bgxvllBLFM+uhucsX3HZWkoDEpotbg8yd0bqMkiPEyMr1OnJq
-eDVDMrB5wnyLgLFfRAAw3mopM0C1PNOAHr/BIYiaDHX2OwnOfep8rMDoRVf2Ge0D
-DBgsJJ6LduQHLeg403SHWL2F6YkCHAQTAQIABgUCQYPWUgAKCRBcD5boTsFta+r9
-EACWVis7YcaGkKKgRB/5ox8rM36XVhMXdh/hnnGHt5rapbbRRkRHRcWU8WIcFO1A
-59+TfwNNd8gN1MEt/5aX5KHWVKHBDexJgIxm6Dm1pisYHf/dnYQPM18hmqqwNlKY
-97hFkPpHd7enrtc/SvGbQhhLXYlpwBrdMl76e9xJLnnrRQksxegGPo8cr+C9HTs1
-Lwa8zzBxyBwYBYX+0moDkDShEhuXx6mEOXrGvQanJuIvpoIwGH+62E65MbJGlwWp
-w/MAtm2jFhBIhGV0bqJCFp9zIgdNgfskBaPr0oilbuJQZqP0Iqe/6CCt4XkS51yW
-ZqxjLAFpEpvDec4PGw3witKf/koGon9X8C035+nEjLBrWy18Q91vw2USyLI+mm9d
-iMAS8pY2gomfxBO2VwYHJryZykjCYQkccRA1tHteRj4gqTObo0Ak47y5MnplTWwi
-40oP7K2cfhCRBmMioxmYES4xsHEupfRBo3xr1Jq9q0t688WTT1NXHPMPoueF9mKZ
-Cf2pa9aHsqBmWTm3sCaNQKGubCDBEUmJUyndmSatJyYM7NVYoUp6EfqMACFuTNdB
-sjKMh7aWVikQpbJDfA1BIU3lZeqgjgrghVAWkEOBfhG0IVZj+RVCJpsqoTJ8asY2
-VreArSCyr/VnLEnfuH/QpgvCiCbepo3E34DJt4SaAOO2ZohGBBARAgAGBQJMGVc1
-AAoJEKY/LL36AvvMgsoAn2G7kXd09BF7ffk1Sfh174SVrvM9AKC7+R7x0+yV3SCd
-JkkUOo3xR5cOxw==
-=1QuR
------END PGP PUBLIC KEY BLOCK-----
+ pub 2048R/EFBADFBC 2004-10-30
+ Key fingerprint = 621D AF64 11E1 851C 4CF9 A2E1 6211 EBF1 EFBA DFBC
+ uid Botan Distribution Key
+
+ -----BEGIN PGP PUBLIC KEY BLOCK-----
+ Version: GnuPG v2.0.17 (GNU/Linux)
+
+ mQELBEGD1j0BCADHxPJkPcjJE+4Dlisx2hVc0Dj6JI1MSLrkM8R+2bOhVUSferxP
+ T1EMPhfrAdOHTAloyvRThJztnZsNKqfLL49GGcBLdEGAVNks1pG37Teze5Lx1XIu
+ zJFrozL2sqBy5C6nHpFgd1tcD68Rah2wp0u2cR9owXf1IqKdEfuo661+MTv7wTB1
+ 4hKV75nB7ZO6676SEZRILYM+7RJwKAKEmEPJc6hEf94VXn9ecNzaTlHgYkjhz9db
+ LOd3od9XvuUw+LMR1dwBqMxbvR90MiXjbedDEkbArcZB9YOAIvEX/lC3qaW4XJt4
+ iwHWl/YVZEfALcvQywe2CDrH5hO794wd9MpBAAYptBZCb3RhbiBEaXN0cmlidXRp
+ b24gS2V5iQEqBBMBAgAUAhsDAh4BAheABQJKfFpnBBUKCQgACgkQYhHr8e+637xk
+ PQf/aOi78XenwwvFrwXOVIVTdZIf8rK1zJksf26h09UD8uVV6z5iiTcpn86+eN9p
+ 6Ar8IH3tD+JuFnPSwZ/r9MNC2XZwenYo4Gb14jqM6/9hBe328vmeM4Y1G7bD4HrL
+ kgV5WEyokqm3zbp3FBLr3Vh68TAC5JB9aHevra+cCA2u3vBNI3YUM5z4TdO150P3
+ J00whkqImQEUni8bgxvllBLFM+uhucsX3HZWkoDEpotbg8yd0bqMkiPEyMr1OnJq
+ eDVDMrB5wnyLgLFfRAAw3mopM0C1PNOAHr/BIYiaDHX2OwnOfep8rMDoRVf2Ge0D
+ DBgsJJ6LduQHLeg403SHWL2F6YkCHAQTAQIABgUCQYPWUgAKCRBcD5boTsFta+r9
+ EACWVis7YcaGkKKgRB/5ox8rM36XVhMXdh/hnnGHt5rapbbRRkRHRcWU8WIcFO1A
+ 59+TfwNNd8gN1MEt/5aX5KHWVKHBDexJgIxm6Dm1pisYHf/dnYQPM18hmqqwNlKY
+ 97hFkPpHd7enrtc/SvGbQhhLXYlpwBrdMl76e9xJLnnrRQksxegGPo8cr+C9HTs1
+ Lwa8zzBxyBwYBYX+0moDkDShEhuXx6mEOXrGvQanJuIvpoIwGH+62E65MbJGlwWp
+ w/MAtm2jFhBIhGV0bqJCFp9zIgdNgfskBaPr0oilbuJQZqP0Iqe/6CCt4XkS51yW
+ ZqxjLAFpEpvDec4PGw3witKf/koGon9X8C035+nEjLBrWy18Q91vw2USyLI+mm9d
+ iMAS8pY2gomfxBO2VwYHJryZykjCYQkccRA1tHteRj4gqTObo0Ak47y5MnplTWwi
+ 40oP7K2cfhCRBmMioxmYES4xsHEupfRBo3xr1Jq9q0t688WTT1NXHPMPoueF9mKZ
+ Cf2pa9aHsqBmWTm3sCaNQKGubCDBEUmJUyndmSatJyYM7NVYoUp6EfqMACFuTNdB
+ sjKMh7aWVikQpbJDfA1BIU3lZeqgjgrghVAWkEOBfhG0IVZj+RVCJpsqoTJ8asY2
+ VreArSCyr/VnLEnfuH/QpgvCiCbepo3E34DJt4SaAOO2ZohGBBARAgAGBQJMGVc1
+ AAoJEKY/LL36AvvMgsoAn2G7kXd09BF7ffk1Sfh174SVrvM9AKC7+R7x0+yV3SCd
+ JkkUOo3xR5cOxw==
+ =1QuR
+ -----END PGP PUBLIC KEY BLOCK-----
diff --git a/doc/pubkey.txt b/doc/pubkey.txt
new file mode 100644
index 000000000..2b765cc10
--- /dev/null
+++ b/doc/pubkey.txt
@@ -0,0 +1,398 @@
+
+.. _public_key_crypto:
+
+Public Key Cryptography
+=================================
+
+Quick Start
+---------------------------------
+
+Let's create a 2048-bit RSA private key, serialize the public key as a
+PKCS #1 file with PEM encoding (which can be understood by many other
+cryptographic programs), and then load it on another machine::
+
+ // everyone does:
+ AutoSeeded_RNG rng;
+
+ // Alice
+ RSA_PrivateKey priv_rsa(rng, 2048 /* bits */);
+
+ std::string alice_pem = X509::PEM_encode(priv_rsa);
+
+ // send alice_pem to Bob, who does
+
+ // Bob
+ std::auto_ptr<Public_Key> alice(load_key(alice_pem));
+
+ RSA_PublicKey* alice_rsa = dynamic_cast<RSA_PublicKey>(alice);
+ if(alice_rsa)
+ {
+ /* ... */
+ }
+
+Creating New Public Key Pairs
+---------------------------------
+
+The library has interfaces for public key encryption, signatures, and
+key agreement that do not require knowing the exact algorithm in
+use. One place where we *do* need to know exactly what kind of
+algorithm is in use is when we are creating a key.
+
+There are currently three kinds of public key algorithms in Botan:
+ones based on integer factorization (RSA and Rabin-Williams), ones
+based on the discrete logarithm problem in the integers modulo a prime
+(DSA, Diffie-Hellman, Nyberg-Rueppel, and ElGamal), and ones based on
+the discrete logarithm problem in an elliptic curve (ECDSA, ECDH, and
+GOST 34.10). The systems based on discrete logarithms (in either
+regular integers or elliptic curves) use a group (a mathematical
+term), which can be shared among many keys. An elliptic curve group is
+represented by the class ``EC_Domain_Params``, while a modulo-prime
+group is represented by a ``DL_Group``.
+
+There are two ways to create a DL private key (such as
+``DSA_PrivateKey``). One is to pass in just a ``DL_Group`` object -- a
+new key will automatically be generated. The other involves passing in
+a group to use, along with both the public and private values (private
+value first).
+
+Since in integer factorization 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 ``size_t`` telling how long (in bits) the key
+should be, or you can copy an pre-existing key by passing in the
+appropriate parameters (primes, exponents, etc). For RSA and
+Rabin-Williams (the two IF schemes in Botan), the parameters are all
+``BigInt``: prime 1, prime 2, encryption exponent, decryption
+exponent, modulus. The last two are optional, since they can easily be
+derived from the first three.
+
+Creating a DL_Group
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+There are quite a few ways to get a ``DL_Group`` object. The best is
+to use the 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 "modp/ietf/N" where N
+is 768, 1024, 1536, 2048, 3072, 4096, 6144, and 8192 for
+Diffie-Hellman and ElGamal. DSA-style groups are named "dsa/jce/N" for
+N 512, 768, 1024, and "dsa/botan/N" for 2048 and 3072.
+
+You can also generate a new random group. This is not recommend,
+because it is quite slow, especially for safe primes.
+
+Key Checking
+---------------------------------
+
+Most public key algorithms have limitations or restrictions on their
+parameters. For example RSA requires an odd exponent, and algorithms
+based on the discrete logarithm problem need a generator $> 1$.
+
+Each low-level public key type has a function named ``check_key`` that
+takes a ``bool``. This function returns a Boolean value that declares
+whether or not the key is valid (from an algorithmic standpoint). For
+example, it will check to make sure that the prime parameters of a DSA
+key are, in fact, prime. 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 ``check_key``'s argument
+is ``true``, then it does "strong" checking, which includes expensive
+operations like primality checking.
+
+Keys are always checked when they are loaded or generated, so typically there
+is no reason to use this function directly. However, you can disable or reduce
+the checks for particular cases (public keys, loaded private keys, generated
+private keys) by setting the right config toggle (see the section on the
+configuration subsystem for details).
+
+Getting a PK algorithm object
+---------------------------------
+
+The key types, like ``RSA_PrivateKey``, do not implement any kind of
+padding or encoding (which is necessary for security). To get an
+object that knows how to do padding, use the wrapper classes included
+in ``pubkey.h``. These take a key, along with a string that specifies
+what hashing and encoding method(s) to use. Examples of such strings
+are "EME1(SHA-256)" for OAEP encryption and "EMSA4(SHA-256)" for PSS
+signatures (where the message is hashed using SHA-256).
+
+Here are some basic examples (using an RSA key) to give you a feel for
+the possibilities. These examples assume ``rsakey`` is an
+``RSA_PrivateKey``, since otherwise we would not be able to create
+a decryption or signature object with it (you can create encryption or
+signature verification objects with public keys, naturally)::
+
+ // PKCS #1 v2.0 / IEEE 1363 compatible encryption
+ PK_Encryptor_EME rsa_enc_pkcs1_v2(rsakey, "EME1(SHA-1)");
+ // PKCS #1 v1.5 compatible encryption
+ PK_Encryptor_EME rsa_enc_pkcs1_v15(rsakey, "PKCS1v15")
+
+ // This object can decrypt things encrypted by rsa_
+ PK_Decryptor_EME rsa_dec_pkcs1_v2(rsakey, "EME1(SHA-1)");
+
+ // PKCS #1 v1.5 compatible signatures
+ PK_Signer rsa_sign_pkcs1_v15(rsakey, "EMSA3(MD5)");
+ PK_Verifier rsa_verify_pkcs1_v15(rsakey, "EMSA3(MD5)");
+
+ // PKCS #1 v2.1 compatible signatures
+ PK_Signer rsa_sign_pkcs1_v2(rsakey, "EMSA4(SHA-1)");
+ PK_Verifier rsa_verify_pkcs1_v2(rsakey, "EMSA4(SHA-1)");
+
+Encryption
+---------------------------------
+
+The ``PK_Encryptor`` and ``PK_Decryptor`` classes are the
+interface for encryption and decryption, respectively.
+
+Calling ``encrypt`` with a ``byte`` array, a length
+parameter, and an RNG object will return the input encrypted with
+whatever scheme is being used. Calling the similar ``decrypt``
+will perform the inverse operation. You can also do these operations
+with ``SecureVector<byte>``s. In all cases, the output is returned
+via a ``SecureVector<byte>``.
+
+If you attempt an operation with a larger size than the key can
+support (this limit varies based on the algorithm, the key size, and
+the padding method used (if any)), an exception will be thrown. You
+can call ``maximum_input_size`` to find out the maximum size
+input (in bytes) that you can safely use with any particular key.
+
+Available public key encryption algorithms in Botan are RSA and
+ElGamal. The encoding methods are EME1, denoted by "EME1(HASHNAME)",
+PKCS #1 v1.5, called "PKCS1v15" or "EME-PKCS1-v1_5", and raw encoding
+("Raw").
+
+For compatibility reasons, PKCS #1 v1.5 is recommend for use with
+ElGamal (most other implementations of ElGamal do not support any
+other encoding format). RSA can also be used with PKCS # 1 encoding,
+but because of various possible attacks, EME1 is the preferred
+encoding. EME1 requires the use of a hash function: unless a competent
+applied cryptographer tells you otherwise, you should use SHA-256 or
+SHA-512.
+
+Don't use "Raw" encoding unless you need it for backward
+compatibility with old protocols. There are many possible attacks
+against both ElGamal and RSA when they are used in this way.
+
+Signatures
+---------------------------------
+
+The signature algorithms look quite a bit like the hash functions. You
+can repeatedly call ``update``, giving more and more of a
+message you wish to sign, and then call ``signature``, which
+will return a signature for that message. If you want to do it all in
+one shot, call ``sign_message``, which will just call
+``update`` with its argument and then return whatever
+``signature`` returns. Generating a signature requires random
+numbers with some schemes, so ``signature`` and
+``sign_message`` both take a ``RandomNumberGenerator&``.
+
+You can validate a signature by updating the verifier class, and finally seeing
+the if the value returned from ``check_signature`` is true (you pass
+the supposed signature to the ``check_signature`` function as a byte
+array and a length or as a ``MemoryRegion<byte>``). There is another
+function, ``verify_message``, which takes a pair of byte array/length
+pairs (or a pair of ``MemoryRegion<byte>`` objects), the first of which is
+the message, the second being the (supposed) signature. It returns true if the
+signature is valid and false otherwise.
+
+Available public key signature algorithms in Botan are RSA, DSA,
+ECDSA, GOST-34.11, Nyberg-Rueppel, and Rabin-Williams. Signature
+encoding methods 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.
+
+There are various interactions that make certain encoding schemes and
+signing algorithms more or less useful.
+
+EMSA2 is the usual method for encoding Rabin-William signatures, so
+for compatibility with other implementations you may have to use
+that. EMSA4 (also called PSS), also works with Rabin-Williams. EMSA1
+and EMSA3 do *not* work with Rabin-Williams.
+
+RSA can be used with any of the available encoding methods. EMSA4 is
+by far the most secure, but is not (as of now) widely
+implemented. EMSA3 (also called "EMSA-PKCS1-v1_5") is commonly used
+with RSA (for example in SSL). EMSA1 signs the message digest
+directly, without any extra padding or encoding. This may be useful,
+but is not as secure as either EMSA3 or EMSA4. EMSA2 may be used but
+is not recommended.
+
+For DSA, ECDSA, GOST-34.11, and Nyberg-Rueppel, you should use
+EMSA1. None of the other encoding methods are particularly useful for
+these algorithms.
+
+Key Agreement
+---------------------------------
+
+You can get a hold of a ``PK_Key_Agreement_Scheme`` object by calling
+``get_pk_kas`` with a key that is of a type that supports key
+agreement (such as a Diffie-Hellman key stored in a ``DH_PrivateKey``
+object), and the name of a key derivation function. This can be "Raw",
+meaning the output of the primitive itself is returned as the key, or
+"KDF1(hash)" or "KDF2(hash)" where "hash" is any string you happen to
+like (hopefully you like strings like "SHA-256" or "RIPEMD-160"), or
+"X9.42-PRF(keywrap)", which uses the PRF specified in ANSI X9.42. It
+takes the name or OID of the key wrap algorithm that will be used to
+encrypt a content encryption key.
+
+How key agreement works is that you trade public values with some
+other party, and then each of you runs a computation with the other's
+value and your key (this should return the same result to both
+parties). This computation can be called by using
+``derive_key`` with either a byte array/length pair, or a
+``SecureVector<byte>`` than holds the public value of the other
+party. The last argument to either call is a number that specifies how
+long a key you want.
+
+Depending on the KDF you're using, you *might not* get back a key
+of the size you requested. In particular "Raw" will return a number
+about the size of the Diffie-Hellman modulus, and KDF1 can only return
+a key that is the same size as the output of the hash. KDF2, on the
+other hand, will always give you a key exactly as long as you request,
+regardless of the underlying hash used with it. The key returned is a
+``SymmetricKey``, ready to pass to a block cipher, MAC, or other
+symmetric algorithm.
+
+The public value that should be used can be obtained by calling
+``public_data``, which exists for any key that is associated with a
+key agreement algorithm. It returns a ``SecureVector<byte>``.
+
+"KDF2(SHA-256)" is by far the preferred algorithm for key derivation
+in new applications. The X9.42 algorithm may be useful in some
+circumstances, but unless you need X9.42 compatibility, KDF2 is easier
+to use.
+
+There is a Diffie-Hellman example included in the distribution, which you may
+want to examine.
+
+.. _pk_import_export:
+
+Importing and Exporting Keys
+---------------------------------
+
+There are many, many different (often conflicting) standards
+surrounding public key cryptography. There is, thankfully, only two
+major standards surrounding the representation of a public or private
+key: the X.509 subject public key info format (for public keys), and
+PKCS #8 (for private keys). Other crypto libraries, such as Crypto++
+and OpenSSL, also support these formats, so you can easily exchange
+keys with software that doesn't use Botan.
+
+In addition to "plain" public keys, Botan also supports X.509
+certificates. These are documented in :ref:`x509_certificates`.
+
+.. _import_export_public_keys:
+
+Importing/Exporting Public Keys
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To import and export public keys, use:
+
+.. cpp:function:: MemoryVector<byte> X509::BER_encode(const Public_Key& key)
+
+ Takes any public key object, and returns a standard binary structure
+ representing the key which can be read by many other crypto
+ libraries.
+
+.. cpp:function:: std::string X509::PEM_encode(const Public_Key& key)
+
+ This formats the key the same 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.
+
+.. cpp:function:: Public_Key* X509::load_key(DataSource& in)
+
+.. cpp:function:: Public_Key* X509::load_key(const SecureVector<byte>& buffer)
+
+.. cpp:function:: Public_Key* X509::load_key(const std::string& filename)
+
+ For loading a public key, use one of the variants of ``load_key``.
+ This function will return a newly allocated key based on the data
+ from whatever source it is using (assuming, of course, the source is
+ in fact storing a representation of a public key). 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``.
+
+Importing/Exporting Private Keys
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+There are two different options for private key import/export. The
+first is a plaintext version of the private key. This is supported by
+the following functions:
+
+.. cpp:function:: SecureVector<byte> PKCS8::BER_encode(const Private_Key& key)
+
+.. cpp:function:: std::string PKCS8::PEM_encode(const Private_Key& key)
+
+These functions are similiar to the X.509 functions described in
+:ref:`import_export_public_keys`. The only difference is that they take
+a ``Private_Key`` object instead. In most situations, using these
+versions 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
+below. For importing, the same functions can be used for encrypted and
+unencrypted keys.
+
+The other way to export a PKCS #8 key is to first encode it in the
+same manner as done above, then encrypt it using a passphrase, and
+store the whole thing into another structure. This method is
+definitely preferred, since otherwise the private key is
+unprotected. The algorithms and structures used here are standardized
+by PKCS #5 and PKCS #8, and can be read by many other crypto
+libraries:
+
+.. cpp:function:: SecureVector<byte> PKCS8::BER_encode(const Private_Key& key, RandomNumberGenerator& rng, const std::string& pass, const std::string& pbe_algo = "")
+
+.. cpp:function:: std::string PKCS8::PEM_encode(const Private_Key& key, RandomNumberGenerator& rng, const std::string& pass, const std::string& pbe_algo = "")
+
+
+There are three new arguments needed here to support the encryption
+process. The first is a ``RandomNumberGenerator``, which is used to
+generate salts to randomize the encryption. The ``pass`` argument is
+the passphrase that will be used to encrypt the key. Both of these are
+required. The final (optional) argument, ``pbe_algo``, specifies a
+particular password based encryption (or PBE) algorithm. If you don't
+specify a PBE, a sensible default will be used.
+
+Last but not least, there are some functions that will load (and
+decrypt, if necessary) a PKCS #8 private key:
+
+.. cpp:function:: Private_Key* PKCS8::load_key(DataSource& in, RandomNumberGenerator& rng, const User_Interface& ui)
+
+.. cpp:function:: Private_Key* PKCS8::load_key(DataSource& in, RandomNumberGenerator& rng, std::string passphrase = "")
+
+.. cpp:function:: Private_Key* PKCS8::load_key(const std::string& filename, RandomNumberGenerator& rng, const User_Interface& ui)
+
+.. cpp:function:: Private_Key* PKCS8::load_key(const std::string& filename, RandomNumberGenerator& rng, const std::string& passphrase = "")
+
+The versions that pass the passphrase as a ``std::string`` are
+primarily for compatibility, but they are useful in limited
+circumstances. The ``User_Interface`` versions are how ``load_key`` is
+implemented, and provides for much more flexibility. If the passphrase
+passed in is not correct, then an exception is thrown and that is
+that. However, if you pass in an UI object, then the UI object can
+keep asking the user for the passphrase until they get it right (or
+until they cancel the action, though the UI interface). 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. You can think of it as a user interface
+interface. The default ``User_Interface`` is rather dumb, and acts
+rather like the versions taking the ``std::string``; it tries the
+passphrase passed in first, and then it cancels.
+
+All versions need access to a ``RandomNumberGenerator`` in order to
+perform probabilistic tests on the loaded key material.
+
+After loading a key, you can use ``dynamic_cast`` to find out what
+operations it supports, and use it appropriately. Remember to
+``delete`` the object once you are done with it.
diff --git a/doc/python.tex b/doc/python.tex
deleted file mode 100644
index afdd66b6a..000000000
--- a/doc/python.tex
+++ /dev/null
@@ -1,68 +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 Python Interface Documentation}}
-\author{Jack Lloyd \\
- \texttt{[email protected]}}
-\date{2009/10/10}
-
-\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{Ciphers}
-
-Botan's Python interface provides a generic interface to any cipher
-supported by the library. The class \type{botan.Cipher} takes three
-arguments, all strings: first, the name of the algorith, second the
-direction (which can be either ``encrypt'' or ``decrypt''), and
-lastly, the key to use. For instance
-
-\begin{verbatim}
- encryptor = botan.Cipher("AES-128/EAX", "encrypt", key)
-\end{verbatim}
-
-creates an object that will encrypt and authenticate messages using
-the EAX mode of operation using the AES cipher. To use this object,
-call the \function{cipher} function with two arguments - the input
-to encrypt, and the IV to use:
-
-\begin{verbatim}
- ciphertext = encryptor.cipher(input, salt)
-\end{verbatim}
-
-
-\subsection{Cryptobox}
-
-
-\subsection{RNGs}
-
-\section{RSA}
-
-
-
-\end{document}
diff --git a/doc/python/cipher.py b/doc/python/cipher.py
deleted file mode 100755
index 1be2759ae..000000000
--- a/doc/python/cipher.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/python
-
-import botan
-import sys
-
-def encrypt(input, passphrase):
- rng = botan.RandomNumberGenerator()
-
- # Use as both EAX IV and PBKDF2 salt
- salt = rng.gen_random(10)
-
- iterations = 10000
- output_size = 16
-
- key = botan.pbkdf2(passphrase, salt, iterations, output_size, "SHA-1")
-
- encryptor = botan.Cipher("AES-128/EAX", "encrypt", key)
-
- ciphertext = encryptor.cipher(input, salt)
- return (ciphertext, salt)
-
-def decrypt(input, salt, passphrase):
- iterations = 10000
- output_size = 16
-
- key = botan.pbkdf2(passphrase, salt, iterations, output_size, "SHA-1")
-
- decryptor = botan.Cipher("AES-128/EAX", "decrypt", key)
-
- return decryptor.cipher(input, salt)
-
-def main(args = None):
- if args is None:
- args = sys.argv
-
- passphrase = args[1]
- input = ''.join(open(args[2]).readlines())
-
- (ciphertext, salt) = encrypt(input, passphrase)
-
- print decrypt(ciphertext, salt, passphrase)
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/doc/python/cryptobox.py b/doc/python/cryptobox.py
deleted file mode 100755
index f76ed6bc3..000000000
--- a/doc/python/cryptobox.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/python
-
-import sys
-import botan
-
-def main(args = None):
- if args is None:
- args = sys.argv
-
- if len(args) != 3:
- raise Exception("Usage: <password> <input>");
-
- password = args[1]
- input = ''.join(open(args[2]).readlines())
-
- rng = botan.RandomNumberGenerator()
-
- ciphertext = botan.cryptobox_encrypt(input, password, rng)
-
- print ciphertext
-
- plaintext = ''
-
- try:
- plaintext = botan.cryptobox_decrypt(ciphertext, password + 'FAIL')
- except Exception, e:
- print "Good news: bad password caused exception: "
- print e
-
- plaintext = botan.cryptobox_decrypt(ciphertext, password)
-
- print "Original input was: "
- print plaintext
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/doc/python/nisttest.py b/doc/python/nisttest.py
deleted file mode 100755
index 3ea8fda0f..000000000
--- a/doc/python/nisttest.py
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/usr/bin/python
-
-import sys, os, botan
-from os.path import join;
-
-def validate(ca_certs, certs, crls, ee_certs):
- store = botan.X509_Store()
- for cert in certs:
- if cert not in ee_certs:
- store.add_cert(botan.X509_Certificate(cert), cert in ca_certs)
-
- for crl in crls:
- r = store.add_crl(botan.X509_CRL(crl))
- if r != botan.verify_result.verified:
- return r
-
- for ee in ee_certs:
- r = store.validate(botan.X509_Certificate(ee))
- if r != botan.verify_result.verified:
- return r
-
- return botan.verify_result.verified
-
-def run_test(files, rootdir, testname, expected):
- crls = [join(rootdir,x) for x in files if x.endswith(".crl")]
- certs = [join(rootdir,x) for x in files if x.endswith(".crt")]
- end_entity = [x for x in certs if x.find("end.crt") != -1]
- ca_certs = [x for x in certs if x.find("root.crt") != -1]
-
- print "%s..." % testname,
-
- result = validate(ca_certs, certs, crls, end_entity)
- result = repr(result).replace('botan._botan.verify_result.', '')
-
- if result != expected:
- print "FAILED: got %s, expected %s" % (result, expected)
- else:
- print "passed"
-
-def main():
- def load_results(file):
- results = {}
- for line in open(file, 'r'):
- line = line[0:line.find('#')].strip()
- if line:
- test,result = line.split(' ')
- results[test] = result
- return results
-
- results = load_results('results.txt')
-
- for root, dirs, files in os.walk('../../checks/nist_tests/tests'):
- if files:
- thistest = root[root.rfind('/')+1:]
- if thistest in results:
- run_test(files, root, thistest, results[thistest])
- else:
- print "%s... skipping - no expected result set" % thistest
-
-if __name__ == "__main__":
- sys.exit(main())
diff --git a/doc/python/results.txt b/doc/python/results.txt
deleted file mode 100644
index 7a3824001..000000000
--- a/doc/python/results.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-# This is the file of expected results for nisttest.py
-test01 verified
-test02 signature_error
-test03 signature_error
-test04 verified
-test05 cert_not_yet_valid
-test06 cert_not_yet_valid
-test07 verified
-test08 cert_not_yet_valid
-test09 cert_has_expired
-test10 cert_has_expired
-test11 cert_has_expired
-test12 verified
-test13 cert_issuer_not_found
-test14 cert_issuer_not_found
-test15 verified
-test16 verified
-test17 verified
-test18 verified
-# changed; should be no_revocation_data_available, but I don't want to
-# force people to use CRLs
-test19 verified
-test20 cert_is_revoked
-test21 cert_is_revoked
-test22 ca_cert_not_for_cert_issuer
-test23 ca_cert_not_for_cert_issuer
-test24 verified
-test25 ca_cert_not_for_cert_issuer
-test26 verified
-test27 verified
-test28 ca_cert_not_for_cert_issuer
-test29 ca_cert_not_for_cert_issuer
-test30 verified
-test31 ca_cert_not_for_crl_issuer
-test32 ca_cert_not_for_crl_issuer
-test33 verified
-test54 cert_chain_too_long
-test55 cert_chain_too_long
-test56 verified
-test57 verified
-test58 cert_chain_too_long
-test59 cert_chain_too_long
-test60 cert_chain_too_long
-test61 cert_chain_too_long
-test62 verified
-test63 verified
-test64 signature_error
-# changed; I have no idea why this test is supposed to fail
-test65 verified
-test66 crl_issuer_not_found
-# changed; one of the CRLs has an unknown creator, so we fail
-# prior to getting to the end-entity check
-test67 crl_issuer_not_found
-test68 cert_is_revoked
-test69 cert_is_revoked
-test70 cert_is_revoked
-test71 cert_is_revoked
-test72 crl_has_expired
-test73 crl_has_expired
-test74 verified
diff --git a/doc/python/rng_test.py b/doc/python/rng_test.py
deleted file mode 100755
index 06c79b84e..000000000
--- a/doc/python/rng_test.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/python
-
-import botan
-
-rng = botan.RandomNumberGenerator()
-
-print "name", rng.name()
-
-rng.add_entropy("blah")
-
-print "random 16", rng.gen_random(16).encode("hex")
-print "random 32", rng.gen_random(32).encode("base64"),
-
-rng.reseed()
-
-for i in range(0, 10):
- print rng.gen_random_byte(),
-print
-
-rng.add_entropy("blah")
-
-print "random 16", rng.gen_random(16).encode("hex")
diff --git a/doc/python/rsa.py b/doc/python/rsa.py
deleted file mode 100755
index 8ca95ff8b..000000000
--- a/doc/python/rsa.py
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/python
-
-import botan
-
-def make_into_c_array(ber):
- output = 'static unsigned char key_data[%d] = {\n\t' % (len(ber))
-
- for (idx,c) in zip(range(len(ber)), ber):
- if idx != 0 and idx % 8 == 0:
- output += "\n\t"
- output += "0x%s, " % (c.encode('hex'))
-
- output += "\n};\n"
-
- return output
-
-rng = botan.RandomNumberGenerator()
-
-rsa_priv = botan.RSA_PrivateKey(768, rng)
-
-print rsa_priv.to_string()
-print int(rsa_priv.get_N())
-print int(rsa_priv.get_E())
-
-rsa_pub = botan.RSA_PublicKey(rsa_priv)
-
-print make_into_c_array(rsa_pub.to_ber())
-#print make_into_c_array(rsa_priv.to_ber())
-
-key = rng.gen_random(20)
-
-ciphertext = rsa_pub.encrypt(key, 'EME1(SHA-1)', rng)
-
-print ciphertext.encode('hex')
-
-plaintext = rsa_priv.decrypt(ciphertext, 'EME1(SHA-1)')
-
-print plaintext == key
-
-signature = rsa_priv.sign(key, 'EMSA4(SHA-256)', rng)
-
-print rsa_pub.verify(key, signature, 'EMSA4(SHA-256)')
-
-# Corrupt the signature, make sure it doesn't verify
-signature = signature.replace(signature[0], '0')
-
-print rsa_pub.verify(key, signature, 'EMSA4(SHA-256)')
diff --git a/doc/scripts/print_deps.py b/doc/scripts/print_deps.py
deleted file mode 100755
index c68fa2617..000000000
--- a/doc/scripts/print_deps.py
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/usr/bin/python
-
-"""
-Analyze the botan source tree and print the module interdependencies
-
-(C) 2009 Jack Lloyd
-Distributed under the terms of the Botan license
-"""
-
-import os
-import os.path
-import sys
-import re
-
-def find_deps_in(filename):
- # By convention #include's with spaces before them are
- # always wrapped in #ifdef blocks
- regexp = re.compile('^#include <botan/(.*)>')
-
- for line in open(filename).readlines():
- match = regexp.match(line)
- if match != None:
- yield match.group(1).replace('internal/', '')
-
-def get_dependencies(dirname):
- all_dirdeps = {}
- file_homes = {}
-
- is_sourcefile = re.compile('\.(cpp|h|S)$')
-
- for (dirpath, dirnames, filenames) in os.walk('src'):
- dirdeps = set()
- for filename in filenames:
- if is_sourcefile.search(filename) != None:
- file_homes[filename] = os.path.basename(dirpath)
-
- for dep in find_deps_in(os.path.join(dirpath, filename)):
- if dep not in filenames and dep != 'build.h':
- dirdeps.add(dep)
-
- dirdeps = sorted(dirdeps)
- if dirdeps != []:
- all_dirdeps[dirpath] = dirdeps
-
- return (all_dirdeps, file_homes)
-
-def main():
- (all_dirdeps, file_homes) = get_dependencies('src')
-
- def interesting_dep_for(dirname):
- def interesting_dep(dep):
- if dep == 'utils':
- return False # everything depends on it
-
- # block/serpent depends on block, etc
- if dirname.find('/%s/' % (dep)) > 0:
- return False
- return True
- return interesting_dep
-
- for dirname in sorted(all_dirdeps.keys()):
- depdirs = sorted(set(map(lambda x: file_homes[x], all_dirdeps[dirname])))
-
- depdirs = filter(interesting_dep_for(dirname), depdirs)
-
- if depdirs != []:
- print "%s: %s" % (dirname, ' '.join(depdirs))
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/doc/scripts/update_deps.py b/doc/scripts/update_deps.py
deleted file mode 100755
index ac19885e0..000000000
--- a/doc/scripts/update_deps.py
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/python
-
-import sys
-import re
-import os.path
-
-def update_requires(dir, deps):
- lines = map(lambda x: x.strip(),
- open(os.path.join(dir, 'info.txt')).readlines())
-
- if '<requires>' in lines:
- start = lines.index('<requires>')
-
- while lines.pop(start) != '</requires>':
- pass
-
- while len(lines) > 0 and lines[-1] == '':
- lines = lines[:-1]
-
- if len(deps) > 0:
- lines.append('')
- lines.append('<requires>')
- for dep in deps:
- lines.append(dep)
- lines.append('</requires>')
- lines.append('')
-
- lines = "\n".join(lines).replace("\n\n\n", "\n\n")
-
- output = open(os.path.join(dir, 'info.txt'), 'w')
- output.write(lines)
- output.close()
-
-def main():
- for line in sys.stdin.readlines():
- (dirname, deps) = line.split(':')
- deps = deps.strip().split(' ')
- update_requires(dirname, deps)
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/doc/thanks.txt b/doc/thanks.txt
deleted file mode 100644
index 68fd81b3b..000000000
--- a/doc/thanks.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-
-The following people (sorted alphabetically) contributed bug reports, useful
-information, or were generally just helpful people to talk to:
-
-Jeff B
-Rickard Bondesson
-Mike Desjardins
-Matthew Gregan
-Hany Greiss
-Friedemann Kleint
-Ying-Chieh Liao
-Dan Nicolaescu
-Vaclav Ovsik
-Ken Perano
-Darren Starsmore
-Kaushik Veeraraghavan
-Dominik Vogt
-James Widener
-
-Cerulean Studios, creators of the Trillian instant messaging client,
-has provided financial assistance to the project.
-
-Barry Kavanagh of AEP Systems Ltd kindly provided an AEP2000 crypto card and
-drivers, enabling the creation of Botan's AEP engine module.
-
-In addition, the following people have unknowingly contributed help
-via public domain code which has been repurposed into the library:
-
- Dean Gaudet wrote the SSE2 implementation of SHA-1
-
- Mike Hamburg wrote x86-64/SSSE3 assembly which was the basis for the
- constant time AES implementation
-
- The implementation of DES is based off a public domain implementation by Phil
- Karn from 1994 (he, in turn, credits Richard Outerbridge and Jim Gillogly).
-
- Rijndael and Square are based on the reference implementations written by
- the inventors, Joan Daemen and Vincent Rijmen.
-
- The Serpent S-boxes used were discovered by Dag Arne Osvik and detailed in
- his paper "Speeding Up Serpent".
-
- Matthew Skala's public domain twofish.c (as given in GnuPG 0.9.8) provided
- the basis for my Twofish code (particularly the key schedule).
-
- Some of the hash functions (MD5, SHA-1, etc) use an optimized implementation
- of one of the boolean functions, which was discovered by Colin Plumb.
-
- The design of Randpool takes some of its design principles from those
- suggested by Eric A. Young in his SSLeay documentation, Peter Gutmann's paper
- "Software Generation of Practically Strong Random Numbers", and the paper
- "Cryptanalytic Attacks on Pseudorandom Number Generators", by Kelsey,
- Schneier, Wagner, and Hall.
diff --git a/doc/x509.txt b/doc/x509.txt
new file mode 100644
index 000000000..3243928de
--- /dev/null
+++ b/doc/x509.txt
@@ -0,0 +1,543 @@
+
+.. _x509_certificates:
+
+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.
+
+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
+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).
+
+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 the section ``Importing and Exporting PK
+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
+and DSA 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``.
+
+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.
+
+ - 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.
+
+ - Subject Alternative Names: Only the "rfc822Name", "dNSName", and
+ "uniformResourceIdentifier" fields will be stored; all others are
+ ignored.
+
+ - Issuer Alternative Names: Same restrictions as the Subject
+ Alternative Names extension. New certificates generated by Botan
+ never include the issuer alternative name.
+
+ - 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.
+
+ - 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.
+
+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
+can either be in raw BER/DER, or in PEM format; the constructor will figure out
+which format without any extra information. For example::
+
+ X509_CRL crl1("crl1.der");
+
+ DataSource_Stream in("crl2.pem");
+ X509_CRL crl2(in);
+
+After that, pass the ``X509_CRL`` object to a ``X509_Store`` object
+with ``X509_Code`` ``add_crl``(``X509_CRL``), and all future
+verifications will take into account the certificates listed, assuming
+``add_crl`` returns ``VERIFIED``. If it doesn't return
+``VERIFIED``, then the return value is an error code signifying that the CRL
+could not be processed due to some problem (which could range from the issuing
+certificate not being found, to the CRL having some format problem). For more
+about the ``X509_Store`` API, read the section later in this chapter.
+
+Reading Certificates
+---------------------------------
+
+``X509_Certificate`` has two constructors, each of which takes a source of
+data; a filename to read, and a ``DataSource&``.
+
+Storing and Using Certificates
+---------------------------------
+
+If you read a certificate, you probably want to verify the signature on
+it. However, consider that to do so, we may have to verify the signature on the
+certificate that we used to verify the first certificate, and on and on until
+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).
+
+Adding Certificates
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You can add new certificates to a certificate store using any of these
+functions:
+
+``add_cert``(``const X509_Certificate&`` ``cert``,
+ ``bool`` ``trusted`` ``= false``)
+
+``add_certs``(``DataSource&`` ``source``)
+
+``add_trusted_certs``(``DataSource&`` ``source``)
+
+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 have some reason to trust are genuine. 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
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+``X509_Code`` ``add_crl``(``const X509_CRL&`` ``crl``);
+
+This will process the CRL and mark the revoked certificates. This will also
+work if a revoked certificate is added to the store sometime after the CRL is
+processed. The function can return an error code (listed later), or will return
+``VERIFIED`` if everything completed successfully.
+
+Storing Certificates
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You can output a set of certificates by calling ``PEM_encode``, which
+will return a ``std::string`` containing each of the certificates in the
+store, PEM encoded and concatenated. This simple format can easily be read by
+both Botan and other libraries/applications.
+
+Searching for Certificates
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You can find certificates in the store with a series of functions contained
+in the ``X509_Store_Search`` namespace::
+
+ std::vector<X509_Certificate> by_email(const X509_Store& store,
+ const std::string& email_addr);
+ std::vector<X509_Certificate> by_name(const X509_Store& store,
+ const std::string& name);
+ std::vector<X509_Certificate> by_dns(const X509_Store&,
+ const std::string& dns_name);
+
+These functions will return a (possibly empty) vector of certificates from
+``store`` matching your search criteria. The email address and DNS name
+searches are case-insensitive but are sensitive to extra whitespace and so
+on. The name search will do case-insensitive substring matching, so, for
+example, calling ``X509_Store_Search::by_name``(``your_store``,
+"dob") will return certificates for ``J.R. 'Bob' Dobbs'' and
+``H. Dobbertin'', assuming both of those certificates are in ``your_store``.
+
+You could then display the results to a user, and allow them to select the
+appropriate one. Searching using an email address as the key is usually more
+effective than the name, since email addresses are rarely shared.
+
+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``.
+
+As for using such a store, you have to tell ``X509_Store`` about
+it, by calling the ``X509_Store`` member function
+
+``add_new_certstore``(``Certificate_Store``* ``new_store``)
+
+The argument, ``new_store``, will be deleted by ``X509_Store``'s
+destructor, so make sure to allocate it with ``new``.
+
+Verifying Certificates
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+There is a single function in ``X509_Store`` related to verifying a
+certificate:
+
+.. .cpp:function:: X509_Code 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.
+
+Return values for ``validate_cert`` (and ``add_crl``) include:
+
+ - VERIFIED: The certificate is valid 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.
+
+ - CERT_CHAIN_TOO_LONG: The certificate chain exceeded the length
+ allowed by a basicConstraints extension.
+
+ - SIGNATURE_ERROR: An invalid signature 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.
+
+Certificate Authorities
+---------------------------------
+
+Setting up a CA for X.509 certificates is perhaps the easiest thing to
+do related to X.509. A CA is represented by the type ``X509_CA``,
+which can be found in ``x509_ca.h``. A CA always needs its own
+certificate, which can either be a self-signed certificate (see below
+on how to create one) or one issued by another CA (see the section on
+PKCS #10 requests). Creating a CA object is done by the following
+constructor::
+
+ X509_CA(const X509_Certificate& cert, const Private_Key& key);
+
+The private key is the private key corresponding to the public key in the
+CA's certificate.
+
+Requests for new certificates are supplied to a CA in the form on PKCS
+#10 certificate requests (called a ``PKCS10_Request`` object in
+Botan). These are decoded in a similar manner to
+certificates/CRLs/etc. A request is vetted by humans (who somehow
+verify that the name in the request corresponds to the name of the
+entity who requested it), and then signed by a CA key, generating a
+new certificate::
+
+ X509_Certificate sign_request(const PKCS10_Request&) const;
+
+Generating CRLs
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+As mentioned previously, the ability to process CRLs is highly important in
+many PKI systems. In fact, according to strict X.509 rules, you must not
+validate any certificate if the appropriate CRLs are not available (though
+hardly any systems are that strict). In any case, a CA should have a valid CRL
+available at all times.
+
+Of course, you might be wondering what to do if no certificates have
+been revoked. Never fear; empty CRLs, which revoke nothing at all, can
+be issued. To generate a new, empty CRL, just call ``X509_CRL``
+``X509_CA::new_crl``(``size_t``~``seconds``~=~0)~--~it
+will create a new, empty, CRL. If ``seconds`` is the default 0, then
+the normal default CRL next update time (the value of the
+``x509/crl/next_update'') will be used. If not, then ``seconds``
+specifies how long (in seconds) it will be until the CRL's next update
+time (after this time, most clients will reject the CRL as too old).
+
+On the other hand, you may have issued a CRL before. In that case, you will
+want to issue a new CRL that contains all previously revoked
+certificates, along with any new ones. This is done by calling the
+``X509_CA`` member function
+``update_crl``(``X509_CRL``~``old_crl``,
+``std::vector<CRL_Entry>``~``new_revoked``,
+``size_t``~``seconds``~=~0), where ``X509_CRL`` is the last CRL this
+CA issued, and ``new_revoked`` is a list of any newly revoked certificates.
+The function returns a new ``X509_CRL`` to make available for clients. The
+semantics for the ``seconds`` argument is the same as ``new_crl``.
+
+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
+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::
+
+.. 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.
+
+Creating PKCS #10 Requests
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Also in ``x509self.h``, there is a function for generating new PKCS #10
+certificate requests::
+
+.. cpp:function:: PKCS10_Request create_cert_req(const X509_Cert_Options&, const Private_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.
+
+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.
+
+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.
+
+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),
+"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.