aboutsummaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
authorlloyd <[email protected]>2010-06-15 04:53:05 +0000
committerlloyd <[email protected]>2010-06-15 04:53:05 +0000
commit165671b144884c8787cf2ccda4ef9799dfe47ccd (patch)
treebc685dcf3958b15d909ea10a3acb605ca6dea720 /doc
parent739ea28b60f9cdf4eb9fe9e37fc7c099e501c5b2 (diff)
Update X509/PKCS8 docs WRT BER_encode
Diffstat (limited to 'doc')
-rw-r--r--doc/api.tex161
1 files changed, 60 insertions, 101 deletions
diff --git a/doc/api.tex b/doc/api.tex
index 31e74c996..e4d4d5cb1 100644
--- a/doc/api.tex
+++ b/doc/api.tex
@@ -1225,7 +1225,7 @@ The interfaces for doing either of these are quite similar. Let's look at the
X.509 stuff first:
\begin{verbatim}
namespace X509 {
- void encode(const Public_Key& key, Pipe& out, X509_Encoding enc = PEM);
+ MemoryVector<byte> BER_encode(const Public_Key& key);
std::string PEM_encode(const Public_Key& out);
Public_Key* load_key(DataSource& in);
@@ -1234,21 +1234,17 @@ namespace X509 {
}
\end{verbatim}
-Basically, \function{X509::encode} will take an \type{Public\_Key}
-(as of now, that's any RSA, DSA, or Diffie-Hellman key) and encodes it
-using \arg{enc}, which can be either \type{PEM} or
-\type{RAW\_BER}. Using \type{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. It will place the
-encoding into \arg{out}. Remember that if you have just created the
-\type{Pipe} that you are passing to \function{X509::encode}, you need
-to call \function{start\_msg} first. Particularly with public keys,
-about 99\% of the time you just want to PEM encode the key and then
-write it to a file or something. In this case, it's probably easier to
-use \function{X509::PEM\_encode}. This function will simply return the
-PEM encoding of the key as a \type{std::string}.
+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, the preferred method is one of the variants
of \function{load\_key}. This function will return a newly allocated
@@ -1257,12 +1253,12 @@ 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 allocate~--~the others are simple wrapper functions that
-take either a filename or a memory buffer.
+are done with it. The first takes a generic \type{DataSource} that you
+have to allocate~--~the others are simple wrapper functions that take
+either a filename or a memory buffer.
So what can you do with the return value of \function{load\_key}? On
-its own, a \type{X509\_PublicKey} isn't particularly useful; you can't
+its own, a \type{Public\_Key} isn't particularly useful; you can't
encrypt messages or verify signatures, or much else. But, using
\function{dynamic\_cast}, you can figure out what kind of operations
the key supports. Then, you can cast the key to the appropriate type
@@ -1281,14 +1277,13 @@ and pass it to a higher-level class. For example:
\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:
+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 {
- void encode(const Private_Key& key, Pipe& to, X509_Encoding enc = PEM);
-
+ SecureVector<byte> BER_encode(const Private_Key& key);
std::string PEM_encode(const Private_Key& key);
}
\end{verbatim}
@@ -1304,60 +1299,39 @@ 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 the techniques of PKCS
-\#5), and store the whole thing into another structure. This method is
-definitely preferred, since otherwise the private key is unprotected. The
-following functions support this technique:
+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 the
+techniques of PKCS \#5), and store the whole thing into another
+structure. This method is definitely preferred, since otherwise the
+private key is unprotected. The following functions support this
+technique:
\begin{verbatim}
namespace PKCS8 {
- void encrypt_key(const Private_Key& key, Pipe& out,
- std::string passphrase, std::string pbe = "",
- X509_Encoding enc = PEM);
- std::string PEM_encode(const Private_Key& key, std::string passphrase,
- std::string pbe = "");
-}
+ 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}
-To export an encrypted private key, call \function{PKCS8::encrypt\_key}. The
-\arg{key}, \arg{out}, and \arg{enc} arguments are similar in usage to the ones
-for \function{PKCS8::encode}. As you might notice, there are two new arguments
-for \function{PKCS8::encrypt\_key}, however. The first is a passphrase (which
-you presumably got from a user somehow). This will be used to encrypt the key.
-The second new argument is \arg{pbe}; this specifies a particular password
-based encryption (or PBE) algorithm.
-
-The \function{PEM\_encode} version shown here is similar to the one that
-doesn't take a passphrase. Essentially it encrypts the key (using the default
-PBE algorithm), and then returns a C++ string with the PEM encoding of the key.
-
-If \arg{pbe} is blank, then the default algorithm (controlled by the
-``base/default\_pbe'' option) will be used. As shipped, this default is
-``PBE-PKCS5v20(SHA-1,TripleDES/CBC)'' . This is among the more secure options
-of PKCS \#5, and is widely supported among implementations of PKCS \#5 v2.0. It
-offers 168 bits of security against attacks, which should be more that
-sufficient. If you need compatibility with systems that only support PKCS \#5
-v1.5, pass ``PBE-PKCS5v15(MD5,DES/CBC)'' as \arg{pbe}. However, be warned that
-this PBE algorithm only has 56 bits of security against brute force attacks. As
-of 1.4.5, all three keylengths of AES are also available as options, which can
-be used with by specifying a PBE algorithm of
-``PBE-PKCS5v20(SHA-1,AES-256/CBC)'' (or ``AES-128'' or ``AES-192''). Support
-for AES is slightly non-standard, and some applications or libraries might not
-handle it. It is known that OpenSSL (0.9.7 and later) do handle AES for private
-key encryption.
-
-There may be some strange programs out there that support the v2.0 extensions
-to PBES1 but not PBES2; if you need to inter-operate with a program like that,
-use ``PBE-PKCS5v15(MD5,RC2/CBC)''. For example, OpenSSL supports this format
-(though since it also supports the v2.0 schemes, there is no reason not to just
-use TripleDES or AES). This scheme uses a 64-bit key that, while
-significantly better than a 56-bit key, is a bit too small for comfort.
-
-Last but not least, there are some functions that are basically identical to
-\function{X509::load\_key} that will load, and possibly decrypt, a PKCS \#8
-private key:
+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 are basically
+identical to \function{X509::load\_key} that will load, and possibly
+decrypt, a PKCS \#8 private key:
\begin{verbatim}
namespace PKCS8 {
@@ -1396,25 +1370,9 @@ the versions taking the \type{std::string}.
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}
-it 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).
+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} it once you are done with it.
\pagebreak
\section{Certificate Handling}
@@ -1444,15 +1402,16 @@ 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{X509\_PublicKey*}. 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.
+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