diff options
Diffstat (limited to 'src/tests/nist_x509.cpp')
-rw-r--r-- | src/tests/nist_x509.cpp | 118 |
1 files changed, 105 insertions, 13 deletions
diff --git a/src/tests/nist_x509.cpp b/src/tests/nist_x509.cpp index 04b569d32..0ce74334f 100644 --- a/src/tests/nist_x509.cpp +++ b/src/tests/nist_x509.cpp @@ -1,16 +1,7 @@ /* -* (C) 2006,2011,2012,2014 Jack Lloyd +* (C) 2006,2011,2012,2014,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) -* -* Code to run the X.509v3 processing tests described in "Conformance -* Testing of Relying Party Client Certificate Path Proccessing Logic", -* which is available on NIST's web site. -* -* Known Failures/Problems: -* - Policy extensions are not implemented, so we skip tests #34-#53. -* - Tests #75 and #76 are skipped as they make use of relatively -* obscure CRL extensions which are not supported. */ #include "tests.h" @@ -22,6 +13,7 @@ #include <algorithm> #include <iostream> +#include <fstream> #include <iomanip> #include <string> #include <vector> @@ -32,11 +24,110 @@ using namespace Botan; std::map<size_t, Path_Validation_Result::Code> get_expected(); +namespace { + +std::vector<X509_Certificate> load_cert_file(const std::string& filename) + { + DataSource_Stream in(filename); + + std::vector<X509_Certificate> certs; + while(!in.end_of_data()) + { + try { + certs.emplace_back(in); + } + catch(Decoding_Error) {} + } + + return certs; + } + +std::map<std::string, std::string> read_results(const std::string& results_file) + { + std::ifstream in(results_file); + if(!in.good()) + throw std::runtime_error("Failed reading " + results_file); + + std::map<std::string, std::string> m; + std::string line; + while(in.good()) + { + std::getline(in, line); + if(line == "") + continue; + if(line[0] == '#') + continue; + + std::vector<std::string> parts = split_on(line, ':'); + + if(parts.size() != 2) + throw std::runtime_error("Invalid line " + line); + + m[parts[0]] = parts[1]; + } + + return m; + } + +} + +size_t test_x509_x509test() + { + // Test certs generated by https://github.com/yymax/x509test + const std::string test_dir = "src/tests/data/x509test"; + + std::map<std::string, std::string> results = read_results(test_dir + "/expected.txt"); + + const Path_Validation_Restrictions default_restrictions; + + size_t fail = 0; + + X509_Certificate root(test_dir + "/root.pem"); + Certificate_Store_In_Memory trusted; + trusted.add_certificate(root); + + for(auto i = results.begin(); i != results.end(); ++i) + { + const std::string fsname = i->first; + const std::string expected = i->second; + + std::vector<X509_Certificate> certs = load_cert_file(test_dir + "/" + fsname); + + if(certs.empty()) + throw std::runtime_error("Failed to read certs from " + fsname); + + Path_Validation_Result result = x509_path_validate(certs, default_restrictions, trusted, + "www.tls.test", Usage_Type::TLS_SERVER_AUTH); + + if(result.successful_validation() && result.trust_root() != root) + result = Path_Validation_Result(Certificate_Status_Code::CANNOT_ESTABLISH_TRUST); + + if(result.result_string() != expected) + { + std::cout << "FAIL " << fsname << " expected '" << expected << "' got '" << result.result_string() << "'\n"; + ++fail; + } + } + + test_report("X.509 (x509test)", results.size(), fail); + + return fail; + } + size_t test_nist_x509() { + /** + * Code to run the X.509v3 processing tests described in "Conformance + * Testing of Relying Party Client Certificate Path Proccessing Logic", + * which is available on NIST's web site. + * + * Known Failures/Problems: + * - Policy extensions are not implemented, so we skip tests #34-#53. + * - Tests #75 and #76 are skipped as they make use of relatively + * obscure CRL extensions which are not supported. + */ const std::string root_test_dir = "src/tests/data/nist_x509/"; const size_t total_tests = 76; - try { // Do nothing, just test filesystem access @@ -61,8 +152,8 @@ size_t test_nist_x509() for(size_t test_no = 1; test_no <= total_tests; ++test_no) { const std::string test_dir = root_test_dir + "/test" + (test_no <= 9 ? "0" : "") + std::to_string(test_no); - - const std::vector<std::string> all_files = get_files_recursive(test_dir); + + const std::vector<std::string> all_files = get_files_recursive(test_dir); if (all_files.empty()) std::cout << "Warning: No test files found in '" << test_dir << "'" << std::endl; @@ -83,6 +174,7 @@ size_t test_nist_x509() if(expected_results.find(test_no) == expected_results.end()) { + //printf("Skipping %d\n", test_no); skipped++; continue; } |