diff options
author | lloyd <[email protected]> | 2011-04-08 18:13:41 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2011-04-08 18:13:41 +0000 |
commit | 8b543e804375a788ae71d461c0f8cf5d4193fc25 (patch) | |
tree | 6177931cd84a9be204cdab6e62729954e69e0421 /doc | |
parent | 3b66bfd4da97189ec275e5f85b9f85009d3f8370 (diff) |
ECC private keys had two different constructors, one taking a group
and a random number generator, and the other taking a group and a
preset private key value. The DL private keys instead have on
constructor for this; if the x value is zero, then a new random key is
created. For consistency, do this with ECC as well.
ECDH actually didn't have one of these constructors, forcing you to
either load from PKCS #8 or else use a random key.
Rename EC_Domain_Params to EC_Group, with a typedef for compatability.
More doc updates.
Update mtn ignores for Sphinx output
Diffstat (limited to 'doc')
-rw-r--r-- | doc/Makefile | 2 | ||||
-rw-r--r-- | doc/examples/GNUmakefile | 4 | ||||
-rw-r--r-- | doc/examples/asn1.cpp | 80 | ||||
-rw-r--r-- | doc/examples/ca.cpp | 17 | ||||
-rw-r--r-- | doc/examples/dsa_kgen.cpp | 42 | ||||
-rw-r--r-- | doc/examples/dsa_sign.cpp | 13 | ||||
-rw-r--r-- | doc/examples/dsa_ver.cpp | 49 | ||||
-rw-r--r-- | doc/examples/eax.vec (renamed from doc/examples/eax_tv.txt) | 0 | ||||
-rw-r--r-- | doc/examples/eax_test.cpp | 2 | ||||
-rw-r--r-- | doc/examples/ecdsa.cpp | 2 | ||||
-rw-r--r-- | doc/examples/fpe.cpp | 15 | ||||
-rw-r--r-- | doc/examples/pkcs10.cpp | 23 | ||||
-rwxr-xr-x | doc/examples/python/nisttest.py | 2 | ||||
-rw-r--r-- | doc/examples/python/results.vec (renamed from doc/examples/python/results.txt) | 0 | ||||
-rw-r--r-- | doc/examples/readme.txt | 77 | ||||
-rw-r--r-- | doc/examples/rsa_kgen.cpp | 34 | ||||
-rw-r--r-- | doc/examples/self_sig.cpp | 16 | ||||
-rw-r--r-- | doc/examples/x509info.cpp | 35 | ||||
-rw-r--r-- | doc/log.txt | 6 | ||||
-rw-r--r-- | doc/pubkey.txt | 166 |
20 files changed, 160 insertions, 425 deletions
diff --git a/doc/Makefile b/doc/Makefile index 152fa3e09..e183a36ec 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -2,7 +2,7 @@ # # You can set these variables from the command line. -SPHINXOPTS = +SPHINXOPTS = -W SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build diff --git a/doc/examples/GNUmakefile b/doc/examples/GNUmakefile index c386f4390..44fcfeea5 100644 --- a/doc/examples/GNUmakefile +++ b/doc/examples/GNUmakefile @@ -2,8 +2,8 @@ BOTAN_CONFIG = botan-config CXX = g++ -CFLAGS = -O2 -ansi -W -Wall -I../build/include -LIBS = -L.. -lbotan +CFLAGS = -O2 -ansi -W -Wall -I../../build/include +LIBS = -L../.. -lbotan SRCS=$(wildcard *.cpp) diff --git a/doc/examples/asn1.cpp b/doc/examples/asn1.cpp index b0a6aa104..bb891d746 100644 --- a/doc/examples/asn1.cpp +++ b/doc/examples/asn1.cpp @@ -1,37 +1,3 @@ -/* -* (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> @@ -45,6 +11,16 @@ using namespace Botan; #include <stdio.h> #include <ctype.h> +// 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 + void decode(BER_Decoder&, u32bit); void emit(const std::string&, u32bit, u32bit, const std::string& = ""); std::string type_name(ASN1_Tag); @@ -57,7 +33,7 @@ int main(int argc, char* argv[]) return 1; } - Botan::LibraryInitializer init; + LibraryInitializer init; try { DataSource_Stream in(argv[1]); @@ -83,7 +59,7 @@ int main(int argc, char* argv[]) return 0; } -void decode(BER_Decoder& decoder, u32bit level) +void decode(BER_Decoder& decoder, size_t level) { BER_Object obj = decoder.get_next_object(); @@ -91,7 +67,7 @@ void decode(BER_Decoder& decoder, u32bit level) { const ASN1_Tag type_tag = obj.type_tag; const ASN1_Tag class_tag = obj.class_tag; - const u32bit length = obj.value.size(); + const size_t length = obj.value.size(); /* hack to insert the tag+length back in front of the stuff now that we've gotten the type info */ @@ -142,8 +118,8 @@ void decode(BER_Decoder& decoder, u32bit level) { bool not_text = false; - for(u32bit j = 0; j != bits.size(); j++) - if(!isgraph(bits[j]) && !isspace(bits[j])) + for(size_t i = 0; i != bits.size(); ++i) + if(!isgraph(bits[i]) && !isspace(bits[i])) not_text = true; Pipe pipe(((not_text) ? new Hex_Encoder : 0)); @@ -176,8 +152,8 @@ void decode(BER_Decoder& decoder, u32bit level) rep = BigInt::encode(number, BigInt::Hexadecimal); std::string str; - for(u32bit j = 0; j != rep.size(); j++) - str += (char)rep[j]; + for(size_t i = 0; i != rep.size(); ++i) + str += (char)rep[i]; emit(type_name(type_tag), level, length, str); } @@ -198,8 +174,8 @@ void decode(BER_Decoder& decoder, u32bit level) data.decode(bits, type_tag); bool not_text = false; - for(u32bit j = 0; j != bits.size(); j++) - if(!isgraph(bits[j]) && !isspace(bits[j])) + for(size_t i = 0; i != bits.size(); ++i) + if(!isgraph(bits[i]) && !isspace(bits[i])) not_text = true; Pipe pipe(((not_text) ? new Hex_Encoder : 0)); @@ -213,14 +189,14 @@ void decode(BER_Decoder& decoder, u32bit level) 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)); + for(size_t i = 0; i != bits.size(); ++i) + for(size_t j = 0; j != 8; ++j) + bit_set.push_back((bool)((bits[bits.size()-i-1] >> (7-j)) & 1)); std::string bit_str; - for(u32bit j = 0; j != bit_set.size(); j++) + for(size_t i = 0; i != bit_set.size(); ++i) { - bool the_bit = bit_set[bit_set.size()-j-1]; + bool the_bit = bit_set[bit_set.size()-i-1]; if(!the_bit && bit_str.size() == 0) continue; @@ -260,15 +236,15 @@ void decode(BER_Decoder& decoder, u32bit level) } } -void emit(const std::string& type, u32bit level, u32bit length, +void emit(const std::string& type, size_t level, size_t length, const std::string& value) { - const u32bit LIMIT = 128; - const u32bit BIN_LIMIT = 64; + const size_t LIMIT = 128; + const size_t BIN_LIMIT = 64; int written = 0; written += printf(" d=%2d, l=%4d: ", level, length); - for(u32bit j = INITIAL_LEVEL; j != level; j++) + for(size_t i = INITIAL_LEVEL; i != level; ++i) written += printf(" "); written += printf("%s ", type.c_str()); diff --git a/doc/examples/ca.cpp b/doc/examples/ca.cpp index 8dd3e981f..7a3e6daf9 100644 --- a/doc/examples/ca.cpp +++ b/doc/examples/ca.cpp @@ -1,20 +1,3 @@ -/* -* (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> diff --git a/doc/examples/dsa_kgen.cpp b/doc/examples/dsa_kgen.cpp index fe3157370..fc5b7b501 100644 --- a/doc/examples/dsa_kgen.cpp +++ b/doc/examples/dsa_kgen.cpp @@ -1,13 +1,3 @@ -/* -* (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> @@ -20,24 +10,24 @@ using namespace Botan; 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 { + if(argc != 1 && argc != 2) + { + std::cout << "Usage: " << argv[0] << " [passphrase]" << std::endl; + return 1; + } + + std::ofstream priv("dsapriv.pem"); + std::ofstream pub("dsapub.pem"); + if(!priv || !pub) + { + std::cout << "Couldn't write output files" << std::endl; + return 1; + } + + Botan::LibraryInitializer init; + AutoSeeded_RNG rng; DL_Group group(rng, DL_Group::DSA_Kosherizer, 2048, 256); diff --git a/doc/examples/dsa_sign.cpp b/doc/examples/dsa_sign.cpp index 5f02c0dc1..827fc7e0a 100644 --- a/doc/examples/dsa_sign.cpp +++ b/doc/examples/dsa_sign.cpp @@ -1,10 +1,3 @@ -/* -* DSA signature generation example -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - #include <iostream> #include <iomanip> #include <fstream> @@ -66,12 +59,10 @@ int main(int argc, char* argv[]) DataSource_Stream in(message); byte buf[4096] = { 0 }; - while(u32bit got = in.read(buf, sizeof(buf))) + while(size_t 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; + sigfile << base64_encode(signer.signature(rng)) << "\n"; } catch(std::exception& e) { diff --git a/doc/examples/dsa_ver.cpp b/doc/examples/dsa_ver.cpp index a666259c1..9cb85740e 100644 --- a/doc/examples/dsa_ver.cpp +++ b/doc/examples/dsa_ver.cpp @@ -1,18 +1,3 @@ -/* -* (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> @@ -45,28 +30,30 @@ int main(int argc, char* argv[]) 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; - } + try { + Botan::LibraryInitializer init; - std::ifstream sigfile(argv[3]); - if(!sigfile) - { - std::cout << "Couldn't read the signature file." << 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; + } + + 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"; @@ -79,10 +66,10 @@ int main(int argc, char* argv[]) DataSource_Stream in(message); byte buf[4096] = { 0 }; - while(u32bit got = in.read(buf, sizeof(buf))) + while(size_t got = in.read(buf, sizeof(buf))) ver.update(buf, got); - bool ok = ver.check_signature(sig); + const bool ok = ver.check_signature(sig); if(ok) std::cout << "Signature verified\n"; diff --git a/doc/examples/eax_tv.txt b/doc/examples/eax.vec index 95cd7c1ab..95cd7c1ab 100644 --- a/doc/examples/eax_tv.txt +++ b/doc/examples/eax.vec diff --git a/doc/examples/eax_test.cpp b/doc/examples/eax_test.cpp index 32311800d..b43861132 100644 --- a/doc/examples/eax_test.cpp +++ b/doc/examples/eax_test.cpp @@ -236,7 +236,7 @@ void run_tests(std::istream& in) int main() { - std::ifstream in("eax_tv.txt"); + std::ifstream in("eax.vec"); Botan::LibraryInitializer init; diff --git a/doc/examples/ecdsa.cpp b/doc/examples/ecdsa.cpp index df1e1b93a..1607107eb 100644 --- a/doc/examples/ecdsa.cpp +++ b/doc/examples/ecdsa.cpp @@ -21,7 +21,7 @@ int main() { AutoSeeded_RNG rng; - EC_Domain_Params params("1.3.132.0.8"); + EC_Domain_Params params("secp160r1"); ECDSA_PrivateKey ecdsa(rng, params); diff --git a/doc/examples/fpe.cpp b/doc/examples/fpe.cpp index 9b18d4879..a7a483d65 100644 --- a/doc/examples/fpe.cpp +++ b/doc/examples/fpe.cpp @@ -1,17 +1,6 @@ -/* -* (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/botan.h> #include <botan/fpe.h> #include <botan/sha160.h> -#include <botan/init.h> using namespace Botan; @@ -130,7 +119,7 @@ int main(int argc, char* argv[]) 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. */ diff --git a/doc/examples/pkcs10.cpp b/doc/examples/pkcs10.cpp index 3f5ec8e05..b5ad1d1dd 100644 --- a/doc/examples/pkcs10.cpp +++ b/doc/examples/pkcs10.cpp @@ -1,9 +1,3 @@ -/* -* (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> @@ -31,9 +25,6 @@ int main(int argc, char* argv[]) 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]); @@ -45,18 +36,8 @@ int main(int argc, char* argv[]) 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); + PKCS10_Request req = X509::create_cert_req(opts, priv_key, + "SHA-256", rng); std::ofstream req_file("req.pem"); req_file << req.PEM_encode(); diff --git a/doc/examples/python/nisttest.py b/doc/examples/python/nisttest.py index 3ea8fda0f..1260b1226 100755 --- a/doc/examples/python/nisttest.py +++ b/doc/examples/python/nisttest.py @@ -47,7 +47,7 @@ def main(): results[test] = result return results - results = load_results('results.txt') + results = load_results('results.vec') for root, dirs, files in os.walk('../../checks/nist_tests/tests'): if files: diff --git a/doc/examples/python/results.txt b/doc/examples/python/results.vec index 7a3824001..7a3824001 100644 --- a/doc/examples/python/results.txt +++ b/doc/examples/python/results.vec 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/rsa_kgen.cpp b/doc/examples/rsa_kgen.cpp index f4566263b..a1f0fe71d 100644 --- a/doc/examples/rsa_kgen.cpp +++ b/doc/examples/rsa_kgen.cpp @@ -1,15 +1,3 @@ -/* -* (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> @@ -29,25 +17,25 @@ int main(int argc, char* argv[]) return 1; } - u32bit bits = std::atoi(argv[1]); + const size_t 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 { + 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; + } + AutoSeeded_RNG rng; RSA_PrivateKey key(rng, bits); diff --git a/doc/examples/self_sig.cpp b/doc/examples/self_sig.cpp index 6710cfb51..64b778b71 100644 --- a/doc/examples/self_sig.cpp +++ b/doc/examples/self_sig.cpp @@ -1,17 +1,3 @@ -/* -* (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> @@ -49,7 +35,7 @@ int main(int argc, char* argv[]) { AutoSeeded_RNG rng; - RSA_PrivateKey key(rng, 1024); + RSA_PrivateKey key(rng, 2048); std::ofstream priv_key("private.pem"); priv_key << PKCS8::PEM_encode(key, rng, argv[1]); 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/log.txt b/doc/log.txt index 1f7107d8c..d146eb116 100644 --- a/doc/log.txt +++ b/doc/log.txt @@ -14,6 +14,12 @@ Version 1.9.16, Not Yet Released reStructuredText suitable for processing by Sphinx, which can generate nicely formatted HTML and PDFs. + * The class EC_Domain_Params has been renamed EC_Group, with a + typedef for backwards compatability. + + * EC_Group's string constructor didn't understand the standard + names like "secp160r1", forcing use of the OIDs. + * Change shared library versioning to match the normal Unix conventions. Instead of libbotan-X.Y.Z.so, the shared lib is named libbotan.so.X.Y.Z; this allows the runtime linker to do its diff --git a/doc/pubkey.txt b/doc/pubkey.txt index 254880f65..2089434d6 100644 --- a/doc/pubkey.txt +++ b/doc/pubkey.txt @@ -52,7 +52,7 @@ operations, like key agreement, the two keys *must* use the same group. There are currently two kinds of discrete logarithm groups supported in botan: the integers modulo a prime, represented by :ref:`dl_group`, and elliptic curves in GF(p), represented by -:ref:`ec_dompar`. A rough generalization is that the larger the group +:ref:`ec_group`. A rough generalization is that the larger the group is, the more secure the algorithm is, but coorespondingly the slower the operations will be. @@ -74,30 +74,14 @@ Nyberg-Rueppel key pairs with value. Normally, you would leave the value as zero, letting the class generate a new random key. -Finally, given an ``EC_Domain_Params`` object, you can create a new +Finally, given an ``EC_Group`` object, you can create a new ECDSA, ECDH, or GOST 34.10 private key with -.. cpp:function:: ECDSA_PrivateKey::ECDSA_PrivateKey(RandomNumberGenerator& rng, const EC_Domain_Params& domain) +.. cpp:function:: ECDSA_PrivateKey::ECDSA_PrivateKey(RandomNumberGenerator& rng, const EC_Group& domain, const BigInt& x = 0) -.. cpp:function:: ECDH_PrivateKey::ECDH_PrivateKey(RandomNumberGenerator& rng, const EC_Domain_Params& domain) +.. cpp:function:: ECDH_PrivateKey::ECDH_PrivateKey(RandomNumberGenerator& rng, const EC_Group& domain, const BigInt& x = 0) -.. cpp:function:: GOST_3410_PrivateKey::GOST_3410_PrivateKey(RandomNumberGenerator& rng, const EC_Domain_Params& domain) - -Unlike the integer modulo a prime key types, the constructor that takes a -predefined ``BigInt`` private key value is different: - -.. cpp:function:: ECDSA_PrivateKey::ECDSA_PrivateKey(const EC_Domain_Params& domain, const BigInt& x) - -.. cpp:function:: ECDH_PrivateKey::ECDH_PrivateKey(const EC_Domain_Params& domain, const BigInt& x) - -.. cpp:function:: GOST_3410_PrivateKey::GOST_3410_PrivateKey(const EC_Domain_Params& domain, const BigInt& x) - -.. note:: - - It is likely that these constructors will be removed in a future - release, and a third optional parameter will be added to the - constructors described above, to match the integer modulo prime - versions. Only use them if you really need them. +.. cpp:function:: GOST_3410_PrivateKey::GOST_3410_PrivateKey(RandomNumberGenerator& rng, const EC_Group& domain, const BigInt& x = 0) .. _serializing_private_keys: @@ -274,12 +258,12 @@ You can reload a serialized group using .. cpp:function:: void DL_Group::PEM_decode(DataSource& source) -.. _ec_dompar: +.. _ec_group: -EC_Domain_Params +EC_Group ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -An ``EC_Domain_Params`` is initialized by passing the name of the +An ``EC_Group`` is initialized by passing the name of the group to be used to the constructor. These groups have semi-standardized names like "secp256r1" and "brainpool512r1". @@ -305,96 +289,82 @@ Each public key type has a function checking, which includes expensive operations like primality checking. -Getting a PK algorithm object +Encryption --------------------------------- -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). +Safe public key encryption requires the use of a padding scheme which +hides the underlying mathematical properties of the algorithm. +Additionally, they will add randomness, so encrypting the same +plaintext twice produces two different ciphertexts. -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):: +The primary interface for encryption is ``PK_Encryptor``, which +provides the following interface: - // 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") +.. cpp:function:: SecureVector<byte> PK_Encryptor::encrypt(const byte in[], size_t length, RandomNumberGenerator& rng) const - // This object can decrypt things encrypted by rsa_ - PK_Decryptor_EME rsa_dec_pkcs1_v2(rsakey, "EME1(SHA-1)"); +.. cpp:function:: SecureVector<byte> PK_Encryptor::encrypt(const MemoryRegion<byte>& in, RandomNumberGenerator& rng) const - // 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)"); +.. cpp:function:: size_t PK_Encryptor::maximum_input_size() const -Encryption ---------------------------------- + This function returns the maximum size of the message that can + be processed, in bytes. If you call ``encrypt`` with a value + larger than this the operation will fail with an exception. + +``PK_Encryptor`` is only an interface; to use one you have to create +an implementation; there are currently two availabie in the library, +``PK_Encryptor_EME`` and ``DLIES_Encryptor``. DLIES is a standard +method (from IEEE 1363) that uses a key agreement technique such as DH +or ECDH to perform message encryption. Normally, public key encryption +is done using algorithms which support it directly, such as RSA or +ElGamal; these use ``PK_Encryptor_EME``. The construction method is +simple; call + +.. cpp:function:: PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key, std::string eme) + + With *key* being the key you want to encrypt messages to. The + padding method to use is specified in *eme*. + + The recommended values for *eme* is "EME1(SHA-1)" or + "EME1(SHA-256)". If you need compatability with protocols using the + PKCS #1 v1.5 standard, you can also use "EME-PKCS1-v1_5". + +The DLIES encryptor is defined in the header ``dlies.h``, and +is created by the constructor: + +.. cpp:function:: DLIES_Encryptor::DLIES_Encryptor(const PK_Key_Agreement_Key&, KDF* kdf, MessageAuthenticationCode* mac, size_t mac_key_len = 20) + + Where *kdf* is a :ref:`key_derivation_function` and *mac* is a + :ref:`message_auth_code`. + +The decryption classes are named ``PK_Decryptor``, +``PK_Decryptor_EME``, and ``DLIES_Decryptor``. They are created in the +exact same way, except they take the private key, and the processing +function is named ``decrypt``. -The ``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 +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. +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 |