From 5730a7a8e59492e6b9aa3ab188d077c1f8bc3386 Mon Sep 17 00:00:00 2001
From: tls-n
Date: Fri, 11 Aug 2017 01:23:47 +0200
Subject: [PATCH] Initial commit
---
README.md | 30 +
ca/cert_creation.sh | 20 +
ca/client_db/cert.req | 18 +
ca/client_db/cert.req2 | Bin 0 -> 247 bytes
ca/client_db/cert8.db | Bin 0 -> 65536 bytes
ca/client_db/key3.db | Bin 0 -> 16384 bytes
ca/client_db/secmod.db | Bin 0 -> 16384 bytes
ca/client_db/server.crt | Bin 0 -> 325 bytes
ca/noise.txt | 250 +
ca/server_db/cert.req | 18 +
ca/server_db/cert.req2 | Bin 0 -> 247 bytes
ca/server_db/cert8.db | Bin 0 -> 65536 bytes
ca/server_db/key3.db | Bin 0 -> 16384 bytes
ca/server_db/secmod.db | Bin 0 -> 16384 bytes
ca/server_db/server.crt | Bin 0 -> 325 bytes
nss/.clang-format | 65 +
nss/.gitignore | 20 +
nss/.hg_archival.txt | 4 +
nss/.hgignore | 20 +
nss/.taskcluster.yml | 89 +
nss/COPYING | 403 +
nss/Makefile | 159 +
.../buildbot-slave/bbenv-example.sh | 67 +
nss/automation/buildbot-slave/build.sh | 414 +
nss/automation/buildbot-slave/reboot.bat | 6 +
nss/automation/buildbot-slave/startbuild.bat | 14 +
nss/automation/ossfuzz/build.sh | 57 +
nss/automation/release/nss-release-helper.py | 250 +
.../taskcluster/docker-aarch64/Dockerfile | 30 +
.../docker-aarch64/bin/checkout.sh | 20 +
.../taskcluster/docker-aarch64/setup.sh | 40 +
.../taskcluster/docker-arm/Dockerfile | 27 +
.../taskcluster/docker-arm/bin/checkout.sh | 25 +
.../taskcluster/docker-arm/bin/uname.sh | 18 +
.../taskcluster/docker-arm/setup.sh | 35 +
.../taskcluster/docker-decision/Dockerfile | 27 +
.../docker-decision/bin/checkout.sh | 20 +
.../taskcluster/docker-decision/setup.sh | 31 +
.../taskcluster/docker-fuzz/Dockerfile | 33 +
.../taskcluster/docker-fuzz/bin/checkout.sh | 20 +
.../taskcluster/docker-fuzz/setup.sh | 48 +
nss/automation/taskcluster/docker/Dockerfile | 33 +
.../taskcluster/docker/bin/checkout.sh | 20 +
nss/automation/taskcluster/docker/setup.sh | 66 +
.../taskcluster/graph/npm-shrinkwrap.json | 1643 +
nss/automation/taskcluster/graph/package.json | 24 +
.../taskcluster/graph/src/context_hash.js | 43 +
.../taskcluster/graph/src/extend.js | 601 +
.../taskcluster/graph/src/image_builder.js | 62 +
nss/automation/taskcluster/graph/src/index.js | 14 +
nss/automation/taskcluster/graph/src/merge.js | 10 +
nss/automation/taskcluster/graph/src/queue.js | 248 +
.../taskcluster/graph/src/try_syntax.js | 153 +
nss/automation/taskcluster/scripts/build.sh | 21 +
.../taskcluster/scripts/build_gyp.sh | 13 +
.../taskcluster/scripts/build_nspr.sh | 18 +
.../taskcluster/scripts/build_nss.sh | 39 +
.../taskcluster/scripts/build_softoken.sh | 30 +
.../taskcluster/scripts/build_util.sh | 25 +
.../taskcluster/scripts/extend_task_graph.sh | 11 +
nss/automation/taskcluster/scripts/fuzz.sh | 32 +
.../taskcluster/scripts/gen_certs.sh | 16 +
.../taskcluster/scripts/run_clang_format.sh | 60 +
.../taskcluster/scripts/run_scan_build.sh | 51 +
.../taskcluster/scripts/run_tests.sh | 9 +
nss/automation/taskcluster/scripts/split.sh | 152 +
nss/automation/taskcluster/scripts/tools.sh | 38 +
nss/automation/taskcluster/windows/build.sh | 15 +
.../taskcluster/windows/gen_certs.sh | 19 +
.../taskcluster/windows/releng.manifest | 10 +
.../taskcluster/windows/run_tests.sh | 13 +
nss/automation/taskcluster/windows/setup.sh | 30 +
nss/automation/travis/validate-formatting.sh | 18 +
nss/build.sh | 236 +
nss/cmd/Makefile | 44 +
nss/cmd/addbuiltin/Makefile | 48 +
nss/cmd/addbuiltin/addbuiltin.c | 574 +
nss/cmd/addbuiltin/addbuiltin.gyp | 24 +
nss/cmd/addbuiltin/manifest.mn | 20 +
nss/cmd/atob/Makefile | 48 +
nss/cmd/atob/atob.c | 174 +
nss/cmd/atob/atob.gyp | 30 +
nss/cmd/atob/manifest.mn | 22 +
nss/cmd/benchmark/.gitignore | 2 +
nss/cmd/benchmark/Makefile | 46 +
nss/cmd/benchmark/README.md | 5 +
nss/cmd/benchmark/client_db | 1 +
nss/cmd/benchmark/main.c | 247 +
nss/cmd/benchmark/manifest.mn | 23 +
nss/cmd/benchmark/messages.txt | 0
nss/cmd/bltest/Makefile | 54 +
nss/cmd/bltest/blapitest.c | 4234 +
nss/cmd/bltest/bltest.gyp | 35 +
nss/cmd/bltest/manifest.mn | 26 +
nss/cmd/bltest/pkcs1_vectors.h | 789 +
nss/cmd/bltest/tests/README | 56 +
nss/cmd/bltest/tests/aes_cbc/ciphertext0 | 1 +
nss/cmd/bltest/tests/aes_cbc/ciphertext1 | 1 +
nss/cmd/bltest/tests/aes_cbc/ciphertext10 | 3 +
nss/cmd/bltest/tests/aes_cbc/ciphertext11 | 3 +
nss/cmd/bltest/tests/aes_cbc/ciphertext12 | 4 +
nss/cmd/bltest/tests/aes_cbc/ciphertext13 | 1 +
nss/cmd/bltest/tests/aes_cbc/ciphertext14 | 2 +
nss/cmd/bltest/tests/aes_cbc/ciphertext15 | 2 +
nss/cmd/bltest/tests/aes_cbc/ciphertext16 | 3 +
nss/cmd/bltest/tests/aes_cbc/ciphertext17 | 3 +
nss/cmd/bltest/tests/aes_cbc/ciphertext18 | 4 +
nss/cmd/bltest/tests/aes_cbc/ciphertext19 | 1 +
nss/cmd/bltest/tests/aes_cbc/ciphertext2 | 1 +
nss/cmd/bltest/tests/aes_cbc/ciphertext20 | 2 +
nss/cmd/bltest/tests/aes_cbc/ciphertext21 | 2 +
nss/cmd/bltest/tests/aes_cbc/ciphertext22 | 3 +
nss/cmd/bltest/tests/aes_cbc/ciphertext23 | 3 +
nss/cmd/bltest/tests/aes_cbc/ciphertext24 | 4 +
nss/cmd/bltest/tests/aes_cbc/ciphertext3 | 1 +
nss/cmd/bltest/tests/aes_cbc/ciphertext4 | 1 +
nss/cmd/bltest/tests/aes_cbc/ciphertext5 | 1 +
nss/cmd/bltest/tests/aes_cbc/ciphertext6 | 1 +
nss/cmd/bltest/tests/aes_cbc/ciphertext7 | 1 +
nss/cmd/bltest/tests/aes_cbc/ciphertext8 | 2 +
nss/cmd/bltest/tests/aes_cbc/ciphertext9 | 2 +
nss/cmd/bltest/tests/aes_cbc/iv0 | 1 +
nss/cmd/bltest/tests/aes_cbc/iv1 | Bin 0 -> 16 bytes
nss/cmd/bltest/tests/aes_cbc/iv10 | 1 +
nss/cmd/bltest/tests/aes_cbc/iv11 | 1 +
nss/cmd/bltest/tests/aes_cbc/iv12 | 1 +
nss/cmd/bltest/tests/aes_cbc/iv13 | 1 +
nss/cmd/bltest/tests/aes_cbc/iv14 | 1 +
nss/cmd/bltest/tests/aes_cbc/iv15 | 1 +
nss/cmd/bltest/tests/aes_cbc/iv16 | 1 +
nss/cmd/bltest/tests/aes_cbc/iv17 | 1 +
nss/cmd/bltest/tests/aes_cbc/iv18 | 1 +
nss/cmd/bltest/tests/aes_cbc/iv19 | 1 +
nss/cmd/bltest/tests/aes_cbc/iv2 | Bin 0 -> 16 bytes
nss/cmd/bltest/tests/aes_cbc/iv20 | 1 +
nss/cmd/bltest/tests/aes_cbc/iv21 | 2 +
nss/cmd/bltest/tests/aes_cbc/iv22 | 1 +
nss/cmd/bltest/tests/aes_cbc/iv23 | Bin 0 -> 16 bytes
nss/cmd/bltest/tests/aes_cbc/iv24 | 1 +
nss/cmd/bltest/tests/aes_cbc/iv3 | Bin 0 -> 16 bytes
nss/cmd/bltest/tests/aes_cbc/iv4 | Bin 0 -> 16 bytes
nss/cmd/bltest/tests/aes_cbc/iv5 | Bin 0 -> 16 bytes
nss/cmd/bltest/tests/aes_cbc/iv6 | Bin 0 -> 16 bytes
nss/cmd/bltest/tests/aes_cbc/iv7 | 1 +
nss/cmd/bltest/tests/aes_cbc/iv8 | 1 +
nss/cmd/bltest/tests/aes_cbc/iv9 | 1 +
nss/cmd/bltest/tests/aes_cbc/key0 | 1 +
nss/cmd/bltest/tests/aes_cbc/key1 | Bin 0 -> 16 bytes
nss/cmd/bltest/tests/aes_cbc/key10 | 1 +
nss/cmd/bltest/tests/aes_cbc/key11 | 1 +
nss/cmd/bltest/tests/aes_cbc/key12 | 1 +
nss/cmd/bltest/tests/aes_cbc/key13 | 1 +
nss/cmd/bltest/tests/aes_cbc/key14 | 1 +
nss/cmd/bltest/tests/aes_cbc/key15 | 1 +
nss/cmd/bltest/tests/aes_cbc/key16 | Bin 0 -> 24 bytes
nss/cmd/bltest/tests/aes_cbc/key17 | 1 +
nss/cmd/bltest/tests/aes_cbc/key18 | 1 +
nss/cmd/bltest/tests/aes_cbc/key19 | 1 +
nss/cmd/bltest/tests/aes_cbc/key2 | Bin 0 -> 16 bytes
nss/cmd/bltest/tests/aes_cbc/key20 | 1 +
nss/cmd/bltest/tests/aes_cbc/key21 | 2 +
nss/cmd/bltest/tests/aes_cbc/key22 | 1 +
nss/cmd/bltest/tests/aes_cbc/key23 | 1 +
nss/cmd/bltest/tests/aes_cbc/key24 | 1 +
nss/cmd/bltest/tests/aes_cbc/key3 | Bin 0 -> 24 bytes
nss/cmd/bltest/tests/aes_cbc/key4 | Bin 0 -> 24 bytes
nss/cmd/bltest/tests/aes_cbc/key5 | Bin 0 -> 32 bytes
nss/cmd/bltest/tests/aes_cbc/key6 | Bin 0 -> 32 bytes
nss/cmd/bltest/tests/aes_cbc/key7 | Bin 0 -> 16 bytes
nss/cmd/bltest/tests/aes_cbc/key8 | 1 +
nss/cmd/bltest/tests/aes_cbc/key9 | 1 +
nss/cmd/bltest/tests/aes_cbc/mktst.sh | 11 +
nss/cmd/bltest/tests/aes_cbc/numtests | 1 +
nss/cmd/bltest/tests/aes_cbc/plaintext0 | 1 +
nss/cmd/bltest/tests/aes_cbc/plaintext1 | 1 +
nss/cmd/bltest/tests/aes_cbc/plaintext10 | 2 +
nss/cmd/bltest/tests/aes_cbc/plaintext11 | 1 +
nss/cmd/bltest/tests/aes_cbc/plaintext12 | 1 +
nss/cmd/bltest/tests/aes_cbc/plaintext13 | 1 +
nss/cmd/bltest/tests/aes_cbc/plaintext14 | 1 +
nss/cmd/bltest/tests/aes_cbc/plaintext15 | 1 +
nss/cmd/bltest/tests/aes_cbc/plaintext16 | 1 +
nss/cmd/bltest/tests/aes_cbc/plaintext17 | 2 +
nss/cmd/bltest/tests/aes_cbc/plaintext18 | Bin 0 -> 160 bytes
nss/cmd/bltest/tests/aes_cbc/plaintext19 | Bin 0 -> 32 bytes
nss/cmd/bltest/tests/aes_cbc/plaintext2 | 1 +
nss/cmd/bltest/tests/aes_cbc/plaintext20 | 1 +
nss/cmd/bltest/tests/aes_cbc/plaintext21 | 1 +
nss/cmd/bltest/tests/aes_cbc/plaintext22 | Bin 0 -> 128 bytes
nss/cmd/bltest/tests/aes_cbc/plaintext23 | Bin 0 -> 144 bytes
nss/cmd/bltest/tests/aes_cbc/plaintext24 | Bin 0 -> 160 bytes
nss/cmd/bltest/tests/aes_cbc/plaintext3 | 1 +
nss/cmd/bltest/tests/aes_cbc/plaintext4 | 1 +
nss/cmd/bltest/tests/aes_cbc/plaintext5 | 2 +
nss/cmd/bltest/tests/aes_cbc/plaintext6 | 1 +
nss/cmd/bltest/tests/aes_cbc/plaintext7 | 1 +
nss/cmd/bltest/tests/aes_cbc/plaintext8 | 1 +
nss/cmd/bltest/tests/aes_cbc/plaintext9 | 2 +
nss/cmd/bltest/tests/aes_cbc/test1.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test10.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test11.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test12.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test13.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test14.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test15.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test16.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test17.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test18.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test19.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test2.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test20.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test21.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test22.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test23.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test24.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test3.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test4.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test5.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test6.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test7.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test8.txt | 5 +
nss/cmd/bltest/tests/aes_cbc/test9.txt | 5 +
nss/cmd/bltest/tests/aes_ctr/aes_ctr_0.txt | 28 +
nss/cmd/bltest/tests/aes_ctr/aes_ctr_1.txt | 28 +
nss/cmd/bltest/tests/aes_ctr/aes_ctr_2.txt | 28 +
.../tests/aes_ctr/aes_ctr_tests_source.txt | 199 +
nss/cmd/bltest/tests/aes_ctr/ciphertext0 | 2 +
nss/cmd/bltest/tests/aes_ctr/ciphertext1 | 2 +
nss/cmd/bltest/tests/aes_ctr/ciphertext2 | 2 +
nss/cmd/bltest/tests/aes_ctr/iv0 | 1 +
nss/cmd/bltest/tests/aes_ctr/iv1 | 1 +
nss/cmd/bltest/tests/aes_ctr/iv2 | 1 +
nss/cmd/bltest/tests/aes_ctr/key0 | 1 +
nss/cmd/bltest/tests/aes_ctr/key1 | 1 +
nss/cmd/bltest/tests/aes_ctr/key2 | 1 +
nss/cmd/bltest/tests/aes_ctr/mktst.sh | 9 +
nss/cmd/bltest/tests/aes_ctr/numtests | 1 +
nss/cmd/bltest/tests/aes_ctr/plaintext0 | 2 +
nss/cmd/bltest/tests/aes_ctr/plaintext1 | 2 +
nss/cmd/bltest/tests/aes_ctr/plaintext2 | 2 +
.../tests/aes_cts/aes-cts-type-1-vectors.txt | 47 +
nss/cmd/bltest/tests/aes_cts/aes_cts_0.txt | 6 +
nss/cmd/bltest/tests/aes_cts/aes_cts_1.txt | 6 +
nss/cmd/bltest/tests/aes_cts/aes_cts_2.txt | 6 +
nss/cmd/bltest/tests/aes_cts/aes_cts_3.txt | 6 +
nss/cmd/bltest/tests/aes_cts/aes_cts_4.txt | 6 +
nss/cmd/bltest/tests/aes_cts/aes_cts_5.txt | 6 +
nss/cmd/bltest/tests/aes_cts/ciphertext0 | 1 +
nss/cmd/bltest/tests/aes_cts/ciphertext1 | 1 +
nss/cmd/bltest/tests/aes_cts/ciphertext2 | 1 +
nss/cmd/bltest/tests/aes_cts/ciphertext3 | 1 +
nss/cmd/bltest/tests/aes_cts/ciphertext4 | 1 +
nss/cmd/bltest/tests/aes_cts/ciphertext5 | 2 +
nss/cmd/bltest/tests/aes_cts/iv0 | Bin 0 -> 34 bytes
nss/cmd/bltest/tests/aes_cts/iv1 | Bin 0 -> 34 bytes
nss/cmd/bltest/tests/aes_cts/iv2 | Bin 0 -> 34 bytes
nss/cmd/bltest/tests/aes_cts/iv3 | Bin 0 -> 34 bytes
nss/cmd/bltest/tests/aes_cts/iv4 | Bin 0 -> 34 bytes
nss/cmd/bltest/tests/aes_cts/iv5 | Bin 0 -> 34 bytes
nss/cmd/bltest/tests/aes_cts/key0 | 1 +
nss/cmd/bltest/tests/aes_cts/key1 | 1 +
nss/cmd/bltest/tests/aes_cts/key2 | 1 +
nss/cmd/bltest/tests/aes_cts/key3 | 1 +
nss/cmd/bltest/tests/aes_cts/key4 | 1 +
nss/cmd/bltest/tests/aes_cts/key5 | 1 +
nss/cmd/bltest/tests/aes_cts/mktst.sh | 9 +
nss/cmd/bltest/tests/aes_cts/numtests | 1 +
nss/cmd/bltest/tests/aes_cts/plaintext0 | 1 +
nss/cmd/bltest/tests/aes_cts/plaintext1 | 1 +
nss/cmd/bltest/tests/aes_cts/plaintext2 | 1 +
nss/cmd/bltest/tests/aes_cts/plaintext3 | 1 +
nss/cmd/bltest/tests/aes_cts/plaintext4 | 1 +
nss/cmd/bltest/tests/aes_cts/plaintext5 | 1 +
nss/cmd/bltest/tests/aes_ecb/ciphertext0 | 1 +
nss/cmd/bltest/tests/aes_ecb/ciphertext1 | 1 +
nss/cmd/bltest/tests/aes_ecb/ciphertext2 | 1 +
nss/cmd/bltest/tests/aes_ecb/ciphertext3 | 1 +
nss/cmd/bltest/tests/aes_ecb/ciphertext4 | 1 +
nss/cmd/bltest/tests/aes_ecb/ciphertext5 | 1 +
nss/cmd/bltest/tests/aes_ecb/ciphertext6 | 1 +
nss/cmd/bltest/tests/aes_ecb/key0 | 1 +
nss/cmd/bltest/tests/aes_ecb/key1 | Bin 0 -> 16 bytes
nss/cmd/bltest/tests/aes_ecb/key2 | Bin 0 -> 16 bytes
nss/cmd/bltest/tests/aes_ecb/key3 | Bin 0 -> 24 bytes
nss/cmd/bltest/tests/aes_ecb/key4 | Bin 0 -> 24 bytes
nss/cmd/bltest/tests/aes_ecb/key5 | Bin 0 -> 32 bytes
nss/cmd/bltest/tests/aes_ecb/key6 | Bin 0 -> 32 bytes
nss/cmd/bltest/tests/aes_ecb/mktst.sh | 10 +
nss/cmd/bltest/tests/aes_ecb/numtests | 1 +
nss/cmd/bltest/tests/aes_ecb/plaintext0 | 1 +
nss/cmd/bltest/tests/aes_ecb/plaintext1 | 1 +
nss/cmd/bltest/tests/aes_ecb/plaintext2 | 1 +
nss/cmd/bltest/tests/aes_ecb/plaintext3 | 1 +
nss/cmd/bltest/tests/aes_ecb/plaintext4 | 1 +
nss/cmd/bltest/tests/aes_ecb/plaintext5 | 2 +
nss/cmd/bltest/tests/aes_ecb/plaintext6 | 1 +
nss/cmd/bltest/tests/aes_ecb/test1.txt | 4 +
nss/cmd/bltest/tests/aes_ecb/test2.txt | 4 +
nss/cmd/bltest/tests/aes_ecb/test3.txt | 4 +
nss/cmd/bltest/tests/aes_ecb/test4.txt | 4 +
nss/cmd/bltest/tests/aes_ecb/test5.txt | 4 +
nss/cmd/bltest/tests/aes_ecb/test6.txt | 4 +
nss/cmd/bltest/tests/aes_gcm/aad0 | 0
nss/cmd/bltest/tests/aes_gcm/aad1 | 0
nss/cmd/bltest/tests/aes_gcm/aad10 | 1 +
nss/cmd/bltest/tests/aes_gcm/aad11 | 1 +
nss/cmd/bltest/tests/aes_gcm/aad12 | 0
nss/cmd/bltest/tests/aes_gcm/aad13 | 0
nss/cmd/bltest/tests/aes_gcm/aad14 | 0
nss/cmd/bltest/tests/aes_gcm/aad15 | 1 +
nss/cmd/bltest/tests/aes_gcm/aad16 | 1 +
nss/cmd/bltest/tests/aes_gcm/aad17 | 1 +
nss/cmd/bltest/tests/aes_gcm/aad2 | 0
nss/cmd/bltest/tests/aes_gcm/aad3 | 1 +
nss/cmd/bltest/tests/aes_gcm/aad4 | 1 +
nss/cmd/bltest/tests/aes_gcm/aad5 | 1 +
nss/cmd/bltest/tests/aes_gcm/aad6 | 0
nss/cmd/bltest/tests/aes_gcm/aad7 | 0
nss/cmd/bltest/tests/aes_gcm/aad8 | 0
nss/cmd/bltest/tests/aes_gcm/aad9 | 1 +
nss/cmd/bltest/tests/aes_gcm/ciphertext0 | 1 +
nss/cmd/bltest/tests/aes_gcm/ciphertext1 | 1 +
nss/cmd/bltest/tests/aes_gcm/ciphertext10 | 2 +
nss/cmd/bltest/tests/aes_gcm/ciphertext11 | 2 +
nss/cmd/bltest/tests/aes_gcm/ciphertext12 | 1 +
nss/cmd/bltest/tests/aes_gcm/ciphertext13 | 1 +
nss/cmd/bltest/tests/aes_gcm/ciphertext14 | 2 +
nss/cmd/bltest/tests/aes_gcm/ciphertext15 | 2 +
nss/cmd/bltest/tests/aes_gcm/ciphertext16 | 2 +
nss/cmd/bltest/tests/aes_gcm/ciphertext17 | 2 +
nss/cmd/bltest/tests/aes_gcm/ciphertext2 | 2 +
nss/cmd/bltest/tests/aes_gcm/ciphertext3 | 2 +
nss/cmd/bltest/tests/aes_gcm/ciphertext4 | 2 +
nss/cmd/bltest/tests/aes_gcm/ciphertext5 | 2 +
nss/cmd/bltest/tests/aes_gcm/ciphertext6 | 1 +
nss/cmd/bltest/tests/aes_gcm/ciphertext7 | 1 +
nss/cmd/bltest/tests/aes_gcm/ciphertext8 | 2 +
nss/cmd/bltest/tests/aes_gcm/ciphertext9 | 2 +
nss/cmd/bltest/tests/aes_gcm/hex.c | 78 +
nss/cmd/bltest/tests/aes_gcm/iv0 | Bin 0 -> 12 bytes
nss/cmd/bltest/tests/aes_gcm/iv1 | Bin 0 -> 12 bytes
nss/cmd/bltest/tests/aes_gcm/iv10 | 1 +
nss/cmd/bltest/tests/aes_gcm/iv11 | 1 +
nss/cmd/bltest/tests/aes_gcm/iv12 | Bin 0 -> 12 bytes
nss/cmd/bltest/tests/aes_gcm/iv13 | Bin 0 -> 12 bytes
nss/cmd/bltest/tests/aes_gcm/iv14 | 1 +
nss/cmd/bltest/tests/aes_gcm/iv15 | 1 +
nss/cmd/bltest/tests/aes_gcm/iv16 | 1 +
nss/cmd/bltest/tests/aes_gcm/iv17 | 1 +
nss/cmd/bltest/tests/aes_gcm/iv2 | 1 +
nss/cmd/bltest/tests/aes_gcm/iv3 | 1 +
nss/cmd/bltest/tests/aes_gcm/iv4 | 1 +
nss/cmd/bltest/tests/aes_gcm/iv5 | 1 +
nss/cmd/bltest/tests/aes_gcm/iv6 | Bin 0 -> 12 bytes
nss/cmd/bltest/tests/aes_gcm/iv7 | Bin 0 -> 12 bytes
nss/cmd/bltest/tests/aes_gcm/iv8 | 1 +
nss/cmd/bltest/tests/aes_gcm/iv9 | 1 +
nss/cmd/bltest/tests/aes_gcm/key0 | Bin 0 -> 16 bytes
nss/cmd/bltest/tests/aes_gcm/key1 | Bin 0 -> 16 bytes
nss/cmd/bltest/tests/aes_gcm/key10 | 1 +
nss/cmd/bltest/tests/aes_gcm/key11 | 1 +
nss/cmd/bltest/tests/aes_gcm/key12 | Bin 0 -> 32 bytes
nss/cmd/bltest/tests/aes_gcm/key13 | Bin 0 -> 32 bytes
nss/cmd/bltest/tests/aes_gcm/key14 | 1 +
nss/cmd/bltest/tests/aes_gcm/key15 | 1 +
nss/cmd/bltest/tests/aes_gcm/key16 | 1 +
nss/cmd/bltest/tests/aes_gcm/key17 | 1 +
nss/cmd/bltest/tests/aes_gcm/key2 | 1 +
nss/cmd/bltest/tests/aes_gcm/key3 | 1 +
nss/cmd/bltest/tests/aes_gcm/key4 | 1 +
nss/cmd/bltest/tests/aes_gcm/key5 | 1 +
nss/cmd/bltest/tests/aes_gcm/key6 | Bin 0 -> 24 bytes
nss/cmd/bltest/tests/aes_gcm/key7 | Bin 0 -> 24 bytes
nss/cmd/bltest/tests/aes_gcm/key8 | 1 +
nss/cmd/bltest/tests/aes_gcm/key9 | 1 +
nss/cmd/bltest/tests/aes_gcm/mktst.sh | 13 +
nss/cmd/bltest/tests/aes_gcm/numtests | 1 +
nss/cmd/bltest/tests/aes_gcm/plaintext0 | 0
nss/cmd/bltest/tests/aes_gcm/plaintext1 | Bin 0 -> 16 bytes
nss/cmd/bltest/tests/aes_gcm/plaintext10 | 1 +
nss/cmd/bltest/tests/aes_gcm/plaintext11 | 1 +
nss/cmd/bltest/tests/aes_gcm/plaintext12 | 0
nss/cmd/bltest/tests/aes_gcm/plaintext13 | Bin 0 -> 16 bytes
nss/cmd/bltest/tests/aes_gcm/plaintext14 | 1 +
nss/cmd/bltest/tests/aes_gcm/plaintext15 | 1 +
nss/cmd/bltest/tests/aes_gcm/plaintext16 | 1 +
nss/cmd/bltest/tests/aes_gcm/plaintext17 | 1 +
nss/cmd/bltest/tests/aes_gcm/plaintext2 | 1 +
nss/cmd/bltest/tests/aes_gcm/plaintext3 | 1 +
nss/cmd/bltest/tests/aes_gcm/plaintext4 | 1 +
nss/cmd/bltest/tests/aes_gcm/plaintext5 | 1 +
nss/cmd/bltest/tests/aes_gcm/plaintext6 | 0
nss/cmd/bltest/tests/aes_gcm/plaintext7 | Bin 0 -> 16 bytes
nss/cmd/bltest/tests/aes_gcm/plaintext8 | 1 +
nss/cmd/bltest/tests/aes_gcm/plaintext9 | 1 +
nss/cmd/bltest/tests/aes_gcm/test0.txt | 11 +
nss/cmd/bltest/tests/aes_gcm/test1.txt | 14 +
nss/cmd/bltest/tests/aes_gcm/test10.txt | 28 +
nss/cmd/bltest/tests/aes_gcm/test11.txt | 31 +
nss/cmd/bltest/tests/aes_gcm/test12.txt | 11 +
nss/cmd/bltest/tests/aes_gcm/test13.txt | 14 +
nss/cmd/bltest/tests/aes_gcm/test14.txt | 23 +
nss/cmd/bltest/tests/aes_gcm/test15.txt | 26 +
nss/cmd/bltest/tests/aes_gcm/test16.txt | 28 +
nss/cmd/bltest/tests/aes_gcm/test17.txt | 31 +
nss/cmd/bltest/tests/aes_gcm/test2.txt | 23 +
nss/cmd/bltest/tests/aes_gcm/test3.txt | 26 +
nss/cmd/bltest/tests/aes_gcm/test4.txt | 28 +
nss/cmd/bltest/tests/aes_gcm/test5.txt | 31 +
nss/cmd/bltest/tests/aes_gcm/test6.txt | 11 +
nss/cmd/bltest/tests/aes_gcm/test7.txt | 14 +
nss/cmd/bltest/tests/aes_gcm/test8.txt | 23 +
nss/cmd/bltest/tests/aes_gcm/test9.txt | 26 +
nss/cmd/bltest/tests/aes_gcm/test_source.txt | 439 +
nss/cmd/bltest/tests/camellia_cbc/ciphertext0 | 1 +
nss/cmd/bltest/tests/camellia_cbc/ciphertext1 | 1 +
nss/cmd/bltest/tests/camellia_cbc/ciphertext2 | 1 +
nss/cmd/bltest/tests/camellia_cbc/iv0 | 1 +
nss/cmd/bltest/tests/camellia_cbc/key0 | 1 +
nss/cmd/bltest/tests/camellia_cbc/key1 | 1 +
nss/cmd/bltest/tests/camellia_cbc/key2 | 1 +
nss/cmd/bltest/tests/camellia_cbc/numtests | 1 +
nss/cmd/bltest/tests/camellia_cbc/plaintext0 | 1 +
nss/cmd/bltest/tests/camellia_ecb/ciphertext0 | 1 +
nss/cmd/bltest/tests/camellia_ecb/ciphertext1 | 1 +
nss/cmd/bltest/tests/camellia_ecb/ciphertext2 | 1 +
nss/cmd/bltest/tests/camellia_ecb/key0 | 1 +
nss/cmd/bltest/tests/camellia_ecb/key1 | 1 +
nss/cmd/bltest/tests/camellia_ecb/key2 | 1 +
nss/cmd/bltest/tests/camellia_ecb/numtests | 1 +
nss/cmd/bltest/tests/camellia_ecb/plaintext0 | 1 +
nss/cmd/bltest/tests/chacha20_poly1305/aad0 | 1 +
nss/cmd/bltest/tests/chacha20_poly1305/aad1 | Bin 0 -> 12 bytes
.../tests/chacha20_poly1305/ciphertext0 | 1 +
.../tests/chacha20_poly1305/ciphertext1 | 1 +
nss/cmd/bltest/tests/chacha20_poly1305/iv0 | Bin 0 -> 12 bytes
nss/cmd/bltest/tests/chacha20_poly1305/iv1 | Bin 0 -> 12 bytes
nss/cmd/bltest/tests/chacha20_poly1305/key0 | 1 +
nss/cmd/bltest/tests/chacha20_poly1305/key1 | 1 +
.../bltest/tests/chacha20_poly1305/numtests | 1 +
.../bltest/tests/chacha20_poly1305/plaintext0 | 1 +
.../bltest/tests/chacha20_poly1305/plaintext1 | 1 +
nss/cmd/bltest/tests/des3_cbc/ciphertext0 | 1 +
nss/cmd/bltest/tests/des3_cbc/iv0 | 1 +
nss/cmd/bltest/tests/des3_cbc/key0 | 1 +
nss/cmd/bltest/tests/des3_cbc/numtests | 1 +
nss/cmd/bltest/tests/des3_cbc/plaintext0 | 1 +
nss/cmd/bltest/tests/des3_ecb/ciphertext0 | 1 +
nss/cmd/bltest/tests/des3_ecb/key0 | 1 +
nss/cmd/bltest/tests/des3_ecb/numtests | 1 +
nss/cmd/bltest/tests/des3_ecb/plaintext0 | 1 +
nss/cmd/bltest/tests/des_cbc/ciphertext0 | 1 +
nss/cmd/bltest/tests/des_cbc/iv0 | 1 +
nss/cmd/bltest/tests/des_cbc/key0 | 1 +
nss/cmd/bltest/tests/des_cbc/numtests | 1 +
nss/cmd/bltest/tests/des_cbc/plaintext0 | 1 +
nss/cmd/bltest/tests/des_ecb/ciphertext0 | 1 +
nss/cmd/bltest/tests/des_ecb/key0 | 1 +
nss/cmd/bltest/tests/des_ecb/numtests | 1 +
nss/cmd/bltest/tests/des_ecb/plaintext0 | 1 +
nss/cmd/bltest/tests/dsa/ciphertext0 | 1 +
nss/cmd/bltest/tests/dsa/ciphertext1 | 1 +
nss/cmd/bltest/tests/dsa/ciphertext10 | 2 +
nss/cmd/bltest/tests/dsa/ciphertext11 | 2 +
nss/cmd/bltest/tests/dsa/ciphertext12 | 2 +
nss/cmd/bltest/tests/dsa/ciphertext13 | 2 +
nss/cmd/bltest/tests/dsa/ciphertext14 | 2 +
nss/cmd/bltest/tests/dsa/ciphertext15 | 2 +
nss/cmd/bltest/tests/dsa/ciphertext16 | 2 +
nss/cmd/bltest/tests/dsa/ciphertext17 | 2 +
nss/cmd/bltest/tests/dsa/ciphertext18 | 2 +
nss/cmd/bltest/tests/dsa/ciphertext19 | 2 +
nss/cmd/bltest/tests/dsa/ciphertext2 | 1 +
nss/cmd/bltest/tests/dsa/ciphertext20 | 2 +
nss/cmd/bltest/tests/dsa/ciphertext3 | 1 +
nss/cmd/bltest/tests/dsa/ciphertext4 | 1 +
nss/cmd/bltest/tests/dsa/ciphertext5 | 1 +
nss/cmd/bltest/tests/dsa/ciphertext6 | 2 +
nss/cmd/bltest/tests/dsa/ciphertext7 | 2 +
nss/cmd/bltest/tests/dsa/ciphertext8 | 2 +
nss/cmd/bltest/tests/dsa/ciphertext9 | 2 +
nss/cmd/bltest/tests/dsa/dsa_fips.txt | 248 +
nss/cmd/bltest/tests/dsa/key0 | 6 +
nss/cmd/bltest/tests/dsa/key1 | 10 +
nss/cmd/bltest/tests/dsa/key10 | 18 +
nss/cmd/bltest/tests/dsa/key11 | 18 +
nss/cmd/bltest/tests/dsa/key12 | 18 +
nss/cmd/bltest/tests/dsa/key13 | 18 +
nss/cmd/bltest/tests/dsa/key14 | 18 +
nss/cmd/bltest/tests/dsa/key15 | 18 +
nss/cmd/bltest/tests/dsa/key16 | 26 +
nss/cmd/bltest/tests/dsa/key17 | 26 +
nss/cmd/bltest/tests/dsa/key18 | 26 +
nss/cmd/bltest/tests/dsa/key19 | 26 +
nss/cmd/bltest/tests/dsa/key2 | 10 +
nss/cmd/bltest/tests/dsa/key20 | 26 +
nss/cmd/bltest/tests/dsa/key3 | 10 +
nss/cmd/bltest/tests/dsa/key4 | 10 +
nss/cmd/bltest/tests/dsa/key5 | 10 +
nss/cmd/bltest/tests/dsa/key6 | 18 +
nss/cmd/bltest/tests/dsa/key7 | 18 +
nss/cmd/bltest/tests/dsa/key8 | 18 +
nss/cmd/bltest/tests/dsa/key9 | 18 +
nss/cmd/bltest/tests/dsa/keyseed0 | 1 +
nss/cmd/bltest/tests/dsa/keyseed1 | 1 +
nss/cmd/bltest/tests/dsa/keyseed10 | 1 +
nss/cmd/bltest/tests/dsa/keyseed11 | 1 +
nss/cmd/bltest/tests/dsa/keyseed12 | 1 +
nss/cmd/bltest/tests/dsa/keyseed13 | 1 +
nss/cmd/bltest/tests/dsa/keyseed14 | 1 +
nss/cmd/bltest/tests/dsa/keyseed15 | 1 +
nss/cmd/bltest/tests/dsa/keyseed16 | 1 +
nss/cmd/bltest/tests/dsa/keyseed17 | 1 +
nss/cmd/bltest/tests/dsa/keyseed18 | 1 +
nss/cmd/bltest/tests/dsa/keyseed19 | 1 +
nss/cmd/bltest/tests/dsa/keyseed2 | 1 +
nss/cmd/bltest/tests/dsa/keyseed20 | 1 +
nss/cmd/bltest/tests/dsa/keyseed3 | 1 +
nss/cmd/bltest/tests/dsa/keyseed4 | 1 +
nss/cmd/bltest/tests/dsa/keyseed5 | 1 +
nss/cmd/bltest/tests/dsa/keyseed6 | 1 +
nss/cmd/bltest/tests/dsa/keyseed7 | 1 +
nss/cmd/bltest/tests/dsa/keyseed8 | 1 +
nss/cmd/bltest/tests/dsa/keyseed9 | 1 +
nss/cmd/bltest/tests/dsa/numtests | 1 +
nss/cmd/bltest/tests/dsa/plaintext0 | 1 +
nss/cmd/bltest/tests/dsa/plaintext1 | 1 +
nss/cmd/bltest/tests/dsa/plaintext10 | 2 +
nss/cmd/bltest/tests/dsa/plaintext11 | 1 +
nss/cmd/bltest/tests/dsa/plaintext12 | 1 +
nss/cmd/bltest/tests/dsa/plaintext13 | 1 +
nss/cmd/bltest/tests/dsa/plaintext14 | 1 +
nss/cmd/bltest/tests/dsa/plaintext15 | 2 +
nss/cmd/bltest/tests/dsa/plaintext16 | 1 +
nss/cmd/bltest/tests/dsa/plaintext17 | 1 +
nss/cmd/bltest/tests/dsa/plaintext18 | 1 +
nss/cmd/bltest/tests/dsa/plaintext19 | 1 +
nss/cmd/bltest/tests/dsa/plaintext2 | 1 +
nss/cmd/bltest/tests/dsa/plaintext20 | 2 +
nss/cmd/bltest/tests/dsa/plaintext3 | 1 +
nss/cmd/bltest/tests/dsa/plaintext4 | 1 +
nss/cmd/bltest/tests/dsa/plaintext5 | 2 +
nss/cmd/bltest/tests/dsa/plaintext6 | 1 +
nss/cmd/bltest/tests/dsa/plaintext7 | 1 +
nss/cmd/bltest/tests/dsa/plaintext8 | 1 +
nss/cmd/bltest/tests/dsa/plaintext9 | 1 +
nss/cmd/bltest/tests/dsa/pqg0 | 4 +
nss/cmd/bltest/tests/dsa/pqg1 | 6 +
nss/cmd/bltest/tests/dsa/pqg10 | 12 +
nss/cmd/bltest/tests/dsa/pqg11 | 12 +
nss/cmd/bltest/tests/dsa/pqg12 | 12 +
nss/cmd/bltest/tests/dsa/pqg13 | 12 +
nss/cmd/bltest/tests/dsa/pqg14 | 12 +
nss/cmd/bltest/tests/dsa/pqg15 | 12 +
nss/cmd/bltest/tests/dsa/pqg16 | 17 +
nss/cmd/bltest/tests/dsa/pqg17 | 17 +
nss/cmd/bltest/tests/dsa/pqg18 | 17 +
nss/cmd/bltest/tests/dsa/pqg19 | 17 +
nss/cmd/bltest/tests/dsa/pqg2 | 6 +
nss/cmd/bltest/tests/dsa/pqg20 | 17 +
nss/cmd/bltest/tests/dsa/pqg3 | 6 +
nss/cmd/bltest/tests/dsa/pqg4 | 6 +
nss/cmd/bltest/tests/dsa/pqg5 | 6 +
nss/cmd/bltest/tests/dsa/pqg6 | 12 +
nss/cmd/bltest/tests/dsa/pqg7 | 12 +
nss/cmd/bltest/tests/dsa/pqg8 | 12 +
nss/cmd/bltest/tests/dsa/pqg9 | 12 +
nss/cmd/bltest/tests/dsa/sigseed0 | 1 +
nss/cmd/bltest/tests/dsa/sigseed1 | 1 +
nss/cmd/bltest/tests/dsa/sigseed10 | 1 +
nss/cmd/bltest/tests/dsa/sigseed11 | 1 +
nss/cmd/bltest/tests/dsa/sigseed12 | 1 +
nss/cmd/bltest/tests/dsa/sigseed13 | 1 +
nss/cmd/bltest/tests/dsa/sigseed14 | 1 +
nss/cmd/bltest/tests/dsa/sigseed15 | 1 +
nss/cmd/bltest/tests/dsa/sigseed16 | 1 +
nss/cmd/bltest/tests/dsa/sigseed17 | 1 +
nss/cmd/bltest/tests/dsa/sigseed18 | 1 +
nss/cmd/bltest/tests/dsa/sigseed19 | 1 +
nss/cmd/bltest/tests/dsa/sigseed2 | 1 +
nss/cmd/bltest/tests/dsa/sigseed20 | 1 +
nss/cmd/bltest/tests/dsa/sigseed3 | 1 +
nss/cmd/bltest/tests/dsa/sigseed4 | 1 +
nss/cmd/bltest/tests/dsa/sigseed5 | 1 +
nss/cmd/bltest/tests/dsa/sigseed6 | 1 +
nss/cmd/bltest/tests/dsa/sigseed7 | 1 +
nss/cmd/bltest/tests/dsa/sigseed8 | 1 +
nss/cmd/bltest/tests/dsa/sigseed9 | 1 +
nss/cmd/bltest/tests/ecdsa/README | 4 +
nss/cmd/bltest/tests/ecdsa/ciphertext0 | 1 +
nss/cmd/bltest/tests/ecdsa/ciphertext1 | 1 +
nss/cmd/bltest/tests/ecdsa/ciphertext10 | 2 +
nss/cmd/bltest/tests/ecdsa/ciphertext11 | 2 +
nss/cmd/bltest/tests/ecdsa/ciphertext12 | 2 +
nss/cmd/bltest/tests/ecdsa/ciphertext13 | 2 +
nss/cmd/bltest/tests/ecdsa/ciphertext14 | 2 +
nss/cmd/bltest/tests/ecdsa/ciphertext15 | 2 +
nss/cmd/bltest/tests/ecdsa/ciphertext16 | 3 +
nss/cmd/bltest/tests/ecdsa/ciphertext17 | 3 +
nss/cmd/bltest/tests/ecdsa/ciphertext18 | 3 +
nss/cmd/bltest/tests/ecdsa/ciphertext19 | 3 +
nss/cmd/bltest/tests/ecdsa/ciphertext2 | 1 +
nss/cmd/bltest/tests/ecdsa/ciphertext20 | 3 +
nss/cmd/bltest/tests/ecdsa/ciphertext3 | 1 +
nss/cmd/bltest/tests/ecdsa/ciphertext4 | 1 +
nss/cmd/bltest/tests/ecdsa/ciphertext5 | 1 +
nss/cmd/bltest/tests/ecdsa/ciphertext6 | 1 +
nss/cmd/bltest/tests/ecdsa/ciphertext7 | 1 +
nss/cmd/bltest/tests/ecdsa/ciphertext8 | 2 +
nss/cmd/bltest/tests/ecdsa/ciphertext9 | 2 +
nss/cmd/bltest/tests/ecdsa/key0 | 3 +
nss/cmd/bltest/tests/ecdsa/key1 | 4 +
nss/cmd/bltest/tests/ecdsa/key10 | 3 +
nss/cmd/bltest/tests/ecdsa/key11 | 3 +
nss/cmd/bltest/tests/ecdsa/key12 | 3 +
nss/cmd/bltest/tests/ecdsa/key13 | 3 +
nss/cmd/bltest/tests/ecdsa/key14 | 3 +
nss/cmd/bltest/tests/ecdsa/key15 | 4 +
nss/cmd/bltest/tests/ecdsa/key16 | 4 +
nss/cmd/bltest/tests/ecdsa/key17 | 4 +
nss/cmd/bltest/tests/ecdsa/key18 | 5 +
nss/cmd/bltest/tests/ecdsa/key19 | 5 +
nss/cmd/bltest/tests/ecdsa/key2 | 5 +
nss/cmd/bltest/tests/ecdsa/key20 | 5 +
nss/cmd/bltest/tests/ecdsa/key3 | 2 +
nss/cmd/bltest/tests/ecdsa/key4 | 2 +
nss/cmd/bltest/tests/ecdsa/key5 | 2 +
nss/cmd/bltest/tests/ecdsa/key6 | 2 +
nss/cmd/bltest/tests/ecdsa/key7 | 2 +
nss/cmd/bltest/tests/ecdsa/key8 | 3 +
nss/cmd/bltest/tests/ecdsa/key9 | 3 +
nss/cmd/bltest/tests/ecdsa/numtests | 1 +
nss/cmd/bltest/tests/ecdsa/plaintext0 | 1 +
nss/cmd/bltest/tests/ecdsa/plaintext1 | 1 +
nss/cmd/bltest/tests/ecdsa/plaintext10 | 1 +
nss/cmd/bltest/tests/ecdsa/plaintext11 | 1 +
nss/cmd/bltest/tests/ecdsa/plaintext12 | 1 +
nss/cmd/bltest/tests/ecdsa/plaintext13 | 1 +
nss/cmd/bltest/tests/ecdsa/plaintext14 | 1 +
nss/cmd/bltest/tests/ecdsa/plaintext15 | 1 +
nss/cmd/bltest/tests/ecdsa/plaintext16 | 1 +
nss/cmd/bltest/tests/ecdsa/plaintext17 | 1 +
nss/cmd/bltest/tests/ecdsa/plaintext18 | 1 +
nss/cmd/bltest/tests/ecdsa/plaintext19 | 1 +
nss/cmd/bltest/tests/ecdsa/plaintext2 | 1 +
nss/cmd/bltest/tests/ecdsa/plaintext20 | 1 +
nss/cmd/bltest/tests/ecdsa/plaintext3 | 1 +
nss/cmd/bltest/tests/ecdsa/plaintext4 | 1 +
nss/cmd/bltest/tests/ecdsa/plaintext5 | 1 +
nss/cmd/bltest/tests/ecdsa/plaintext6 | 1 +
nss/cmd/bltest/tests/ecdsa/plaintext7 | 1 +
nss/cmd/bltest/tests/ecdsa/plaintext8 | 1 +
nss/cmd/bltest/tests/ecdsa/plaintext9 | 1 +
nss/cmd/bltest/tests/ecdsa/sigseed0 | 1 +
nss/cmd/bltest/tests/ecdsa/sigseed1 | 1 +
nss/cmd/bltest/tests/ecdsa/sigseed10 | 1 +
nss/cmd/bltest/tests/ecdsa/sigseed11 | 1 +
nss/cmd/bltest/tests/ecdsa/sigseed12 | 1 +
nss/cmd/bltest/tests/ecdsa/sigseed13 | 1 +
nss/cmd/bltest/tests/ecdsa/sigseed14 | 1 +
nss/cmd/bltest/tests/ecdsa/sigseed15 | 1 +
nss/cmd/bltest/tests/ecdsa/sigseed16 | 1 +
nss/cmd/bltest/tests/ecdsa/sigseed17 | 1 +
nss/cmd/bltest/tests/ecdsa/sigseed18 | 2 +
nss/cmd/bltest/tests/ecdsa/sigseed19 | 2 +
nss/cmd/bltest/tests/ecdsa/sigseed2 | 1 +
nss/cmd/bltest/tests/ecdsa/sigseed20 | 2 +
nss/cmd/bltest/tests/ecdsa/sigseed3 | 1 +
nss/cmd/bltest/tests/ecdsa/sigseed4 | 1 +
nss/cmd/bltest/tests/ecdsa/sigseed5 | 1 +
nss/cmd/bltest/tests/ecdsa/sigseed6 | 1 +
nss/cmd/bltest/tests/ecdsa/sigseed7 | 1 +
nss/cmd/bltest/tests/ecdsa/sigseed8 | 1 +
nss/cmd/bltest/tests/ecdsa/sigseed9 | 1 +
nss/cmd/bltest/tests/md2/ciphertext0 | 1 +
nss/cmd/bltest/tests/md2/numtests | 1 +
nss/cmd/bltest/tests/md2/plaintext0 | 1 +
nss/cmd/bltest/tests/md5/ciphertext0 | 1 +
nss/cmd/bltest/tests/md5/numtests | 1 +
nss/cmd/bltest/tests/md5/plaintext0 | 1 +
nss/cmd/bltest/tests/rc2_cbc/ciphertext0 | 1 +
nss/cmd/bltest/tests/rc2_cbc/iv0 | 1 +
nss/cmd/bltest/tests/rc2_cbc/key0 | 1 +
nss/cmd/bltest/tests/rc2_cbc/numtests | 1 +
nss/cmd/bltest/tests/rc2_cbc/plaintext0 | 1 +
nss/cmd/bltest/tests/rc2_ecb/ciphertext0 | 1 +
nss/cmd/bltest/tests/rc2_ecb/key0 | 1 +
nss/cmd/bltest/tests/rc2_ecb/numtests | 1 +
nss/cmd/bltest/tests/rc2_ecb/plaintext0 | 1 +
nss/cmd/bltest/tests/rc4/ciphertext0 | 1 +
nss/cmd/bltest/tests/rc4/ciphertext1 | 1 +
nss/cmd/bltest/tests/rc4/key0 | 1 +
nss/cmd/bltest/tests/rc4/key1 | 1 +
nss/cmd/bltest/tests/rc4/numtests | 1 +
nss/cmd/bltest/tests/rc4/plaintext0 | 1 +
nss/cmd/bltest/tests/rc4/plaintext1 | 1 +
nss/cmd/bltest/tests/rc5_cbc/ciphertext0 | 1 +
nss/cmd/bltest/tests/rc5_cbc/iv0 | 1 +
nss/cmd/bltest/tests/rc5_cbc/key0 | 1 +
nss/cmd/bltest/tests/rc5_cbc/numtests | 1 +
nss/cmd/bltest/tests/rc5_cbc/params0 | 2 +
nss/cmd/bltest/tests/rc5_cbc/plaintext0 | 1 +
nss/cmd/bltest/tests/rc5_ecb/ciphertext0 | 1 +
nss/cmd/bltest/tests/rc5_ecb/key0 | 1 +
nss/cmd/bltest/tests/rc5_ecb/numtests | 1 +
nss/cmd/bltest/tests/rc5_ecb/params0 | 2 +
nss/cmd/bltest/tests/rc5_ecb/plaintext0 | 1 +
nss/cmd/bltest/tests/rsa/ciphertext0 | 1 +
nss/cmd/bltest/tests/rsa/key0 | 4 +
nss/cmd/bltest/tests/rsa/numtests | 1 +
nss/cmd/bltest/tests/rsa/plaintext0 | 1 +
nss/cmd/bltest/tests/rsa_oaep/ciphertext0 | 3 +
nss/cmd/bltest/tests/rsa_oaep/ciphertext1 | 3 +
nss/cmd/bltest/tests/rsa_oaep/ciphertext10 | 4 +
nss/cmd/bltest/tests/rsa_oaep/ciphertext11 | 4 +
nss/cmd/bltest/tests/rsa_oaep/ciphertext12 | 5 +
nss/cmd/bltest/tests/rsa_oaep/ciphertext13 | 5 +
nss/cmd/bltest/tests/rsa_oaep/ciphertext14 | 5 +
nss/cmd/bltest/tests/rsa_oaep/ciphertext15 | 5 +
nss/cmd/bltest/tests/rsa_oaep/ciphertext16 | 5 +
nss/cmd/bltest/tests/rsa_oaep/ciphertext17 | 5 +
nss/cmd/bltest/tests/rsa_oaep/ciphertext2 | 3 +
nss/cmd/bltest/tests/rsa_oaep/ciphertext3 | 3 +
nss/cmd/bltest/tests/rsa_oaep/ciphertext4 | 3 +
nss/cmd/bltest/tests/rsa_oaep/ciphertext5 | 3 +
nss/cmd/bltest/tests/rsa_oaep/ciphertext6 | 4 +
nss/cmd/bltest/tests/rsa_oaep/ciphertext7 | 4 +
nss/cmd/bltest/tests/rsa_oaep/ciphertext8 | 4 +
nss/cmd/bltest/tests/rsa_oaep/ciphertext9 | 4 +
nss/cmd/bltest/tests/rsa_oaep/hash0 | 1 +
nss/cmd/bltest/tests/rsa_oaep/hash1 | 1 +
nss/cmd/bltest/tests/rsa_oaep/hash10 | 1 +
nss/cmd/bltest/tests/rsa_oaep/hash11 | 1 +
nss/cmd/bltest/tests/rsa_oaep/hash12 | 1 +
nss/cmd/bltest/tests/rsa_oaep/hash13 | 1 +
nss/cmd/bltest/tests/rsa_oaep/hash14 | 1 +
nss/cmd/bltest/tests/rsa_oaep/hash15 | 1 +
nss/cmd/bltest/tests/rsa_oaep/hash16 | 1 +
nss/cmd/bltest/tests/rsa_oaep/hash17 | 1 +
nss/cmd/bltest/tests/rsa_oaep/hash2 | 1 +
nss/cmd/bltest/tests/rsa_oaep/hash3 | 1 +
nss/cmd/bltest/tests/rsa_oaep/hash4 | 1 +
nss/cmd/bltest/tests/rsa_oaep/hash5 | 1 +
nss/cmd/bltest/tests/rsa_oaep/hash6 | 1 +
nss/cmd/bltest/tests/rsa_oaep/hash7 | 1 +
nss/cmd/bltest/tests/rsa_oaep/hash8 | 1 +
nss/cmd/bltest/tests/rsa_oaep/hash9 | 1 +
nss/cmd/bltest/tests/rsa_oaep/key0 | 1 +
nss/cmd/bltest/tests/rsa_oaep/key1 | 1 +
nss/cmd/bltest/tests/rsa_oaep/key10 | 1 +
nss/cmd/bltest/tests/rsa_oaep/key11 | 1 +
nss/cmd/bltest/tests/rsa_oaep/key12 | 1 +
nss/cmd/bltest/tests/rsa_oaep/key13 | 1 +
nss/cmd/bltest/tests/rsa_oaep/key14 | 1 +
nss/cmd/bltest/tests/rsa_oaep/key15 | 1 +
nss/cmd/bltest/tests/rsa_oaep/key16 | 1 +
nss/cmd/bltest/tests/rsa_oaep/key17 | 1 +
nss/cmd/bltest/tests/rsa_oaep/key2 | 1 +
nss/cmd/bltest/tests/rsa_oaep/key3 | 1 +
nss/cmd/bltest/tests/rsa_oaep/key4 | 1 +
nss/cmd/bltest/tests/rsa_oaep/key5 | 1 +
nss/cmd/bltest/tests/rsa_oaep/key6 | 1 +
nss/cmd/bltest/tests/rsa_oaep/key7 | 1 +
nss/cmd/bltest/tests/rsa_oaep/key8 | 1 +
nss/cmd/bltest/tests/rsa_oaep/key9 | 1 +
nss/cmd/bltest/tests/rsa_oaep/maskhash0 | 1 +
nss/cmd/bltest/tests/rsa_oaep/maskhash1 | 1 +
nss/cmd/bltest/tests/rsa_oaep/maskhash10 | 1 +
nss/cmd/bltest/tests/rsa_oaep/maskhash11 | 1 +
nss/cmd/bltest/tests/rsa_oaep/maskhash12 | 1 +
nss/cmd/bltest/tests/rsa_oaep/maskhash13 | 1 +
nss/cmd/bltest/tests/rsa_oaep/maskhash14 | 1 +
nss/cmd/bltest/tests/rsa_oaep/maskhash15 | 1 +
nss/cmd/bltest/tests/rsa_oaep/maskhash16 | 1 +
nss/cmd/bltest/tests/rsa_oaep/maskhash17 | 1 +
nss/cmd/bltest/tests/rsa_oaep/maskhash2 | 1 +
nss/cmd/bltest/tests/rsa_oaep/maskhash3 | 1 +
nss/cmd/bltest/tests/rsa_oaep/maskhash4 | 1 +
nss/cmd/bltest/tests/rsa_oaep/maskhash5 | 1 +
nss/cmd/bltest/tests/rsa_oaep/maskhash6 | 1 +
nss/cmd/bltest/tests/rsa_oaep/maskhash7 | 1 +
nss/cmd/bltest/tests/rsa_oaep/maskhash8 | 1 +
nss/cmd/bltest/tests/rsa_oaep/maskhash9 | 1 +
nss/cmd/bltest/tests/rsa_oaep/numtests | 1 +
nss/cmd/bltest/tests/rsa_oaep/plaintext0 | Bin 0 -> 28 bytes
nss/cmd/bltest/tests/rsa_oaep/plaintext1 | 1 +
nss/cmd/bltest/tests/rsa_oaep/plaintext10 | 1 +
nss/cmd/bltest/tests/rsa_oaep/plaintext11 | 1 +
nss/cmd/bltest/tests/rsa_oaep/plaintext12 | 1 +
nss/cmd/bltest/tests/rsa_oaep/plaintext13 | 1 +
nss/cmd/bltest/tests/rsa_oaep/plaintext14 | 2 +
nss/cmd/bltest/tests/rsa_oaep/plaintext15 | Bin 0 -> 36 bytes
nss/cmd/bltest/tests/rsa_oaep/plaintext16 | 1 +
nss/cmd/bltest/tests/rsa_oaep/plaintext17 | 1 +
nss/cmd/bltest/tests/rsa_oaep/plaintext2 | 1 +
nss/cmd/bltest/tests/rsa_oaep/plaintext3 | 1 +
nss/cmd/bltest/tests/rsa_oaep/plaintext4 | 1 +
nss/cmd/bltest/tests/rsa_oaep/plaintext5 | 1 +
nss/cmd/bltest/tests/rsa_oaep/plaintext6 | 1 +
nss/cmd/bltest/tests/rsa_oaep/plaintext7 | 1 +
nss/cmd/bltest/tests/rsa_oaep/plaintext8 | 1 +
nss/cmd/bltest/tests/rsa_oaep/plaintext9 | 3 +
nss/cmd/bltest/tests/rsa_oaep/seed0 | 1 +
nss/cmd/bltest/tests/rsa_oaep/seed1 | 1 +
nss/cmd/bltest/tests/rsa_oaep/seed10 | 1 +
nss/cmd/bltest/tests/rsa_oaep/seed11 | 1 +
nss/cmd/bltest/tests/rsa_oaep/seed12 | 1 +
nss/cmd/bltest/tests/rsa_oaep/seed13 | 1 +
nss/cmd/bltest/tests/rsa_oaep/seed14 | 1 +
nss/cmd/bltest/tests/rsa_oaep/seed15 | 1 +
nss/cmd/bltest/tests/rsa_oaep/seed16 | 1 +
nss/cmd/bltest/tests/rsa_oaep/seed17 | 1 +
nss/cmd/bltest/tests/rsa_oaep/seed2 | 1 +
nss/cmd/bltest/tests/rsa_oaep/seed3 | 1 +
nss/cmd/bltest/tests/rsa_oaep/seed4 | 1 +
nss/cmd/bltest/tests/rsa_oaep/seed5 | 1 +
nss/cmd/bltest/tests/rsa_oaep/seed6 | 1 +
nss/cmd/bltest/tests/rsa_oaep/seed7 | 1 +
nss/cmd/bltest/tests/rsa_oaep/seed8 | 1 +
nss/cmd/bltest/tests/rsa_oaep/seed9 | 1 +
nss/cmd/bltest/tests/rsa_pss/ciphertext0 | 3 +
nss/cmd/bltest/tests/rsa_pss/ciphertext1 | 3 +
nss/cmd/bltest/tests/rsa_pss/ciphertext10 | 4 +
nss/cmd/bltest/tests/rsa_pss/ciphertext11 | 4 +
nss/cmd/bltest/tests/rsa_pss/ciphertext12 | 5 +
nss/cmd/bltest/tests/rsa_pss/ciphertext13 | 5 +
nss/cmd/bltest/tests/rsa_pss/ciphertext14 | 5 +
nss/cmd/bltest/tests/rsa_pss/ciphertext15 | 5 +
nss/cmd/bltest/tests/rsa_pss/ciphertext16 | 5 +
nss/cmd/bltest/tests/rsa_pss/ciphertext17 | 5 +
nss/cmd/bltest/tests/rsa_pss/ciphertext2 | 3 +
nss/cmd/bltest/tests/rsa_pss/ciphertext3 | 3 +
nss/cmd/bltest/tests/rsa_pss/ciphertext4 | 3 +
nss/cmd/bltest/tests/rsa_pss/ciphertext5 | 3 +
nss/cmd/bltest/tests/rsa_pss/ciphertext6 | 4 +
nss/cmd/bltest/tests/rsa_pss/ciphertext7 | 4 +
nss/cmd/bltest/tests/rsa_pss/ciphertext8 | 4 +
nss/cmd/bltest/tests/rsa_pss/ciphertext9 | 4 +
nss/cmd/bltest/tests/rsa_pss/hash0 | 1 +
nss/cmd/bltest/tests/rsa_pss/hash1 | 1 +
nss/cmd/bltest/tests/rsa_pss/hash10 | 1 +
nss/cmd/bltest/tests/rsa_pss/hash11 | 1 +
nss/cmd/bltest/tests/rsa_pss/hash12 | 1 +
nss/cmd/bltest/tests/rsa_pss/hash13 | 1 +
nss/cmd/bltest/tests/rsa_pss/hash14 | 1 +
nss/cmd/bltest/tests/rsa_pss/hash15 | 1 +
nss/cmd/bltest/tests/rsa_pss/hash16 | 1 +
nss/cmd/bltest/tests/rsa_pss/hash17 | 1 +
nss/cmd/bltest/tests/rsa_pss/hash2 | 1 +
nss/cmd/bltest/tests/rsa_pss/hash3 | 1 +
nss/cmd/bltest/tests/rsa_pss/hash4 | 1 +
nss/cmd/bltest/tests/rsa_pss/hash5 | 1 +
nss/cmd/bltest/tests/rsa_pss/hash6 | 1 +
nss/cmd/bltest/tests/rsa_pss/hash7 | 1 +
nss/cmd/bltest/tests/rsa_pss/hash8 | 1 +
nss/cmd/bltest/tests/rsa_pss/hash9 | 1 +
nss/cmd/bltest/tests/rsa_pss/key0 | 1 +
nss/cmd/bltest/tests/rsa_pss/key1 | 1 +
nss/cmd/bltest/tests/rsa_pss/key10 | 1 +
nss/cmd/bltest/tests/rsa_pss/key11 | 1 +
nss/cmd/bltest/tests/rsa_pss/key12 | 1 +
nss/cmd/bltest/tests/rsa_pss/key13 | 1 +
nss/cmd/bltest/tests/rsa_pss/key14 | 1 +
nss/cmd/bltest/tests/rsa_pss/key15 | 1 +
nss/cmd/bltest/tests/rsa_pss/key16 | 1 +
nss/cmd/bltest/tests/rsa_pss/key17 | 1 +
nss/cmd/bltest/tests/rsa_pss/key2 | 1 +
nss/cmd/bltest/tests/rsa_pss/key3 | 1 +
nss/cmd/bltest/tests/rsa_pss/key4 | 1 +
nss/cmd/bltest/tests/rsa_pss/key5 | 1 +
nss/cmd/bltest/tests/rsa_pss/key6 | 1 +
nss/cmd/bltest/tests/rsa_pss/key7 | 1 +
nss/cmd/bltest/tests/rsa_pss/key8 | 1 +
nss/cmd/bltest/tests/rsa_pss/key9 | 1 +
nss/cmd/bltest/tests/rsa_pss/maskhash0 | 1 +
nss/cmd/bltest/tests/rsa_pss/maskhash1 | 1 +
nss/cmd/bltest/tests/rsa_pss/maskhash10 | 1 +
nss/cmd/bltest/tests/rsa_pss/maskhash11 | 1 +
nss/cmd/bltest/tests/rsa_pss/maskhash12 | 1 +
nss/cmd/bltest/tests/rsa_pss/maskhash13 | 1 +
nss/cmd/bltest/tests/rsa_pss/maskhash14 | 1 +
nss/cmd/bltest/tests/rsa_pss/maskhash15 | 1 +
nss/cmd/bltest/tests/rsa_pss/maskhash16 | 1 +
nss/cmd/bltest/tests/rsa_pss/maskhash17 | 1 +
nss/cmd/bltest/tests/rsa_pss/maskhash2 | 1 +
nss/cmd/bltest/tests/rsa_pss/maskhash3 | 1 +
nss/cmd/bltest/tests/rsa_pss/maskhash4 | 1 +
nss/cmd/bltest/tests/rsa_pss/maskhash5 | 1 +
nss/cmd/bltest/tests/rsa_pss/maskhash6 | 1 +
nss/cmd/bltest/tests/rsa_pss/maskhash7 | 1 +
nss/cmd/bltest/tests/rsa_pss/maskhash8 | 1 +
nss/cmd/bltest/tests/rsa_pss/maskhash9 | 1 +
nss/cmd/bltest/tests/rsa_pss/numtests | 1 +
nss/cmd/bltest/tests/rsa_pss/plaintext0 | 1 +
nss/cmd/bltest/tests/rsa_pss/plaintext1 | 1 +
nss/cmd/bltest/tests/rsa_pss/plaintext10 | 1 +
nss/cmd/bltest/tests/rsa_pss/plaintext11 | 1 +
nss/cmd/bltest/tests/rsa_pss/plaintext12 | 1 +
nss/cmd/bltest/tests/rsa_pss/plaintext13 | 1 +
nss/cmd/bltest/tests/rsa_pss/plaintext14 | 1 +
nss/cmd/bltest/tests/rsa_pss/plaintext15 | 1 +
nss/cmd/bltest/tests/rsa_pss/plaintext16 | 1 +
nss/cmd/bltest/tests/rsa_pss/plaintext17 | 1 +
nss/cmd/bltest/tests/rsa_pss/plaintext2 | 1 +
nss/cmd/bltest/tests/rsa_pss/plaintext3 | 1 +
nss/cmd/bltest/tests/rsa_pss/plaintext4 | 1 +
nss/cmd/bltest/tests/rsa_pss/plaintext5 | 1 +
nss/cmd/bltest/tests/rsa_pss/plaintext6 | 1 +
nss/cmd/bltest/tests/rsa_pss/plaintext7 | 1 +
nss/cmd/bltest/tests/rsa_pss/plaintext8 | 1 +
nss/cmd/bltest/tests/rsa_pss/plaintext9 | 1 +
nss/cmd/bltest/tests/rsa_pss/seed0 | 1 +
nss/cmd/bltest/tests/rsa_pss/seed1 | 1 +
nss/cmd/bltest/tests/rsa_pss/seed10 | 1 +
nss/cmd/bltest/tests/rsa_pss/seed11 | 1 +
nss/cmd/bltest/tests/rsa_pss/seed12 | 1 +
nss/cmd/bltest/tests/rsa_pss/seed13 | 1 +
nss/cmd/bltest/tests/rsa_pss/seed14 | 1 +
nss/cmd/bltest/tests/rsa_pss/seed15 | 1 +
nss/cmd/bltest/tests/rsa_pss/seed16 | 1 +
nss/cmd/bltest/tests/rsa_pss/seed17 | 1 +
nss/cmd/bltest/tests/rsa_pss/seed2 | 1 +
nss/cmd/bltest/tests/rsa_pss/seed3 | 1 +
nss/cmd/bltest/tests/rsa_pss/seed4 | 1 +
nss/cmd/bltest/tests/rsa_pss/seed5 | 1 +
nss/cmd/bltest/tests/rsa_pss/seed6 | 1 +
nss/cmd/bltest/tests/rsa_pss/seed7 | 1 +
nss/cmd/bltest/tests/rsa_pss/seed8 | 1 +
nss/cmd/bltest/tests/rsa_pss/seed9 | 1 +
nss/cmd/bltest/tests/seed_cbc/ciphertext0 | 1 +
nss/cmd/bltest/tests/seed_cbc/iv0 | 1 +
nss/cmd/bltest/tests/seed_cbc/key0 | 1 +
nss/cmd/bltest/tests/seed_cbc/numtests | 1 +
nss/cmd/bltest/tests/seed_cbc/plaintext0 | 1 +
nss/cmd/bltest/tests/seed_ecb/ciphertext0 | 1 +
nss/cmd/bltest/tests/seed_ecb/iv0 | 1 +
nss/cmd/bltest/tests/seed_ecb/key0 | 1 +
nss/cmd/bltest/tests/seed_ecb/numtests | 1 +
nss/cmd/bltest/tests/seed_ecb/plaintext0 | 1 +
nss/cmd/bltest/tests/sha1/ciphertext0 | 1 +
nss/cmd/bltest/tests/sha1/numtests | 1 +
nss/cmd/bltest/tests/sha1/plaintext0 | 1 +
nss/cmd/bltest/tests/sha224/ciphertext0 | 2 +
nss/cmd/bltest/tests/sha224/ciphertext1 | 2 +
nss/cmd/bltest/tests/sha224/numtests | 1 +
nss/cmd/bltest/tests/sha224/plaintext0 | 1 +
nss/cmd/bltest/tests/sha224/plaintext1 | 1 +
nss/cmd/bltest/tests/sha256/ciphertext0 | 1 +
nss/cmd/bltest/tests/sha256/ciphertext1 | 1 +
nss/cmd/bltest/tests/sha256/numtests | 1 +
nss/cmd/bltest/tests/sha256/plaintext0 | 1 +
nss/cmd/bltest/tests/sha256/plaintext1 | 1 +
nss/cmd/bltest/tests/sha384/ciphertext0 | 1 +
nss/cmd/bltest/tests/sha384/ciphertext1 | 1 +
nss/cmd/bltest/tests/sha384/numtests | 1 +
nss/cmd/bltest/tests/sha384/plaintext0 | 1 +
nss/cmd/bltest/tests/sha384/plaintext1 | 1 +
nss/cmd/bltest/tests/sha512/ciphertext0 | 2 +
nss/cmd/bltest/tests/sha512/ciphertext1 | 2 +
nss/cmd/bltest/tests/sha512/numtests | 1 +
nss/cmd/bltest/tests/sha512/plaintext0 | 1 +
nss/cmd/bltest/tests/sha512/plaintext1 | 1 +
nss/cmd/btoa/Makefile | 47 +
nss/cmd/btoa/btoa.c | 203 +
nss/cmd/btoa/btoa.gyp | 30 +
nss/cmd/btoa/manifest.mn | 21 +
nss/cmd/certcgi/HOWTO.txt | 137 +
nss/cmd/certcgi/Makefile | 48 +
nss/cmd/certcgi/ca.html | 19 +
nss/cmd/certcgi/ca_form.html | 357 +
nss/cmd/certcgi/certcgi.c | 2246 +
nss/cmd/certcgi/certcgi.gyp | 33 +
nss/cmd/certcgi/index.html | 789 +
nss/cmd/certcgi/main.html | 76 +
nss/cmd/certcgi/manifest.mn | 22 +
nss/cmd/certcgi/nscp_ext_form.html | 84 +
nss/cmd/certcgi/stnd_ext_form.html | 219 +
nss/cmd/certutil/Makefile | 48 +
nss/cmd/certutil/certext.c | 2218 +
nss/cmd/certutil/certutil.c | 3707 +
nss/cmd/certutil/certutil.gyp | 32 +
nss/cmd/certutil/certutil.h | 57 +
nss/cmd/certutil/keystuff.c | 609 +
nss/cmd/certutil/manifest.mn | 25 +
nss/cmd/chktest/Makefile | 47 +
nss/cmd/chktest/chktest.c | 45 +
nss/cmd/chktest/chktest.gyp | 32 +
nss/cmd/chktest/manifest.mn | 27 +
nss/cmd/clientProof/.gitignore | 2 +
nss/cmd/clientProof/.project | 27 +
nss/cmd/clientProof/Makefile | 46 +
nss/cmd/clientProof/client_db | 1 +
nss/cmd/clientProof/main.c | 315 +
nss/cmd/clientProof/manifest.mn | 23 +
nss/cmd/crlutil/Makefile | 53 +
nss/cmd/crlutil/crlgen.c | 1542 +
nss/cmd/crlutil/crlgen.h | 178 +
nss/cmd/crlutil/crlgen_lex.c | 1773 +
nss/cmd/crlutil/crlgen_lex_fix.sed | 6 +
nss/cmd/crlutil/crlgen_lex_orig.l | 181 +
nss/cmd/crlutil/crlutil.c | 1156 +
nss/cmd/crlutil/crlutil.gyp | 32 +
nss/cmd/crlutil/manifest.mn | 25 +
nss/cmd/crmf-cgi/Makefile | 53 +
nss/cmd/crmf-cgi/config.mk | 16 +
nss/cmd/crmf-cgi/crmfcgi.c | 1090 +
nss/cmd/crmf-cgi/crmfcgi.html | 136 +
nss/cmd/crmf-cgi/manifest.mn | 33 +
nss/cmd/crmftest/Makefile | 64 +
nss/cmd/crmftest/config.mk | 15 +
nss/cmd/crmftest/crmftest.gyp | 25 +
nss/cmd/crmftest/manifest.mn | 25 +
nss/cmd/crmftest/testcrmf.c | 1654 +
nss/cmd/dbck/Makefile | 47 +
nss/cmd/dbck/dbck.c | 1350 +
nss/cmd/dbck/dbrecover.c | 668 +
nss/cmd/dbck/manifest.mn | 22 +
nss/cmd/dbtest/Makefile | 46 +
nss/cmd/dbtest/dbtest.c | 244 +
nss/cmd/dbtest/dbtest.gyp | 25 +
nss/cmd/dbtest/manifest.mn | 22 +
nss/cmd/derdump/Makefile | 48 +
nss/cmd/derdump/derdump.c | 128 +
nss/cmd/derdump/derdump.gyp | 30 +
nss/cmd/derdump/manifest.mn | 21 +
nss/cmd/digest/Makefile | 48 +
nss/cmd/digest/digest.c | 228 +
nss/cmd/digest/digest.gyp | 30 +
nss/cmd/digest/manifest.mn | 22 +
nss/cmd/ecperf/Makefile | 46 +
nss/cmd/ecperf/ecperf.c | 727 +
nss/cmd/ecperf/ecperf.gyp | 35 +
nss/cmd/ecperf/manifest.mn | 18 +
nss/cmd/ectest/Makefile | 46 +
nss/cmd/ectest/ectest.c | 186 +
nss/cmd/ectest/manifest.mn | 18 +
nss/cmd/ectest/testvecs.h | 728 +
nss/cmd/fbectest/Makefile | 46 +
nss/cmd/fbectest/fbectest.c | 281 +
nss/cmd/fbectest/fbectest.gyp | 34 +
nss/cmd/fbectest/manifest.mn | 18 +
nss/cmd/fbectest/testvecs.h | 818 +
nss/cmd/fipstest/Makefile | 49 +
nss/cmd/fipstest/aes.sh | 112 +
nss/cmd/fipstest/aesgcm.sh | 67 +
nss/cmd/fipstest/dsa.sh | 71 +
nss/cmd/fipstest/ecdsa.sh | 60 +
nss/cmd/fipstest/fipstest.c | 6137 +
nss/cmd/fipstest/fipstest.gyp | 31 +
nss/cmd/fipstest/hmac.sh | 36 +
nss/cmd/fipstest/manifest.mn | 23 +
nss/cmd/fipstest/rng.sh | 34 +
nss/cmd/fipstest/rsa.sh | 50 +
nss/cmd/fipstest/runtest.sh | 17 +
nss/cmd/fipstest/sha.sh | 66 +
nss/cmd/fipstest/tdea.sh | 106 +
nss/cmd/fipstest/tls.sh | 34 +
nss/cmd/fipstest/validate.sh | 7 +
nss/cmd/fipstest/validate1.sh | 30 +
nss/cmd/httpserv/Makefile | 46 +
nss/cmd/httpserv/httpserv.c | 1453 +
nss/cmd/httpserv/httpserv.gyp | 30 +
nss/cmd/httpserv/manifest.mn | 20 +
nss/cmd/lib/Makefile | 49 +
nss/cmd/lib/basicutil.c | 776 +
nss/cmd/lib/basicutil.h | 138 +
nss/cmd/lib/berparse.c | 388 +
nss/cmd/lib/config.mk | 15 +
nss/cmd/lib/derprint.c | 594 +
nss/cmd/lib/exports.gyp | 27 +
nss/cmd/lib/ffs.c | 21 +
nss/cmd/lib/lib.gyp | 36 +
nss/cmd/lib/manifest.mn | 39 +
nss/cmd/lib/moreoids.c | 167 +
nss/cmd/lib/pk11table.c | 1517 +
nss/cmd/lib/pk11table.h | 178 +
nss/cmd/lib/pppolicy.c | 263 +
nss/cmd/lib/secpwd.c | 168 +
nss/cmd/lib/secutil.c | 3962 +
nss/cmd/lib/secutil.h | 436 +
nss/cmd/libpkix/Makefile | 46 +
nss/cmd/libpkix/config.mk | 9 +
nss/cmd/libpkix/manifest.mn | 11 +
nss/cmd/libpkix/perf/Makefile | 46 +
nss/cmd/libpkix/perf/libpkix_buildthreads.c | 337 +
nss/cmd/libpkix/perf/manifest.mn | 21 +
nss/cmd/libpkix/perf/nss_threads.c | 158 +
nss/cmd/libpkix/pkix/Makefile | 48 +
nss/cmd/libpkix/pkix/certsel/Makefile | 47 +
nss/cmd/libpkix/pkix/certsel/manifest.mn | 21 +
.../libpkix/pkix/certsel/test_certselector.c | 1683 +
.../pkix/certsel/test_comcertselparams.c | 800 +
nss/cmd/libpkix/pkix/checker/Makefile | 47 +
nss/cmd/libpkix/pkix/checker/manifest.mn | 19 +
.../pkix/checker/test_certchainchecker.c | 185 +
nss/cmd/libpkix/pkix/crlsel/Makefile | 47 +
nss/cmd/libpkix/pkix/crlsel/manifest.mn | 21 +
.../pkix/crlsel/test_comcrlselparams.c | 406 +
.../libpkix/pkix/crlsel/test_crlselector.c | 168 +
nss/cmd/libpkix/pkix/manifest.mn | 11 +
nss/cmd/libpkix/pkix/params/Makefile | 47 +
nss/cmd/libpkix/pkix/params/manifest.mn | 23 +
nss/cmd/libpkix/pkix/params/test_procparams.c | 478 +
.../libpkix/pkix/params/test_resourcelimits.c | 99 +
.../libpkix/pkix/params/test_trustanchor.c | 251 +
nss/cmd/libpkix/pkix/params/test_valparams.c | 261 +
nss/cmd/libpkix/pkix/results/Makefile | 47 +
nss/cmd/libpkix/pkix/results/manifest.mn | 23 +
.../libpkix/pkix/results/test_buildresult.c | 212 +
.../libpkix/pkix/results/test_policynode.c | 612 +
nss/cmd/libpkix/pkix/results/test_valresult.c | 199 +
.../libpkix/pkix/results/test_verifynode.c | 112 +
nss/cmd/libpkix/pkix/store/Makefile | 47 +
nss/cmd/libpkix/pkix/store/manifest.mn | 19 +
nss/cmd/libpkix/pkix/store/test_store.c | 194 +
nss/cmd/libpkix/pkix/top/Makefile | 47 +
nss/cmd/libpkix/pkix/top/manifest.mn | 33 +
nss/cmd/libpkix/pkix/top/test_basicchecker.c | 238 +
.../pkix/top/test_basicconstraintschecker.c | 145 +
nss/cmd/libpkix/pkix/top/test_buildchain.c | 418 +
.../pkix/top/test_buildchain_partialchain.c | 725 +
.../pkix/top/test_buildchain_resourcelimits.c | 438 +
.../pkix/top/test_buildchain_uchecker.c | 327 +
.../libpkix/pkix/top/test_customcrlchecker.c | 435 +
.../pkix/top/test_defaultcrlchecker2stores.c | 230 +
nss/cmd/libpkix/pkix/top/test_ocsp.c | 288 +
nss/cmd/libpkix/pkix/top/test_policychecker.c | 535 +
.../pkix/top/test_subjaltnamechecker.c | 261 +
nss/cmd/libpkix/pkix/top/test_validatechain.c | 221 +
.../libpkix/pkix/top/test_validatechain_NB.c | 351 +
.../libpkix/pkix/top/test_validatechain_bc.c | 233 +
nss/cmd/libpkix/pkix/util/Makefile | 47 +
nss/cmd/libpkix/pkix/util/manifest.mn | 23 +
nss/cmd/libpkix/pkix/util/test_error.c | 385 +
nss/cmd/libpkix/pkix/util/test_list.c | 765 +
nss/cmd/libpkix/pkix/util/test_list2.c | 120 +
nss/cmd/libpkix/pkix/util/test_logger.c | 314 +
nss/cmd/libpkix/pkix_pl/Makefile | 48 +
nss/cmd/libpkix/pkix_pl/manifest.mn | 11 +
nss/cmd/libpkix/pkix_pl/module/Makefile | 47 +
nss/cmd/libpkix/pkix_pl/module/manifest.mn | 24 +
.../pkix_pl/module/test_colcertstore.c | 247 +
.../libpkix/pkix_pl/module/test_ekuchecker.c | 275 +
.../pkix_pl/module/test_httpcertstore.c | 300 +
.../pkix_pl/module/test_pk11certstore.c | 580 +
nss/cmd/libpkix/pkix_pl/module/test_socket.c | 571 +
nss/cmd/libpkix/pkix_pl/pki/Makefile | 47 +
nss/cmd/libpkix/pkix_pl/pki/manifest.mn | 28 +
.../pkix_pl/pki/test_authorityinfoaccess.c | 105 +
nss/cmd/libpkix/pkix_pl/pki/test_cert.c | 2088 +
nss/cmd/libpkix/pkix_pl/pki/test_crl.c | 302 +
nss/cmd/libpkix/pkix_pl/pki/test_crlentry.c | 208 +
nss/cmd/libpkix/pkix_pl/pki/test_date.c | 106 +
.../libpkix/pkix_pl/pki/test_generalname.c | 123 +
.../pkix_pl/pki/test_nameconstraints.c | 127 +
.../pkix_pl/pki/test_subjectinfoaccess.c | 121 +
nss/cmd/libpkix/pkix_pl/pki/test_x500name.c | 169 +
nss/cmd/libpkix/pkix_pl/system/Makefile | 47 +
nss/cmd/libpkix/pkix_pl/system/manifest.mn | 38 +
nss/cmd/libpkix/pkix_pl/system/stress_test.c | 146 +
nss/cmd/libpkix/pkix_pl/system/test_bigint.c | 190 +
.../libpkix/pkix_pl/system/test_bytearray.c | 231 +
.../libpkix/pkix_pl/system/test_hashtable.c | 380 +
nss/cmd/libpkix/pkix_pl/system/test_mem.c | 133 +
.../libpkix/pkix_pl/system/test_monitorlock.c | 104 +
nss/cmd/libpkix/pkix_pl/system/test_mutex.c | 102 +
nss/cmd/libpkix/pkix_pl/system/test_mutex2.c | 166 +
nss/cmd/libpkix/pkix_pl/system/test_mutex3.c | 104 +
nss/cmd/libpkix/pkix_pl/system/test_object.c | 281 +
nss/cmd/libpkix/pkix_pl/system/test_oid.c | 212 +
nss/cmd/libpkix/pkix_pl/system/test_rwlock.c | 204 +
nss/cmd/libpkix/pkix_pl/system/test_string.c | 434 +
nss/cmd/libpkix/pkix_pl/system/test_string2.c | 337 +
nss/cmd/libpkix/pkixlibs.mk | 27 +
nss/cmd/libpkix/pkixrules.mk | 7 +
nss/cmd/libpkix/pkixutil/Makefile | 43 +
nss/cmd/libpkix/pkixutil/manifest.mn | 41 +
nss/cmd/libpkix/pkixutil/pkixutil.c | 299 +
nss/cmd/libpkix/sample_apps/Makefile | 46 +
nss/cmd/libpkix/sample_apps/build_chain.c | 242 +
nss/cmd/libpkix/sample_apps/dumpcert.c | 182 +
nss/cmd/libpkix/sample_apps/dumpcrl.c | 186 +
nss/cmd/libpkix/sample_apps/manifest.mn | 23 +
nss/cmd/libpkix/sample_apps/validate_chain.c | 220 +
nss/cmd/libpkix/testutil/Makefile | 51 +
nss/cmd/libpkix/testutil/config.mk | 15 +
nss/cmd/libpkix/testutil/manifest.mn | 26 +
nss/cmd/libpkix/testutil/pkixutil.def | 48 +
nss/cmd/libpkix/testutil/testutil.c | 576 +
nss/cmd/libpkix/testutil/testutil.h | 292 +
nss/cmd/libpkix/testutil/testutil_nss.c | 579 +
nss/cmd/libpkix/testutil/testutil_nss.h | 119 +
nss/cmd/listsuites/Makefile | 47 +
nss/cmd/listsuites/listsuites.c | 62 +
nss/cmd/listsuites/listsuites.gyp | 24 +
nss/cmd/listsuites/manifest.mn | 15 +
nss/cmd/lowhashtest/Makefile | 65 +
nss/cmd/lowhashtest/lowhashtest.c | 445 +
nss/cmd/lowhashtest/lowhashtest.gyp | 32 +
nss/cmd/lowhashtest/manifest.mn | 25 +
nss/cmd/makepqg/Makefile | 49 +
nss/cmd/makepqg/makepqg.c | 349 +
nss/cmd/makepqg/makepqg.gyp | 25 +
nss/cmd/makepqg/manifest.mn | 19 +
nss/cmd/makepqg/testit.ksh | 13 +
nss/cmd/manifest.mn | 108 +
nss/cmd/modutil/Makefile | 54 +
nss/cmd/modutil/README | 7 +
nss/cmd/modutil/error.h | 139 +
nss/cmd/modutil/install-ds.c | 1525 +
nss/cmd/modutil/install-ds.h | 260 +
nss/cmd/modutil/install.c | 959 +
nss/cmd/modutil/install.h | 100 +
nss/cmd/modutil/installparse.c | 434 +
nss/cmd/modutil/installparse.h | 7 +
nss/cmd/modutil/installparse.l | 137 +
nss/cmd/modutil/installparse.y | 104 +
nss/cmd/modutil/instsec.c | 153 +
nss/cmd/modutil/lex.Pk11Install_yy.c | 1607 +
nss/cmd/modutil/manifest.mn | 34 +
nss/cmd/modutil/modutil.c | 970 +
nss/cmd/modutil/modutil.gyp | 44 +
nss/cmd/modutil/modutil.h | 40 +
nss/cmd/modutil/pk11.c | 960 +
nss/cmd/modutil/pk11jar.html | 279 +
nss/cmd/modutil/rules.mk | 26 +
nss/cmd/modutil/specification.html | 322 +
nss/cmd/mpitests/mpi-test.c | 2127 +
nss/cmd/mpitests/mpitests.gyp | 39 +
nss/cmd/mpitests/test-info.c | 157 +
nss/cmd/multinit/Makefile | 47 +
nss/cmd/multinit/manifest.mn | 13 +
nss/cmd/multinit/multinit.c | 881 +
nss/cmd/multinit/multinit.gyp | 24 +
nss/cmd/ocspclnt/Makefile | 45 +
nss/cmd/ocspclnt/manifest.mn | 24 +
nss/cmd/ocspclnt/ocspclnt.c | 1243 +
nss/cmd/ocspclnt/ocspclnt.gyp | 25 +
nss/cmd/ocspresp/Makefile | 47 +
nss/cmd/ocspresp/manifest.mn | 15 +
nss/cmd/ocspresp/ocspresp.c | 251 +
nss/cmd/ocspresp/ocspresp.gyp | 24 +
nss/cmd/oidcalc/Makefile | 48 +
nss/cmd/oidcalc/manifest.mn | 19 +
nss/cmd/oidcalc/oidcalc.c | 86 +
nss/cmd/oidcalc/oidcalc.gyp | 30 +
nss/cmd/p7content/Makefile | 47 +
nss/cmd/p7content/manifest.mn | 15 +
nss/cmd/p7content/p7content.c | 269 +
nss/cmd/p7content/p7content.gyp | 24 +
nss/cmd/p7env/Makefile | 47 +
nss/cmd/p7env/manifest.mn | 15 +
nss/cmd/p7env/p7env.c | 261 +
nss/cmd/p7env/p7env.gyp | 24 +
nss/cmd/p7sign/Makefile | 47 +
nss/cmd/p7sign/manifest.mn | 15 +
nss/cmd/p7sign/p7sign.c | 281 +
nss/cmd/p7sign/p7sign.gyp | 24 +
nss/cmd/p7verify/Makefile | 47 +
nss/cmd/p7verify/manifest.mn | 15 +
nss/cmd/p7verify/p7verify.c | 283 +
nss/cmd/p7verify/p7verify.gyp | 24 +
nss/cmd/perfclient/Makefile | 46 +
nss/cmd/perfclient/client_db | 1 +
nss/cmd/perfclient/main.c | 147 +
nss/cmd/perfclient/manifest.mn | 23 +
nss/cmd/perfserver/Makefile | 46 +
nss/cmd/perfserver/main.c | 189 +
nss/cmd/perfserver/manifest.mn | 23 +
nss/cmd/perfserver/server_db | 1 +
nss/cmd/pk11ectest/Makefile | 46 +
nss/cmd/pk11ectest/manifest.mn | 16 +
nss/cmd/pk11ectest/pk11ectest.c | 171 +
nss/cmd/pk11ectest/pk11ectest.gyp | 31 +
nss/cmd/pk11gcmtest/Makefile | 47 +
nss/cmd/pk11gcmtest/manifest.mn | 20 +
nss/cmd/pk11gcmtest/pk11gcmtest.c | 460 +
nss/cmd/pk11gcmtest/pk11gcmtest.gyp | 24 +
nss/cmd/pk11gcmtest/tests/README | 14 +
nss/cmd/pk11gcmtest/tests/gcmDecrypt128.rsp | 1016 +
nss/cmd/pk11gcmtest/tests/gcmDecrypt192.rsp | 1016 +
nss/cmd/pk11gcmtest/tests/gcmDecrypt256.rsp | 1016 +
.../pk11gcmtest/tests/gcmEncryptExtIV128.rsp | 1016 +
.../pk11gcmtest/tests/gcmEncryptExtIV192.rsp | 1016 +
.../pk11gcmtest/tests/gcmEncryptExtIV256.rsp | 1016 +
nss/cmd/pk11mode/Makefile | 65 +
nss/cmd/pk11mode/manifest.mn | 16 +
nss/cmd/pk11mode/pk11mode.c | 5387 +
nss/cmd/pk11mode/pk11mode.gyp | 24 +
nss/cmd/pk11util/Makefile | 48 +
nss/cmd/pk11util/manifest.mn | 23 +
nss/cmd/pk11util/pk11util.c | 2240 +
nss/cmd/pk11util/scripts/dosign | 162 +
nss/cmd/pk11util/scripts/hssign | 48 +
nss/cmd/pk11util/scripts/lcert | 35 +
nss/cmd/pk11util/scripts/mechanisms | 11 +
nss/cmd/pk11util/scripts/pLabel1 | 6 +
nss/cmd/pk11util/scripts/pMechanisms | 8 +
nss/cmd/pk11util/scripts/pcert | 30 +
nss/cmd/pk12util/Makefile | 48 +
nss/cmd/pk12util/manifest.mn | 23 +
nss/cmd/pk12util/pk12util.c | 1103 +
nss/cmd/pk12util/pk12util.gyp | 30 +
nss/cmd/pk12util/pk12util.h | 40 +
nss/cmd/pk1sign/Makefile | 47 +
nss/cmd/pk1sign/manifest.mn | 15 +
nss/cmd/pk1sign/pk1sign.c | 318 +
nss/cmd/pk1sign/pk1sign.gyp | 24 +
nss/cmd/pkix-errcodes/Makefile | 47 +
nss/cmd/pkix-errcodes/manifest.mn | 15 +
nss/cmd/pkix-errcodes/pkix-errcodes.c | 35 +
nss/cmd/pkix-errcodes/pkix-errcodes.gyp | 24 +
nss/cmd/platlibs.gypi | 76 +
nss/cmd/platlibs.mk | 265 +
nss/cmd/platrules.mk | 19 +
nss/cmd/pp/Makefile | 47 +
nss/cmd/pp/manifest.mn | 19 +
nss/cmd/pp/pp.c | 196 +
nss/cmd/pp/pp.gyp | 30 +
nss/cmd/ppcertdata/Makefile | 48 +
nss/cmd/ppcertdata/manifest.mn | 22 +
nss/cmd/ppcertdata/ppcertdata.c | 99 +
nss/cmd/proofgen/.gitignore | 2 +
nss/cmd/proofgen/Makefile | 46 +
nss/cmd/proofgen/client_db | 1 +
nss/cmd/proofgen/main.c | 188 +
nss/cmd/proofgen/manifest.mn | 23 +
nss/cmd/pwdecrypt/Makefile | 45 +
nss/cmd/pwdecrypt/manifest.mn | 26 +
nss/cmd/pwdecrypt/pwdecrypt.c | 330 +
nss/cmd/pwdecrypt/pwdecrypt.gyp | 25 +
nss/cmd/randtrafficClient/Makefile | 46 +
nss/cmd/randtrafficClient/client_db | 1 +
nss/cmd/randtrafficClient/main.c | 206 +
nss/cmd/randtrafficClient/manifest.mn | 23 +
nss/cmd/randtrafficServer/Makefile | 46 +
nss/cmd/randtrafficServer/main.c | 190 +
nss/cmd/randtrafficServer/manifest.mn | 23 +
nss/cmd/randtrafficServer/server_db | 1 +
nss/cmd/replayClient/.gitignore | 2 +
nss/cmd/replayClient/Makefile | 46 +
nss/cmd/replayClient/client_db | 1 +
nss/cmd/replayClient/main.c | 213 +
nss/cmd/replayClient/manifest.mn | 23 +
nss/cmd/replayClient/messages.txt | 0
nss/cmd/replayServer/Makefile | 46 +
nss/cmd/replayServer/main.c | 217 +
nss/cmd/replayServer/manifest.mn | 23 +
nss/cmd/replayServer/server_db | 1 +
nss/cmd/rsaperf/Makefile | 46 +
nss/cmd/rsaperf/defkey.c | 293 +
nss/cmd/rsaperf/manifest.mn | 24 +
nss/cmd/rsaperf/rsaperf.c | 696 +
nss/cmd/rsaperf/rsaperf.gyp | 36 +
nss/cmd/rsapoptst/Makefile | 54 +
nss/cmd/rsapoptst/manifest.mn | 22 +
nss/cmd/rsapoptst/rsapoptst.c | 535 +
nss/cmd/samples/cert | 15 +
nss/cmd/samples/cert0 | Bin 0 -> 505 bytes
nss/cmd/samples/cert1 | Bin 0 -> 515 bytes
nss/cmd/samples/cert2 | Bin 0 -> 528 bytes
nss/cmd/samples/pkcs7.ber | Bin 0 -> 1771 bytes
nss/cmd/samples/pkcs7bday.ber | Bin 0 -> 1881 bytes
nss/cmd/samples/pkcs7cnet.ber | Bin 0 -> 3330 bytes
nss/cmd/samples/pkcs7news.ber | Bin 0 -> 255328 bytes
nss/cmd/samples/x509v3.der | Bin 0 -> 463 bytes
nss/cmd/samples/x509v3.txt | 10 +
nss/cmd/sdrtest/Makefile | 45 +
nss/cmd/sdrtest/manifest.mn | 26 +
nss/cmd/sdrtest/sdrtest.c | 427 +
nss/cmd/sdrtest/sdrtest.gyp | 25 +
nss/cmd/selfserv/Makefile | 46 +
nss/cmd/selfserv/manifest.mn | 20 +
nss/cmd/selfserv/selfserv.c | 2784 +
nss/cmd/selfserv/selfserv.gyp | 30 +
nss/cmd/serverProof/.cproject | 56 +
nss/cmd/serverProof/.project | 27 +
nss/cmd/serverProof/Makefile | 46 +
nss/cmd/serverProof/main.c | 192 +
nss/cmd/serverProof/manifest.mn | 23 +
nss/cmd/serverProof/server_db | 1 +
nss/cmd/shlibsign/Makefile | 99 +
nss/cmd/shlibsign/mangle/Makefile | 65 +
nss/cmd/shlibsign/mangle/mangle.c | 140 +
nss/cmd/shlibsign/mangle/mangle.gyp | 31 +
nss/cmd/shlibsign/mangle/manifest.mn | 24 +
nss/cmd/shlibsign/manifest.mn | 27 +
nss/cmd/shlibsign/shlibsign.c | 1332 +
nss/cmd/shlibsign/shlibsign.gyp | 30 +
nss/cmd/shlibsign/sign.cmd | 25 +
nss/cmd/shlibsign/sign.sh | 51 +
nss/cmd/signtool/Makefile | 44 +
nss/cmd/signtool/README | 128 +
nss/cmd/signtool/certgen.c | 713 +
nss/cmd/signtool/javascript.c | 1817 +
nss/cmd/signtool/list.c | 215 +
nss/cmd/signtool/manifest.mn | 25 +
nss/cmd/signtool/sign.c | 834 +
nss/cmd/signtool/signtool.c | 1068 +
nss/cmd/signtool/signtool.gyp | 33 +
nss/cmd/signtool/signtool.h | 113 +
nss/cmd/signtool/util.c | 1086 +
nss/cmd/signtool/verify.c | 337 +
nss/cmd/signtool/zip.c | 676 +
nss/cmd/signtool/zip.h | 69 +
nss/cmd/signver/Makefile | 43 +
nss/cmd/signver/examples/1/form.pl | 22 +
nss/cmd/signver/examples/1/signedForm.html | 55 +
nss/cmd/signver/examples/1/signedForm.nt.html | 55 +
nss/cmd/signver/examples/1/signedForm.pl | 60 +
nss/cmd/signver/manifest.mn | 24 +
nss/cmd/signver/pk7print.c | 872 +
nss/cmd/signver/signver.c | 315 +
nss/cmd/signver/signver.gyp | 26 +
nss/cmd/smimetools/Makefile | 49 +
nss/cmd/smimetools/cmsutil.c | 1628 +
nss/cmd/smimetools/manifest.mn | 17 +
nss/cmd/smimetools/rules.mk | 7 +
nss/cmd/smimetools/smime | 547 +
nss/cmd/smimetools/smimetools.gyp | 25 +
nss/cmd/ssltap/Makefile | 51 +
nss/cmd/ssltap/manifest.mn | 23 +
nss/cmd/ssltap/ssltap-manual.html | 170 +
nss/cmd/ssltap/ssltap.c | 2590 +
nss/cmd/ssltap/ssltap.gyp | 25 +
nss/cmd/strsclnt/Makefile | 47 +
nss/cmd/strsclnt/manifest.mn | 19 +
nss/cmd/strsclnt/strsclnt.c | 1554 +
nss/cmd/strsclnt/strsclnt.gyp | 30 +
nss/cmd/symkeyutil/Makefile | 48 +
nss/cmd/symkeyutil/manifest.mn | 23 +
nss/cmd/symkeyutil/symkey.man | 182 +
nss/cmd/symkeyutil/symkeyutil.c | 1102 +
nss/cmd/symkeyutil/symkeyutil.gyp | 30 +
nss/cmd/test/Makefile | 46 +
nss/cmd/test/client_db | 1 +
nss/cmd/test/main.c | 179 +
nss/cmd/test/manifest.mn | 23 +
nss/cmd/tests/Makefile | 45 +
nss/cmd/tests/baddbdir.c | 38 +
nss/cmd/tests/conflict.c | 27 +
nss/cmd/tests/dertimetest.c | 102 +
nss/cmd/tests/encodeinttest.c | 62 +
nss/cmd/tests/manifest.mn | 29 +
nss/cmd/tests/nonspr10.c | 90 +
nss/cmd/tests/remtest.c | 136 +
nss/cmd/tests/secmodtest.c | 126 +
nss/cmd/tests/tests.gyp | 91 +
nss/cmd/tstclnt/Makefile | 46 +
nss/cmd/tstclnt/manifest.mn | 23 +
nss/cmd/tstclnt/tstclnt.c | 1927 +
nss/cmd/tstclnt/tstclnt.gyp | 31 +
nss/cmd/verifier/.gitignore | 2 +
nss/cmd/verifier/Makefile | 46 +
nss/cmd/verifier/client_db | 1 +
nss/cmd/verifier/main.c | 76 +
nss/cmd/verifier/manifest.mn | 23 +
nss/cmd/vfychain/Makefile | 46 +
nss/cmd/vfychain/manifest.mn | 23 +
nss/cmd/vfychain/vfychain.c | 820 +
nss/cmd/vfychain/vfychain.gyp | 30 +
nss/cmd/vfyserv/Makefile | 46 +
nss/cmd/vfyserv/manifest.mn | 23 +
nss/cmd/vfyserv/vfyserv.c | 572 +
nss/cmd/vfyserv/vfyserv.gyp | 32 +
nss/cmd/vfyserv/vfyserv.h | 138 +
nss/cmd/vfyserv/vfyutil.c | 620 +
nss/coreconf/AIX.mk | 67 +
nss/coreconf/Android.mk | 6 +
nss/coreconf/BSD_OS.mk | 56 +
nss/coreconf/BeOS.mk | 47 +
nss/coreconf/Darwin.mk | 147 +
nss/coreconf/FreeBSD.mk | 58 +
nss/coreconf/HP-UX.mk | 84 +
nss/coreconf/HP-UXA.09.03.mk | 17 +
nss/coreconf/HP-UXA.09.07.mk | 16 +
nss/coreconf/HP-UXA.09.mk | 11 +
nss/coreconf/HP-UXB.10.01.mk | 12 +
nss/coreconf/HP-UXB.10.10.mk | 22 +
nss/coreconf/HP-UXB.10.20.mk | 22 +
nss/coreconf/HP-UXB.10.30.mk | 28 +
nss/coreconf/HP-UXB.10.mk | 8 +
nss/coreconf/HP-UXB.11.00.mk | 17 +
nss/coreconf/HP-UXB.11.11.mk | 17 +
nss/coreconf/HP-UXB.11.20.mk | 17 +
nss/coreconf/HP-UXB.11.22.mk | 17 +
nss/coreconf/HP-UXB.11.23.mk | 17 +
nss/coreconf/HP-UXB.11.mk | 48 +
nss/coreconf/IRIX.mk | 94 +
nss/coreconf/IRIX5.2.mk | 5 +
nss/coreconf/IRIX5.3.mk | 7 +
nss/coreconf/IRIX5.mk | 10 +
nss/coreconf/IRIX6.2.mk | 13 +
nss/coreconf/IRIX6.3.mk | 12 +
nss/coreconf/IRIX6.5.mk | 15 +
nss/coreconf/IRIX6.mk | 17 +
nss/coreconf/Linux.mk | 209 +
nss/coreconf/Makefile | 15 +
nss/coreconf/NCR3.0.mk | 65 +
nss/coreconf/NEC4.2.mk | 36 +
nss/coreconf/NetBSD.mk | 55 +
nss/coreconf/OS2.mk | 156 +
nss/coreconf/OSF1.mk | 48 +
nss/coreconf/OSF1V2.0.mk | 5 +
nss/coreconf/OSF1V3.0.mk | 5 +
nss/coreconf/OSF1V3.2.mk | 16 +
nss/coreconf/OSF1V4.0.mk | 24 +
nss/coreconf/OSF1V4.0B.mk | 5 +
nss/coreconf/OSF1V4.0D.mk | 9 +
nss/coreconf/OSF1V5.0.mk | 20 +
nss/coreconf/OSF1V5.1.mk | 20 +
nss/coreconf/OpenBSD.mk | 41 +
nss/coreconf/OpenUNIX.mk | 60 +
nss/coreconf/QNX.mk | 39 +
nss/coreconf/README | 555 +
nss/coreconf/RISCOS.mk | 22 +
nss/coreconf/ReliantUNIX.mk | 58 +
nss/coreconf/ReliantUNIX5.4.mk | 5 +
nss/coreconf/SCOOS5.0.mk | 6 +
nss/coreconf/SCO_SV3.2.mk | 60 +
nss/coreconf/SunOS4.1.3_U1.mk | 28 +
nss/coreconf/SunOS5.mk | 144 +
nss/coreconf/UNIX.mk | 66 +
nss/coreconf/UNIXWARE2.1.mk | 29 +
nss/coreconf/WIN32.mk | 378 +
nss/coreconf/WIN95.mk | 15 +
nss/coreconf/WINNT.mk | 20 +
nss/coreconf/Werror.mk | 105 +
nss/coreconf/arch.mk | 323 +
nss/coreconf/check_cc_clang.py | 21 +
nss/coreconf/command.mk | 39 +
nss/coreconf/config.gypi | 548 +
nss/coreconf/config.mk | 210 +
nss/coreconf/coreconf.dep | 13 +
nss/coreconf/coreconf.pl | 128 +
nss/coreconf/cpdist.pl | 167 +
nss/coreconf/detect_host_arch.py | 25 +
nss/coreconf/empty.c | 1 +
nss/coreconf/fuzz.sh | 38 +
nss/coreconf/headers.mk | 24 +
nss/coreconf/import.pl | 189 +
nss/coreconf/jdk.mk | 504 +
nss/coreconf/jniregen.pl | 79 +
nss/coreconf/location.mk | 78 +
nss/coreconf/mkdepend/Makefile | 60 +
nss/coreconf/mkdepend/cppsetup.c | 233 +
nss/coreconf/mkdepend/def.h | 184 +
nss/coreconf/mkdepend/ifparser.c | 551 +
nss/coreconf/mkdepend/ifparser.h | 83 +
nss/coreconf/mkdepend/imakemdep.h | 782 +
nss/coreconf/mkdepend/include.c | 337 +
nss/coreconf/mkdepend/main.c | 870 +
nss/coreconf/mkdepend/mkdepend.man | 382 +
nss/coreconf/mkdepend/parse.c | 693 +
nss/coreconf/mkdepend/pr.c | 124 +
nss/coreconf/module.mk | 37 +
nss/coreconf/nsinstall/Makefile | 42 +
nss/coreconf/nsinstall/nsinstall.c | 407 +
nss/coreconf/nsinstall/nsinstall.gyp | 21 +
nss/coreconf/nsinstall/pathsub.c | 272 +
nss/coreconf/nsinstall/pathsub.h | 48 +
nss/coreconf/nsinstall/sunos4.h | 134 +
nss/coreconf/nspr.sh | 51 +
nss/coreconf/outofdate.pl | 39 +
nss/coreconf/precommit.clang-format.sh | 63 +
nss/coreconf/prefix.mk | 44 +
nss/coreconf/release.pl | 112 +
nss/coreconf/rules.mk | 970 +
nss/coreconf/ruleset.mk | 220 +
nss/coreconf/sanitizers.mk | 19 +
nss/coreconf/sanitizers.py | 33 +
nss/coreconf/sanitizers.sh | 78 +
nss/coreconf/shlibsign.py | 30 +
nss/coreconf/source.mk | 162 +
nss/coreconf/suffix.mk | 67 +
nss/coreconf/tree.mk | 52 +
nss/coreconf/version.mk | 77 +
nss/coreconf/version.pl | 48 +
nss/coreconf/werror.py | 60 +
nss/coreconf/zlib.mk | 17 +
nss/cpputil/.clang-format | 4 +
nss/cpputil/README | 11 +
nss/cpputil/cpputil.gyp | 27 +
nss/cpputil/dummy_io.cc | 221 +
nss/cpputil/dummy_io.h | 62 +
nss/cpputil/dummy_io_fwd.cc | 162 +
nss/cpputil/scoped_ptrs.h | 63 +
nss/doc/.hgignore | 3 +
nss/doc/Makefile | 69 +
nss/doc/README | 7 +
nss/doc/certutil.xml | 1243 +
nss/doc/cmsutil.xml | 299 +
nss/doc/crlutil.xml | 525 +
nss/doc/derdump.xml | 96 +
nss/doc/html/.hgignore | 1 +
nss/doc/html/certutil.html | 354 +
nss/doc/html/cmsutil.html | 27 +
nss/doc/html/crlutil.html | 204 +
nss/doc/html/derdump.html | 7 +
nss/doc/html/modutil.html | 250 +
nss/doc/html/pk12util.html | 77 +
nss/doc/html/pp.html | 7 +
nss/doc/html/signtool.html | 284 +
nss/doc/html/signver.html | 33 +
nss/doc/html/ssltap.html | 417 +
nss/doc/html/vfychain.html | 26 +
nss/doc/html/vfyserv.html | 5 +
nss/doc/modutil.xml | 761 +
nss/doc/nroff/certutil.1 | 2050 +
nss/doc/nroff/cmsutil.1 | 271 +
nss/doc/nroff/crlutil.1 | 389 +
nss/doc/nroff/derdump.1 | 92 +
nss/doc/nroff/modutil.1 | 1452 +
nss/doc/nroff/pk12util.1 | 1040 +
nss/doc/nroff/pp.1 | 108 +
nss/doc/nroff/signtool.1 | 681 +
nss/doc/nroff/signver.1 | 320 +
nss/doc/nroff/ssltap.1 | 609 +
nss/doc/nroff/vfychain.1 | 169 +
nss/doc/nroff/vfyserv.1 | 70 +
nss/doc/pk12util.xml | 478 +
nss/doc/pp.xml | 123 +
nss/doc/signtool.xml | 681 +
nss/doc/signver.xml | 230 +
nss/doc/ssltap.xml | 579 +
nss/doc/vfychain.xml | 232 +
nss/doc/vfyserv.xml | 85 +
nss/exports.gyp | 77 +
nss/external_tests/.clang-format | 4 +
nss/external_tests/Makefile | 44 +
nss/external_tests/README | 15 +
nss/external_tests/common/Makefile | 41 +
nss/external_tests/common/gtest.mk | 36 +
nss/external_tests/common/gtests.cc | 22 +
nss/external_tests/common/manifest.mn | 21 +
nss/external_tests/common/scoped_ptrs.h | 55 +
nss/external_tests/der_gtest/Makefile | 43 +
.../der_gtest/der_getint_unittest.cc | 110 +
nss/external_tests/der_gtest/manifest.mn | 21 +
nss/external_tests/google_test/Makefile | 44 +
nss/external_tests/google_test/gtest/CHANGES | 157 +
.../google_test/gtest/CMakeLists.txt | 260 +
.../google_test/gtest/CONTRIBUTORS | 37 +
nss/external_tests/google_test/gtest/LICENSE | 28 +
.../google_test/gtest/Makefile.am | 306 +
nss/external_tests/google_test/gtest/README | 435 +
.../google_test/gtest/build-aux/.keep | 0
.../gtest/cmake/internal_utils.cmake | 242 +
.../google_test/gtest/codegear/gtest.cbproj | 138 +
.../gtest/codegear/gtest.groupproj | 54 +
.../google_test/gtest/codegear/gtest_all.cc | 38 +
.../google_test/gtest/codegear/gtest_link.cc | 40 +
.../gtest/codegear/gtest_main.cbproj | 82 +
.../gtest/codegear/gtest_unittest.cbproj | 88 +
.../google_test/gtest/configure.ac | 68 +
.../gtest/include/gtest/gtest-death-test.h | 294 +
.../gtest/include/gtest/gtest-message.h | 250 +
.../gtest/include/gtest/gtest-param-test.h | 1421 +
.../include/gtest/gtest-param-test.h.pump | 487 +
.../gtest/include/gtest/gtest-printers.h | 891 +
.../gtest/include/gtest/gtest-spi.h | 232 +
.../gtest/include/gtest/gtest-test-part.h | 179 +
.../gtest/include/gtest/gtest-typed-test.h | 259 +
.../google_test/gtest/include/gtest/gtest.h | 2307 +
.../gtest/include/gtest/gtest_pred_impl.h | 358 +
.../gtest/include/gtest/gtest_prod.h | 58 +
.../internal/gtest-death-test-internal.h | 319 +
.../include/gtest/internal/gtest-filepath.h | 206 +
.../include/gtest/internal/gtest-internal.h | 1193 +
.../include/gtest/internal/gtest-linked_ptr.h | 233 +
.../internal/gtest-param-util-generated.h | 5143 +
.../gtest-param-util-generated.h.pump | 301 +
.../include/gtest/internal/gtest-param-util.h | 619 +
.../gtest/include/gtest/internal/gtest-port.h | 2432 +
.../include/gtest/internal/gtest-string.h | 167 +
.../include/gtest/internal/gtest-tuple.h | 1020 +
.../include/gtest/internal/gtest-tuple.h.pump | 347 +
.../include/gtest/internal/gtest-type-util.h | 3331 +
.../gtest/internal/gtest-type-util.h.pump | 297 +
.../google_test/gtest/m4/acx_pthread.m4 | 363 +
.../google_test/gtest/m4/gtest.m4 | 74 +
.../google_test/gtest/make/Makefile | 82 +
.../google_test/gtest/msvc/gtest-md.sln | 45 +
.../google_test/gtest/msvc/gtest-md.vcproj | 126 +
.../google_test/gtest/msvc/gtest.sln | 45 +
.../google_test/gtest/msvc/gtest.vcproj | 126 +
.../gtest/msvc/gtest_main-md.vcproj | 129 +
.../google_test/gtest/msvc/gtest_main.vcproj | 129 +
.../gtest/msvc/gtest_prod_test-md.vcproj | 164 +
.../gtest/msvc/gtest_prod_test.vcproj | 164 +
.../gtest/msvc/gtest_unittest-md.vcproj | 147 +
.../gtest/msvc/gtest_unittest.vcproj | 147 +
.../google_test/gtest/samples/prime_tables.h | 123 +
.../google_test/gtest/samples/sample1.cc | 68 +
.../google_test/gtest/samples/sample1.h | 43 +
.../gtest/samples/sample10_unittest.cc | 144 +
.../gtest/samples/sample1_unittest.cc | 153 +
.../google_test/gtest/samples/sample2.cc | 56 +
.../google_test/gtest/samples/sample2.h | 85 +
.../gtest/samples/sample2_unittest.cc | 109 +
.../google_test/gtest/samples/sample3-inl.h | 172 +
.../gtest/samples/sample3_unittest.cc | 151 +
.../google_test/gtest/samples/sample4.cc | 46 +
.../google_test/gtest/samples/sample4.h | 53 +
.../gtest/samples/sample4_unittest.cc | 45 +
.../gtest/samples/sample5_unittest.cc | 199 +
.../gtest/samples/sample6_unittest.cc | 224 +
.../gtest/samples/sample7_unittest.cc | 130 +
.../gtest/samples/sample8_unittest.cc | 173 +
.../gtest/samples/sample9_unittest.cc | 160 +
.../google_test/gtest/scripts/common.py | 83 +
.../gtest/scripts/fuse_gtest_files.py | 250 +
.../gtest/scripts/gen_gtest_pred_impl.py | 730 +
.../google_test/gtest/scripts/gtest-config.in | 274 +
.../google_test/gtest/scripts/pump.py | 855 +
.../google_test/gtest/scripts/release_docs.py | 158 +
.../google_test/gtest/scripts/test/Makefile | 59 +
.../google_test/gtest/scripts/upload.py | 1387 +
.../google_test/gtest/scripts/upload_gtest.py | 78 +
.../google_test/gtest/src/gtest-all.cc | 48 +
.../google_test/gtest/src/gtest-death-test.cc | 1346 +
.../google_test/gtest/src/gtest-filepath.cc | 387 +
.../gtest/src/gtest-internal-inl.h | 1192 +
.../google_test/gtest/src/gtest-port.cc | 1184 +
.../google_test/gtest/src/gtest-printers.cc | 373 +
.../google_test/gtest/src/gtest-test-part.cc | 110 +
.../google_test/gtest/src/gtest-typed-test.cc | 110 +
.../google_test/gtest/src/gtest.cc | 5291 +
.../google_test/gtest/src/gtest_main.cc | 38 +
.../gtest/test/gtest-death-test_ex_test.cc | 93 +
.../gtest/test/gtest-death-test_test.cc | 1423 +
.../gtest/test/gtest-filepath_test.cc | 680 +
.../gtest/test/gtest-linked_ptr_test.cc | 154 +
.../gtest/test/gtest-listener_test.cc | 310 +
.../gtest/test/gtest-message_test.cc | 159 +
.../gtest/test/gtest-options_test.cc | 215 +
.../gtest/test/gtest-param-test2_test.cc | 65 +
.../gtest/test/gtest-param-test_test.cc | 904 +
.../gtest/test/gtest-param-test_test.h | 57 +
.../google_test/gtest/test/gtest-port_test.cc | 1323 +
.../gtest/test/gtest-printers_test.cc | 1651 +
.../gtest/test/gtest-test-part_test.cc | 208 +
.../gtest/test/gtest-tuple_test.cc | 320 +
.../gtest/test/gtest-typed-test2_test.cc | 45 +
.../gtest/test/gtest-typed-test_test.cc | 361 +
.../gtest/test/gtest-typed-test_test.h | 66 +
.../gtest/test/gtest-unittest-api_test.cc | 341 +
.../google_test/gtest/test/gtest_all_test.cc | 47 +
.../test/gtest_break_on_failure_unittest.py | 212 +
.../test/gtest_break_on_failure_unittest_.cc | 88 +
.../gtest/test/gtest_catch_exceptions_test.py | 237 +
.../test/gtest_catch_exceptions_test_.cc | 311 +
.../gtest/test/gtest_color_test.py | 130 +
.../gtest/test/gtest_color_test_.cc | 71 +
.../gtest/test/gtest_env_var_test.py | 103 +
.../gtest/test/gtest_env_var_test_.cc | 126 +
.../gtest/test/gtest_environment_test.cc | 192 +
.../gtest/test/gtest_filter_unittest.py | 633 +
.../gtest/test/gtest_filter_unittest_.cc | 140 +
.../google_test/gtest/test/gtest_help_test.py | 172 +
.../gtest/test/gtest_help_test_.cc | 46 +
.../gtest/test/gtest_list_tests_unittest.py | 207 +
.../gtest/test/gtest_list_tests_unittest_.cc | 157 +
.../gtest/test/gtest_main_unittest.cc | 45 +
.../gtest/test/gtest_no_test_unittest.cc | 56 +
.../gtest/test/gtest_output_test.py | 335 +
.../gtest/test/gtest_output_test_.cc | 1039 +
.../test/gtest_output_test_golden_lin.txt | 732 +
.../gtest/test/gtest_pred_impl_unittest.cc | 2427 +
.../gtest/test/gtest_premature_exit_test.cc | 143 +
.../google_test/gtest/test/gtest_prod_test.cc | 57 +
.../gtest/test/gtest_repeat_test.cc | 253 +
.../gtest/test/gtest_shuffle_test.py | 325 +
.../gtest/test/gtest_shuffle_test_.cc | 103 +
.../gtest/test/gtest_sole_header_test.cc | 57 +
.../gtest/test/gtest_stress_test.cc | 256 +
.../gtest/test/gtest_test_utils.py | 320 +
.../test/gtest_throw_on_failure_ex_test.cc | 92 +
.../gtest/test/gtest_throw_on_failure_test.py | 171 +
.../test/gtest_throw_on_failure_test_.cc | 72 +
.../gtest/test/gtest_uninitialized_test.py | 70 +
.../gtest/test/gtest_uninitialized_test_.cc | 43 +
.../google_test/gtest/test/gtest_unittest.cc | 7525 +
.../gtest/test/gtest_xml_outfile1_test_.cc | 49 +
.../gtest/test/gtest_xml_outfile2_test_.cc | 49 +
.../gtest/test/gtest_xml_outfiles_test.py | 132 +
.../gtest/test/gtest_xml_output_unittest.py | 307 +
.../gtest/test/gtest_xml_output_unittest_.cc | 181 +
.../gtest/test/gtest_xml_test_utils.py | 194 +
.../google_test/gtest/test/production.cc | 36 +
.../google_test/gtest/test/production.h | 55 +
.../gtest/xcode/Config/DebugProject.xcconfig | 30 +
.../xcode/Config/FrameworkTarget.xcconfig | 17 +
.../gtest/xcode/Config/General.xcconfig | 41 +
.../xcode/Config/ReleaseProject.xcconfig | 32 +
.../xcode/Config/StaticLibraryTarget.xcconfig | 18 +
.../gtest/xcode/Config/TestTarget.xcconfig | 8 +
.../gtest/xcode/Resources/Info.plist | 30 +
.../xcode/Samples/FrameworkSample/Info.plist | 28 +
.../WidgetFramework.xcodeproj/project.pbxproj | 457 +
.../xcode/Samples/FrameworkSample/runtests.sh | 62 +
.../xcode/Samples/FrameworkSample/widget.cc | 63 +
.../xcode/Samples/FrameworkSample/widget.h | 59 +
.../Samples/FrameworkSample/widget_test.cc | 68 +
.../gtest/xcode/Scripts/runtests.sh | 65 +
.../gtest/xcode/Scripts/versiongenerate.py | 100 +
.../xcode/gtest.xcodeproj/project.pbxproj | 1135 +
nss/external_tests/google_test/manifest.mn | 23 +
nss/external_tests/manifest.mn | 16 +
nss/external_tests/nss_bogo_shim/Makefile | 52 +
nss/external_tests/nss_bogo_shim/config.cc | 58 +
nss/external_tests/nss_bogo_shim/config.h | 89 +
nss/external_tests/nss_bogo_shim/config.json | 41 +
nss/external_tests/nss_bogo_shim/manifest.mn | 20 +
.../nss_bogo_shim/nss_bogo_shim.cc | 314 +
nss/external_tests/nss_bogo_shim/nsskeys.cc | 84 +
nss/external_tests/nss_bogo_shim/nsskeys.h | 20 +
nss/external_tests/pk11_gtest/Makefile | 43 +
nss/external_tests/pk11_gtest/manifest.mn | 26 +
.../pk11_gtest/pk11_aeskeywrap_unittest.cc | 132 +
.../pk11_chacha20poly1305_unittest.cc | 263 +
.../pk11_gtest/pk11_pbkdf2_unittest.cc | 96 +
.../pk11_gtest/pk11_prf_unittest.cc | 229 +
.../pk11_gtest/pk11_rsapss_unittest.cc | 242 +
nss/external_tests/ssl_gtest/Makefile | 59 +
nss/external_tests/ssl_gtest/databuffer.h | 183 +
nss/external_tests/ssl_gtest/gtest_utils.h | 57 +
.../ssl_gtest/libssl_internals.c | 285 +
.../ssl_gtest/libssl_internals.h | 40 +
nss/external_tests/ssl_gtest/manifest.mn | 52 +
.../ssl_gtest/ssl_0rtt_unittest.cc | 196 +
.../ssl_gtest/ssl_agent_unittest.cc | 254 +
.../ssl_gtest/ssl_auth_unittest.cc | 523 +
.../ssl_gtest/ssl_cert_ext_unittest.cc | 214 +
.../ssl_gtest/ssl_ciphersuite_unittest.cc | 438 +
.../ssl_gtest/ssl_damage_unittest.cc | 61 +
.../ssl_gtest/ssl_dhe_unittest.cc | 520 +
.../ssl_gtest/ssl_drop_unittest.cc | 113 +
.../ssl_gtest/ssl_ecdh_unittest.cc | 343 +
.../ssl_gtest/ssl_ems_unittest.cc | 100 +
.../ssl_gtest/ssl_extension_unittest.cc | 580 +
nss/external_tests/ssl_gtest/ssl_gtest.cc | 44 +
.../ssl_gtest/ssl_hrr_unittest.cc | 197 +
.../ssl_gtest/ssl_loopback_unittest.cc | 241 +
.../ssl_gtest/ssl_record_unittest.cc | 111 +
.../ssl_gtest/ssl_resumption_unittest.cc | 443 +
.../ssl_gtest/ssl_skip_unittest.cc | 159 +
.../ssl_gtest/ssl_staticrsa_unittest.cc | 123 +
.../ssl_gtest/ssl_v2_client_hello_unittest.cc | 355 +
.../ssl_gtest/ssl_version_unittest.cc | 244 +
nss/external_tests/ssl_gtest/test_io.cc | 536 +
nss/external_tests/ssl_gtest/test_io.h | 146 +
nss/external_tests/ssl_gtest/tls_agent.cc | 883 +
nss/external_tests/ssl_gtest/tls_agent.h | 425 +
nss/external_tests/ssl_gtest/tls_connect.cc | 546 +
nss/external_tests/ssl_gtest/tls_connect.h | 224 +
nss/external_tests/ssl_gtest/tls_filter.cc | 475 +
nss/external_tests/ssl_gtest/tls_filter.h | 303 +
.../ssl_gtest/tls_hkdf_unittest.cc | 262 +
nss/external_tests/ssl_gtest/tls_parser.cc | 73 +
nss/external_tests/ssl_gtest/tls_parser.h | 125 +
nss/external_tests/util_gtest/Makefile | 45 +
nss/external_tests/util_gtest/manifest.mn | 26 +
.../util_gtest/util_utf8_unittest.cc | 979 +
nss/fuzz/.clang-format | 4 +
nss/fuzz/asn1_mutators.cc | 122 +
nss/fuzz/asn1_mutators.h | 16 +
nss/fuzz/certDN.options | 3 +
nss/fuzz/certDN_target.cc | 45 +
nss/fuzz/clone_corpus.sh | 4 +
nss/fuzz/clone_libfuzzer.sh | 46 +
nss/fuzz/fuzz.gyp | 302 +
nss/fuzz/git-copy.sh | 32 +
nss/fuzz/mpi-add.options | 3 +
nss/fuzz/mpi-addmod.options | 3 +
nss/fuzz/mpi-div.options | 3 +
nss/fuzz/mpi-expmod.options | 3 +
nss/fuzz/mpi-invmod.options | 2 +
nss/fuzz/mpi-mod.options | 3 +
nss/fuzz/mpi-mulmod.options | 3 +
nss/fuzz/mpi-sqr.options | 3 +
nss/fuzz/mpi-sqrmod.options | 3 +
nss/fuzz/mpi-sub.options | 3 +
nss/fuzz/mpi-submod.options | 3 +
nss/fuzz/mpi_add_target.cc | 42 +
nss/fuzz/mpi_addmod_target.cc | 27 +
nss/fuzz/mpi_div_target.cc | 36 +
nss/fuzz/mpi_expmod_target.cc | 27 +
nss/fuzz/mpi_helper.cc | 100 +
nss/fuzz/mpi_helper.h | 86 +
nss/fuzz/mpi_invmod_target.cc | 70 +
nss/fuzz/mpi_mod_target.cc | 36 +
nss/fuzz/mpi_mulmod_target.cc | 27 +
nss/fuzz/mpi_sqr_target.cc | 40 +
nss/fuzz/mpi_sqrmod_target.cc | 36 +
nss/fuzz/mpi_sub_target.cc | 42 +
nss/fuzz/mpi_submod_target.cc | 27 +
nss/fuzz/pkcs8_target.cc | 39 +
nss/fuzz/quickder.options | 3 +
nss/fuzz/quickder_target.cc | 85 +
nss/fuzz/shared.h | 40 +
nss/fuzz/tls-client-no_fuzzer_mode.options | 3 +
nss/fuzz/tls-client.options | 3 +
nss/fuzz/tls_client_config.cc | 35 +
nss/fuzz/tls_client_config.h | 24 +
nss/fuzz/tls_client_socket.cc | 34 +
nss/fuzz/tls_client_socket.h | 24 +
nss/fuzz/tls_client_target.cc | 130 +
nss/fuzz/warning.txt | 16 +
nss/gtests/.clang-format | 4 +
nss/gtests/Makefile | 44 +
nss/gtests/README | 15 +
nss/gtests/common/Makefile | 41 +
nss/gtests/common/gtest.gypi | 45 +
nss/gtests/common/gtest.mk | 36 +
nss/gtests/common/gtests.cc | 26 +
nss/gtests/common/manifest.mn | 22 +
nss/gtests/der_gtest/Makefile | 43 +
nss/gtests/der_gtest/der_getint_unittest.cc | 122 +
nss/gtests/der_gtest/der_gtest.gyp | 30 +
.../der_private_key_import_unittest.cc | 110 +
nss/gtests/der_gtest/manifest.mn | 23 +
nss/gtests/freebl_gtest/freebl_gtest.gyp | 69 +
nss/gtests/freebl_gtest/kat/Hash_DRBG.rsp | 17702 ++
nss/gtests/freebl_gtest/kat/Hash_DRBG.txt | 44582 ++++
nss/gtests/freebl_gtest/mpi_unittest.cc | 120 +
nss/gtests/freebl_gtest/prng_kat_unittest.cc | 195 +
nss/gtests/google_test/Makefile | 44 +
nss/gtests/google_test/google_test.gyp | 26 +
nss/gtests/google_test/gtest/CHANGES | 157 +
nss/gtests/google_test/gtest/CMakeLists.txt | 260 +
nss/gtests/google_test/gtest/CONTRIBUTORS | 37 +
nss/gtests/google_test/gtest/LICENSE | 28 +
nss/gtests/google_test/gtest/Makefile.am | 306 +
nss/gtests/google_test/gtest/README | 435 +
nss/gtests/google_test/gtest/build-aux/.keep | 0
.../gtest/cmake/internal_utils.cmake | 242 +
.../google_test/gtest/codegear/gtest.cbproj | 138 +
.../gtest/codegear/gtest.groupproj | 54 +
.../google_test/gtest/codegear/gtest_all.cc | 38 +
.../google_test/gtest/codegear/gtest_link.cc | 40 +
.../gtest/codegear/gtest_main.cbproj | 82 +
.../gtest/codegear/gtest_unittest.cbproj | 88 +
nss/gtests/google_test/gtest/configure.ac | 68 +
.../gtest/include/gtest/gtest-death-test.h | 294 +
.../gtest/include/gtest/gtest-message.h | 250 +
.../gtest/include/gtest/gtest-param-test.h | 1421 +
.../include/gtest/gtest-param-test.h.pump | 487 +
.../gtest/include/gtest/gtest-printers.h | 891 +
.../gtest/include/gtest/gtest-spi.h | 232 +
.../gtest/include/gtest/gtest-test-part.h | 179 +
.../gtest/include/gtest/gtest-typed-test.h | 259 +
.../google_test/gtest/include/gtest/gtest.h | 2307 +
.../gtest/include/gtest/gtest_pred_impl.h | 358 +
.../gtest/include/gtest/gtest_prod.h | 58 +
.../internal/gtest-death-test-internal.h | 319 +
.../include/gtest/internal/gtest-filepath.h | 206 +
.../include/gtest/internal/gtest-internal.h | 1193 +
.../include/gtest/internal/gtest-linked_ptr.h | 233 +
.../internal/gtest-param-util-generated.h | 5143 +
.../gtest-param-util-generated.h.pump | 301 +
.../include/gtest/internal/gtest-param-util.h | 619 +
.../gtest/include/gtest/internal/gtest-port.h | 2432 +
.../include/gtest/internal/gtest-string.h | 167 +
.../include/gtest/internal/gtest-tuple.h | 1020 +
.../include/gtest/internal/gtest-tuple.h.pump | 347 +
.../include/gtest/internal/gtest-type-util.h | 3331 +
.../gtest/internal/gtest-type-util.h.pump | 297 +
.../google_test/gtest/m4/acx_pthread.m4 | 363 +
nss/gtests/google_test/gtest/m4/gtest.m4 | 74 +
nss/gtests/google_test/gtest/make/Makefile | 82 +
.../google_test/gtest/msvc/gtest-md.sln | 45 +
.../google_test/gtest/msvc/gtest-md.vcproj | 126 +
nss/gtests/google_test/gtest/msvc/gtest.sln | 45 +
.../google_test/gtest/msvc/gtest.vcproj | 126 +
.../gtest/msvc/gtest_main-md.vcproj | 129 +
.../google_test/gtest/msvc/gtest_main.vcproj | 129 +
.../gtest/msvc/gtest_prod_test-md.vcproj | 164 +
.../gtest/msvc/gtest_prod_test.vcproj | 164 +
.../gtest/msvc/gtest_unittest-md.vcproj | 147 +
.../gtest/msvc/gtest_unittest.vcproj | 147 +
.../google_test/gtest/samples/prime_tables.h | 123 +
.../google_test/gtest/samples/sample1.cc | 68 +
.../google_test/gtest/samples/sample1.h | 43 +
.../gtest/samples/sample10_unittest.cc | 144 +
.../gtest/samples/sample1_unittest.cc | 153 +
.../google_test/gtest/samples/sample2.cc | 56 +
.../google_test/gtest/samples/sample2.h | 85 +
.../gtest/samples/sample2_unittest.cc | 109 +
.../google_test/gtest/samples/sample3-inl.h | 172 +
.../gtest/samples/sample3_unittest.cc | 151 +
.../google_test/gtest/samples/sample4.cc | 46 +
.../google_test/gtest/samples/sample4.h | 53 +
.../gtest/samples/sample4_unittest.cc | 45 +
.../gtest/samples/sample5_unittest.cc | 199 +
.../gtest/samples/sample6_unittest.cc | 224 +
.../gtest/samples/sample7_unittest.cc | 130 +
.../gtest/samples/sample8_unittest.cc | 173 +
.../gtest/samples/sample9_unittest.cc | 160 +
.../google_test/gtest/scripts/common.py | 83 +
.../gtest/scripts/fuse_gtest_files.py | 250 +
.../gtest/scripts/gen_gtest_pred_impl.py | 730 +
.../google_test/gtest/scripts/gtest-config.in | 274 +
nss/gtests/google_test/gtest/scripts/pump.py | 855 +
.../google_test/gtest/scripts/release_docs.py | 158 +
.../google_test/gtest/scripts/test/Makefile | 59 +
.../google_test/gtest/scripts/upload.py | 1387 +
.../google_test/gtest/scripts/upload_gtest.py | 78 +
nss/gtests/google_test/gtest/src/gtest-all.cc | 48 +
.../google_test/gtest/src/gtest-death-test.cc | 1346 +
.../google_test/gtest/src/gtest-filepath.cc | 387 +
.../gtest/src/gtest-internal-inl.h | 1192 +
.../google_test/gtest/src/gtest-port.cc | 1184 +
.../google_test/gtest/src/gtest-printers.cc | 373 +
.../google_test/gtest/src/gtest-test-part.cc | 110 +
.../google_test/gtest/src/gtest-typed-test.cc | 110 +
nss/gtests/google_test/gtest/src/gtest.cc | 5291 +
.../google_test/gtest/src/gtest_main.cc | 38 +
.../gtest/test/gtest-death-test_ex_test.cc | 93 +
.../gtest/test/gtest-death-test_test.cc | 1423 +
.../gtest/test/gtest-filepath_test.cc | 680 +
.../gtest/test/gtest-linked_ptr_test.cc | 154 +
.../gtest/test/gtest-listener_test.cc | 310 +
.../gtest/test/gtest-message_test.cc | 159 +
.../gtest/test/gtest-options_test.cc | 215 +
.../gtest/test/gtest-param-test2_test.cc | 65 +
.../gtest/test/gtest-param-test_test.cc | 904 +
.../gtest/test/gtest-param-test_test.h | 57 +
.../google_test/gtest/test/gtest-port_test.cc | 1323 +
.../gtest/test/gtest-printers_test.cc | 1651 +
.../gtest/test/gtest-test-part_test.cc | 208 +
.../gtest/test/gtest-tuple_test.cc | 320 +
.../gtest/test/gtest-typed-test2_test.cc | 45 +
.../gtest/test/gtest-typed-test_test.cc | 361 +
.../gtest/test/gtest-typed-test_test.h | 66 +
.../gtest/test/gtest-unittest-api_test.cc | 341 +
.../google_test/gtest/test/gtest_all_test.cc | 47 +
.../test/gtest_break_on_failure_unittest.py | 212 +
.../test/gtest_break_on_failure_unittest_.cc | 88 +
.../gtest/test/gtest_catch_exceptions_test.py | 237 +
.../test/gtest_catch_exceptions_test_.cc | 311 +
.../gtest/test/gtest_color_test.py | 130 +
.../gtest/test/gtest_color_test_.cc | 71 +
.../gtest/test/gtest_env_var_test.py | 103 +
.../gtest/test/gtest_env_var_test_.cc | 126 +
.../gtest/test/gtest_environment_test.cc | 192 +
.../gtest/test/gtest_filter_unittest.py | 633 +
.../gtest/test/gtest_filter_unittest_.cc | 140 +
.../google_test/gtest/test/gtest_help_test.py | 172 +
.../gtest/test/gtest_help_test_.cc | 46 +
.../gtest/test/gtest_list_tests_unittest.py | 207 +
.../gtest/test/gtest_list_tests_unittest_.cc | 157 +
.../gtest/test/gtest_main_unittest.cc | 45 +
.../gtest/test/gtest_no_test_unittest.cc | 56 +
.../gtest/test/gtest_output_test.py | 335 +
.../gtest/test/gtest_output_test_.cc | 1039 +
.../test/gtest_output_test_golden_lin.txt | 732 +
.../gtest/test/gtest_pred_impl_unittest.cc | 2427 +
.../gtest/test/gtest_premature_exit_test.cc | 143 +
.../google_test/gtest/test/gtest_prod_test.cc | 57 +
.../gtest/test/gtest_repeat_test.cc | 253 +
.../gtest/test/gtest_shuffle_test.py | 325 +
.../gtest/test/gtest_shuffle_test_.cc | 103 +
.../gtest/test/gtest_sole_header_test.cc | 57 +
.../gtest/test/gtest_stress_test.cc | 256 +
.../gtest/test/gtest_test_utils.py | 320 +
.../test/gtest_throw_on_failure_ex_test.cc | 92 +
.../gtest/test/gtest_throw_on_failure_test.py | 171 +
.../test/gtest_throw_on_failure_test_.cc | 72 +
.../gtest/test/gtest_uninitialized_test.py | 70 +
.../gtest/test/gtest_uninitialized_test_.cc | 43 +
.../google_test/gtest/test/gtest_unittest.cc | 7525 +
.../gtest/test/gtest_xml_outfile1_test_.cc | 49 +
.../gtest/test/gtest_xml_outfile2_test_.cc | 49 +
.../gtest/test/gtest_xml_outfiles_test.py | 132 +
.../gtest/test/gtest_xml_output_unittest.py | 307 +
.../gtest/test/gtest_xml_output_unittest_.cc | 181 +
.../gtest/test/gtest_xml_test_utils.py | 194 +
.../google_test/gtest/test/production.cc | 36 +
.../google_test/gtest/test/production.h | 55 +
.../gtest/xcode/Config/DebugProject.xcconfig | 30 +
.../xcode/Config/FrameworkTarget.xcconfig | 17 +
.../gtest/xcode/Config/General.xcconfig | 41 +
.../xcode/Config/ReleaseProject.xcconfig | 32 +
.../xcode/Config/StaticLibraryTarget.xcconfig | 18 +
.../gtest/xcode/Config/TestTarget.xcconfig | 8 +
.../gtest/xcode/Resources/Info.plist | 30 +
.../xcode/Samples/FrameworkSample/Info.plist | 28 +
.../WidgetFramework.xcodeproj/project.pbxproj | 457 +
.../xcode/Samples/FrameworkSample/runtests.sh | 62 +
.../xcode/Samples/FrameworkSample/widget.cc | 63 +
.../xcode/Samples/FrameworkSample/widget.h | 59 +
.../Samples/FrameworkSample/widget_test.cc | 68 +
.../gtest/xcode/Scripts/runtests.sh | 65 +
.../gtest/xcode/Scripts/versiongenerate.py | 100 +
.../xcode/gtest.xcodeproj/project.pbxproj | 1135 +
nss/gtests/google_test/manifest.mn | 23 +
nss/gtests/manifest.mn | 16 +
nss/gtests/nss_bogo_shim/Makefile | 52 +
nss/gtests/nss_bogo_shim/config.cc | 58 +
nss/gtests/nss_bogo_shim/config.h | 93 +
nss/gtests/nss_bogo_shim/config.json | 68 +
nss/gtests/nss_bogo_shim/manifest.mn | 20 +
nss/gtests/nss_bogo_shim/nss_bogo_shim.cc | 579 +
nss/gtests/nss_bogo_shim/nss_bogo_shim.gyp | 76 +
nss/gtests/nss_bogo_shim/nsskeys.cc | 83 +
nss/gtests/nss_bogo_shim/nsskeys.h | 20 +
nss/gtests/pk11_gtest/Makefile | 43 +
nss/gtests/pk11_gtest/manifest.mn | 31 +
.../pk11_gtest/pk11_aeskeywrap_unittest.cc | 132 +
.../pk11_chacha20poly1305_unittest.cc | 263 +
.../pk11_gtest/pk11_curve25519_unittest.cc | 117 +
nss/gtests/pk11_gtest/pk11_ecdsa_unittest.cc | 156 +
nss/gtests/pk11_gtest/pk11_ecdsa_vectors.h | 251 +
nss/gtests/pk11_gtest/pk11_export_unittest.cc | 66 +
nss/gtests/pk11_gtest/pk11_gtest.gyp | 54 +
nss/gtests/pk11_gtest/pk11_pbkdf2_unittest.cc | 96 +
nss/gtests/pk11_gtest/pk11_prf_unittest.cc | 229 +
nss/gtests/pk11_gtest/pk11_prng_unittest.cc | 78 +
nss/gtests/pk11_gtest/pk11_rsapss_unittest.cc | 199 +
nss/gtests/pk11_gtest/pk11_rsapss_vectors.h | 1083 +
nss/gtests/pk11_gtest/pk11_signature_test.h | 140 +
nss/gtests/ssl_gtest/Makefile | 56 +
nss/gtests/ssl_gtest/databuffer.h | 191 +
nss/gtests/ssl_gtest/gtest_utils.h | 57 +
nss/gtests/ssl_gtest/libssl_internals.c | 373 +
nss/gtests/ssl_gtest/libssl_internals.h | 54 +
nss/gtests/ssl_gtest/manifest.mn | 59 +
nss/gtests/ssl_gtest/ssl_0rtt_unittest.cc | 285 +
nss/gtests/ssl_gtest/ssl_agent_unittest.cc | 210 +
nss/gtests/ssl_gtest/ssl_auth_unittest.cc | 831 +
nss/gtests/ssl_gtest/ssl_cert_ext_unittest.cc | 257 +
.../ssl_gtest/ssl_ciphersuite_unittest.cc | 464 +
nss/gtests/ssl_gtest/ssl_damage_unittest.cc | 61 +
nss/gtests/ssl_gtest/ssl_dhe_unittest.cc | 614 +
nss/gtests/ssl_gtest/ssl_drop_unittest.cc | 133 +
nss/gtests/ssl_gtest/ssl_ecdh_unittest.cc | 586 +
nss/gtests/ssl_gtest/ssl_ems_unittest.cc | 100 +
nss/gtests/ssl_gtest/ssl_exporter_unittest.cc | 125 +
.../ssl_gtest/ssl_extension_unittest.cc | 1032 +
nss/gtests/ssl_gtest/ssl_fragment_unittest.cc | 157 +
nss/gtests/ssl_gtest/ssl_fuzz_unittest.cc | 229 +
nss/gtests/ssl_gtest/ssl_gather_unittest.cc | 153 +
nss/gtests/ssl_gtest/ssl_gtest.cc | 50 +
nss/gtests/ssl_gtest/ssl_gtest.gyp | 112 +
nss/gtests/ssl_gtest/ssl_hrr_unittest.cc | 363 +
nss/gtests/ssl_gtest/ssl_loopback_unittest.cc | 273 +
nss/gtests/ssl_gtest/ssl_record_unittest.cc | 111 +
.../ssl_gtest/ssl_resumption_unittest.cc | 699 +
nss/gtests/ssl_gtest/ssl_skip_unittest.cc | 235 +
.../ssl_gtest/ssl_staticrsa_unittest.cc | 125 +
.../ssl_gtest/ssl_v2_client_hello_unittest.cc | 373 +
nss/gtests/ssl_gtest/ssl_version_unittest.cc | 319 +
nss/gtests/ssl_gtest/test_io.cc | 251 +
nss/gtests/ssl_gtest/test_io.h | 174 +
nss/gtests/ssl_gtest/tls_agent.cc | 1027 +
nss/gtests/ssl_gtest/tls_agent.h | 535 +
nss/gtests/ssl_gtest/tls_connect.cc | 729 +
nss/gtests/ssl_gtest/tls_connect.h | 275 +
nss/gtests/ssl_gtest/tls_filter.cc | 617 +
nss/gtests/ssl_gtest/tls_filter.h | 401 +
nss/gtests/ssl_gtest/tls_hkdf_unittest.cc | 262 +
nss/gtests/ssl_gtest/tls_parser.cc | 73 +
nss/gtests/ssl_gtest/tls_parser.h | 132 +
nss/gtests/ssl_gtest/tls_protect.cc | 145 +
nss/gtests/ssl_gtest/tls_protect.h | 76 +
nss/gtests/util_gtest/Makefile | 45 +
nss/gtests/util_gtest/manifest.mn | 28 +
nss/gtests/util_gtest/util_b64_unittest.cc | 79 +
nss/gtests/util_gtest/util_gtest.gyp | 42 +
nss/gtests/util_gtest/util_utf8_unittest.cc | 986 +
nss/lib/Makefile | 97 +
nss/lib/base/Makefile | 11 +
nss/lib/base/arena.c | 1143 +
nss/lib/base/base.gyp | 32 +
nss/lib/base/base.h | 1106 +
nss/lib/base/baset.h | 124 +
nss/lib/base/config.mk | 19 +
nss/lib/base/error.c | 272 +
nss/lib/base/errorval.c | 65 +
nss/lib/base/exports.gyp | 33 +
nss/lib/base/hash.c | 314 +
nss/lib/base/hashops.c | 64 +
nss/lib/base/item.c | 186 +
nss/lib/base/libc.c | 143 +
nss/lib/base/list.c | 405 +
nss/lib/base/manifest.mn | 38 +
nss/lib/base/nssbase.h | 233 +
nss/lib/base/nssbaset.h | 118 +
nss/lib/base/tracker.c | 378 +
nss/lib/base/utf8.c | 679 +
nss/lib/certdb/Makefile | 48 +
nss/lib/certdb/alg1485.c | 1579 +
nss/lib/certdb/cert.h | 1584 +
nss/lib/certdb/certdb.c | 3231 +
nss/lib/certdb/certdb.gyp | 34 +
nss/lib/certdb/certdb.h | 89 +
nss/lib/certdb/certi.h | 381 +
nss/lib/certdb/certt.h | 1328 +
nss/lib/certdb/certv3.c | 222 +
nss/lib/certdb/certxutl.c | 493 +
nss/lib/certdb/certxutl.h | 44 +
nss/lib/certdb/config.mk | 15 +
nss/lib/certdb/crl.c | 3045 +
nss/lib/certdb/exports.gyp | 36 +
nss/lib/certdb/genname.c | 1990 +
nss/lib/certdb/genname.h | 93 +
nss/lib/certdb/manifest.mn | 40 +
nss/lib/certdb/polcyxtn.c | 806 +
nss/lib/certdb/secname.c | 711 +
nss/lib/certdb/stanpcertdb.c | 1035 +
nss/lib/certdb/xauthkid.c | 128 +
nss/lib/certdb/xbsconst.c | 143 +
nss/lib/certdb/xconst.c | 269 +
nss/lib/certdb/xconst.h | 30 +
nss/lib/certhigh/Makefile | 48 +
nss/lib/certhigh/certhigh.c | 1207 +
nss/lib/certhigh/certhigh.gyp | 31 +
nss/lib/certhigh/certhtml.c | 300 +
nss/lib/certhigh/certreq.c | 331 +
nss/lib/certhigh/certvfy.c | 2082 +
nss/lib/certhigh/certvfypkix.c | 2305 +
nss/lib/certhigh/config.mk | 15 +
nss/lib/certhigh/crlv2.c | 160 +
nss/lib/certhigh/exports.gyp | 33 +
nss/lib/certhigh/manifest.mn | 34 +
nss/lib/certhigh/ocsp.c | 6120 +
nss/lib/certhigh/ocsp.h | 723 +
nss/lib/certhigh/ocspi.h | 166 +
nss/lib/certhigh/ocspsig.c | 597 +
nss/lib/certhigh/ocspt.h | 301 +
nss/lib/certhigh/ocspti.h | 356 +
nss/lib/certhigh/xcrldist.c | 212 +
nss/lib/ckfw/Makefile | 39 +
nss/lib/ckfw/builtins/Makefile | 54 +
nss/lib/ckfw/builtins/README | 45 +
nss/lib/ckfw/builtins/anchor.c | 17 +
nss/lib/ckfw/builtins/bfind.c | 261 +
nss/lib/ckfw/builtins/binst.c | 87 +
nss/lib/ckfw/builtins/bobject.c | 206 +
nss/lib/ckfw/builtins/bsession.c | 71 +
nss/lib/ckfw/builtins/bslot.c | 81 +
nss/lib/ckfw/builtins/btoken.c | 135 +
nss/lib/ckfw/builtins/builtins.gyp | 61 +
nss/lib/ckfw/builtins/builtins.h | 66 +
nss/lib/ckfw/builtins/certdata.perl | 192 +
nss/lib/ckfw/builtins/certdata.txt | 30029 +++
nss/lib/ckfw/builtins/ckbiver.c | 18 +
nss/lib/ckfw/builtins/config.mk | 38 +
nss/lib/ckfw/builtins/constants.c | 64 +
nss/lib/ckfw/builtins/exports.gyp | 25 +
nss/lib/ckfw/builtins/manifest.mn | 30 +
nss/lib/ckfw/builtins/nssckbi.def | 26 +
nss/lib/ckfw/builtins/nssckbi.h | 60 +
nss/lib/ckfw/builtins/nssckbi.rc | 64 +
nss/lib/ckfw/capi/Makefile | 75 +
nss/lib/ckfw/capi/README | 7 +
nss/lib/ckfw/capi/anchor.c | 17 +
nss/lib/ckfw/capi/cfind.c | 562 +
nss/lib/ckfw/capi/cinst.c | 97 +
nss/lib/ckfw/capi/ckcapi.h | 242 +
nss/lib/ckfw/capi/ckcapiver.c | 17 +
nss/lib/ckfw/capi/cobject.c | 2226 +
nss/lib/ckfw/capi/config.mk | 31 +
nss/lib/ckfw/capi/constants.c | 63 +
nss/lib/ckfw/capi/crsa.c | 687 +
nss/lib/ckfw/capi/csession.c | 87 +
nss/lib/ckfw/capi/cslot.c | 81 +
nss/lib/ckfw/capi/ctoken.c | 184 +
nss/lib/ckfw/capi/manifest.mn | 33 +
nss/lib/ckfw/capi/nsscapi.def | 26 +
nss/lib/ckfw/capi/nsscapi.h | 41 +
nss/lib/ckfw/capi/nsscapi.rc | 64 +
nss/lib/ckfw/capi/staticobj.c | 40 +
nss/lib/ckfw/ck.api | 541 +
nss/lib/ckfw/ck.h | 88 +
nss/lib/ckfw/ckapi.perl | 434 +
nss/lib/ckfw/ckfw.gyp | 34 +
nss/lib/ckfw/ckfw.h | 2049 +
nss/lib/ckfw/ckfwm.h | 112 +
nss/lib/ckfw/ckfwtm.h | 23 +
nss/lib/ckfw/ckmd.h | 28 +
nss/lib/ckfw/ckt.h | 8 +
nss/lib/ckfw/config.mk | 25 +
nss/lib/ckfw/crypto.c | 318 +
nss/lib/ckfw/dbm/Makefile | 9 +
nss/lib/ckfw/dbm/anchor.c | 17 +
nss/lib/ckfw/dbm/ckdbm.h | 210 +
nss/lib/ckfw/dbm/config.mk | 8 +
nss/lib/ckfw/dbm/db.c | 1069 +
nss/lib/ckfw/dbm/find.c | 126 +
nss/lib/ckfw/dbm/instance.c | 147 +
nss/lib/ckfw/dbm/manifest.mn | 25 +
nss/lib/ckfw/dbm/object.c | 155 +
nss/lib/ckfw/dbm/session.c | 255 +
nss/lib/ckfw/dbm/slot.c | 165 +
nss/lib/ckfw/dbm/token.c | 260 +
nss/lib/ckfw/exports.gyp | 44 +
nss/lib/ckfw/find.c | 362 +
nss/lib/ckfw/hash.c | 280 +
nss/lib/ckfw/instance.c | 1294 +
nss/lib/ckfw/manifest.mn | 53 +
nss/lib/ckfw/mechanism.c | 1102 +
nss/lib/ckfw/mutex.c | 248 +
nss/lib/ckfw/nssck.api | 1854 +
nss/lib/ckfw/nssckepv.h | 10 +
nss/lib/ckfw/nssckft.h | 11 +
nss/lib/ckfw/nssckfw.h | 462 +
nss/lib/ckfw/nssckfwc.h | 879 +
nss/lib/ckfw/nssckfwt.h | 109 +
nss/lib/ckfw/nssckg.h | 10 +
nss/lib/ckfw/nssckmdt.h | 1904 +
nss/lib/ckfw/nssckt.h | 12 +
nss/lib/ckfw/nssmkey/Makefile | 72 +
nss/lib/ckfw/nssmkey/README | 21 +
nss/lib/ckfw/nssmkey/ckmk.h | 182 +
nss/lib/ckfw/nssmkey/ckmkver.c | 17 +
nss/lib/ckfw/nssmkey/config.mk | 24 +
nss/lib/ckfw/nssmkey/manchor.c | 17 +
nss/lib/ckfw/nssmkey/manifest.mn | 33 +
nss/lib/ckfw/nssmkey/mconstants.c | 61 +
nss/lib/ckfw/nssmkey/mfind.c | 352 +
nss/lib/ckfw/nssmkey/minst.c | 97 +
nss/lib/ckfw/nssmkey/mobject.c | 1861 +
nss/lib/ckfw/nssmkey/mrsa.c | 479 +
nss/lib/ckfw/nssmkey/msession.c | 87 +
nss/lib/ckfw/nssmkey/mslot.c | 81 +
nss/lib/ckfw/nssmkey/mtoken.c | 184 +
nss/lib/ckfw/nssmkey/nssmkey.def | 26 +
nss/lib/ckfw/nssmkey/nssmkey.h | 41 +
nss/lib/ckfw/nssmkey/staticobj.c | 36 +
nss/lib/ckfw/object.c | 973 +
nss/lib/ckfw/session.c | 2390 +
nss/lib/ckfw/sessobj.c | 1012 +
nss/lib/ckfw/slot.c | 694 +
nss/lib/ckfw/token.c | 1791 +
nss/lib/ckfw/wrap.c | 5550 +
nss/lib/crmf/Makefile | 49 +
nss/lib/crmf/asn1cmn.c | 216 +
nss/lib/crmf/challcli.c | 238 +
nss/lib/crmf/cmmf.h | 1082 +
nss/lib/crmf/cmmfasn1.c | 131 +
nss/lib/crmf/cmmfchal.c | 289 +
nss/lib/crmf/cmmfi.h | 92 +
nss/lib/crmf/cmmfit.h | 115 +
nss/lib/crmf/cmmfrec.c | 316 +
nss/lib/crmf/cmmfresp.c | 280 +
nss/lib/crmf/cmmft.h | 73 +
nss/lib/crmf/config.mk | 16 +
nss/lib/crmf/crmf.gyp | 43 +
nss/lib/crmf/crmf.h | 1741 +
nss/lib/crmf/crmfcont.c | 1161 +
nss/lib/crmf/crmfdec.c | 360 +
nss/lib/crmf/crmfenc.c | 48 +
nss/lib/crmf/crmffut.h | 357 +
nss/lib/crmf/crmfget.c | 443 +
nss/lib/crmf/crmfi.h | 185 +
nss/lib/crmf/crmfit.h | 185 +
nss/lib/crmf/crmfpop.c | 598 +
nss/lib/crmf/crmfreq.c | 663 +
nss/lib/crmf/crmft.h | 186 +
nss/lib/crmf/crmftmpl.c | 240 +
nss/lib/crmf/encutil.c | 33 +
nss/lib/crmf/exports.gyp | 37 +
nss/lib/crmf/manifest.mn | 46 +
nss/lib/crmf/respcli.c | 136 +
nss/lib/crmf/respcmn.c | 399 +
nss/lib/crmf/servget.c | 974 +
nss/lib/cryptohi/Makefile | 49 +
nss/lib/cryptohi/config.mk | 15 +
nss/lib/cryptohi/cryptohi.gyp | 27 +
nss/lib/cryptohi/cryptohi.h | 364 +
nss/lib/cryptohi/cryptoht.h | 14 +
nss/lib/cryptohi/dsautil.c | 272 +
nss/lib/cryptohi/exports.gyp | 37 +
nss/lib/cryptohi/key.h | 12 +
nss/lib/cryptohi/keyhi.h | 271 +
nss/lib/cryptohi/keyi.h | 22 +
nss/lib/cryptohi/keyt.h | 10 +
nss/lib/cryptohi/keythi.h | 247 +
nss/lib/cryptohi/manifest.mn | 36 +
nss/lib/cryptohi/sechash.c | 438 +
nss/lib/cryptohi/sechash.h | 58 +
nss/lib/cryptohi/seckey.c | 1976 +
nss/lib/cryptohi/secsign.c | 510 +
nss/lib/cryptohi/secvfy.c | 781 +
nss/lib/dbm/Makefile | 52 +
nss/lib/dbm/config/config.mk | 35 +
nss/lib/dbm/include/Makefile | 47 +
nss/lib/dbm/include/exports.gyp | 38 +
nss/lib/dbm/include/extern.h | 63 +
nss/lib/dbm/include/hash.h | 341 +
nss/lib/dbm/include/hsearch.h | 50 +
nss/lib/dbm/include/include.gyp | 12 +
nss/lib/dbm/include/manifest.mn | 23 +
nss/lib/dbm/include/mcom_db.h | 423 +
nss/lib/dbm/include/ncompat.h | 224 +
nss/lib/dbm/include/page.h | 93 +
nss/lib/dbm/include/queue.h | 258 +
nss/lib/dbm/include/search.h | 50 +
nss/lib/dbm/include/winfile.h | 103 +
nss/lib/dbm/manifest.mn | 17 +
nss/lib/dbm/src/Makefile | 48 +
nss/lib/dbm/src/config.mk | 33 +
nss/lib/dbm/src/db.c | 134 +
nss/lib/dbm/src/dirent.c | 344 +
nss/lib/dbm/src/dirent.h | 97 +
nss/lib/dbm/src/h_bigkey.c | 707 +
nss/lib/dbm/src/h_func.c | 207 +
nss/lib/dbm/src/h_log2.c | 54 +
nss/lib/dbm/src/h_page.c | 1252 +
nss/lib/dbm/src/hash.c | 1172 +
nss/lib/dbm/src/hash_buf.c | 407 +
nss/lib/dbm/src/manifest.mn | 28 +
nss/lib/dbm/src/memmove.c | 146 +
nss/lib/dbm/src/mktemp.c | 149 +
nss/lib/dbm/src/snprintf.c | 50 +
nss/lib/dbm/src/src.gyp | 40 +
nss/lib/dbm/src/strerror.c | 73 +
nss/lib/dbm/tests/Makefile | 41 +
nss/lib/dbm/tests/dbmtest.pkg | 2 +
nss/lib/dbm/tests/lots.c | 553 +
nss/lib/dev/Makefile | 24 +
nss/lib/dev/ckhelper.c | 592 +
nss/lib/dev/ckhelper.h | 148 +
nss/lib/dev/config.mk | 19 +
nss/lib/dev/dev.gyp | 26 +
nss/lib/dev/dev.h | 747 +
nss/lib/dev/devm.h | 157 +
nss/lib/dev/devslot.c | 254 +
nss/lib/dev/devt.h | 147 +
nss/lib/dev/devtm.h | 25 +
nss/lib/dev/devtoken.c | 1558 +
nss/lib/dev/devutil.c | 998 +
nss/lib/dev/exports.gyp | 31 +
nss/lib/dev/manifest.mn | 35 +
nss/lib/dev/nssdev.h | 36 +
nss/lib/dev/nssdevt.h | 36 +
nss/lib/freebl/Makefile | 751 +
nss/lib/freebl/aeskeywrap.c | 389 +
nss/lib/freebl/alg2268.c | 509 +
nss/lib/freebl/alghmac.c | 166 +
nss/lib/freebl/alghmac.h | 64 +
nss/lib/freebl/arcfive.c | 87 +
nss/lib/freebl/arcfour-amd64-gas.s | 88 +
nss/lib/freebl/arcfour-amd64-masm.asm | 107 +
nss/lib/freebl/arcfour-amd64-sun.s | 84 +
nss/lib/freebl/arcfour.c | 594 +
nss/lib/freebl/blapi.h | 1625 +
nss/lib/freebl/blapii.h | 61 +
nss/lib/freebl/blapit.h | 414 +
nss/lib/freebl/blname.c | 100 +
nss/lib/freebl/camellia.c | 1896 +
nss/lib/freebl/camellia.h | 42 +
nss/lib/freebl/chacha20.c | 119 +
nss/lib/freebl/chacha20.h | 26 +
nss/lib/freebl/chacha20_vec.c | 327 +
nss/lib/freebl/chacha20poly1305.c | 198 +
nss/lib/freebl/chacha20poly1305.h | 15 +
nss/lib/freebl/config.mk | 97 +
nss/lib/freebl/ctr.c | 246 +
nss/lib/freebl/ctr.h | 53 +
nss/lib/freebl/cts.c | 307 +
nss/lib/freebl/cts.h | 33 +
nss/lib/freebl/des.c | 676 +
nss/lib/freebl/des.h | 43 +
nss/lib/freebl/desblapi.c | 256 +
nss/lib/freebl/det_rng.c | 67 +
nss/lib/freebl/det_rng.h | 12 +
nss/lib/freebl/dh.c | 452 +
nss/lib/freebl/drbg.c | 972 +
nss/lib/freebl/dsa.c | 647 +
nss/lib/freebl/ec.c | 1169 +
nss/lib/freebl/ec.h | 21 +
nss/lib/freebl/ecdecode.c | 311 +
nss/lib/freebl/ecl/README | 163 +
nss/lib/freebl/ecl/README.FP | 284 +
nss/lib/freebl/ecl/curve25519_32.c | 390 +
nss/lib/freebl/ecl/curve25519_64.c | 514 +
nss/lib/freebl/ecl/ec2.h | 92 +
nss/lib/freebl/ecl/ec2_163.c | 223 +
nss/lib/freebl/ecl/ec2_193.c | 240 +
nss/lib/freebl/ecl/ec2_233.c | 263 +
nss/lib/freebl/ecl/ec2_aff.c | 298 +
nss/lib/freebl/ecl/ec2_mont.c | 230 +
nss/lib/freebl/ecl/ec2_proj.c | 328 +
nss/lib/freebl/ecl/ec_naf.c | 68 +
nss/lib/freebl/ecl/ecl-curve.h | 123 +
nss/lib/freebl/ecl/ecl-exp.h | 167 +
nss/lib/freebl/ecl/ecl-priv.h | 257 +
nss/lib/freebl/ecl/ecl.c | 301 +
nss/lib/freebl/ecl/ecl.h | 60 +
nss/lib/freebl/ecl/ecl_curve.c | 93 +
nss/lib/freebl/ecl/ecl_gf.c | 958 +
nss/lib/freebl/ecl/ecl_mult.c | 305 +
nss/lib/freebl/ecl/ecp.h | 106 +
nss/lib/freebl/ecl/ecp_192.c | 493 +
nss/lib/freebl/ecl/ecp_224.c | 351 +
nss/lib/freebl/ecl/ecp_25519.c | 119 +
nss/lib/freebl/ecl/ecp_256.c | 401 +
nss/lib/freebl/ecl/ecp_256_32.c | 1535 +
nss/lib/freebl/ecl/ecp_384.c | 258 +
nss/lib/freebl/ecl/ecp_521.c | 137 +
nss/lib/freebl/ecl/ecp_aff.c | 308 +
nss/lib/freebl/ecl/ecp_fp.c | 531 +
nss/lib/freebl/ecl/ecp_fp.h | 371 +
nss/lib/freebl/ecl/ecp_fp160.c | 145 +
nss/lib/freebl/ecl/ecp_fp192.c | 143 +
nss/lib/freebl/ecl/ecp_fp224.c | 156 +
nss/lib/freebl/ecl/ecp_fpinc.c | 1077 +
nss/lib/freebl/ecl/ecp_jac.c | 513 +
nss/lib/freebl/ecl/ecp_jm.c | 283 +
nss/lib/freebl/ecl/ecp_mont.c | 154 +
nss/lib/freebl/ecl/tests/ec2_test.c | 461 +
nss/lib/freebl/ecl/tests/ec_naft.c | 121 +
nss/lib/freebl/ecl/tests/ecp_fpt.c | 1075 +
nss/lib/freebl/ecl/tests/ecp_test.c | 408 +
nss/lib/freebl/ecl/uint128.c | 90 +
nss/lib/freebl/ecl/uint128.h | 35 +
nss/lib/freebl/exports.gyp | 48 +
nss/lib/freebl/fipsfreebl.c | 1715 +
nss/lib/freebl/freebl.def | 26 +
nss/lib/freebl/freebl.gyp | 268 +
nss/lib/freebl/freebl.rc | 68 +
nss/lib/freebl/freebl_base.gypi | 199 +
nss/lib/freebl/freebl_hash.def | 39 +
nss/lib/freebl/freebl_hash_vector.def | 34 +
nss/lib/freebl/freeblver.c | 18 +
nss/lib/freebl/gcm.c | 860 +
nss/lib/freebl/gcm.h | 31 +
nss/lib/freebl/genload.c | 167 +
nss/lib/freebl/hmacct.c | 335 +
nss/lib/freebl/hmacct.h | 38 +
nss/lib/freebl/intel-aes-x64-masm.asm | 971 +
nss/lib/freebl/intel-aes-x86-masm.asm | 949 +
nss/lib/freebl/intel-aes.h | 143 +
nss/lib/freebl/intel-aes.s | 2514 +
nss/lib/freebl/intel-gcm-wrap.c | 254 +
nss/lib/freebl/intel-gcm-x64-masm.asm | 1295 +
nss/lib/freebl/intel-gcm-x86-masm.asm | 1209 +
nss/lib/freebl/intel-gcm.h | 83 +
nss/lib/freebl/intel-gcm.s | 1340 +
nss/lib/freebl/jpake.c | 495 +
nss/lib/freebl/ldvector.c | 353 +
nss/lib/freebl/loader.c | 2126 +
nss/lib/freebl/loader.h | 788 +
nss/lib/freebl/lowhash_vector.c | 217 +
nss/lib/freebl/manifest.mn | 195 +
nss/lib/freebl/md2.c | 269 +
nss/lib/freebl/md5.c | 598 +
nss/lib/freebl/mknewpc2.c | 208 +
nss/lib/freebl/mksp.c | 119 +
nss/lib/freebl/mpi/Makefile | 244 +
nss/lib/freebl/mpi/Makefile.os2 | 243 +
nss/lib/freebl/mpi/Makefile.win | 254 +
nss/lib/freebl/mpi/README | 746 +
nss/lib/freebl/mpi/all-tests | 83 +
nss/lib/freebl/mpi/doc/LICENSE | 11 +
nss/lib/freebl/mpi/doc/LICENSE-MPL | 3 +
nss/lib/freebl/mpi/doc/basecvt.pod | 65 +
nss/lib/freebl/mpi/doc/build | 30 +
nss/lib/freebl/mpi/doc/div.txt | 64 +
nss/lib/freebl/mpi/doc/expt.txt | 94 +
nss/lib/freebl/mpi/doc/gcd.pod | 28 +
nss/lib/freebl/mpi/doc/invmod.pod | 34 +
nss/lib/freebl/mpi/doc/isprime.pod | 63 +
nss/lib/freebl/mpi/doc/lap.pod | 36 +
nss/lib/freebl/mpi/doc/mpi-test.pod | 51 +
nss/lib/freebl/mpi/doc/mul.txt | 77 +
nss/lib/freebl/mpi/doc/pi.txt | 53 +
nss/lib/freebl/mpi/doc/prime.txt | 6542 +
nss/lib/freebl/mpi/doc/prng.pod | 38 +
nss/lib/freebl/mpi/doc/redux.txt | 86 +
nss/lib/freebl/mpi/doc/sqrt.txt | 50 +
nss/lib/freebl/mpi/doc/square.txt | 72 +
nss/lib/freebl/mpi/doc/timing.txt | 213 +
nss/lib/freebl/mpi/hpma512.s | 615 +
nss/lib/freebl/mpi/hppa20.s | 904 +
nss/lib/freebl/mpi/hppatch.adb | 21 +
nss/lib/freebl/mpi/logtab.h | 28 +
nss/lib/freebl/mpi/make-logtab | 29 +
nss/lib/freebl/mpi/make-test-arrays | 98 +
nss/lib/freebl/mpi/mdxptest.c | 306 +
nss/lib/freebl/mpi/montmulf.c | 286 +
nss/lib/freebl/mpi/montmulf.h | 65 +
nss/lib/freebl/mpi/montmulf.il | 108 +
nss/lib/freebl/mpi/montmulf.s | 1938 +
nss/lib/freebl/mpi/montmulfv8.il | 108 +
nss/lib/freebl/mpi/montmulfv8.s | 1818 +
nss/lib/freebl/mpi/montmulfv9.il | 93 +
nss/lib/freebl/mpi/montmulfv9.s | 2346 +
nss/lib/freebl/mpi/mp_comba.c | 3235 +
nss/lib/freebl/mpi/mp_comba_amd64_masm.asm | 13066 +
nss/lib/freebl/mpi/mp_comba_amd64_sun.s | 16097 ++
nss/lib/freebl/mpi/mp_gf2m-priv.h | 73 +
nss/lib/freebl/mpi/mp_gf2m.c | 678 +
nss/lib/freebl/mpi/mp_gf2m.h | 28 +
nss/lib/freebl/mpi/mpcpucache.c | 808 +
nss/lib/freebl/mpi/mpcpucache_amd64.s | 861 +
nss/lib/freebl/mpi/mpcpucache_x86.s | 902 +
nss/lib/freebl/mpi/mpi-config.h | 64 +
nss/lib/freebl/mpi/mpi-priv.h | 243 +
nss/lib/freebl/mpi/mpi-test.c | 2160 +
nss/lib/freebl/mpi/mpi.c | 4837 +
nss/lib/freebl/mpi/mpi.h | 311 +
nss/lib/freebl/mpi/mpi_amd64.c | 32 +
nss/lib/freebl/mpi/mpi_amd64_gas.s | 389 +
nss/lib/freebl/mpi/mpi_amd64_masm.asm | 388 +
nss/lib/freebl/mpi/mpi_amd64_sun.s | 385 +
nss/lib/freebl/mpi/mpi_arm.c | 175 +
nss/lib/freebl/mpi/mpi_hp.c | 81 +
nss/lib/freebl/mpi/mpi_i86pc.s | 313 +
nss/lib/freebl/mpi/mpi_mips.s | 472 +
nss/lib/freebl/mpi/mpi_sparc.c | 226 +
nss/lib/freebl/mpi/mpi_sse2.s | 294 +
nss/lib/freebl/mpi/mpi_x86.s | 541 +
nss/lib/freebl/mpi/mpi_x86_asm.c | 531 +
nss/lib/freebl/mpi/mpi_x86_os2.s | 538 +
nss/lib/freebl/mpi/mplogic.c | 443 +
nss/lib/freebl/mpi/mplogic.h | 52 +
nss/lib/freebl/mpi/mpmontg.c | 1141 +
nss/lib/freebl/mpi/mpprime.c | 599 +
nss/lib/freebl/mpi/mpprime.h | 42 +
nss/lib/freebl/mpi/mpv_sparc.c | 221 +
nss/lib/freebl/mpi/mpv_sparcv8.s | 1607 +
nss/lib/freebl/mpi/mpv_sparcv9.s | 1645 +
nss/lib/freebl/mpi/mpvalpha.c | 183 +
nss/lib/freebl/mpi/mulsqr.c | 84 +
nss/lib/freebl/mpi/multest | 76 +
nss/lib/freebl/mpi/primes.c | 841 +
nss/lib/freebl/mpi/stats | 39 +
nss/lib/freebl/mpi/target.mk | 233 +
nss/lib/freebl/mpi/test-arrays.txt | 55 +
nss/lib/freebl/mpi/test-info.c | 160 +
nss/lib/freebl/mpi/tests/LICENSE | 6 +
nss/lib/freebl/mpi/tests/LICENSE-MPL | 3 +
nss/lib/freebl/mpi/tests/mptest-1.c | 43 +
nss/lib/freebl/mpi/tests/mptest-2.c | 62 +
nss/lib/freebl/mpi/tests/mptest-3.c | 105 +
nss/lib/freebl/mpi/tests/mptest-3a.c | 123 +
nss/lib/freebl/mpi/tests/mptest-4.c | 111 +
nss/lib/freebl/mpi/tests/mptest-4a.c | 109 +
nss/lib/freebl/mpi/tests/mptest-4b.c | 107 +
nss/lib/freebl/mpi/tests/mptest-5.c | 85 +
nss/lib/freebl/mpi/tests/mptest-5a.c | 147 +
nss/lib/freebl/mpi/tests/mptest-6.c | 78 +
nss/lib/freebl/mpi/tests/mptest-7.c | 85 +
nss/lib/freebl/mpi/tests/mptest-8.c | 68 +
nss/lib/freebl/mpi/tests/mptest-9.c | 109 +
nss/lib/freebl/mpi/tests/mptest-b.c | 230 +
nss/lib/freebl/mpi/tests/pi1k.txt | 1 +
nss/lib/freebl/mpi/tests/pi2k.txt | 1 +
nss/lib/freebl/mpi/tests/pi5k.txt | 1 +
nss/lib/freebl/mpi/timetest | 99 +
nss/lib/freebl/mpi/types.pl | 127 +
nss/lib/freebl/mpi/utils/LICENSE | 4 +
nss/lib/freebl/mpi/utils/LICENSE-MPL | 3 +
nss/lib/freebl/mpi/utils/PRIMES | 41 +
nss/lib/freebl/mpi/utils/README | 206 +
nss/lib/freebl/mpi/utils/basecvt.c | 68 +
nss/lib/freebl/mpi/utils/bbs_rand.c | 65 +
nss/lib/freebl/mpi/utils/bbs_rand.h | 24 +
nss/lib/freebl/mpi/utils/bbsrand.c | 35 +
nss/lib/freebl/mpi/utils/dec2hex.c | 40 +
nss/lib/freebl/mpi/utils/exptmod.c | 55 +
nss/lib/freebl/mpi/utils/fact.c | 84 +
nss/lib/freebl/mpi/utils/gcd.c | 95 +
nss/lib/freebl/mpi/utils/hex2dec.c | 40 +
nss/lib/freebl/mpi/utils/identest.c | 84 +
nss/lib/freebl/mpi/utils/invmod.c | 61 +
nss/lib/freebl/mpi/utils/isprime.c | 89 +
nss/lib/freebl/mpi/utils/lap.c | 90 +
nss/lib/freebl/mpi/utils/makeprime.c | 116 +
nss/lib/freebl/mpi/utils/metime.c | 102 +
nss/lib/freebl/mpi/utils/pi.c | 171 +
nss/lib/freebl/mpi/utils/primegen.c | 159 +
nss/lib/freebl/mpi/utils/prng.c | 57 +
nss/lib/freebl/mpi/utils/ptab.pl | 26 +
nss/lib/freebl/mpi/utils/sieve.c | 243 +
nss/lib/freebl/mpi/vis_32.il | 1291 +
nss/lib/freebl/mpi/vis_64.il | 997 +
nss/lib/freebl/mpi/vis_proto.h | 234 +
nss/lib/freebl/nsslowhash.c | 150 +
nss/lib/freebl/nsslowhash.h | 33 +
nss/lib/freebl/os2_rand.c | 334 +
...ly1305-donna-x64-sse2-incremental-source.c | 881 +
nss/lib/freebl/poly1305.c | 314 +
nss/lib/freebl/poly1305.h | 28 +
nss/lib/freebl/pqg.c | 1878 +
nss/lib/freebl/pqg.h | 25 +
nss/lib/freebl/rawhash.c | 154 +
nss/lib/freebl/ret_cr16.s | 27 +
nss/lib/freebl/rijndael.c | 1375 +
nss/lib/freebl/rijndael.h | 67 +
nss/lib/freebl/rijndael32.tab | 1219 +
nss/lib/freebl/rijndael_tables.c | 215 +
nss/lib/freebl/rsa.c | 1628 +
nss/lib/freebl/rsapkcs.c | 1425 +
nss/lib/freebl/secmpi.h | 54 +
nss/lib/freebl/secrng.h | 65 +
nss/lib/freebl/seed.c | 641 +
nss/lib/freebl/seed.h | 125 +
nss/lib/freebl/sha-fast-amd64-sun.s | 2151 +
nss/lib/freebl/sha256.h | 19 +
nss/lib/freebl/sha512.c | 1655 +
nss/lib/freebl/sha_fast.c | 545 +
nss/lib/freebl/sha_fast.h | 176 +
nss/lib/freebl/shsign.h | 14 +
nss/lib/freebl/shvfy.c | 534 +
nss/lib/freebl/stubs.c | 711 +
nss/lib/freebl/stubs.h | 66 +
nss/lib/freebl/sysrand.c | 16 +
nss/lib/freebl/tlsprfalg.c | 134 +
nss/lib/freebl/unix_rand.c | 1083 +
nss/lib/freebl/win_rand.c | 161 +
nss/lib/jar/Makefile | 11 +
nss/lib/jar/config.mk | 26 +
nss/lib/jar/exports.gyp | 27 +
nss/lib/jar/jar-ds.c | 36 +
nss/lib/jar/jar-ds.h | 77 +
nss/lib/jar/jar.c | 687 +
nss/lib/jar/jar.gyp | 76 +
nss/lib/jar/jar.h | 372 +
nss/lib/jar/jarfile.c | 966 +
nss/lib/jar/jarfile.h | 76 +
nss/lib/jar/jarint.c | 52 +
nss/lib/jar/jarint.h | 54 +
nss/lib/jar/jarnav.c | 63 +
nss/lib/jar/jarsign.c | 250 +
nss/lib/jar/jarver.c | 1167 +
nss/lib/jar/jzconf.h | 189 +
nss/lib/jar/jzlib.h | 916 +
nss/lib/jar/manifest.mn | 25 +
nss/lib/libpkix/Makefile | 48 +
nss/lib/libpkix/config.mk | 16 +
nss/lib/libpkix/include/Makefile | 48 +
nss/lib/libpkix/include/config.mk | 15 +
nss/lib/libpkix/include/exports.gyp | 38 +
nss/lib/libpkix/include/include.gyp | 12 +
nss/lib/libpkix/include/manifest.mn | 32 +
nss/lib/libpkix/include/pkix.h | 301 +
nss/lib/libpkix/include/pkix_certsel.h | 1826 +
nss/lib/libpkix/include/pkix_certstore.h | 714 +
nss/lib/libpkix/include/pkix_checker.h | 394 +
nss/lib/libpkix/include/pkix_crlsel.h | 759 +
nss/lib/libpkix/include/pkix_errorstrings.h | 1099 +
nss/lib/libpkix/include/pkix_params.h | 1793 +
nss/lib/libpkix/include/pkix_pl_pki.h | 2735 +
nss/lib/libpkix/include/pkix_pl_system.h | 1545 +
nss/lib/libpkix/include/pkix_results.h | 425 +
nss/lib/libpkix/include/pkix_revchecker.h | 215 +
nss/lib/libpkix/include/pkix_sample_modules.h | 420 +
nss/lib/libpkix/include/pkix_util.h | 941 +
nss/lib/libpkix/include/pkixt.h | 485 +
nss/lib/libpkix/manifest.mn | 13 +
nss/lib/libpkix/pkix/Makefile | 48 +
nss/lib/libpkix/pkix/certsel/Makefile | 48 +
nss/lib/libpkix/pkix/certsel/certsel.gyp | 24 +
nss/lib/libpkix/pkix/certsel/config.mk | 15 +
nss/lib/libpkix/pkix/certsel/exports.gyp | 26 +
nss/lib/libpkix/pkix/certsel/manifest.mn | 23 +
.../libpkix/pkix/certsel/pkix_certselector.c | 1637 +
.../libpkix/pkix/certsel/pkix_certselector.h | 41 +
.../pkix/certsel/pkix_comcertselparams.c | 1188 +
.../pkix/certsel/pkix_comcertselparams.h | 57 +
nss/lib/libpkix/pkix/checker/Makefile | 48 +
nss/lib/libpkix/pkix/checker/checker.gyp | 35 +
nss/lib/libpkix/pkix/checker/config.mk | 15 +
nss/lib/libpkix/pkix/checker/exports.gyp | 37 +
nss/lib/libpkix/pkix/checker/manifest.mn | 45 +
.../checker/pkix_basicconstraintschecker.c | 306 +
.../checker/pkix_basicconstraintschecker.h | 42 +
.../pkix/checker/pkix_certchainchecker.c | 322 +
.../pkix/checker/pkix_certchainchecker.h | 36 +
.../libpkix/pkix/checker/pkix_crlchecker.c | 438 +
.../libpkix/pkix/checker/pkix_crlchecker.h | 68 +
.../libpkix/pkix/checker/pkix_ekuchecker.c | 328 +
.../libpkix/pkix/checker/pkix_ekuchecker.h | 92 +
.../pkix/checker/pkix_expirationchecker.c | 113 +
.../pkix/checker/pkix_expirationchecker.h | 30 +
.../pkix/checker/pkix_namechainingchecker.c | 121 +
.../pkix/checker/pkix_namechainingchecker.h | 30 +
.../checker/pkix_nameconstraintschecker.c | 308 +
.../checker/pkix_nameconstraintschecker.h | 43 +
.../libpkix/pkix/checker/pkix_ocspchecker.c | 419 +
.../libpkix/pkix/checker/pkix_ocspchecker.h | 67 +
.../libpkix/pkix/checker/pkix_policychecker.c | 2783 +
.../libpkix/pkix/checker/pkix_policychecker.h | 73 +
.../pkix/checker/pkix_revocationchecker.c | 475 +
.../pkix/checker/pkix_revocationchecker.h | 151 +
.../pkix/checker/pkix_revocationmethod.c | 66 +
.../pkix/checker/pkix_revocationmethod.h | 81 +
.../pkix/checker/pkix_signaturechecker.c | 443 +
.../pkix/checker/pkix_signaturechecker.h | 44 +
.../pkix/checker/pkix_targetcertchecker.c | 516 +
.../pkix/checker/pkix_targetcertchecker.h | 47 +
nss/lib/libpkix/pkix/config.mk | 15 +
nss/lib/libpkix/pkix/crlsel/Makefile | 48 +
nss/lib/libpkix/pkix/crlsel/config.mk | 15 +
nss/lib/libpkix/pkix/crlsel/crlsel.gyp | 24 +
nss/lib/libpkix/pkix/crlsel/exports.gyp | 26 +
nss/lib/libpkix/pkix/crlsel/manifest.mn | 23 +
.../pkix/crlsel/pkix_comcrlselparams.c | 826 +
.../pkix/crlsel/pkix_comcrlselparams.h | 38 +
.../libpkix/pkix/crlsel/pkix_crlselector.c | 870 +
.../libpkix/pkix/crlsel/pkix_crlselector.h | 40 +
nss/lib/libpkix/pkix/manifest.mn | 11 +
nss/lib/libpkix/pkix/params/Makefile | 48 +
nss/lib/libpkix/pkix/params/config.mk | 15 +
nss/lib/libpkix/pkix/params/exports.gyp | 28 +
nss/lib/libpkix/pkix/params/manifest.mn | 27 +
nss/lib/libpkix/pkix/params/params.gyp | 26 +
nss/lib/libpkix/pkix/params/pkix_procparams.c | 1417 +
nss/lib/libpkix/pkix/params/pkix_procparams.h | 50 +
.../libpkix/pkix/params/pkix_resourcelimits.c | 433 +
.../libpkix/pkix/params/pkix_resourcelimits.h | 36 +
.../libpkix/pkix/params/pkix_trustanchor.c | 525 +
.../libpkix/pkix/params/pkix_trustanchor.h | 35 +
nss/lib/libpkix/pkix/params/pkix_valparams.c | 335 +
nss/lib/libpkix/pkix/params/pkix_valparams.h | 33 +
nss/lib/libpkix/pkix/results/Makefile | 48 +
nss/lib/libpkix/pkix/results/config.mk | 15 +
nss/lib/libpkix/pkix/results/exports.gyp | 28 +
nss/lib/libpkix/pkix/results/manifest.mn | 27 +
.../libpkix/pkix/results/pkix_buildresult.c | 362 +
.../libpkix/pkix/results/pkix_buildresult.h | 40 +
.../libpkix/pkix/results/pkix_policynode.c | 1377 +
.../libpkix/pkix/results/pkix_policynode.h | 74 +
nss/lib/libpkix/pkix/results/pkix_valresult.c | 442 +
nss/lib/libpkix/pkix/results/pkix_valresult.h | 43 +
.../libpkix/pkix/results/pkix_verifynode.c | 1182 +
.../libpkix/pkix/results/pkix_verifynode.h | 75 +
nss/lib/libpkix/pkix/results/results.gyp | 26 +
nss/lib/libpkix/pkix/store/Makefile | 48 +
nss/lib/libpkix/pkix/store/config.mk | 15 +
nss/lib/libpkix/pkix/store/exports.gyp | 25 +
nss/lib/libpkix/pkix/store/manifest.mn | 21 +
nss/lib/libpkix/pkix/store/pkix_store.c | 415 +
nss/lib/libpkix/pkix/store/pkix_store.h | 41 +
nss/lib/libpkix/pkix/store/store.gyp | 23 +
nss/lib/libpkix/pkix/top/Makefile | 48 +
nss/lib/libpkix/pkix/top/config.mk | 15 +
nss/lib/libpkix/pkix/top/exports.gyp | 27 +
nss/lib/libpkix/pkix/top/manifest.mn | 25 +
nss/lib/libpkix/pkix/top/pkix_build.c | 3763 +
nss/lib/libpkix/pkix/top/pkix_build.h | 120 +
nss/lib/libpkix/pkix/top/pkix_lifecycle.c | 210 +
nss/lib/libpkix/pkix/top/pkix_lifecycle.h | 23 +
nss/lib/libpkix/pkix/top/pkix_validate.c | 1451 +
nss/lib/libpkix/pkix/top/pkix_validate.h | 42 +
nss/lib/libpkix/pkix/top/top.gyp | 25 +
nss/lib/libpkix/pkix/util/Makefile | 48 +
nss/lib/libpkix/pkix/util/config.mk | 15 +
nss/lib/libpkix/pkix/util/exports.gyp | 28 +
nss/lib/libpkix/pkix/util/manifest.mn | 28 +
nss/lib/libpkix/pkix/util/pkix_error.c | 565 +
nss/lib/libpkix/pkix/util/pkix_error.h | 36 +
nss/lib/libpkix/pkix/util/pkix_errpaths.c | 103 +
nss/lib/libpkix/pkix/util/pkix_list.c | 1701 +
nss/lib/libpkix/pkix/util/pkix_list.h | 95 +
nss/lib/libpkix/pkix/util/pkix_logger.c | 1088 +
nss/lib/libpkix/pkix/util/pkix_logger.h | 57 +
nss/lib/libpkix/pkix/util/pkix_tools.c | 1519 +
nss/lib/libpkix/pkix/util/pkix_tools.h | 1588 +
nss/lib/libpkix/pkix/util/util.gyp | 27 +
nss/lib/libpkix/pkix_pl_nss/Makefile | 48 +
nss/lib/libpkix/pkix_pl_nss/config.mk | 15 +
nss/lib/libpkix/pkix_pl_nss/manifest.mn | 11 +
nss/lib/libpkix/pkix_pl_nss/module/Makefile | 48 +
nss/lib/libpkix/pkix_pl_nss/module/config.mk | 35 +
.../libpkix/pkix_pl_nss/module/exports.gyp | 36 +
.../libpkix/pkix_pl_nss/module/manifest.mn | 38 +
nss/lib/libpkix/pkix_pl_nss/module/module.gyp | 41 +
.../pkix_pl_nss/module/pkix_pl_aiamgr.c | 699 +
.../pkix_pl_nss/module/pkix_pl_aiamgr.h | 65 +
.../pkix_pl_nss/module/pkix_pl_colcertstore.c | 1282 +
.../pkix_pl_nss/module/pkix_pl_colcertstore.h | 34 +
.../module/pkix_pl_httpcertstore.c | 1147 +
.../module/pkix_pl_httpcertstore.h | 62 +
.../module/pkix_pl_httpdefaultclient.c | 1654 +
.../module/pkix_pl_httpdefaultclient.h | 139 +
.../module/pkix_pl_ldapcertstore.c | 1116 +
.../module/pkix_pl_ldapcertstore.h | 75 +
.../module/pkix_pl_ldapdefaultclient.c | 2493 +
.../module/pkix_pl_ldapdefaultclient.h | 82 +
.../pkix_pl_nss/module/pkix_pl_ldaprequest.c | 757 +
.../pkix_pl_nss/module/pkix_pl_ldaprequest.h | 86 +
.../pkix_pl_nss/module/pkix_pl_ldapresponse.c | 786 +
.../pkix_pl_nss/module/pkix_pl_ldapresponse.h | 96 +
.../pkix_pl_nss/module/pkix_pl_ldapt.h | 314 +
.../module/pkix_pl_ldaptemplates.c | 417 +
.../pkix_pl_nss/module/pkix_pl_nsscontext.c | 319 +
.../pkix_pl_nss/module/pkix_pl_nsscontext.h | 52 +
.../module/pkix_pl_pk11certstore.c | 1039 +
.../module/pkix_pl_pk11certstore.h | 31 +
.../pkix_pl_nss/module/pkix_pl_socket.c | 1695 +
.../pkix_pl_nss/module/pkix_pl_socket.h | 209 +
nss/lib/libpkix/pkix_pl_nss/pki/Makefile | 49 +
nss/lib/libpkix/pkix_pl_nss/pki/config.mk | 15 +
nss/lib/libpkix/pkix_pl_nss/pki/exports.gyp | 41 +
nss/lib/libpkix/pkix_pl_nss/pki/manifest.mn | 53 +
nss/lib/libpkix/pkix_pl_nss/pki/pki.gyp | 39 +
.../pki/pkix_pl_basicconstraints.c | 407 +
.../pki/pkix_pl_basicconstraints.h | 47 +
.../libpkix/pkix_pl_nss/pki/pkix_pl_cert.c | 3714 +
.../libpkix/pkix_pl_nss/pki/pkix_pl_cert.h | 107 +
.../pkix_pl_nss/pki/pkix_pl_certpolicyinfo.c | 371 +
.../pkix_pl_nss/pki/pkix_pl_certpolicyinfo.h | 50 +
.../pkix_pl_nss/pki/pkix_pl_certpolicymap.c | 386 +
.../pkix_pl_nss/pki/pkix_pl_certpolicymap.h | 49 +
.../pki/pkix_pl_certpolicyqualifier.c | 365 +
.../pki/pkix_pl_certpolicyqualifier.h | 52 +
nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.c | 1068 +
nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.h | 48 +
.../libpkix/pkix_pl_nss/pki/pkix_pl_crldp.c | 151 +
.../libpkix/pkix_pl_nss/pki/pkix_pl_crldp.h | 53 +
.../pkix_pl_nss/pki/pkix_pl_crlentry.c | 880 +
.../pkix_pl_nss/pki/pkix_pl_crlentry.h | 46 +
.../libpkix/pkix_pl_nss/pki/pkix_pl_date.c | 466 +
.../libpkix/pkix_pl_nss/pki/pkix_pl_date.h | 55 +
.../pkix_pl_nss/pki/pkix_pl_generalname.c | 873 +
.../pkix_pl_nss/pki/pkix_pl_generalname.h | 49 +
.../pkix_pl_nss/pki/pkix_pl_infoaccess.c | 874 +
.../pkix_pl_nss/pki/pkix_pl_infoaccess.h | 49 +
.../pkix_pl_nss/pki/pkix_pl_nameconstraints.c | 1274 +
.../pkix_pl_nss/pki/pkix_pl_nameconstraints.h | 68 +
.../pkix_pl_nss/pki/pkix_pl_ocspcertid.c | 251 +
.../pkix_pl_nss/pki/pkix_pl_ocspcertid.h | 53 +
.../pkix_pl_nss/pki/pkix_pl_ocsprequest.c | 441 +
.../pkix_pl_nss/pki/pkix_pl_ocsprequest.h | 61 +
.../pkix_pl_nss/pki/pkix_pl_ocspresponse.c | 1067 +
.../pkix_pl_nss/pki/pkix_pl_ocspresponse.h | 106 +
.../pkix_pl_nss/pki/pkix_pl_publickey.c | 489 +
.../pkix_pl_nss/pki/pkix_pl_publickey.h | 38 +
.../pkix_pl_nss/pki/pkix_pl_x500name.c | 667 +
.../pkix_pl_nss/pki/pkix_pl_x500name.h | 74 +
nss/lib/libpkix/pkix_pl_nss/system/Makefile | 49 +
nss/lib/libpkix/pkix_pl_nss/system/config.mk | 15 +
.../libpkix/pkix_pl_nss/system/exports.gyp | 37 +
.../libpkix/pkix_pl_nss/system/manifest.mn | 46 +
.../pkix_pl_nss/system/pkix_pl_bigint.c | 398 +
.../pkix_pl_nss/system/pkix_pl_bigint.h | 40 +
.../pkix_pl_nss/system/pkix_pl_bytearray.c | 504 +
.../pkix_pl_nss/system/pkix_pl_bytearray.h | 40 +
.../pkix_pl_nss/system/pkix_pl_common.c | 1073 +
.../pkix_pl_nss/system/pkix_pl_common.h | 159 +
.../pkix_pl_nss/system/pkix_pl_error.c | 26 +
.../pkix_pl_nss/system/pkix_pl_hashtable.c | 383 +
.../pkix_pl_nss/system/pkix_pl_hashtable.h | 29 +
.../pkix_pl_nss/system/pkix_pl_lifecycle.c | 279 +
.../pkix_pl_nss/system/pkix_pl_lifecycle.h | 91 +
.../libpkix/pkix_pl_nss/system/pkix_pl_mem.c | 168 +
.../libpkix/pkix_pl_nss/system/pkix_pl_mem.h | 24 +
.../pkix_pl_nss/system/pkix_pl_monitorlock.c | 136 +
.../pkix_pl_nss/system/pkix_pl_monitorlock.h | 33 +
.../pkix_pl_nss/system/pkix_pl_mutex.c | 163 +
.../pkix_pl_nss/system/pkix_pl_mutex.h | 33 +
.../pkix_pl_nss/system/pkix_pl_object.c | 1440 +
.../pkix_pl_nss/system/pkix_pl_object.h | 76 +
.../libpkix/pkix_pl_nss/system/pkix_pl_oid.c | 316 +
.../libpkix/pkix_pl_nss/system/pkix_pl_oid.h | 39 +
.../pkix_pl_nss/system/pkix_pl_primhash.c | 584 +
.../pkix_pl_nss/system/pkix_pl_primhash.h | 102 +
.../pkix_pl_nss/system/pkix_pl_rwlock.c | 217 +
.../pkix_pl_nss/system/pkix_pl_rwlock.h | 35 +
.../pkix_pl_nss/system/pkix_pl_string.c | 621 +
.../pkix_pl_nss/system/pkix_pl_string.h | 37 +
nss/lib/libpkix/pkix_pl_nss/system/system.gyp | 36 +
nss/lib/manifest.mn | 62 +
nss/lib/nss/Makefile | 46 +
nss/lib/nss/config.mk | 114 +
nss/lib/nss/exports.gyp | 32 +
nss/lib/nss/manifest.mn | 31 +
nss/lib/nss/nss.def | 1107 +
nss/lib/nss/nss.gyp | 83 +
nss/lib/nss/nss.h | 322 +
nss/lib/nss/nss.rc | 68 +
nss/lib/nss/nssinit.c | 1372 +
nss/lib/nss/nssoptions.c | 104 +
nss/lib/nss/nssoptions.h | 20 +
nss/lib/nss/nssrenam.h | 15 +
nss/lib/nss/nssver.c | 18 +
nss/lib/nss/pkixpriv.def | 322 +
nss/lib/nss/utilwrap.c | 870 +
nss/lib/pk11wrap/Makefile | 62 +
nss/lib/pk11wrap/config.mk | 15 +
nss/lib/pk11wrap/debug_module.c | 2760 +
nss/lib/pk11wrap/dev3hack.c | 279 +
nss/lib/pk11wrap/dev3hack.h | 30 +
nss/lib/pk11wrap/exports.gyp | 39 +
nss/lib/pk11wrap/manifest.mn | 63 +
nss/lib/pk11wrap/pk11akey.c | 2529 +
nss/lib/pk11wrap/pk11auth.c | 807 +
nss/lib/pk11wrap/pk11cert.c | 2739 +
nss/lib/pk11wrap/pk11cxt.c | 1019 +
nss/lib/pk11wrap/pk11err.c | 141 +
nss/lib/pk11wrap/pk11func.h | 15 +
nss/lib/pk11wrap/pk11kea.c | 140 +
nss/lib/pk11wrap/pk11list.c | 99 +
nss/lib/pk11wrap/pk11load.c | 657 +
nss/lib/pk11wrap/pk11mech.c | 1917 +
nss/lib/pk11wrap/pk11merge.c | 1432 +
nss/lib/pk11wrap/pk11nobj.c | 791 +
nss/lib/pk11wrap/pk11obj.c | 2106 +
nss/lib/pk11wrap/pk11pars.c | 1796 +
nss/lib/pk11wrap/pk11pbe.c | 1474 +
nss/lib/pk11wrap/pk11pk12.c | 786 +
nss/lib/pk11wrap/pk11pqg.c | 522 +
nss/lib/pk11wrap/pk11pqg.h | 135 +
nss/lib/pk11wrap/pk11priv.h | 187 +
nss/lib/pk11wrap/pk11pub.h | 888 +
nss/lib/pk11wrap/pk11sdr.c | 437 +
nss/lib/pk11wrap/pk11sdr.h | 28 +
nss/lib/pk11wrap/pk11skey.c | 2770 +
nss/lib/pk11wrap/pk11slot.c | 2484 +
nss/lib/pk11wrap/pk11util.c | 1629 +
nss/lib/pk11wrap/pk11wrap.gyp | 70 +
nss/lib/pk11wrap/secmod.h | 167 +
nss/lib/pk11wrap/secmodi.h | 170 +
nss/lib/pk11wrap/secmodt.h | 444 +
nss/lib/pk11wrap/secmodti.h | 183 +
nss/lib/pk11wrap/secpkcs5.h | 61 +
nss/lib/pkcs12/Makefile | 49 +
nss/lib/pkcs12/config.mk | 16 +
nss/lib/pkcs12/exports.gyp | 29 +
nss/lib/pkcs12/manifest.mn | 31 +
nss/lib/pkcs12/p12.h | 236 +
nss/lib/pkcs12/p12creat.c | 218 +
nss/lib/pkcs12/p12d.c | 3612 +
nss/lib/pkcs12/p12dec.c | 670 +
nss/lib/pkcs12/p12e.c | 2085 +
nss/lib/pkcs12/p12exp.c | 1374 +
nss/lib/pkcs12/p12local.c | 1368 +
nss/lib/pkcs12/p12local.h | 60 +
nss/lib/pkcs12/p12plcy.c | 125 +
nss/lib/pkcs12/p12plcy.h | 25 +
nss/lib/pkcs12/p12t.h | 155 +
nss/lib/pkcs12/p12tmpl.c | 290 +
nss/lib/pkcs12/pkcs12.gyp | 29 +
nss/lib/pkcs12/pkcs12.h | 41 +
nss/lib/pkcs12/pkcs12t.h | 341 +
nss/lib/pkcs7/Makefile | 48 +
nss/lib/pkcs7/certread.c | 528 +
nss/lib/pkcs7/config.mk | 14 +
nss/lib/pkcs7/exports.gyp | 33 +
nss/lib/pkcs7/manifest.mn | 33 +
nss/lib/pkcs7/p7common.c | 663 +
nss/lib/pkcs7/p7create.c | 1300 +
nss/lib/pkcs7/p7decode.c | 1914 +
nss/lib/pkcs7/p7encode.c | 1079 +
nss/lib/pkcs7/p7local.c | 1310 +
nss/lib/pkcs7/p7local.h | 137 +
nss/lib/pkcs7/pkcs7.gyp | 29 +
nss/lib/pkcs7/pkcs7t.h | 233 +
nss/lib/pkcs7/secmime.c | 800 +
nss/lib/pkcs7/secmime.h | 160 +
nss/lib/pkcs7/secpkcs7.h | 626 +
nss/lib/pki/Makefile | 11 +
nss/lib/pki/asymmkey.c | 361 +
nss/lib/pki/certdecode.c | 60 +
nss/lib/pki/certificate.c | 1101 +
nss/lib/pki/config.mk | 19 +
nss/lib/pki/cryptocontext.c | 914 +
nss/lib/pki/doc/standiag.png | Bin 0 -> 20475 bytes
nss/lib/pki/doc/standoc.html | 442 +
nss/lib/pki/exports.gyp | 32 +
nss/lib/pki/manifest.mn | 45 +
nss/lib/pki/nsspki.h | 2779 +
nss/lib/pki/nsspkit.h | 247 +
nss/lib/pki/pki.gyp | 32 +
nss/lib/pki/pki.h | 141 +
nss/lib/pki/pki3hack.c | 1441 +
nss/lib/pki/pki3hack.h | 149 +
nss/lib/pki/pkibase.c | 1222 +
nss/lib/pki/pkim.h | 547 +
nss/lib/pki/pkistore.c | 675 +
nss/lib/pki/pkistore.h | 138 +
nss/lib/pki/pkit.h | 183 +
nss/lib/pki/pkitm.h | 88 +
nss/lib/pki/symmkey.c | 238 +
nss/lib/pki/tdcache.c | 1106 +
nss/lib/pki/trustdomain.c | 1192 +
nss/lib/smime/Makefile | 48 +
nss/lib/smime/cms.h | 1153 +
nss/lib/smime/cmsarray.c | 186 +
nss/lib/smime/cmsasn1.c | 491 +
nss/lib/smime/cmsattr.c | 425 +
nss/lib/smime/cmscinfo.c | 375 +
nss/lib/smime/cmscipher.c | 722 +
nss/lib/smime/cmsdecode.c | 738 +
nss/lib/smime/cmsdigdata.c | 210 +
nss/lib/smime/cmsdigest.c | 259 +
nss/lib/smime/cmsencdata.c | 260 +
nss/lib/smime/cmsencode.c | 763 +
nss/lib/smime/cmsenvdata.c | 398 +
nss/lib/smime/cmslocal.h | 351 +
nss/lib/smime/cmsmessage.c | 293 +
nss/lib/smime/cmspubkey.c | 285 +
nss/lib/smime/cmsrecinfo.c | 669 +
nss/lib/smime/cmsreclist.c | 170 +
nss/lib/smime/cmsreclist.h | 27 +
nss/lib/smime/cmssigdata.c | 1141 +
nss/lib/smime/cmssiginfo.c | 1024 +
nss/lib/smime/cmst.h | 491 +
nss/lib/smime/cmsudf.c | 440 +
nss/lib/smime/cmsutil.c | 367 +
nss/lib/smime/config.mk | 63 +
nss/lib/smime/exports.gyp | 34 +
nss/lib/smime/manifest.mn | 51 +
nss/lib/smime/smime.def | 287 +
nss/lib/smime/smime.gyp | 80 +
nss/lib/smime/smime.h | 141 +
nss/lib/smime/smime.rc | 68 +
nss/lib/smime/smimemessage.c | 183 +
nss/lib/smime/smimesym.c | 12 +
nss/lib/smime/smimeutil.c | 776 +
nss/lib/smime/smimever.c | 18 +
nss/lib/softoken/Makefile | 78 +
nss/lib/softoken/config.mk | 63 +
nss/lib/softoken/exports.gyp | 38 +
nss/lib/softoken/fipsaudt.c | 321 +
nss/lib/softoken/fipstest.c | 654 +
nss/lib/softoken/fipstokn.c | 1656 +
nss/lib/softoken/jpakesftk.c | 359 +
nss/lib/softoken/legacydb/Makefile | 62 +
nss/lib/softoken/legacydb/cdbhdl.h | 51 +
nss/lib/softoken/legacydb/config.mk | 57 +
nss/lib/softoken/legacydb/dbmshim.c | 539 +
nss/lib/softoken/legacydb/keydb.c | 2250 +
nss/lib/softoken/legacydb/keydbi.h | 52 +
nss/lib/softoken/legacydb/legacydb.gyp | 66 +
nss/lib/softoken/legacydb/lgattr.c | 1792 +
nss/lib/softoken/legacydb/lgcreate.c | 1017 +
nss/lib/softoken/legacydb/lgdb.h | 175 +
nss/lib/softoken/legacydb/lgdestroy.c | 110 +
nss/lib/softoken/legacydb/lgfind.c | 912 +
nss/lib/softoken/legacydb/lgfips.c | 115 +
nss/lib/softoken/legacydb/lginit.c | 660 +
nss/lib/softoken/legacydb/lgutil.c | 399 +
nss/lib/softoken/legacydb/lowcert.c | 856 +
nss/lib/softoken/legacydb/lowkey.c | 395 +
nss/lib/softoken/legacydb/lowkeyi.h | 151 +
nss/lib/softoken/legacydb/lowkeyti.h | 132 +
nss/lib/softoken/legacydb/manifest.mn | 32 +
nss/lib/softoken/legacydb/nssdbm.def | 31 +
nss/lib/softoken/legacydb/nssdbm.rc | 68 +
nss/lib/softoken/legacydb/pcert.h | 228 +
nss/lib/softoken/legacydb/pcertdb.c | 5333 +
nss/lib/softoken/legacydb/pcertt.h | 418 +
nss/lib/softoken/legacydb/pk11db.c | 731 +
nss/lib/softoken/lgglue.c | 408 +
nss/lib/softoken/lgglue.h | 59 +
nss/lib/softoken/lowkey.c | 500 +
nss/lib/softoken/lowkeyi.h | 71 +
nss/lib/softoken/lowkeyti.h | 93 +
nss/lib/softoken/lowpbe.c | 1366 +
nss/lib/softoken/lowpbe.h | 107 +
nss/lib/softoken/manifest.mn | 61 +
nss/lib/softoken/padbuf.c | 49 +
nss/lib/softoken/pkcs11.c | 4936 +
nss/lib/softoken/pkcs11c.c | 7804 +
nss/lib/softoken/pkcs11i.h | 763 +
nss/lib/softoken/pkcs11ni.h | 20 +
nss/lib/softoken/pkcs11u.c | 1994 +
nss/lib/softoken/sdb.c | 2107 +
nss/lib/softoken/sdb.h | 93 +
nss/lib/softoken/sftkdb.c | 2716 +
nss/lib/softoken/sftkdb.h | 71 +
nss/lib/softoken/sftkdbt.h | 12 +
nss/lib/softoken/sftkdbti.h | 58 +
nss/lib/softoken/sftkhmac.c | 190 +
nss/lib/softoken/sftkpars.c | 251 +
nss/lib/softoken/sftkpars.h | 14 +
nss/lib/softoken/sftkpwd.c | 1261 +
nss/lib/softoken/softkver.c | 18 +
nss/lib/softoken/softkver.h | 31 +
nss/lib/softoken/softoken.gyp | 101 +
nss/lib/softoken/softoken.h | 265 +
nss/lib/softoken/softokn.def | 28 +
nss/lib/softoken/softokn.rc | 68 +
nss/lib/softoken/softoknt.h | 43 +
nss/lib/softoken/tlsprf.c | 198 +
nss/lib/sqlite/Makefile | 54 +
nss/lib/sqlite/README | 3 +
nss/lib/sqlite/config.mk | 43 +
nss/lib/sqlite/exports.gyp | 25 +
nss/lib/sqlite/manifest.mn | 34 +
nss/lib/sqlite/sqlite.def | 147 +
nss/lib/sqlite/sqlite.gyp | 50 +
nss/lib/sqlite/sqlite3.c | 186041 +++++++++++++++
nss/lib/sqlite/sqlite3.h | 8630 +
nss/lib/ssl/Makefile | 67 +
nss/lib/ssl/SSLerrs.h | 510 +
nss/lib/ssl/authcert.c | 89 +
nss/lib/ssl/cmpcert.c | 89 +
nss/lib/ssl/config.mk | 67 +
nss/lib/ssl/derive.c | 885 +
nss/lib/ssl/dhe-param.c | 418 +
nss/lib/ssl/dtlscon.c | 1208 +
nss/lib/ssl/exports.gyp | 29 +
nss/lib/ssl/manifest.mn | 59 +
nss/lib/ssl/notes.txt | 104 +
nss/lib/ssl/os2_err.c | 330 +
nss/lib/ssl/os2_err.h | 53 +
nss/lib/ssl/preenc.h | 113 +
nss/lib/ssl/prelib.c | 34 +
nss/lib/ssl/ssl.def | 242 +
nss/lib/ssl/ssl.gyp | 103 +
nss/lib/ssl/ssl.h | 1405 +
nss/lib/ssl/ssl.rc | 68 +
nss/lib/ssl/ssl3con.c | 13432 ++
nss/lib/ssl/ssl3ecc.c | 1005 +
nss/lib/ssl/ssl3ext.c | 533 +
nss/lib/ssl/ssl3ext.h | 161 +
nss/lib/ssl/ssl3exthandle.c | 2488 +
nss/lib/ssl/ssl3exthandle.h | 95 +
nss/lib/ssl/ssl3gthr.c | 596 +
nss/lib/ssl/ssl3prot.h | 341 +
nss/lib/ssl/sslauth.c | 292 +
nss/lib/ssl/sslcert.c | 915 +
nss/lib/ssl/sslcert.h | 60 +
nss/lib/ssl/sslcon.c | 264 +
nss/lib/ssl/ssldef.c | 226 +
nss/lib/ssl/sslenum.c | 157 +
nss/lib/ssl/sslerr.c | 41 +
nss/lib/ssl/sslerr.h | 254 +
nss/lib/ssl/sslerrstrs.c | 36 +
nss/lib/ssl/sslgrp.c | 164 +
nss/lib/ssl/sslimpl.h | 1910 +
nss/lib/ssl/sslinfo.c | 495 +
nss/lib/ssl/sslinit.c | 59 +
nss/lib/ssl/sslmutex.c | 659 +
nss/lib/ssl/sslmutex.h | 129 +
nss/lib/ssl/sslnonce.c | 509 +
nss/lib/ssl/sslproto.h | 294 +
nss/lib/ssl/sslreveal.c | 110 +
nss/lib/ssl/sslsecur.c | 1271 +
nss/lib/ssl/sslsnce.c | 2193 +
nss/lib/ssl/sslsock.c | 3833 +
nss/lib/ssl/sslt.h | 422 +
nss/lib/ssl/ssltrace.c | 114 +
nss/lib/ssl/sslver.c | 18 +
nss/lib/ssl/tls13con.c | 4494 +
nss/lib/ssl/tls13con.h | 89 +
nss/lib/ssl/tls13exthandle.c | 1367 +
nss/lib/ssl/tls13exthandle.h | 84 +
nss/lib/ssl/tls13hkdf.c | 270 +
nss/lib/ssl/tls13hkdf.h | 38 +
nss/lib/ssl/tlsproof.c | 2418 +
nss/lib/ssl/tlsproof.h | 129 +
nss/lib/ssl/tlsproofstr.h | 45 +
nss/lib/ssl/unix_err.c | 837 +
nss/lib/ssl/unix_err.h | 57 +
nss/lib/ssl/win32err.c | 550 +
nss/lib/ssl/win32err.h | 51 +
nss/lib/sysinit/Makefile | 48 +
nss/lib/sysinit/config.mk | 80 +
nss/lib/sysinit/manifest.mn | 15 +
nss/lib/sysinit/nsssysinit.c | 403 +
nss/lib/sysinit/sysinit.gyp | 31 +
nss/lib/util/Makefile | 50 +
nss/lib/util/SECerrs.h | 551 +
nss/lib/util/base64.h | 41 +
nss/lib/util/ciferfam.h | 62 +
nss/lib/util/config.mk | 45 +
nss/lib/util/derdec.c | 189 +
nss/lib/util/derenc.c | 460 +
nss/lib/util/dersubr.c | 249 +
nss/lib/util/dertime.c | 310 +
nss/lib/util/eccutil.h | 15 +
nss/lib/util/errstrs.c | 41 +
nss/lib/util/exports.gyp | 67 +
nss/lib/util/hasht.h | 63 +
nss/lib/util/manifest.mn | 90 +
nss/lib/util/nssb64.h | 94 +
nss/lib/util/nssb64d.c | 823 +
nss/lib/util/nssb64e.c | 734 +
nss/lib/util/nssb64t.h | 15 +
nss/lib/util/nssilckt.h | 191 +
nss/lib/util/nssilock.c | 479 +
nss/lib/util/nssilock.h | 267 +
nss/lib/util/nsslocks.h | 10 +
nss/lib/util/nssrwlk.c | 448 +
nss/lib/util/nssrwlk.h | 132 +
nss/lib/util/nssrwlkt.h | 19 +
nss/lib/util/nssutil.def | 298 +
nss/lib/util/nssutil.h | 41 +
nss/lib/util/nssutil.rc | 68 +
nss/lib/util/oidstring.c | 114 +
nss/lib/util/pkcs11.h | 252 +
nss/lib/util/pkcs11f.h | 812 +
nss/lib/util/pkcs11n.h | 509 +
nss/lib/util/pkcs11p.h | 21 +
nss/lib/util/pkcs11t.h | 1800 +
nss/lib/util/pkcs11u.h | 19 +
nss/lib/util/pkcs1sig.c | 169 +
nss/lib/util/pkcs1sig.h | 30 +
nss/lib/util/portreg.c | 375 +
nss/lib/util/portreg.h | 81 +
nss/lib/util/quickder.c | 819 +
nss/lib/util/secalgid.c | 129 +
nss/lib/util/secasn1.h | 303 +
nss/lib/util/secasn1d.c | 3416 +
nss/lib/util/secasn1e.c | 1568 +
nss/lib/util/secasn1t.h | 267 +
nss/lib/util/secasn1u.c | 94 +
nss/lib/util/seccomon.h | 91 +
nss/lib/util/secder.h | 172 +
nss/lib/util/secdert.h | 129 +
nss/lib/util/secdig.c | 182 +
nss/lib/util/secdig.h | 100 +
nss/lib/util/secdigt.h | 26 +
nss/lib/util/secerr.h | 218 +
nss/lib/util/secitem.c | 487 +
nss/lib/util/secitem.h | 118 +
nss/lib/util/secload.c | 182 +
nss/lib/util/secoid.c | 2306 +
nss/lib/util/secoid.h | 140 +
nss/lib/util/secoidt.h | 540 +
nss/lib/util/secplcy.c | 83 +
nss/lib/util/secplcy.h | 104 +
nss/lib/util/secport.c | 732 +
nss/lib/util/secport.h | 287 +
nss/lib/util/sectime.c | 163 +
nss/lib/util/templates.c | 136 +
nss/lib/util/utf8.c | 445 +
nss/lib/util/util.gyp | 59 +
nss/lib/util/utilmod.c | 771 +
nss/lib/util/utilmodt.h | 43 +
nss/lib/util/utilpars.c | 1231 +
nss/lib/util/utilpars.h | 63 +
nss/lib/util/utilparst.h | 78 +
nss/lib/util/utilrename.h | 162 +
nss/lib/util/verref.h | 43 +
nss/lib/zlib/Makefile | 55 +
nss/lib/zlib/README | 115 +
nss/lib/zlib/README.nss | 18 +
nss/lib/zlib/adler32.c | 169 +
nss/lib/zlib/compress.c | 80 +
nss/lib/zlib/config.mk | 20 +
nss/lib/zlib/crc32.c | 442 +
nss/lib/zlib/crc32.h | 445 +
nss/lib/zlib/deflate.c | 1834 +
nss/lib/zlib/deflate.h | 342 +
nss/lib/zlib/example.c | 565 +
nss/lib/zlib/exports.gyp | 33 +
nss/lib/zlib/gzclose.c | 25 +
nss/lib/zlib/gzguts.h | 132 +
nss/lib/zlib/gzlib.c | 537 +
nss/lib/zlib/gzread.c | 653 +
nss/lib/zlib/gzwrite.c | 531 +
nss/lib/zlib/infback.c | 632 +
nss/lib/zlib/inffast.c | 340 +
nss/lib/zlib/inffast.h | 11 +
nss/lib/zlib/inffixed.h | 98 +
nss/lib/zlib/inflate.c | 1480 +
nss/lib/zlib/inflate.h | 122 +
nss/lib/zlib/inftrees.c | 330 +
nss/lib/zlib/inftrees.h | 62 +
nss/lib/zlib/manifest.mn | 39 +
nss/lib/zlib/minigzip.c | 440 +
nss/lib/zlib/patches/prune-zlib.sh | 34 +
nss/lib/zlib/trees.c | 1244 +
nss/lib/zlib/trees.h | 132 +
nss/lib/zlib/uncompr.c | 59 +
nss/lib/zlib/zconf.h | 428 +
nss/lib/zlib/zlib.gyp | 49 +
nss/lib/zlib/zlib.h | 1613 +
nss/lib/zlib/zutil.c | 318 +
nss/lib/zlib/zutil.h | 275 +
nss/manifest.mn | 13 +
nss/nss-tool/.clang-format | 4 +
nss/nss-tool/common/argparse.cc | 23 +
nss/nss-tool/common/argparse.h | 30 +
nss/nss-tool/common/util.cc | 135 +
nss/nss-tool/common/util.h | 23 +
nss/nss-tool/db/dbtool.cc | 369 +
nss/nss-tool/db/dbtool.h | 25 +
nss/nss-tool/nss_tool.cc | 42 +
nss/nss-tool/nss_tool.gyp | 29 +
nss/nss.gyp | 273 +
nss/pkg/Makefile | 27 +
nss/pkg/linux/Makefile | 88 +
nss/pkg/linux/sun-nss.spec | 52 +
nss/pkg/pkg-config/nss-config.in | 145 +
nss/pkg/pkg-config/nss.pc.in | 11 +
nss/pkg/solaris/Makefile | 91 +
nss/pkg/solaris/Makefile-devl.com | 37 +
nss/pkg/solaris/Makefile-devl.targ | 28 +
nss/pkg/solaris/Makefile-tlsu.com | 37 +
nss/pkg/solaris/Makefile-tlsu.targ | 36 +
nss/pkg/solaris/Makefile.com | 37 +
nss/pkg/solaris/Makefile.targ | 36 +
nss/pkg/solaris/SUNWtls/Makefile | 18 +
nss/pkg/solaris/SUNWtls/pkgdepend | 30 +
nss/pkg/solaris/SUNWtls/pkginfo.tmpl | 35 +
nss/pkg/solaris/SUNWtls/prototype_com | 43 +
nss/pkg/solaris/SUNWtls/prototype_i386 | 56 +
nss/pkg/solaris/SUNWtls/prototype_sparc | 69 +
nss/pkg/solaris/SUNWtlsd/Makefile | 18 +
nss/pkg/solaris/SUNWtlsd/pkgdepend | 25 +
nss/pkg/solaris/SUNWtlsd/pkginfo.tmpl | 35 +
nss/pkg/solaris/SUNWtlsd/prototype | 128 +
nss/pkg/solaris/SUNWtlsu/Makefile | 18 +
nss/pkg/solaris/SUNWtlsu/pkgdepend | 24 +
nss/pkg/solaris/SUNWtlsu/pkginfo.tmpl | 35 +
nss/pkg/solaris/SUNWtlsu/prototype_com | 39 +
nss/pkg/solaris/SUNWtlsu/prototype_i386 | 44 +
nss/pkg/solaris/SUNWtlsu/prototype_sparc | 44 +
nss/pkg/solaris/bld_awk_pkginfo.ksh | 107 +
nss/pkg/solaris/common_files/copyright | 6 +
nss/pkg/solaris/proto64.mk | 16 +
nss/readme.md | 174 +
nss/tests/README.txt | 6 +
nss/tests/all.sh | 312 +
nss/tests/bogo/bogo.sh | 53 +
nss/tests/cert/cert.sh | 2012 +
nss/tests/cert/certext.txt | 130 +
nss/tests/chains/chains.sh | 1308 +
nss/tests/chains/ocspd-config/ocspd-certs.sh | 116 +
.../chains/ocspd-config/ocspd.conf.template | 46 +
nss/tests/chains/ocspd-config/readme | 3 +
nss/tests/chains/scenarios/aia.cfg | 35 +
nss/tests/chains/scenarios/anypolicy.cfg | 77 +
.../chains/scenarios/anypolicywithlevel.cfg | 399 +
nss/tests/chains/scenarios/bridge.cfg | 106 +
nss/tests/chains/scenarios/bridgewithaia.cfg | 54 +
.../chains/scenarios/bridgewithhalfaia.cfg | 89 +
.../bridgewithpolicyextensionandmapping.cfg | 187 +
nss/tests/chains/scenarios/crldp.cfg | 105 +
nss/tests/chains/scenarios/dsa.cfg | 72 +
nss/tests/chains/scenarios/explicitPolicy.cfg | 78 +
nss/tests/chains/scenarios/extension.cfg | 102 +
nss/tests/chains/scenarios/extension2.cfg | 140 +
nss/tests/chains/scenarios/mapping.cfg | 63 +
nss/tests/chains/scenarios/mapping2.cfg | 71 +
nss/tests/chains/scenarios/megabridge_3_2.cfg | 130 +
nss/tests/chains/scenarios/method.cfg | 25 +
.../chains/scenarios/nameconstraints.cfg | 161 +
nss/tests/chains/scenarios/ocsp.cfg | 177 +
nss/tests/chains/scenarios/ocspd.cfg | 172 +
nss/tests/chains/scenarios/realcerts.cfg | 29 +
nss/tests/chains/scenarios/revoc.cfg | 86 +
nss/tests/chains/scenarios/scenarios | 24 +
nss/tests/chains/scenarios/trustanchors.cfg | 114 +
nss/tests/cipher/cipher.sh | 140 +
nss/tests/cipher/cipher.txt | 57 +
nss/tests/cipher/dsa.txt | 13 +
nss/tests/cipher/gcm.txt | 16 +
nss/tests/cipher/hash.txt | 11 +
nss/tests/cipher/performance.sh | 156 +
nss/tests/cipher/rsa.txt | 11 +
nss/tests/cipher/symmkey.txt | 36 +
nss/tests/clean_tbx | 172 +
nss/tests/cmdtests/cmdtests.sh | 101 +
nss/tests/common/Makefile | 24 +
nss/tests/common/cleanup.sh | 55 +
nss/tests/common/init.sh | 672 +
nss/tests/common/parsegtestreport.sed | 8 +
nss/tests/common/results_header.html | 6 +
nss/tests/core_watch | 45 +
nss/tests/crmf/crmf.sh | 89 +
nss/tests/dbtests/dbtests.sh | 262 +
nss/tests/dbupgrade/dbupgrade.sh | 106 +
nss/tests/dll_version.sh | 50 +
nss/tests/doc/clean.gif | Bin 0 -> 5503 bytes
nss/tests/doc/nssqa.txt | 108 +
nss/tests/doc/platform_specific_problems | 110 +
nss/tests/doc/qa_wrapper.html | 269 +
nss/tests/dummy/dummy.sh | 19 +
nss/tests/ec/ec.sh | 37 +
nss/tests/ec/ecperf.sh | 52 +
nss/tests/ec/ectest.sh | 93 +
nss/tests/fips/fips.sh | 293 +
nss/tests/gtests/gtests.sh | 90 +
nss/tests/header | 1636 +
nss/tests/interop/interop.sh | 68 +
nss/tests/iopr/cert_iopr.sh | 405 +
nss/tests/iopr/ocsp_iopr.sh | 231 +
nss/tests/iopr/server_scr/apache_unix.cfg | 47 +
nss/tests/iopr/server_scr/cert_gen.sh | 367 +
nss/tests/iopr/server_scr/cipher.list | 98 +
nss/tests/iopr/server_scr/client.cgi | 526 +
nss/tests/iopr/server_scr/config | 17 +
nss/tests/iopr/server_scr/iis_windows.cfg | 33 +
nss/tests/iopr/server_scr/iopr_server.cfg | 67 +
nss/tests/iopr/server_scr/sslreq.dat | 2 +
nss/tests/iopr/ssl_iopr.sh | 643 +
nss/tests/jss_dll_version.sh | 22 +
nss/tests/jssdir | 28 +
nss/tests/jssqa | 220 +
nss/tests/libpkix/cert_trust.map | 6 +
nss/tests/libpkix/certs/BrAirWaysBadSig.cert | Bin 0 -> 1647 bytes
.../certs/CertificatePoliciesCritical.crt | Bin 0 -> 805 bytes
nss/tests/libpkix/certs/GoodCACert.crt | Bin 0 -> 625 bytes
.../libpkix/certs/NameConstraints.ca.cert | Bin 0 -> 626 bytes
.../certs/NameConstraints.dcissallowed.cert | Bin 0 -> 888 bytes
.../certs/NameConstraints.dcissblocked.cert | Bin 0 -> 889 bytes
.../certs/NameConstraints.dcisscopy.cert | Bin 0 -> 957 bytes
.../certs/NameConstraints.intermediate.cert | Bin 0 -> 662 bytes
.../certs/NameConstraints.intermediate2.cert | Bin 0 -> 644 bytes
.../certs/NameConstraints.intermediate3.cert | Bin 0 -> 716 bytes
.../certs/NameConstraints.intermediate4.cert | Bin 0 -> 607 bytes
.../certs/NameConstraints.intermediate5.cert | Bin 0 -> 612 bytes
.../certs/NameConstraints.intermediate6.cert | Bin 0 -> 611 bytes
.../libpkix/certs/NameConstraints.ncca.cert | Bin 0 -> 672 bytes
.../certs/NameConstraints.server1.cert | Bin 0 -> 660 bytes
.../certs/NameConstraints.server10.cert | Bin 0 -> 560 bytes
.../certs/NameConstraints.server11.cert | Bin 0 -> 585 bytes
.../certs/NameConstraints.server12.cert | Bin 0 -> 562 bytes
.../certs/NameConstraints.server13.cert | Bin 0 -> 574 bytes
.../certs/NameConstraints.server14.cert | Bin 0 -> 574 bytes
.../certs/NameConstraints.server15.cert | Bin 0 -> 634 bytes
.../certs/NameConstraints.server16.cert | Bin 0 -> 612 bytes
.../certs/NameConstraints.server17.cert | Bin 0 -> 630 bytes
.../certs/NameConstraints.server2.cert | Bin 0 -> 643 bytes
.../certs/NameConstraints.server3.cert | Bin 0 -> 660 bytes
.../certs/NameConstraints.server4.cert | Bin 0 -> 663 bytes
.../certs/NameConstraints.server5.cert | Bin 0 -> 646 bytes
.../certs/NameConstraints.server6.cert | Bin 0 -> 663 bytes
.../certs/NameConstraints.server7.cert | Bin 0 -> 578 bytes
.../certs/NameConstraints.server8.cert | Bin 0 -> 564 bytes
.../certs/NameConstraints.server9.cert | Bin 0 -> 551 bytes
nss/tests/libpkix/certs/OCSPCA1.cert | Bin 0 -> 574 bytes
nss/tests/libpkix/certs/OCSPCA1.p12 | Bin 0 -> 1690 bytes
nss/tests/libpkix/certs/OCSPCA2.cert | Bin 0 -> 574 bytes
nss/tests/libpkix/certs/OCSPCA2.p12 | Bin 0 -> 1690 bytes
nss/tests/libpkix/certs/OCSPCA3.cert | Bin 0 -> 574 bytes
nss/tests/libpkix/certs/OCSPCA3.p12 | Bin 0 -> 1690 bytes
nss/tests/libpkix/certs/OCSPEE11.cert | Bin 0 -> 552 bytes
nss/tests/libpkix/certs/OCSPEE12.cert | Bin 0 -> 552 bytes
nss/tests/libpkix/certs/OCSPEE13.cert | Bin 0 -> 552 bytes
nss/tests/libpkix/certs/OCSPEE14.cert | Bin 0 -> 552 bytes
nss/tests/libpkix/certs/OCSPEE15.cert | Bin 0 -> 552 bytes
nss/tests/libpkix/certs/OCSPEE21.cert | Bin 0 -> 552 bytes
nss/tests/libpkix/certs/OCSPEE22.cert | Bin 0 -> 552 bytes
nss/tests/libpkix/certs/OCSPEE23.cert | Bin 0 -> 552 bytes
nss/tests/libpkix/certs/OCSPEE31.cert | Bin 0 -> 552 bytes
nss/tests/libpkix/certs/OCSPEE32.cert | Bin 0 -> 552 bytes
nss/tests/libpkix/certs/OCSPEE33.cert | Bin 0 -> 552 bytes
nss/tests/libpkix/certs/OCSPRoot.cert | Bin 0 -> 549 bytes
nss/tests/libpkix/certs/OCSPRoot.p12 | Bin 0 -> 1668 bytes
nss/tests/libpkix/certs/PayPalEE.cert | Bin 0 -> 1376 bytes
nss/tests/libpkix/certs/PayPalICA.cert | Bin 0 -> 1205 bytes
nss/tests/libpkix/certs/PayPalRootCA.cert | Bin 0 -> 969 bytes
nss/tests/libpkix/certs/TestCA.ca.cert | Bin 0 -> 628 bytes
nss/tests/libpkix/certs/TestUser50.cert | Bin 0 -> 615 bytes
nss/tests/libpkix/certs/TestUser51.cert | Bin 0 -> 615 bytes
.../certs/TrustAnchorRootCertificate.crt | Bin 0 -> 572 bytes
.../certs/ValidCertificatePathTest1EE.crt | Bin 0 -> 622 bytes
nss/tests/libpkix/certs/anchor2dsa | Bin 0 -> 906 bytes
nss/tests/libpkix/certs/crldiff.crl | Bin 0 -> 237 bytes
nss/tests/libpkix/certs/crlgood.crl | Bin 0 -> 237 bytes
.../certs/extKeyUsage/codeSigningEKUCert | Bin 0 -> 696 bytes
.../libpkix/certs/extKeyUsage/multiEKUCert | Bin 0 -> 716 bytes
nss/tests/libpkix/certs/extKeyUsage/noEKUCert | Bin 0 -> 742 bytes
.../libpkix/certs/generalName/altNameDnCert | Bin 0 -> 748 bytes
.../certs/generalName/altNameDnCert_diff | Bin 0 -> 747 bytes
.../libpkix/certs/generalName/altNameDnsCert | Bin 0 -> 700 bytes
.../certs/generalName/altNameDnsCert_diff | Bin 0 -> 700 bytes
.../libpkix/certs/generalName/altNameEdiCert | Bin 0 -> 702 bytes
.../certs/generalName/altNameEdiCert_diff | Bin 0 -> 700 bytes
.../libpkix/certs/generalName/altNameIpCert | Bin 0 -> 692 bytes
.../certs/generalName/altNameIpCert_diff | Bin 0 -> 692 bytes
.../libpkix/certs/generalName/altNameNoneCert | Bin 0 -> 742 bytes
.../libpkix/certs/generalName/altNameOidCert | Bin 0 -> 691 bytes
.../certs/generalName/altNameOidCert_diff | Bin 0 -> 694 bytes
.../certs/generalName/altNameOtherCert | Bin 0 -> 698 bytes
.../certs/generalName/altNameOtherCert_diff | Bin 0 -> 698 bytes
.../certs/generalName/altNameRfc822Cert | Bin 0 -> 740 bytes
.../certs/generalName/altNameRfc822Cert_diff | Bin 0 -> 703 bytes
.../certs/generalName/altNameRfc822DnsCert | Bin 0 -> 718 bytes
.../libpkix/certs/generalName/altNameUriCert | Bin 0 -> 706 bytes
.../certs/generalName/altNameUriCert_diff | Bin 0 -> 708 bytes
.../libpkix/certs/generalName/altNameX400Cert | Bin 0 -> 691 bytes
.../certs/generalName/altNameX400Cert_diff | Bin 0 -> 691 bytes
nss/tests/libpkix/certs/hanfeiyu2hanfeiyu | Bin 0 -> 669 bytes
nss/tests/libpkix/certs/hy2hc-bc | Bin 0 -> 668 bytes
nss/tests/libpkix/certs/hy2hy-bc0 | Bin 0 -> 685 bytes
nss/tests/libpkix/certs/issuer-hanfei.crl | Bin 0 -> 199 bytes
nss/tests/libpkix/certs/issuer-none.crl | Bin 0 -> 196 bytes
.../libpkix/certs/keyIdentifier/authKeyIDCert | Bin 0 -> 536 bytes
.../libpkix/certs/keyIdentifier/subjKeyIDCert | Bin 0 -> 906 bytes
.../libpkix/certs/keyUsage/decipherOnlyCert | Bin 0 -> 692 bytes
.../libpkix/certs/keyUsage/encipherOnlyCert | Bin 0 -> 692 bytes
.../libpkix/certs/keyUsage/multiKeyUsagesCert | Bin 0 -> 742 bytes
.../libpkix/certs/keyUsage/noKeyUsagesCert | Bin 0 -> 675 bytes
nss/tests/libpkix/certs/make-ca-u50-u51 | 37 +
nss/tests/libpkix/certs/make-nc | 508 +
nss/tests/libpkix/certs/noExtensionsCert | Bin 0 -> 680 bytes
nss/tests/libpkix/certs/nss2alice | Bin 0 -> 602 bytes
.../libpkix/certs/publicKey/dsaWithParams | Bin 0 -> 906 bytes
.../libpkix/certs/publicKey/dsaWithoutParams | Bin 0 -> 536 bytes
nss/tests/libpkix/certs/publicKey/labs2yassir | Bin 0 -> 676 bytes
nss/tests/libpkix/certs/publicKey/yassir2labs | Bin 0 -> 676 bytes
nss/tests/libpkix/certs/sun2sun | Bin 0 -> 666 bytes
nss/tests/libpkix/certs/yassir2bcn | Bin 0 -> 742 bytes
nss/tests/libpkix/certs/yassir2yassir | Bin 0 -> 760 bytes
nss/tests/libpkix/common/libpkix_init.sh | 324 +
nss/tests/libpkix/common/libpkix_init_nist.sh | 70 +
nss/tests/libpkix/libpkix.sh | 139 +
.../libpkix/pkix_pl_tests/module/cert8.db | Bin 0 -> 65536 bytes
.../libpkix/pkix_pl_tests/module/key3.db | Bin 0 -> 32768 bytes
.../module/rev_data/local/crldiff.crl | Bin 0 -> 237 bytes
.../module/rev_data/local/crlgood.crl | Bin 0 -> 237 bytes
.../module/rev_data/local/issuer-hanfei.crl | Bin 0 -> 199 bytes
.../module/rev_data/local/issuer-none.crl | Bin 0 -> 196 bytes
.../module/rev_data/test_eku_all.crt | Bin 0 -> 774 bytes
.../rev_data/test_eku_allbutcodesigningEE.crt | Bin 0 -> 732 bytes
.../module/rev_data/test_eku_clientauth.crt | Bin 0 -> 726 bytes
.../module/rev_data/test_eku_clientauthEE.crt | Bin 0 -> 694 bytes
.../test_eku_codesigning_clientauth.crt | Bin 0 -> 734 bytes
.../pkix_pl_tests/module/runPLTests.sh | 101 +
.../libpkix/pkix_pl_tests/module/secmod.db | Bin 0 -> 32768 bytes
.../pkix_pl_tests/pki/rev_data/local/README | 3 +
.../pki/rev_data/local/crldiff.crl | Bin 0 -> 237 bytes
.../pki/rev_data/local/crlgood.crl | Bin 0 -> 237 bytes
.../pki/rev_data/local/issuer-hanfei.crl | Bin 0 -> 199 bytes
.../pki/rev_data/local/issuer-none.crl | Bin 0 -> 196 bytes
.../libpkix/pkix_pl_tests/pki/runPLTests.sh | 81 +
nss/tests/libpkix/pkix_pl_tests/runPLTests.sh | 67 +
.../pkix_pl_tests/system/runPLTests.sh | 46 +
nss/tests/libpkix/pkix_tests/certsel/keyUsage | 0
.../libpkix/pkix_tests/certsel/runTests.sh | 33 +
.../libpkix/pkix_tests/checker/runTests.sh | 31 +
.../libpkix/pkix_tests/crlsel/runTests.sh | 33 +
.../libpkix/pkix_tests/params/runTests.sh | 36 +
.../libpkix/pkix_tests/results/runTests.sh | 36 +
nss/tests/libpkix/pkix_tests/runTests.sh | 98 +
.../libpkix/pkix_tests/store/runTests.sh | 32 +
.../libpkix/pkix_tests/top/anchorcert.crt | Bin 0 -> 694 bytes
.../backtracking/signature/greg.crl | Bin 0 -> 169 bytes
.../signature/greg2yassir_badsig.crt | Bin 0 -> 689 bytes
.../build_data/backtracking/signature/jes.crl | Bin 0 -> 153 bytes
.../backtracking/signature/jes2greg.crt | Bin 0 -> 671 bytes
.../backtracking/signature/jes2jes.crt | Bin 0 -> 656 bytes
.../backtracking/signature/jes2labs.crt | Bin 0 -> 555 bytes
.../backtracking/signature/labs.crl | Bin 0 -> 155 bytes
.../backtracking/signature/labs2yassir.crt | Bin 0 -> 675 bytes
.../backtracking/signature/yassir.crl | Bin 0 -> 173 bytes
.../backtracking/signature/yassir2hanfei.crt | Bin 0 -> 692 bytes
.../multi_path/signature/fail/greg.crl | Bin 0 -> 169 bytes
.../multi_path/signature/fail/greg2yassir.crt | Bin 0 -> 689 bytes
.../multi_path/signature/fail/jes.crl | Bin 0 -> 153 bytes
.../multi_path/signature/fail/jes2greg.crt | Bin 0 -> 671 bytes
.../multi_path/signature/fail/jes2jes.crt | Bin 0 -> 656 bytes
.../multi_path/signature/fail/jes2labs.crt | Bin 0 -> 555 bytes
.../multi_path/signature/fail/labs.crl | Bin 0 -> 155 bytes
.../multi_path/signature/fail/labs2yassir.crt | Bin 0 -> 676 bytes
.../multi_path/signature/fail/yassir.crl | Bin 0 -> 173 bytes
.../signature/fail/yassir2hanfei.crt | Bin 0 -> 692 bytes
.../multi_path/signature/pass/greg.crl | Bin 0 -> 169 bytes
.../multi_path/signature/pass/greg2yassir.crt | Bin 0 -> 689 bytes
.../multi_path/signature/pass/jes.crl | Bin 0 -> 153 bytes
.../multi_path/signature/pass/jes2greg.crt | Bin 0 -> 671 bytes
.../multi_path/signature/pass/jes2jes.crt | Bin 0 -> 656 bytes
.../multi_path/signature/pass/jes2labs.crt | Bin 0 -> 555 bytes
.../multi_path/signature/pass/labs.crl | Bin 0 -> 155 bytes
.../multi_path/signature/pass/labs2yassir.crt | Bin 0 -> 676 bytes
.../multi_path/signature/pass/yassir.crl | Bin 0 -> 173 bytes
.../signature/pass/yassir2hanfei.crt | Bin 0 -> 692 bytes
.../single_path/signature/fail/greg.crl | Bin 0 -> 169 bytes
.../signature/fail/greg2yassir_badsig.crt | Bin 0 -> 689 bytes
.../single_path/signature/fail/jes.crl | Bin 0 -> 153 bytes
.../single_path/signature/fail/jes2greg.crt | Bin 0 -> 671 bytes
.../single_path/signature/fail/jes2jes.crt | Bin 0 -> 656 bytes
.../single_path/signature/fail/yassir.crl | Bin 0 -> 173 bytes
.../signature/fail/yassir2hanfei.crt | Bin 0 -> 692 bytes
.../single_path/signature/pass/greg.crl | Bin 0 -> 169 bytes
.../signature/pass/greg2yassir.crt | Bin 0 -> 689 bytes
.../single_path/signature/pass/jes.crl | Bin 0 -> 153 bytes
.../single_path/signature/pass/jes2greg.crt | Bin 0 -> 671 bytes
.../single_path/signature/pass/jes2jes.crt | Bin 0 -> 656 bytes
.../single_path/signature/pass/yassir.crl | Bin 0 -> 173 bytes
.../signature/pass/yassir2hanfei.crt | Bin 0 -> 692 bytes
.../top/build_data/test1/greg2yassir.crt | Bin 0 -> 689 bytes
.../top/build_data/test1/jes2greg.crt | Bin 0 -> 671 bytes
.../top/build_data/test1/jes2jes.crt | Bin 0 -> 656 bytes
.../top/build_data/test1/jes2labs.crt | Bin 0 -> 555 bytes
.../top/build_data/test1/labs2yassir.crt | Bin 0 -> 676 bytes
.../top/build_data/test1/yassir2hanfei.crt | Bin 0 -> 692 bytes
.../top/build_data/test1/yassir2richard.crt | Bin 0 -> 520 bytes
.../top/build_data/test2/jes2greg.crt | Bin 0 -> 671 bytes
.../top/build_data/test2/jes2jes.crt | Bin 0 -> 656 bytes
.../top/build_data/test2/jes2labs.crt | Bin 0 -> 555 bytes
.../top/build_data/test2/labs2yassir.crt | Bin 0 -> 669 bytes
.../top/build_data/test2/nelson2yassir.crt | Bin 0 -> 676 bytes
.../top/build_data/test2/yassir2hanfei.crt | Bin 0 -> 692 bytes
.../top/build_data/test2/yassir2richard.crt | Bin 0 -> 520 bytes
.../top/build_data/test3/jes2greg.crt | Bin 0 -> 671 bytes
.../top/build_data/test3/jes2jes.crt | Bin 0 -> 656 bytes
.../top/build_data/test3/jes2labs.crt | Bin 0 -> 555 bytes
.../top/build_data/test3/labs2yassir.crt | Bin 0 -> 669 bytes
.../top/build_data/test3/nelson2yassir.crt | Bin 0 -> 676 bytes
.../top/build_data/test3/yassir2hanfei.crt | Bin 0 -> 692 bytes
nss/tests/libpkix/pkix_tests/top/cert8.db | Bin 0 -> 65536 bytes
nss/tests/libpkix/pkix_tests/top/goodcert.crt | Bin 0 -> 1031 bytes
nss/tests/libpkix/pkix_tests/top/key3.db | Bin 0 -> 32768 bytes
.../top/rev_data/crlchecker/chem.crl | Bin 0 -> 239 bytes
.../top/rev_data/crlchecker/chem2prof.crt | Bin 0 -> 709 bytes
.../top/rev_data/crlchecker/phy2prof.crt | Bin 0 -> 707 bytes
.../top/rev_data/crlchecker/phys.crl | Bin 0 -> 201 bytes
.../top/rev_data/crlchecker/prof.crl | Bin 0 -> 203 bytes
.../top/rev_data/crlchecker/prof2test.crt | Bin 0 -> 691 bytes
.../top/rev_data/crlchecker/sci.crl | Bin 0 -> 200 bytes
.../top/rev_data/crlchecker/sci2chem.crt | Bin 0 -> 707 bytes
.../top/rev_data/crlchecker/sci2phy.crt | Bin 0 -> 703 bytes
.../top/rev_data/crlchecker/sci2sci.crt | Bin 0 -> 703 bytes
.../top/rev_data/crlchecker/test.crl | Bin 0 -> 205 bytes
.../libpkix/pkix_tests/top/revokedcert.crt | Bin 0 -> 1034 bytes
nss/tests/libpkix/pkix_tests/top/runTests.sh | 517 +
nss/tests/libpkix/pkix_tests/top/secmod.db | Bin 0 -> 32768 bytes
nss/tests/libpkix/pkix_tests/util/runTests.sh | 33 +
nss/tests/libpkix/runTests.sh | 87 +
nss/tests/libpkix/sample_apps/README | 77 +
nss/tests/libpkix/sample_apps/cert8.db | Bin 0 -> 65536 bytes
nss/tests/libpkix/sample_apps/key3.db | Bin 0 -> 32768 bytes
nss/tests/libpkix/sample_apps/runPerf.sh | 143 +
nss/tests/libpkix/sample_apps/secmod.db | Bin 0 -> 32768 bytes
nss/tests/libpkix/vfychain_test.lst | 4 +
nss/tests/lowhash/lowhash.sh | 97 +
nss/tests/memleak/ignored | 58 +
nss/tests/memleak/memleak.sh | 915 +
nss/tests/memleak/sslreq.dat | 2 +
nss/tests/merge/merge.sh | 277 +
nss/tests/mksymlinks | 115 +
nss/tests/mpi/mpi.sh | 40 +
nss/tests/multinit/multinit.sh | 158 +
nss/tests/multinit/multinit.txt | 79 +
nss/tests/nssdir | 28 +
nss/tests/nsspath | 12 +
nss/tests/nssqa | 286 +
nss/tests/ocsp/ocsp.sh | 54 +
nss/tests/path_uniq | 107 +
nss/tests/perf/perf.sh | 61 +
.../netscape/suites/security/ssl/cert7.db | Bin 0 -> 90112 bytes
.../netscape/suites/security/ssl/key3.db | Bin 0 -> 16384 bytes
nss/tests/pkits/pkits.sh | 1988 +
nss/tests/platformlist | 11 +
nss/tests/platformlist.tbx | 14 +
nss/tests/qa_stage | 336 +
nss/tests/qa_stat | 938 +
nss/tests/qaclean | 144 +
nss/tests/remote/Makefile | 153 +
nss/tests/remote/manifest.mn | 6 +
nss/tests/run_niscc.sh | 982 +
nss/tests/sdr/sdr.sh | 111 +
nss/tests/set_environment | 234 +
nss/tests/smime/alice.txt | 6 +
nss/tests/smime/bob.txt | 6 +
nss/tests/smime/smime.sh | 259 +
nss/tests/ssl/ssl.sh | 1199 +
nss/tests/ssl/ssl_dist_stress.sh | 313 +
nss/tests/ssl/sslauth.txt | 76 +
nss/tests/ssl/sslcov.txt | 143 +
nss/tests/ssl/sslpolicy.txt | 174 +
nss/tests/ssl/sslreq.dat | 2 +
nss/tests/ssl/sslreq.txt | 2 +
nss/tests/ssl/sslstress.txt | 87 +
nss/tests/ssl_gtests/ssl_gtests.sh | 159 +
nss/tests/tools/sign.html | 8 +
nss/tests/tools/signjs.html | 11 +
nss/tests/tools/tools.sh | 498 +
nss/trademarks.txt | 129 +
3764 files changed, 1221505 insertions(+)
create mode 100644 README.md
create mode 100644 ca/cert_creation.sh
create mode 100644 ca/client_db/cert.req
create mode 100644 ca/client_db/cert.req2
create mode 100644 ca/client_db/cert8.db
create mode 100644 ca/client_db/key3.db
create mode 100644 ca/client_db/secmod.db
create mode 100644 ca/client_db/server.crt
create mode 100644 ca/noise.txt
create mode 100644 ca/server_db/cert.req
create mode 100644 ca/server_db/cert.req2
create mode 100644 ca/server_db/cert8.db
create mode 100644 ca/server_db/key3.db
create mode 100644 ca/server_db/secmod.db
create mode 100644 ca/server_db/server.crt
create mode 100644 nss/.clang-format
create mode 100644 nss/.gitignore
create mode 100644 nss/.hg_archival.txt
create mode 100644 nss/.hgignore
create mode 100644 nss/.taskcluster.yml
create mode 100644 nss/COPYING
create mode 100644 nss/Makefile
create mode 100644 nss/automation/buildbot-slave/bbenv-example.sh
create mode 100755 nss/automation/buildbot-slave/build.sh
create mode 100644 nss/automation/buildbot-slave/reboot.bat
create mode 100644 nss/automation/buildbot-slave/startbuild.bat
create mode 100755 nss/automation/ossfuzz/build.sh
create mode 100644 nss/automation/release/nss-release-helper.py
create mode 100644 nss/automation/taskcluster/docker-aarch64/Dockerfile
create mode 100755 nss/automation/taskcluster/docker-aarch64/bin/checkout.sh
create mode 100755 nss/automation/taskcluster/docker-aarch64/setup.sh
create mode 100644 nss/automation/taskcluster/docker-arm/Dockerfile
create mode 100755 nss/automation/taskcluster/docker-arm/bin/checkout.sh
create mode 100755 nss/automation/taskcluster/docker-arm/bin/uname.sh
create mode 100755 nss/automation/taskcluster/docker-arm/setup.sh
create mode 100644 nss/automation/taskcluster/docker-decision/Dockerfile
create mode 100644 nss/automation/taskcluster/docker-decision/bin/checkout.sh
create mode 100644 nss/automation/taskcluster/docker-decision/setup.sh
create mode 100644 nss/automation/taskcluster/docker-fuzz/Dockerfile
create mode 100644 nss/automation/taskcluster/docker-fuzz/bin/checkout.sh
create mode 100644 nss/automation/taskcluster/docker-fuzz/setup.sh
create mode 100644 nss/automation/taskcluster/docker/Dockerfile
create mode 100644 nss/automation/taskcluster/docker/bin/checkout.sh
create mode 100644 nss/automation/taskcluster/docker/setup.sh
create mode 100644 nss/automation/taskcluster/graph/npm-shrinkwrap.json
create mode 100644 nss/automation/taskcluster/graph/package.json
create mode 100644 nss/automation/taskcluster/graph/src/context_hash.js
create mode 100644 nss/automation/taskcluster/graph/src/extend.js
create mode 100644 nss/automation/taskcluster/graph/src/image_builder.js
create mode 100644 nss/automation/taskcluster/graph/src/index.js
create mode 100644 nss/automation/taskcluster/graph/src/merge.js
create mode 100644 nss/automation/taskcluster/graph/src/queue.js
create mode 100644 nss/automation/taskcluster/graph/src/try_syntax.js
create mode 100755 nss/automation/taskcluster/scripts/build.sh
create mode 100755 nss/automation/taskcluster/scripts/build_gyp.sh
create mode 100755 nss/automation/taskcluster/scripts/build_nspr.sh
create mode 100755 nss/automation/taskcluster/scripts/build_nss.sh
create mode 100755 nss/automation/taskcluster/scripts/build_softoken.sh
create mode 100755 nss/automation/taskcluster/scripts/build_util.sh
create mode 100755 nss/automation/taskcluster/scripts/extend_task_graph.sh
create mode 100755 nss/automation/taskcluster/scripts/fuzz.sh
create mode 100755 nss/automation/taskcluster/scripts/gen_certs.sh
create mode 100755 nss/automation/taskcluster/scripts/run_clang_format.sh
create mode 100755 nss/automation/taskcluster/scripts/run_scan_build.sh
create mode 100755 nss/automation/taskcluster/scripts/run_tests.sh
create mode 100644 nss/automation/taskcluster/scripts/split.sh
create mode 100644 nss/automation/taskcluster/scripts/tools.sh
create mode 100644 nss/automation/taskcluster/windows/build.sh
create mode 100644 nss/automation/taskcluster/windows/gen_certs.sh
create mode 100644 nss/automation/taskcluster/windows/releng.manifest
create mode 100644 nss/automation/taskcluster/windows/run_tests.sh
create mode 100644 nss/automation/taskcluster/windows/setup.sh
create mode 100755 nss/automation/travis/validate-formatting.sh
create mode 100755 nss/build.sh
create mode 100644 nss/cmd/Makefile
create mode 100644 nss/cmd/addbuiltin/Makefile
create mode 100644 nss/cmd/addbuiltin/addbuiltin.c
create mode 100644 nss/cmd/addbuiltin/addbuiltin.gyp
create mode 100644 nss/cmd/addbuiltin/manifest.mn
create mode 100644 nss/cmd/atob/Makefile
create mode 100644 nss/cmd/atob/atob.c
create mode 100644 nss/cmd/atob/atob.gyp
create mode 100644 nss/cmd/atob/manifest.mn
create mode 100644 nss/cmd/benchmark/.gitignore
create mode 100644 nss/cmd/benchmark/Makefile
create mode 100644 nss/cmd/benchmark/README.md
create mode 120000 nss/cmd/benchmark/client_db
create mode 100644 nss/cmd/benchmark/main.c
create mode 100644 nss/cmd/benchmark/manifest.mn
create mode 100644 nss/cmd/benchmark/messages.txt
create mode 100644 nss/cmd/bltest/Makefile
create mode 100644 nss/cmd/bltest/blapitest.c
create mode 100644 nss/cmd/bltest/bltest.gyp
create mode 100644 nss/cmd/bltest/manifest.mn
create mode 100644 nss/cmd/bltest/pkcs1_vectors.h
create mode 100644 nss/cmd/bltest/tests/README
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext0
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext1
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext10
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext11
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext12
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext13
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext14
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext15
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext16
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext17
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext18
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext19
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext2
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext20
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext21
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext22
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext23
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext24
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext3
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext4
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext5
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext6
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext7
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext8
create mode 100644 nss/cmd/bltest/tests/aes_cbc/ciphertext9
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv0
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv1
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv10
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv11
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv12
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv13
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv14
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv15
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv16
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv17
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv18
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv19
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv2
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv20
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv21
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv22
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv23
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv24
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv3
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv4
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv5
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv6
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv7
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv8
create mode 100644 nss/cmd/bltest/tests/aes_cbc/iv9
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key0
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key1
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key10
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key11
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key12
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key13
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key14
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key15
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key16
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key17
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key18
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key19
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key2
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key20
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key21
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key22
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key23
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key24
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key3
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key4
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key5
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key6
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key7
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key8
create mode 100644 nss/cmd/bltest/tests/aes_cbc/key9
create mode 100644 nss/cmd/bltest/tests/aes_cbc/mktst.sh
create mode 100644 nss/cmd/bltest/tests/aes_cbc/numtests
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext0
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext1
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext10
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext11
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext12
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext13
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext14
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext15
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext16
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext17
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext18
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext19
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext2
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext20
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext21
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext22
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext23
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext24
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext3
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext4
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext5
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext6
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext7
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext8
create mode 100644 nss/cmd/bltest/tests/aes_cbc/plaintext9
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test1.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test10.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test11.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test12.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test13.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test14.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test15.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test16.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test17.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test18.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test19.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test2.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test20.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test21.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test22.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test23.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test24.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test3.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test4.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test5.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test6.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test7.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test8.txt
create mode 100644 nss/cmd/bltest/tests/aes_cbc/test9.txt
create mode 100644 nss/cmd/bltest/tests/aes_ctr/aes_ctr_0.txt
create mode 100644 nss/cmd/bltest/tests/aes_ctr/aes_ctr_1.txt
create mode 100644 nss/cmd/bltest/tests/aes_ctr/aes_ctr_2.txt
create mode 100644 nss/cmd/bltest/tests/aes_ctr/aes_ctr_tests_source.txt
create mode 100644 nss/cmd/bltest/tests/aes_ctr/ciphertext0
create mode 100644 nss/cmd/bltest/tests/aes_ctr/ciphertext1
create mode 100644 nss/cmd/bltest/tests/aes_ctr/ciphertext2
create mode 100644 nss/cmd/bltest/tests/aes_ctr/iv0
create mode 100644 nss/cmd/bltest/tests/aes_ctr/iv1
create mode 100644 nss/cmd/bltest/tests/aes_ctr/iv2
create mode 100644 nss/cmd/bltest/tests/aes_ctr/key0
create mode 100644 nss/cmd/bltest/tests/aes_ctr/key1
create mode 100644 nss/cmd/bltest/tests/aes_ctr/key2
create mode 100644 nss/cmd/bltest/tests/aes_ctr/mktst.sh
create mode 100644 nss/cmd/bltest/tests/aes_ctr/numtests
create mode 100644 nss/cmd/bltest/tests/aes_ctr/plaintext0
create mode 100644 nss/cmd/bltest/tests/aes_ctr/plaintext1
create mode 100644 nss/cmd/bltest/tests/aes_ctr/plaintext2
create mode 100644 nss/cmd/bltest/tests/aes_cts/aes-cts-type-1-vectors.txt
create mode 100644 nss/cmd/bltest/tests/aes_cts/aes_cts_0.txt
create mode 100644 nss/cmd/bltest/tests/aes_cts/aes_cts_1.txt
create mode 100644 nss/cmd/bltest/tests/aes_cts/aes_cts_2.txt
create mode 100644 nss/cmd/bltest/tests/aes_cts/aes_cts_3.txt
create mode 100644 nss/cmd/bltest/tests/aes_cts/aes_cts_4.txt
create mode 100644 nss/cmd/bltest/tests/aes_cts/aes_cts_5.txt
create mode 100644 nss/cmd/bltest/tests/aes_cts/ciphertext0
create mode 100644 nss/cmd/bltest/tests/aes_cts/ciphertext1
create mode 100644 nss/cmd/bltest/tests/aes_cts/ciphertext2
create mode 100644 nss/cmd/bltest/tests/aes_cts/ciphertext3
create mode 100644 nss/cmd/bltest/tests/aes_cts/ciphertext4
create mode 100644 nss/cmd/bltest/tests/aes_cts/ciphertext5
create mode 100644 nss/cmd/bltest/tests/aes_cts/iv0
create mode 100644 nss/cmd/bltest/tests/aes_cts/iv1
create mode 100644 nss/cmd/bltest/tests/aes_cts/iv2
create mode 100644 nss/cmd/bltest/tests/aes_cts/iv3
create mode 100644 nss/cmd/bltest/tests/aes_cts/iv4
create mode 100644 nss/cmd/bltest/tests/aes_cts/iv5
create mode 100644 nss/cmd/bltest/tests/aes_cts/key0
create mode 100644 nss/cmd/bltest/tests/aes_cts/key1
create mode 100644 nss/cmd/bltest/tests/aes_cts/key2
create mode 100644 nss/cmd/bltest/tests/aes_cts/key3
create mode 100644 nss/cmd/bltest/tests/aes_cts/key4
create mode 100644 nss/cmd/bltest/tests/aes_cts/key5
create mode 100644 nss/cmd/bltest/tests/aes_cts/mktst.sh
create mode 100644 nss/cmd/bltest/tests/aes_cts/numtests
create mode 100644 nss/cmd/bltest/tests/aes_cts/plaintext0
create mode 100644 nss/cmd/bltest/tests/aes_cts/plaintext1
create mode 100644 nss/cmd/bltest/tests/aes_cts/plaintext2
create mode 100644 nss/cmd/bltest/tests/aes_cts/plaintext3
create mode 100644 nss/cmd/bltest/tests/aes_cts/plaintext4
create mode 100644 nss/cmd/bltest/tests/aes_cts/plaintext5
create mode 100644 nss/cmd/bltest/tests/aes_ecb/ciphertext0
create mode 100644 nss/cmd/bltest/tests/aes_ecb/ciphertext1
create mode 100644 nss/cmd/bltest/tests/aes_ecb/ciphertext2
create mode 100644 nss/cmd/bltest/tests/aes_ecb/ciphertext3
create mode 100644 nss/cmd/bltest/tests/aes_ecb/ciphertext4
create mode 100644 nss/cmd/bltest/tests/aes_ecb/ciphertext5
create mode 100644 nss/cmd/bltest/tests/aes_ecb/ciphertext6
create mode 100644 nss/cmd/bltest/tests/aes_ecb/key0
create mode 100644 nss/cmd/bltest/tests/aes_ecb/key1
create mode 100644 nss/cmd/bltest/tests/aes_ecb/key2
create mode 100644 nss/cmd/bltest/tests/aes_ecb/key3
create mode 100644 nss/cmd/bltest/tests/aes_ecb/key4
create mode 100644 nss/cmd/bltest/tests/aes_ecb/key5
create mode 100644 nss/cmd/bltest/tests/aes_ecb/key6
create mode 100644 nss/cmd/bltest/tests/aes_ecb/mktst.sh
create mode 100644 nss/cmd/bltest/tests/aes_ecb/numtests
create mode 100644 nss/cmd/bltest/tests/aes_ecb/plaintext0
create mode 100644 nss/cmd/bltest/tests/aes_ecb/plaintext1
create mode 100644 nss/cmd/bltest/tests/aes_ecb/plaintext2
create mode 100644 nss/cmd/bltest/tests/aes_ecb/plaintext3
create mode 100644 nss/cmd/bltest/tests/aes_ecb/plaintext4
create mode 100644 nss/cmd/bltest/tests/aes_ecb/plaintext5
create mode 100644 nss/cmd/bltest/tests/aes_ecb/plaintext6
create mode 100644 nss/cmd/bltest/tests/aes_ecb/test1.txt
create mode 100644 nss/cmd/bltest/tests/aes_ecb/test2.txt
create mode 100644 nss/cmd/bltest/tests/aes_ecb/test3.txt
create mode 100644 nss/cmd/bltest/tests/aes_ecb/test4.txt
create mode 100644 nss/cmd/bltest/tests/aes_ecb/test5.txt
create mode 100644 nss/cmd/bltest/tests/aes_ecb/test6.txt
create mode 100644 nss/cmd/bltest/tests/aes_gcm/aad0
create mode 100644 nss/cmd/bltest/tests/aes_gcm/aad1
create mode 100644 nss/cmd/bltest/tests/aes_gcm/aad10
create mode 100644 nss/cmd/bltest/tests/aes_gcm/aad11
create mode 100644 nss/cmd/bltest/tests/aes_gcm/aad12
create mode 100644 nss/cmd/bltest/tests/aes_gcm/aad13
create mode 100644 nss/cmd/bltest/tests/aes_gcm/aad14
create mode 100644 nss/cmd/bltest/tests/aes_gcm/aad15
create mode 100644 nss/cmd/bltest/tests/aes_gcm/aad16
create mode 100644 nss/cmd/bltest/tests/aes_gcm/aad17
create mode 100644 nss/cmd/bltest/tests/aes_gcm/aad2
create mode 100644 nss/cmd/bltest/tests/aes_gcm/aad3
create mode 100644 nss/cmd/bltest/tests/aes_gcm/aad4
create mode 100644 nss/cmd/bltest/tests/aes_gcm/aad5
create mode 100644 nss/cmd/bltest/tests/aes_gcm/aad6
create mode 100644 nss/cmd/bltest/tests/aes_gcm/aad7
create mode 100644 nss/cmd/bltest/tests/aes_gcm/aad8
create mode 100644 nss/cmd/bltest/tests/aes_gcm/aad9
create mode 100644 nss/cmd/bltest/tests/aes_gcm/ciphertext0
create mode 100644 nss/cmd/bltest/tests/aes_gcm/ciphertext1
create mode 100644 nss/cmd/bltest/tests/aes_gcm/ciphertext10
create mode 100644 nss/cmd/bltest/tests/aes_gcm/ciphertext11
create mode 100644 nss/cmd/bltest/tests/aes_gcm/ciphertext12
create mode 100644 nss/cmd/bltest/tests/aes_gcm/ciphertext13
create mode 100644 nss/cmd/bltest/tests/aes_gcm/ciphertext14
create mode 100644 nss/cmd/bltest/tests/aes_gcm/ciphertext15
create mode 100644 nss/cmd/bltest/tests/aes_gcm/ciphertext16
create mode 100644 nss/cmd/bltest/tests/aes_gcm/ciphertext17
create mode 100644 nss/cmd/bltest/tests/aes_gcm/ciphertext2
create mode 100644 nss/cmd/bltest/tests/aes_gcm/ciphertext3
create mode 100644 nss/cmd/bltest/tests/aes_gcm/ciphertext4
create mode 100644 nss/cmd/bltest/tests/aes_gcm/ciphertext5
create mode 100644 nss/cmd/bltest/tests/aes_gcm/ciphertext6
create mode 100644 nss/cmd/bltest/tests/aes_gcm/ciphertext7
create mode 100644 nss/cmd/bltest/tests/aes_gcm/ciphertext8
create mode 100644 nss/cmd/bltest/tests/aes_gcm/ciphertext9
create mode 100644 nss/cmd/bltest/tests/aes_gcm/hex.c
create mode 100644 nss/cmd/bltest/tests/aes_gcm/iv0
create mode 100644 nss/cmd/bltest/tests/aes_gcm/iv1
create mode 100644 nss/cmd/bltest/tests/aes_gcm/iv10
create mode 100644 nss/cmd/bltest/tests/aes_gcm/iv11
create mode 100644 nss/cmd/bltest/tests/aes_gcm/iv12
create mode 100644 nss/cmd/bltest/tests/aes_gcm/iv13
create mode 100644 nss/cmd/bltest/tests/aes_gcm/iv14
create mode 100644 nss/cmd/bltest/tests/aes_gcm/iv15
create mode 100644 nss/cmd/bltest/tests/aes_gcm/iv16
create mode 100644 nss/cmd/bltest/tests/aes_gcm/iv17
create mode 100644 nss/cmd/bltest/tests/aes_gcm/iv2
create mode 100644 nss/cmd/bltest/tests/aes_gcm/iv3
create mode 100644 nss/cmd/bltest/tests/aes_gcm/iv4
create mode 100644 nss/cmd/bltest/tests/aes_gcm/iv5
create mode 100644 nss/cmd/bltest/tests/aes_gcm/iv6
create mode 100644 nss/cmd/bltest/tests/aes_gcm/iv7
create mode 100644 nss/cmd/bltest/tests/aes_gcm/iv8
create mode 100644 nss/cmd/bltest/tests/aes_gcm/iv9
create mode 100644 nss/cmd/bltest/tests/aes_gcm/key0
create mode 100644 nss/cmd/bltest/tests/aes_gcm/key1
create mode 100644 nss/cmd/bltest/tests/aes_gcm/key10
create mode 100644 nss/cmd/bltest/tests/aes_gcm/key11
create mode 100644 nss/cmd/bltest/tests/aes_gcm/key12
create mode 100644 nss/cmd/bltest/tests/aes_gcm/key13
create mode 100644 nss/cmd/bltest/tests/aes_gcm/key14
create mode 100644 nss/cmd/bltest/tests/aes_gcm/key15
create mode 100644 nss/cmd/bltest/tests/aes_gcm/key16
create mode 100644 nss/cmd/bltest/tests/aes_gcm/key17
create mode 100644 nss/cmd/bltest/tests/aes_gcm/key2
create mode 100644 nss/cmd/bltest/tests/aes_gcm/key3
create mode 100644 nss/cmd/bltest/tests/aes_gcm/key4
create mode 100644 nss/cmd/bltest/tests/aes_gcm/key5
create mode 100644 nss/cmd/bltest/tests/aes_gcm/key6
create mode 100644 nss/cmd/bltest/tests/aes_gcm/key7
create mode 100644 nss/cmd/bltest/tests/aes_gcm/key8
create mode 100644 nss/cmd/bltest/tests/aes_gcm/key9
create mode 100644 nss/cmd/bltest/tests/aes_gcm/mktst.sh
create mode 100644 nss/cmd/bltest/tests/aes_gcm/numtests
create mode 100644 nss/cmd/bltest/tests/aes_gcm/plaintext0
create mode 100644 nss/cmd/bltest/tests/aes_gcm/plaintext1
create mode 100644 nss/cmd/bltest/tests/aes_gcm/plaintext10
create mode 100644 nss/cmd/bltest/tests/aes_gcm/plaintext11
create mode 100644 nss/cmd/bltest/tests/aes_gcm/plaintext12
create mode 100644 nss/cmd/bltest/tests/aes_gcm/plaintext13
create mode 100644 nss/cmd/bltest/tests/aes_gcm/plaintext14
create mode 100644 nss/cmd/bltest/tests/aes_gcm/plaintext15
create mode 100644 nss/cmd/bltest/tests/aes_gcm/plaintext16
create mode 100644 nss/cmd/bltest/tests/aes_gcm/plaintext17
create mode 100644 nss/cmd/bltest/tests/aes_gcm/plaintext2
create mode 100644 nss/cmd/bltest/tests/aes_gcm/plaintext3
create mode 100644 nss/cmd/bltest/tests/aes_gcm/plaintext4
create mode 100644 nss/cmd/bltest/tests/aes_gcm/plaintext5
create mode 100644 nss/cmd/bltest/tests/aes_gcm/plaintext6
create mode 100644 nss/cmd/bltest/tests/aes_gcm/plaintext7
create mode 100644 nss/cmd/bltest/tests/aes_gcm/plaintext8
create mode 100644 nss/cmd/bltest/tests/aes_gcm/plaintext9
create mode 100644 nss/cmd/bltest/tests/aes_gcm/test0.txt
create mode 100644 nss/cmd/bltest/tests/aes_gcm/test1.txt
create mode 100644 nss/cmd/bltest/tests/aes_gcm/test10.txt
create mode 100644 nss/cmd/bltest/tests/aes_gcm/test11.txt
create mode 100644 nss/cmd/bltest/tests/aes_gcm/test12.txt
create mode 100644 nss/cmd/bltest/tests/aes_gcm/test13.txt
create mode 100644 nss/cmd/bltest/tests/aes_gcm/test14.txt
create mode 100644 nss/cmd/bltest/tests/aes_gcm/test15.txt
create mode 100644 nss/cmd/bltest/tests/aes_gcm/test16.txt
create mode 100644 nss/cmd/bltest/tests/aes_gcm/test17.txt
create mode 100644 nss/cmd/bltest/tests/aes_gcm/test2.txt
create mode 100644 nss/cmd/bltest/tests/aes_gcm/test3.txt
create mode 100644 nss/cmd/bltest/tests/aes_gcm/test4.txt
create mode 100644 nss/cmd/bltest/tests/aes_gcm/test5.txt
create mode 100644 nss/cmd/bltest/tests/aes_gcm/test6.txt
create mode 100644 nss/cmd/bltest/tests/aes_gcm/test7.txt
create mode 100644 nss/cmd/bltest/tests/aes_gcm/test8.txt
create mode 100644 nss/cmd/bltest/tests/aes_gcm/test9.txt
create mode 100644 nss/cmd/bltest/tests/aes_gcm/test_source.txt
create mode 100644 nss/cmd/bltest/tests/camellia_cbc/ciphertext0
create mode 100644 nss/cmd/bltest/tests/camellia_cbc/ciphertext1
create mode 100644 nss/cmd/bltest/tests/camellia_cbc/ciphertext2
create mode 100644 nss/cmd/bltest/tests/camellia_cbc/iv0
create mode 100644 nss/cmd/bltest/tests/camellia_cbc/key0
create mode 100644 nss/cmd/bltest/tests/camellia_cbc/key1
create mode 100644 nss/cmd/bltest/tests/camellia_cbc/key2
create mode 100644 nss/cmd/bltest/tests/camellia_cbc/numtests
create mode 100644 nss/cmd/bltest/tests/camellia_cbc/plaintext0
create mode 100644 nss/cmd/bltest/tests/camellia_ecb/ciphertext0
create mode 100644 nss/cmd/bltest/tests/camellia_ecb/ciphertext1
create mode 100644 nss/cmd/bltest/tests/camellia_ecb/ciphertext2
create mode 100644 nss/cmd/bltest/tests/camellia_ecb/key0
create mode 100644 nss/cmd/bltest/tests/camellia_ecb/key1
create mode 100644 nss/cmd/bltest/tests/camellia_ecb/key2
create mode 100644 nss/cmd/bltest/tests/camellia_ecb/numtests
create mode 100644 nss/cmd/bltest/tests/camellia_ecb/plaintext0
create mode 100644 nss/cmd/bltest/tests/chacha20_poly1305/aad0
create mode 100644 nss/cmd/bltest/tests/chacha20_poly1305/aad1
create mode 100644 nss/cmd/bltest/tests/chacha20_poly1305/ciphertext0
create mode 100644 nss/cmd/bltest/tests/chacha20_poly1305/ciphertext1
create mode 100644 nss/cmd/bltest/tests/chacha20_poly1305/iv0
create mode 100644 nss/cmd/bltest/tests/chacha20_poly1305/iv1
create mode 100644 nss/cmd/bltest/tests/chacha20_poly1305/key0
create mode 100644 nss/cmd/bltest/tests/chacha20_poly1305/key1
create mode 100644 nss/cmd/bltest/tests/chacha20_poly1305/numtests
create mode 100644 nss/cmd/bltest/tests/chacha20_poly1305/plaintext0
create mode 100644 nss/cmd/bltest/tests/chacha20_poly1305/plaintext1
create mode 100644 nss/cmd/bltest/tests/des3_cbc/ciphertext0
create mode 100644 nss/cmd/bltest/tests/des3_cbc/iv0
create mode 100644 nss/cmd/bltest/tests/des3_cbc/key0
create mode 100644 nss/cmd/bltest/tests/des3_cbc/numtests
create mode 100644 nss/cmd/bltest/tests/des3_cbc/plaintext0
create mode 100644 nss/cmd/bltest/tests/des3_ecb/ciphertext0
create mode 100644 nss/cmd/bltest/tests/des3_ecb/key0
create mode 100644 nss/cmd/bltest/tests/des3_ecb/numtests
create mode 100644 nss/cmd/bltest/tests/des3_ecb/plaintext0
create mode 100644 nss/cmd/bltest/tests/des_cbc/ciphertext0
create mode 100644 nss/cmd/bltest/tests/des_cbc/iv0
create mode 100644 nss/cmd/bltest/tests/des_cbc/key0
create mode 100644 nss/cmd/bltest/tests/des_cbc/numtests
create mode 100644 nss/cmd/bltest/tests/des_cbc/plaintext0
create mode 100644 nss/cmd/bltest/tests/des_ecb/ciphertext0
create mode 100644 nss/cmd/bltest/tests/des_ecb/key0
create mode 100644 nss/cmd/bltest/tests/des_ecb/numtests
create mode 100644 nss/cmd/bltest/tests/des_ecb/plaintext0
create mode 100644 nss/cmd/bltest/tests/dsa/ciphertext0
create mode 100644 nss/cmd/bltest/tests/dsa/ciphertext1
create mode 100644 nss/cmd/bltest/tests/dsa/ciphertext10
create mode 100644 nss/cmd/bltest/tests/dsa/ciphertext11
create mode 100644 nss/cmd/bltest/tests/dsa/ciphertext12
create mode 100644 nss/cmd/bltest/tests/dsa/ciphertext13
create mode 100644 nss/cmd/bltest/tests/dsa/ciphertext14
create mode 100644 nss/cmd/bltest/tests/dsa/ciphertext15
create mode 100644 nss/cmd/bltest/tests/dsa/ciphertext16
create mode 100644 nss/cmd/bltest/tests/dsa/ciphertext17
create mode 100644 nss/cmd/bltest/tests/dsa/ciphertext18
create mode 100644 nss/cmd/bltest/tests/dsa/ciphertext19
create mode 100644 nss/cmd/bltest/tests/dsa/ciphertext2
create mode 100644 nss/cmd/bltest/tests/dsa/ciphertext20
create mode 100644 nss/cmd/bltest/tests/dsa/ciphertext3
create mode 100644 nss/cmd/bltest/tests/dsa/ciphertext4
create mode 100644 nss/cmd/bltest/tests/dsa/ciphertext5
create mode 100644 nss/cmd/bltest/tests/dsa/ciphertext6
create mode 100644 nss/cmd/bltest/tests/dsa/ciphertext7
create mode 100644 nss/cmd/bltest/tests/dsa/ciphertext8
create mode 100644 nss/cmd/bltest/tests/dsa/ciphertext9
create mode 100644 nss/cmd/bltest/tests/dsa/dsa_fips.txt
create mode 100644 nss/cmd/bltest/tests/dsa/key0
create mode 100644 nss/cmd/bltest/tests/dsa/key1
create mode 100644 nss/cmd/bltest/tests/dsa/key10
create mode 100644 nss/cmd/bltest/tests/dsa/key11
create mode 100644 nss/cmd/bltest/tests/dsa/key12
create mode 100644 nss/cmd/bltest/tests/dsa/key13
create mode 100644 nss/cmd/bltest/tests/dsa/key14
create mode 100644 nss/cmd/bltest/tests/dsa/key15
create mode 100644 nss/cmd/bltest/tests/dsa/key16
create mode 100644 nss/cmd/bltest/tests/dsa/key17
create mode 100644 nss/cmd/bltest/tests/dsa/key18
create mode 100644 nss/cmd/bltest/tests/dsa/key19
create mode 100644 nss/cmd/bltest/tests/dsa/key2
create mode 100644 nss/cmd/bltest/tests/dsa/key20
create mode 100644 nss/cmd/bltest/tests/dsa/key3
create mode 100644 nss/cmd/bltest/tests/dsa/key4
create mode 100644 nss/cmd/bltest/tests/dsa/key5
create mode 100644 nss/cmd/bltest/tests/dsa/key6
create mode 100644 nss/cmd/bltest/tests/dsa/key7
create mode 100644 nss/cmd/bltest/tests/dsa/key8
create mode 100644 nss/cmd/bltest/tests/dsa/key9
create mode 100644 nss/cmd/bltest/tests/dsa/keyseed0
create mode 100644 nss/cmd/bltest/tests/dsa/keyseed1
create mode 100644 nss/cmd/bltest/tests/dsa/keyseed10
create mode 100644 nss/cmd/bltest/tests/dsa/keyseed11
create mode 100644 nss/cmd/bltest/tests/dsa/keyseed12
create mode 100644 nss/cmd/bltest/tests/dsa/keyseed13
create mode 100644 nss/cmd/bltest/tests/dsa/keyseed14
create mode 100644 nss/cmd/bltest/tests/dsa/keyseed15
create mode 100644 nss/cmd/bltest/tests/dsa/keyseed16
create mode 100644 nss/cmd/bltest/tests/dsa/keyseed17
create mode 100644 nss/cmd/bltest/tests/dsa/keyseed18
create mode 100644 nss/cmd/bltest/tests/dsa/keyseed19
create mode 100644 nss/cmd/bltest/tests/dsa/keyseed2
create mode 100644 nss/cmd/bltest/tests/dsa/keyseed20
create mode 100644 nss/cmd/bltest/tests/dsa/keyseed3
create mode 100644 nss/cmd/bltest/tests/dsa/keyseed4
create mode 100644 nss/cmd/bltest/tests/dsa/keyseed5
create mode 100644 nss/cmd/bltest/tests/dsa/keyseed6
create mode 100644 nss/cmd/bltest/tests/dsa/keyseed7
create mode 100644 nss/cmd/bltest/tests/dsa/keyseed8
create mode 100644 nss/cmd/bltest/tests/dsa/keyseed9
create mode 100644 nss/cmd/bltest/tests/dsa/numtests
create mode 100644 nss/cmd/bltest/tests/dsa/plaintext0
create mode 100644 nss/cmd/bltest/tests/dsa/plaintext1
create mode 100644 nss/cmd/bltest/tests/dsa/plaintext10
create mode 100644 nss/cmd/bltest/tests/dsa/plaintext11
create mode 100644 nss/cmd/bltest/tests/dsa/plaintext12
create mode 100644 nss/cmd/bltest/tests/dsa/plaintext13
create mode 100644 nss/cmd/bltest/tests/dsa/plaintext14
create mode 100644 nss/cmd/bltest/tests/dsa/plaintext15
create mode 100644 nss/cmd/bltest/tests/dsa/plaintext16
create mode 100644 nss/cmd/bltest/tests/dsa/plaintext17
create mode 100644 nss/cmd/bltest/tests/dsa/plaintext18
create mode 100644 nss/cmd/bltest/tests/dsa/plaintext19
create mode 100644 nss/cmd/bltest/tests/dsa/plaintext2
create mode 100644 nss/cmd/bltest/tests/dsa/plaintext20
create mode 100644 nss/cmd/bltest/tests/dsa/plaintext3
create mode 100644 nss/cmd/bltest/tests/dsa/plaintext4
create mode 100644 nss/cmd/bltest/tests/dsa/plaintext5
create mode 100644 nss/cmd/bltest/tests/dsa/plaintext6
create mode 100644 nss/cmd/bltest/tests/dsa/plaintext7
create mode 100644 nss/cmd/bltest/tests/dsa/plaintext8
create mode 100644 nss/cmd/bltest/tests/dsa/plaintext9
create mode 100644 nss/cmd/bltest/tests/dsa/pqg0
create mode 100644 nss/cmd/bltest/tests/dsa/pqg1
create mode 100644 nss/cmd/bltest/tests/dsa/pqg10
create mode 100644 nss/cmd/bltest/tests/dsa/pqg11
create mode 100644 nss/cmd/bltest/tests/dsa/pqg12
create mode 100644 nss/cmd/bltest/tests/dsa/pqg13
create mode 100644 nss/cmd/bltest/tests/dsa/pqg14
create mode 100644 nss/cmd/bltest/tests/dsa/pqg15
create mode 100644 nss/cmd/bltest/tests/dsa/pqg16
create mode 100644 nss/cmd/bltest/tests/dsa/pqg17
create mode 100644 nss/cmd/bltest/tests/dsa/pqg18
create mode 100644 nss/cmd/bltest/tests/dsa/pqg19
create mode 100644 nss/cmd/bltest/tests/dsa/pqg2
create mode 100644 nss/cmd/bltest/tests/dsa/pqg20
create mode 100644 nss/cmd/bltest/tests/dsa/pqg3
create mode 100644 nss/cmd/bltest/tests/dsa/pqg4
create mode 100644 nss/cmd/bltest/tests/dsa/pqg5
create mode 100644 nss/cmd/bltest/tests/dsa/pqg6
create mode 100644 nss/cmd/bltest/tests/dsa/pqg7
create mode 100644 nss/cmd/bltest/tests/dsa/pqg8
create mode 100644 nss/cmd/bltest/tests/dsa/pqg9
create mode 100644 nss/cmd/bltest/tests/dsa/sigseed0
create mode 100644 nss/cmd/bltest/tests/dsa/sigseed1
create mode 100644 nss/cmd/bltest/tests/dsa/sigseed10
create mode 100644 nss/cmd/bltest/tests/dsa/sigseed11
create mode 100644 nss/cmd/bltest/tests/dsa/sigseed12
create mode 100644 nss/cmd/bltest/tests/dsa/sigseed13
create mode 100644 nss/cmd/bltest/tests/dsa/sigseed14
create mode 100644 nss/cmd/bltest/tests/dsa/sigseed15
create mode 100644 nss/cmd/bltest/tests/dsa/sigseed16
create mode 100644 nss/cmd/bltest/tests/dsa/sigseed17
create mode 100644 nss/cmd/bltest/tests/dsa/sigseed18
create mode 100644 nss/cmd/bltest/tests/dsa/sigseed19
create mode 100644 nss/cmd/bltest/tests/dsa/sigseed2
create mode 100644 nss/cmd/bltest/tests/dsa/sigseed20
create mode 100644 nss/cmd/bltest/tests/dsa/sigseed3
create mode 100644 nss/cmd/bltest/tests/dsa/sigseed4
create mode 100644 nss/cmd/bltest/tests/dsa/sigseed5
create mode 100644 nss/cmd/bltest/tests/dsa/sigseed6
create mode 100644 nss/cmd/bltest/tests/dsa/sigseed7
create mode 100644 nss/cmd/bltest/tests/dsa/sigseed8
create mode 100644 nss/cmd/bltest/tests/dsa/sigseed9
create mode 100644 nss/cmd/bltest/tests/ecdsa/README
create mode 100644 nss/cmd/bltest/tests/ecdsa/ciphertext0
create mode 100644 nss/cmd/bltest/tests/ecdsa/ciphertext1
create mode 100644 nss/cmd/bltest/tests/ecdsa/ciphertext10
create mode 100644 nss/cmd/bltest/tests/ecdsa/ciphertext11
create mode 100644 nss/cmd/bltest/tests/ecdsa/ciphertext12
create mode 100644 nss/cmd/bltest/tests/ecdsa/ciphertext13
create mode 100644 nss/cmd/bltest/tests/ecdsa/ciphertext14
create mode 100644 nss/cmd/bltest/tests/ecdsa/ciphertext15
create mode 100644 nss/cmd/bltest/tests/ecdsa/ciphertext16
create mode 100644 nss/cmd/bltest/tests/ecdsa/ciphertext17
create mode 100644 nss/cmd/bltest/tests/ecdsa/ciphertext18
create mode 100644 nss/cmd/bltest/tests/ecdsa/ciphertext19
create mode 100644 nss/cmd/bltest/tests/ecdsa/ciphertext2
create mode 100644 nss/cmd/bltest/tests/ecdsa/ciphertext20
create mode 100644 nss/cmd/bltest/tests/ecdsa/ciphertext3
create mode 100644 nss/cmd/bltest/tests/ecdsa/ciphertext4
create mode 100644 nss/cmd/bltest/tests/ecdsa/ciphertext5
create mode 100644 nss/cmd/bltest/tests/ecdsa/ciphertext6
create mode 100644 nss/cmd/bltest/tests/ecdsa/ciphertext7
create mode 100644 nss/cmd/bltest/tests/ecdsa/ciphertext8
create mode 100644 nss/cmd/bltest/tests/ecdsa/ciphertext9
create mode 100644 nss/cmd/bltest/tests/ecdsa/key0
create mode 100644 nss/cmd/bltest/tests/ecdsa/key1
create mode 100644 nss/cmd/bltest/tests/ecdsa/key10
create mode 100644 nss/cmd/bltest/tests/ecdsa/key11
create mode 100644 nss/cmd/bltest/tests/ecdsa/key12
create mode 100644 nss/cmd/bltest/tests/ecdsa/key13
create mode 100644 nss/cmd/bltest/tests/ecdsa/key14
create mode 100644 nss/cmd/bltest/tests/ecdsa/key15
create mode 100644 nss/cmd/bltest/tests/ecdsa/key16
create mode 100644 nss/cmd/bltest/tests/ecdsa/key17
create mode 100644 nss/cmd/bltest/tests/ecdsa/key18
create mode 100644 nss/cmd/bltest/tests/ecdsa/key19
create mode 100644 nss/cmd/bltest/tests/ecdsa/key2
create mode 100644 nss/cmd/bltest/tests/ecdsa/key20
create mode 100644 nss/cmd/bltest/tests/ecdsa/key3
create mode 100644 nss/cmd/bltest/tests/ecdsa/key4
create mode 100644 nss/cmd/bltest/tests/ecdsa/key5
create mode 100644 nss/cmd/bltest/tests/ecdsa/key6
create mode 100644 nss/cmd/bltest/tests/ecdsa/key7
create mode 100644 nss/cmd/bltest/tests/ecdsa/key8
create mode 100644 nss/cmd/bltest/tests/ecdsa/key9
create mode 100644 nss/cmd/bltest/tests/ecdsa/numtests
create mode 100644 nss/cmd/bltest/tests/ecdsa/plaintext0
create mode 100644 nss/cmd/bltest/tests/ecdsa/plaintext1
create mode 100644 nss/cmd/bltest/tests/ecdsa/plaintext10
create mode 100644 nss/cmd/bltest/tests/ecdsa/plaintext11
create mode 100644 nss/cmd/bltest/tests/ecdsa/plaintext12
create mode 100644 nss/cmd/bltest/tests/ecdsa/plaintext13
create mode 100644 nss/cmd/bltest/tests/ecdsa/plaintext14
create mode 100644 nss/cmd/bltest/tests/ecdsa/plaintext15
create mode 100644 nss/cmd/bltest/tests/ecdsa/plaintext16
create mode 100644 nss/cmd/bltest/tests/ecdsa/plaintext17
create mode 100644 nss/cmd/bltest/tests/ecdsa/plaintext18
create mode 100644 nss/cmd/bltest/tests/ecdsa/plaintext19
create mode 100644 nss/cmd/bltest/tests/ecdsa/plaintext2
create mode 100644 nss/cmd/bltest/tests/ecdsa/plaintext20
create mode 100644 nss/cmd/bltest/tests/ecdsa/plaintext3
create mode 100644 nss/cmd/bltest/tests/ecdsa/plaintext4
create mode 100644 nss/cmd/bltest/tests/ecdsa/plaintext5
create mode 100644 nss/cmd/bltest/tests/ecdsa/plaintext6
create mode 100644 nss/cmd/bltest/tests/ecdsa/plaintext7
create mode 100644 nss/cmd/bltest/tests/ecdsa/plaintext8
create mode 100644 nss/cmd/bltest/tests/ecdsa/plaintext9
create mode 100644 nss/cmd/bltest/tests/ecdsa/sigseed0
create mode 100644 nss/cmd/bltest/tests/ecdsa/sigseed1
create mode 100644 nss/cmd/bltest/tests/ecdsa/sigseed10
create mode 100644 nss/cmd/bltest/tests/ecdsa/sigseed11
create mode 100644 nss/cmd/bltest/tests/ecdsa/sigseed12
create mode 100644 nss/cmd/bltest/tests/ecdsa/sigseed13
create mode 100644 nss/cmd/bltest/tests/ecdsa/sigseed14
create mode 100644 nss/cmd/bltest/tests/ecdsa/sigseed15
create mode 100644 nss/cmd/bltest/tests/ecdsa/sigseed16
create mode 100644 nss/cmd/bltest/tests/ecdsa/sigseed17
create mode 100644 nss/cmd/bltest/tests/ecdsa/sigseed18
create mode 100644 nss/cmd/bltest/tests/ecdsa/sigseed19
create mode 100644 nss/cmd/bltest/tests/ecdsa/sigseed2
create mode 100644 nss/cmd/bltest/tests/ecdsa/sigseed20
create mode 100644 nss/cmd/bltest/tests/ecdsa/sigseed3
create mode 100644 nss/cmd/bltest/tests/ecdsa/sigseed4
create mode 100644 nss/cmd/bltest/tests/ecdsa/sigseed5
create mode 100644 nss/cmd/bltest/tests/ecdsa/sigseed6
create mode 100644 nss/cmd/bltest/tests/ecdsa/sigseed7
create mode 100644 nss/cmd/bltest/tests/ecdsa/sigseed8
create mode 100644 nss/cmd/bltest/tests/ecdsa/sigseed9
create mode 100644 nss/cmd/bltest/tests/md2/ciphertext0
create mode 100644 nss/cmd/bltest/tests/md2/numtests
create mode 100644 nss/cmd/bltest/tests/md2/plaintext0
create mode 100644 nss/cmd/bltest/tests/md5/ciphertext0
create mode 100644 nss/cmd/bltest/tests/md5/numtests
create mode 100644 nss/cmd/bltest/tests/md5/plaintext0
create mode 100644 nss/cmd/bltest/tests/rc2_cbc/ciphertext0
create mode 100644 nss/cmd/bltest/tests/rc2_cbc/iv0
create mode 100644 nss/cmd/bltest/tests/rc2_cbc/key0
create mode 100644 nss/cmd/bltest/tests/rc2_cbc/numtests
create mode 100644 nss/cmd/bltest/tests/rc2_cbc/plaintext0
create mode 100644 nss/cmd/bltest/tests/rc2_ecb/ciphertext0
create mode 100644 nss/cmd/bltest/tests/rc2_ecb/key0
create mode 100644 nss/cmd/bltest/tests/rc2_ecb/numtests
create mode 100644 nss/cmd/bltest/tests/rc2_ecb/plaintext0
create mode 100644 nss/cmd/bltest/tests/rc4/ciphertext0
create mode 100644 nss/cmd/bltest/tests/rc4/ciphertext1
create mode 100644 nss/cmd/bltest/tests/rc4/key0
create mode 100644 nss/cmd/bltest/tests/rc4/key1
create mode 100644 nss/cmd/bltest/tests/rc4/numtests
create mode 100644 nss/cmd/bltest/tests/rc4/plaintext0
create mode 100644 nss/cmd/bltest/tests/rc4/plaintext1
create mode 100644 nss/cmd/bltest/tests/rc5_cbc/ciphertext0
create mode 100644 nss/cmd/bltest/tests/rc5_cbc/iv0
create mode 100644 nss/cmd/bltest/tests/rc5_cbc/key0
create mode 100644 nss/cmd/bltest/tests/rc5_cbc/numtests
create mode 100644 nss/cmd/bltest/tests/rc5_cbc/params0
create mode 100644 nss/cmd/bltest/tests/rc5_cbc/plaintext0
create mode 100644 nss/cmd/bltest/tests/rc5_ecb/ciphertext0
create mode 100644 nss/cmd/bltest/tests/rc5_ecb/key0
create mode 100644 nss/cmd/bltest/tests/rc5_ecb/numtests
create mode 100644 nss/cmd/bltest/tests/rc5_ecb/params0
create mode 100644 nss/cmd/bltest/tests/rc5_ecb/plaintext0
create mode 100644 nss/cmd/bltest/tests/rsa/ciphertext0
create mode 100644 nss/cmd/bltest/tests/rsa/key0
create mode 100644 nss/cmd/bltest/tests/rsa/numtests
create mode 100644 nss/cmd/bltest/tests/rsa/plaintext0
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/ciphertext0
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/ciphertext1
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/ciphertext10
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/ciphertext11
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/ciphertext12
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/ciphertext13
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/ciphertext14
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/ciphertext15
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/ciphertext16
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/ciphertext17
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/ciphertext2
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/ciphertext3
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/ciphertext4
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/ciphertext5
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/ciphertext6
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/ciphertext7
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/ciphertext8
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/ciphertext9
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/hash0
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/hash1
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/hash10
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/hash11
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/hash12
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/hash13
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/hash14
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/hash15
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/hash16
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/hash17
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/hash2
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/hash3
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/hash4
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/hash5
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/hash6
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/hash7
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/hash8
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/hash9
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/key0
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/key1
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/key10
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/key11
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/key12
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/key13
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/key14
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/key15
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/key16
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/key17
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/key2
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/key3
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/key4
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/key5
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/key6
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/key7
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/key8
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/key9
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/maskhash0
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/maskhash1
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/maskhash10
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/maskhash11
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/maskhash12
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/maskhash13
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/maskhash14
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/maskhash15
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/maskhash16
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/maskhash17
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/maskhash2
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/maskhash3
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/maskhash4
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/maskhash5
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/maskhash6
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/maskhash7
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/maskhash8
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/maskhash9
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/numtests
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/plaintext0
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/plaintext1
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/plaintext10
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/plaintext11
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/plaintext12
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/plaintext13
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/plaintext14
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/plaintext15
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/plaintext16
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/plaintext17
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/plaintext2
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/plaintext3
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/plaintext4
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/plaintext5
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/plaintext6
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/plaintext7
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/plaintext8
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/plaintext9
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/seed0
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/seed1
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/seed10
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/seed11
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/seed12
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/seed13
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/seed14
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/seed15
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/seed16
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/seed17
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/seed2
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/seed3
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/seed4
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/seed5
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/seed6
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/seed7
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/seed8
create mode 100644 nss/cmd/bltest/tests/rsa_oaep/seed9
create mode 100644 nss/cmd/bltest/tests/rsa_pss/ciphertext0
create mode 100644 nss/cmd/bltest/tests/rsa_pss/ciphertext1
create mode 100644 nss/cmd/bltest/tests/rsa_pss/ciphertext10
create mode 100644 nss/cmd/bltest/tests/rsa_pss/ciphertext11
create mode 100644 nss/cmd/bltest/tests/rsa_pss/ciphertext12
create mode 100644 nss/cmd/bltest/tests/rsa_pss/ciphertext13
create mode 100644 nss/cmd/bltest/tests/rsa_pss/ciphertext14
create mode 100644 nss/cmd/bltest/tests/rsa_pss/ciphertext15
create mode 100644 nss/cmd/bltest/tests/rsa_pss/ciphertext16
create mode 100644 nss/cmd/bltest/tests/rsa_pss/ciphertext17
create mode 100644 nss/cmd/bltest/tests/rsa_pss/ciphertext2
create mode 100644 nss/cmd/bltest/tests/rsa_pss/ciphertext3
create mode 100644 nss/cmd/bltest/tests/rsa_pss/ciphertext4
create mode 100644 nss/cmd/bltest/tests/rsa_pss/ciphertext5
create mode 100644 nss/cmd/bltest/tests/rsa_pss/ciphertext6
create mode 100644 nss/cmd/bltest/tests/rsa_pss/ciphertext7
create mode 100644 nss/cmd/bltest/tests/rsa_pss/ciphertext8
create mode 100644 nss/cmd/bltest/tests/rsa_pss/ciphertext9
create mode 100644 nss/cmd/bltest/tests/rsa_pss/hash0
create mode 100644 nss/cmd/bltest/tests/rsa_pss/hash1
create mode 100644 nss/cmd/bltest/tests/rsa_pss/hash10
create mode 100644 nss/cmd/bltest/tests/rsa_pss/hash11
create mode 100644 nss/cmd/bltest/tests/rsa_pss/hash12
create mode 100644 nss/cmd/bltest/tests/rsa_pss/hash13
create mode 100644 nss/cmd/bltest/tests/rsa_pss/hash14
create mode 100644 nss/cmd/bltest/tests/rsa_pss/hash15
create mode 100644 nss/cmd/bltest/tests/rsa_pss/hash16
create mode 100644 nss/cmd/bltest/tests/rsa_pss/hash17
create mode 100644 nss/cmd/bltest/tests/rsa_pss/hash2
create mode 100644 nss/cmd/bltest/tests/rsa_pss/hash3
create mode 100644 nss/cmd/bltest/tests/rsa_pss/hash4
create mode 100644 nss/cmd/bltest/tests/rsa_pss/hash5
create mode 100644 nss/cmd/bltest/tests/rsa_pss/hash6
create mode 100644 nss/cmd/bltest/tests/rsa_pss/hash7
create mode 100644 nss/cmd/bltest/tests/rsa_pss/hash8
create mode 100644 nss/cmd/bltest/tests/rsa_pss/hash9
create mode 100644 nss/cmd/bltest/tests/rsa_pss/key0
create mode 100644 nss/cmd/bltest/tests/rsa_pss/key1
create mode 100644 nss/cmd/bltest/tests/rsa_pss/key10
create mode 100644 nss/cmd/bltest/tests/rsa_pss/key11
create mode 100644 nss/cmd/bltest/tests/rsa_pss/key12
create mode 100644 nss/cmd/bltest/tests/rsa_pss/key13
create mode 100644 nss/cmd/bltest/tests/rsa_pss/key14
create mode 100644 nss/cmd/bltest/tests/rsa_pss/key15
create mode 100644 nss/cmd/bltest/tests/rsa_pss/key16
create mode 100644 nss/cmd/bltest/tests/rsa_pss/key17
create mode 100644 nss/cmd/bltest/tests/rsa_pss/key2
create mode 100644 nss/cmd/bltest/tests/rsa_pss/key3
create mode 100644 nss/cmd/bltest/tests/rsa_pss/key4
create mode 100644 nss/cmd/bltest/tests/rsa_pss/key5
create mode 100644 nss/cmd/bltest/tests/rsa_pss/key6
create mode 100644 nss/cmd/bltest/tests/rsa_pss/key7
create mode 100644 nss/cmd/bltest/tests/rsa_pss/key8
create mode 100644 nss/cmd/bltest/tests/rsa_pss/key9
create mode 100644 nss/cmd/bltest/tests/rsa_pss/maskhash0
create mode 100644 nss/cmd/bltest/tests/rsa_pss/maskhash1
create mode 100644 nss/cmd/bltest/tests/rsa_pss/maskhash10
create mode 100644 nss/cmd/bltest/tests/rsa_pss/maskhash11
create mode 100644 nss/cmd/bltest/tests/rsa_pss/maskhash12
create mode 100644 nss/cmd/bltest/tests/rsa_pss/maskhash13
create mode 100644 nss/cmd/bltest/tests/rsa_pss/maskhash14
create mode 100644 nss/cmd/bltest/tests/rsa_pss/maskhash15
create mode 100644 nss/cmd/bltest/tests/rsa_pss/maskhash16
create mode 100644 nss/cmd/bltest/tests/rsa_pss/maskhash17
create mode 100644 nss/cmd/bltest/tests/rsa_pss/maskhash2
create mode 100644 nss/cmd/bltest/tests/rsa_pss/maskhash3
create mode 100644 nss/cmd/bltest/tests/rsa_pss/maskhash4
create mode 100644 nss/cmd/bltest/tests/rsa_pss/maskhash5
create mode 100644 nss/cmd/bltest/tests/rsa_pss/maskhash6
create mode 100644 nss/cmd/bltest/tests/rsa_pss/maskhash7
create mode 100644 nss/cmd/bltest/tests/rsa_pss/maskhash8
create mode 100644 nss/cmd/bltest/tests/rsa_pss/maskhash9
create mode 100644 nss/cmd/bltest/tests/rsa_pss/numtests
create mode 100644 nss/cmd/bltest/tests/rsa_pss/plaintext0
create mode 100644 nss/cmd/bltest/tests/rsa_pss/plaintext1
create mode 100644 nss/cmd/bltest/tests/rsa_pss/plaintext10
create mode 100644 nss/cmd/bltest/tests/rsa_pss/plaintext11
create mode 100644 nss/cmd/bltest/tests/rsa_pss/plaintext12
create mode 100644 nss/cmd/bltest/tests/rsa_pss/plaintext13
create mode 100644 nss/cmd/bltest/tests/rsa_pss/plaintext14
create mode 100644 nss/cmd/bltest/tests/rsa_pss/plaintext15
create mode 100644 nss/cmd/bltest/tests/rsa_pss/plaintext16
create mode 100644 nss/cmd/bltest/tests/rsa_pss/plaintext17
create mode 100644 nss/cmd/bltest/tests/rsa_pss/plaintext2
create mode 100644 nss/cmd/bltest/tests/rsa_pss/plaintext3
create mode 100644 nss/cmd/bltest/tests/rsa_pss/plaintext4
create mode 100644 nss/cmd/bltest/tests/rsa_pss/plaintext5
create mode 100644 nss/cmd/bltest/tests/rsa_pss/plaintext6
create mode 100644 nss/cmd/bltest/tests/rsa_pss/plaintext7
create mode 100644 nss/cmd/bltest/tests/rsa_pss/plaintext8
create mode 100644 nss/cmd/bltest/tests/rsa_pss/plaintext9
create mode 100644 nss/cmd/bltest/tests/rsa_pss/seed0
create mode 100644 nss/cmd/bltest/tests/rsa_pss/seed1
create mode 100644 nss/cmd/bltest/tests/rsa_pss/seed10
create mode 100644 nss/cmd/bltest/tests/rsa_pss/seed11
create mode 100644 nss/cmd/bltest/tests/rsa_pss/seed12
create mode 100644 nss/cmd/bltest/tests/rsa_pss/seed13
create mode 100644 nss/cmd/bltest/tests/rsa_pss/seed14
create mode 100644 nss/cmd/bltest/tests/rsa_pss/seed15
create mode 100644 nss/cmd/bltest/tests/rsa_pss/seed16
create mode 100644 nss/cmd/bltest/tests/rsa_pss/seed17
create mode 100644 nss/cmd/bltest/tests/rsa_pss/seed2
create mode 100644 nss/cmd/bltest/tests/rsa_pss/seed3
create mode 100644 nss/cmd/bltest/tests/rsa_pss/seed4
create mode 100644 nss/cmd/bltest/tests/rsa_pss/seed5
create mode 100644 nss/cmd/bltest/tests/rsa_pss/seed6
create mode 100644 nss/cmd/bltest/tests/rsa_pss/seed7
create mode 100644 nss/cmd/bltest/tests/rsa_pss/seed8
create mode 100644 nss/cmd/bltest/tests/rsa_pss/seed9
create mode 100644 nss/cmd/bltest/tests/seed_cbc/ciphertext0
create mode 100644 nss/cmd/bltest/tests/seed_cbc/iv0
create mode 100644 nss/cmd/bltest/tests/seed_cbc/key0
create mode 100644 nss/cmd/bltest/tests/seed_cbc/numtests
create mode 100644 nss/cmd/bltest/tests/seed_cbc/plaintext0
create mode 100644 nss/cmd/bltest/tests/seed_ecb/ciphertext0
create mode 100644 nss/cmd/bltest/tests/seed_ecb/iv0
create mode 100644 nss/cmd/bltest/tests/seed_ecb/key0
create mode 100644 nss/cmd/bltest/tests/seed_ecb/numtests
create mode 100644 nss/cmd/bltest/tests/seed_ecb/plaintext0
create mode 100644 nss/cmd/bltest/tests/sha1/ciphertext0
create mode 100644 nss/cmd/bltest/tests/sha1/numtests
create mode 100644 nss/cmd/bltest/tests/sha1/plaintext0
create mode 100644 nss/cmd/bltest/tests/sha224/ciphertext0
create mode 100644 nss/cmd/bltest/tests/sha224/ciphertext1
create mode 100644 nss/cmd/bltest/tests/sha224/numtests
create mode 100644 nss/cmd/bltest/tests/sha224/plaintext0
create mode 100644 nss/cmd/bltest/tests/sha224/plaintext1
create mode 100644 nss/cmd/bltest/tests/sha256/ciphertext0
create mode 100644 nss/cmd/bltest/tests/sha256/ciphertext1
create mode 100644 nss/cmd/bltest/tests/sha256/numtests
create mode 100644 nss/cmd/bltest/tests/sha256/plaintext0
create mode 100644 nss/cmd/bltest/tests/sha256/plaintext1
create mode 100644 nss/cmd/bltest/tests/sha384/ciphertext0
create mode 100644 nss/cmd/bltest/tests/sha384/ciphertext1
create mode 100644 nss/cmd/bltest/tests/sha384/numtests
create mode 100644 nss/cmd/bltest/tests/sha384/plaintext0
create mode 100644 nss/cmd/bltest/tests/sha384/plaintext1
create mode 100644 nss/cmd/bltest/tests/sha512/ciphertext0
create mode 100644 nss/cmd/bltest/tests/sha512/ciphertext1
create mode 100644 nss/cmd/bltest/tests/sha512/numtests
create mode 100644 nss/cmd/bltest/tests/sha512/plaintext0
create mode 100644 nss/cmd/bltest/tests/sha512/plaintext1
create mode 100644 nss/cmd/btoa/Makefile
create mode 100644 nss/cmd/btoa/btoa.c
create mode 100644 nss/cmd/btoa/btoa.gyp
create mode 100644 nss/cmd/btoa/manifest.mn
create mode 100644 nss/cmd/certcgi/HOWTO.txt
create mode 100644 nss/cmd/certcgi/Makefile
create mode 100644 nss/cmd/certcgi/ca.html
create mode 100644 nss/cmd/certcgi/ca_form.html
create mode 100644 nss/cmd/certcgi/certcgi.c
create mode 100644 nss/cmd/certcgi/certcgi.gyp
create mode 100644 nss/cmd/certcgi/index.html
create mode 100644 nss/cmd/certcgi/main.html
create mode 100644 nss/cmd/certcgi/manifest.mn
create mode 100644 nss/cmd/certcgi/nscp_ext_form.html
create mode 100644 nss/cmd/certcgi/stnd_ext_form.html
create mode 100644 nss/cmd/certutil/Makefile
create mode 100644 nss/cmd/certutil/certext.c
create mode 100644 nss/cmd/certutil/certutil.c
create mode 100644 nss/cmd/certutil/certutil.gyp
create mode 100644 nss/cmd/certutil/certutil.h
create mode 100644 nss/cmd/certutil/keystuff.c
create mode 100644 nss/cmd/certutil/manifest.mn
create mode 100644 nss/cmd/chktest/Makefile
create mode 100644 nss/cmd/chktest/chktest.c
create mode 100644 nss/cmd/chktest/chktest.gyp
create mode 100644 nss/cmd/chktest/manifest.mn
create mode 100644 nss/cmd/clientProof/.gitignore
create mode 100644 nss/cmd/clientProof/.project
create mode 100644 nss/cmd/clientProof/Makefile
create mode 120000 nss/cmd/clientProof/client_db
create mode 100644 nss/cmd/clientProof/main.c
create mode 100644 nss/cmd/clientProof/manifest.mn
create mode 100644 nss/cmd/crlutil/Makefile
create mode 100644 nss/cmd/crlutil/crlgen.c
create mode 100644 nss/cmd/crlutil/crlgen.h
create mode 100644 nss/cmd/crlutil/crlgen_lex.c
create mode 100644 nss/cmd/crlutil/crlgen_lex_fix.sed
create mode 100644 nss/cmd/crlutil/crlgen_lex_orig.l
create mode 100644 nss/cmd/crlutil/crlutil.c
create mode 100644 nss/cmd/crlutil/crlutil.gyp
create mode 100644 nss/cmd/crlutil/manifest.mn
create mode 100644 nss/cmd/crmf-cgi/Makefile
create mode 100644 nss/cmd/crmf-cgi/config.mk
create mode 100644 nss/cmd/crmf-cgi/crmfcgi.c
create mode 100644 nss/cmd/crmf-cgi/crmfcgi.html
create mode 100644 nss/cmd/crmf-cgi/manifest.mn
create mode 100644 nss/cmd/crmftest/Makefile
create mode 100644 nss/cmd/crmftest/config.mk
create mode 100644 nss/cmd/crmftest/crmftest.gyp
create mode 100644 nss/cmd/crmftest/manifest.mn
create mode 100644 nss/cmd/crmftest/testcrmf.c
create mode 100644 nss/cmd/dbck/Makefile
create mode 100644 nss/cmd/dbck/dbck.c
create mode 100644 nss/cmd/dbck/dbrecover.c
create mode 100644 nss/cmd/dbck/manifest.mn
create mode 100644 nss/cmd/dbtest/Makefile
create mode 100644 nss/cmd/dbtest/dbtest.c
create mode 100644 nss/cmd/dbtest/dbtest.gyp
create mode 100644 nss/cmd/dbtest/manifest.mn
create mode 100644 nss/cmd/derdump/Makefile
create mode 100644 nss/cmd/derdump/derdump.c
create mode 100644 nss/cmd/derdump/derdump.gyp
create mode 100644 nss/cmd/derdump/manifest.mn
create mode 100644 nss/cmd/digest/Makefile
create mode 100644 nss/cmd/digest/digest.c
create mode 100644 nss/cmd/digest/digest.gyp
create mode 100644 nss/cmd/digest/manifest.mn
create mode 100644 nss/cmd/ecperf/Makefile
create mode 100644 nss/cmd/ecperf/ecperf.c
create mode 100644 nss/cmd/ecperf/ecperf.gyp
create mode 100755 nss/cmd/ecperf/manifest.mn
create mode 100644 nss/cmd/ectest/Makefile
create mode 100644 nss/cmd/ectest/ectest.c
create mode 100644 nss/cmd/ectest/manifest.mn
create mode 100644 nss/cmd/ectest/testvecs.h
create mode 100644 nss/cmd/fbectest/Makefile
create mode 100644 nss/cmd/fbectest/fbectest.c
create mode 100644 nss/cmd/fbectest/fbectest.gyp
create mode 100644 nss/cmd/fbectest/manifest.mn
create mode 100644 nss/cmd/fbectest/testvecs.h
create mode 100755 nss/cmd/fipstest/Makefile
create mode 100644 nss/cmd/fipstest/aes.sh
create mode 100644 nss/cmd/fipstest/aesgcm.sh
create mode 100755 nss/cmd/fipstest/dsa.sh
create mode 100644 nss/cmd/fipstest/ecdsa.sh
create mode 100644 nss/cmd/fipstest/fipstest.c
create mode 100644 nss/cmd/fipstest/fipstest.gyp
create mode 100755 nss/cmd/fipstest/hmac.sh
create mode 100644 nss/cmd/fipstest/manifest.mn
create mode 100644 nss/cmd/fipstest/rng.sh
create mode 100644 nss/cmd/fipstest/rsa.sh
create mode 100644 nss/cmd/fipstest/runtest.sh
create mode 100644 nss/cmd/fipstest/sha.sh
create mode 100644 nss/cmd/fipstest/tdea.sh
create mode 100644 nss/cmd/fipstest/tls.sh
create mode 100644 nss/cmd/fipstest/validate.sh
create mode 100644 nss/cmd/fipstest/validate1.sh
create mode 100644 nss/cmd/httpserv/Makefile
create mode 100644 nss/cmd/httpserv/httpserv.c
create mode 100644 nss/cmd/httpserv/httpserv.gyp
create mode 100644 nss/cmd/httpserv/manifest.mn
create mode 100644 nss/cmd/lib/Makefile
create mode 100644 nss/cmd/lib/basicutil.c
create mode 100644 nss/cmd/lib/basicutil.h
create mode 100644 nss/cmd/lib/berparse.c
create mode 100644 nss/cmd/lib/config.mk
create mode 100644 nss/cmd/lib/derprint.c
create mode 100644 nss/cmd/lib/exports.gyp
create mode 100644 nss/cmd/lib/ffs.c
create mode 100644 nss/cmd/lib/lib.gyp
create mode 100644 nss/cmd/lib/manifest.mn
create mode 100644 nss/cmd/lib/moreoids.c
create mode 100644 nss/cmd/lib/pk11table.c
create mode 100644 nss/cmd/lib/pk11table.h
create mode 100644 nss/cmd/lib/pppolicy.c
create mode 100644 nss/cmd/lib/secpwd.c
create mode 100644 nss/cmd/lib/secutil.c
create mode 100644 nss/cmd/lib/secutil.h
create mode 100755 nss/cmd/libpkix/Makefile
create mode 100644 nss/cmd/libpkix/config.mk
create mode 100755 nss/cmd/libpkix/manifest.mn
create mode 100755 nss/cmd/libpkix/perf/Makefile
create mode 100644 nss/cmd/libpkix/perf/libpkix_buildthreads.c
create mode 100755 nss/cmd/libpkix/perf/manifest.mn
create mode 100644 nss/cmd/libpkix/perf/nss_threads.c
create mode 100755 nss/cmd/libpkix/pkix/Makefile
create mode 100755 nss/cmd/libpkix/pkix/certsel/Makefile
create mode 100755 nss/cmd/libpkix/pkix/certsel/manifest.mn
create mode 100644 nss/cmd/libpkix/pkix/certsel/test_certselector.c
create mode 100644 nss/cmd/libpkix/pkix/certsel/test_comcertselparams.c
create mode 100755 nss/cmd/libpkix/pkix/checker/Makefile
create mode 100755 nss/cmd/libpkix/pkix/checker/manifest.mn
create mode 100644 nss/cmd/libpkix/pkix/checker/test_certchainchecker.c
create mode 100755 nss/cmd/libpkix/pkix/crlsel/Makefile
create mode 100755 nss/cmd/libpkix/pkix/crlsel/manifest.mn
create mode 100644 nss/cmd/libpkix/pkix/crlsel/test_comcrlselparams.c
create mode 100644 nss/cmd/libpkix/pkix/crlsel/test_crlselector.c
create mode 100755 nss/cmd/libpkix/pkix/manifest.mn
create mode 100755 nss/cmd/libpkix/pkix/params/Makefile
create mode 100755 nss/cmd/libpkix/pkix/params/manifest.mn
create mode 100644 nss/cmd/libpkix/pkix/params/test_procparams.c
create mode 100644 nss/cmd/libpkix/pkix/params/test_resourcelimits.c
create mode 100644 nss/cmd/libpkix/pkix/params/test_trustanchor.c
create mode 100644 nss/cmd/libpkix/pkix/params/test_valparams.c
create mode 100755 nss/cmd/libpkix/pkix/results/Makefile
create mode 100755 nss/cmd/libpkix/pkix/results/manifest.mn
create mode 100644 nss/cmd/libpkix/pkix/results/test_buildresult.c
create mode 100644 nss/cmd/libpkix/pkix/results/test_policynode.c
create mode 100644 nss/cmd/libpkix/pkix/results/test_valresult.c
create mode 100644 nss/cmd/libpkix/pkix/results/test_verifynode.c
create mode 100755 nss/cmd/libpkix/pkix/store/Makefile
create mode 100755 nss/cmd/libpkix/pkix/store/manifest.mn
create mode 100644 nss/cmd/libpkix/pkix/store/test_store.c
create mode 100755 nss/cmd/libpkix/pkix/top/Makefile
create mode 100755 nss/cmd/libpkix/pkix/top/manifest.mn
create mode 100644 nss/cmd/libpkix/pkix/top/test_basicchecker.c
create mode 100644 nss/cmd/libpkix/pkix/top/test_basicconstraintschecker.c
create mode 100644 nss/cmd/libpkix/pkix/top/test_buildchain.c
create mode 100644 nss/cmd/libpkix/pkix/top/test_buildchain_partialchain.c
create mode 100644 nss/cmd/libpkix/pkix/top/test_buildchain_resourcelimits.c
create mode 100644 nss/cmd/libpkix/pkix/top/test_buildchain_uchecker.c
create mode 100644 nss/cmd/libpkix/pkix/top/test_customcrlchecker.c
create mode 100644 nss/cmd/libpkix/pkix/top/test_defaultcrlchecker2stores.c
create mode 100644 nss/cmd/libpkix/pkix/top/test_ocsp.c
create mode 100644 nss/cmd/libpkix/pkix/top/test_policychecker.c
create mode 100644 nss/cmd/libpkix/pkix/top/test_subjaltnamechecker.c
create mode 100644 nss/cmd/libpkix/pkix/top/test_validatechain.c
create mode 100644 nss/cmd/libpkix/pkix/top/test_validatechain_NB.c
create mode 100644 nss/cmd/libpkix/pkix/top/test_validatechain_bc.c
create mode 100755 nss/cmd/libpkix/pkix/util/Makefile
create mode 100755 nss/cmd/libpkix/pkix/util/manifest.mn
create mode 100644 nss/cmd/libpkix/pkix/util/test_error.c
create mode 100644 nss/cmd/libpkix/pkix/util/test_list.c
create mode 100644 nss/cmd/libpkix/pkix/util/test_list2.c
create mode 100644 nss/cmd/libpkix/pkix/util/test_logger.c
create mode 100755 nss/cmd/libpkix/pkix_pl/Makefile
create mode 100755 nss/cmd/libpkix/pkix_pl/manifest.mn
create mode 100755 nss/cmd/libpkix/pkix_pl/module/Makefile
create mode 100755 nss/cmd/libpkix/pkix_pl/module/manifest.mn
create mode 100644 nss/cmd/libpkix/pkix_pl/module/test_colcertstore.c
create mode 100644 nss/cmd/libpkix/pkix_pl/module/test_ekuchecker.c
create mode 100644 nss/cmd/libpkix/pkix_pl/module/test_httpcertstore.c
create mode 100644 nss/cmd/libpkix/pkix_pl/module/test_pk11certstore.c
create mode 100644 nss/cmd/libpkix/pkix_pl/module/test_socket.c
create mode 100755 nss/cmd/libpkix/pkix_pl/pki/Makefile
create mode 100755 nss/cmd/libpkix/pkix_pl/pki/manifest.mn
create mode 100644 nss/cmd/libpkix/pkix_pl/pki/test_authorityinfoaccess.c
create mode 100644 nss/cmd/libpkix/pkix_pl/pki/test_cert.c
create mode 100644 nss/cmd/libpkix/pkix_pl/pki/test_crl.c
create mode 100644 nss/cmd/libpkix/pkix_pl/pki/test_crlentry.c
create mode 100644 nss/cmd/libpkix/pkix_pl/pki/test_date.c
create mode 100644 nss/cmd/libpkix/pkix_pl/pki/test_generalname.c
create mode 100644 nss/cmd/libpkix/pkix_pl/pki/test_nameconstraints.c
create mode 100644 nss/cmd/libpkix/pkix_pl/pki/test_subjectinfoaccess.c
create mode 100644 nss/cmd/libpkix/pkix_pl/pki/test_x500name.c
create mode 100755 nss/cmd/libpkix/pkix_pl/system/Makefile
create mode 100755 nss/cmd/libpkix/pkix_pl/system/manifest.mn
create mode 100644 nss/cmd/libpkix/pkix_pl/system/stress_test.c
create mode 100644 nss/cmd/libpkix/pkix_pl/system/test_bigint.c
create mode 100644 nss/cmd/libpkix/pkix_pl/system/test_bytearray.c
create mode 100644 nss/cmd/libpkix/pkix_pl/system/test_hashtable.c
create mode 100644 nss/cmd/libpkix/pkix_pl/system/test_mem.c
create mode 100644 nss/cmd/libpkix/pkix_pl/system/test_monitorlock.c
create mode 100644 nss/cmd/libpkix/pkix_pl/system/test_mutex.c
create mode 100644 nss/cmd/libpkix/pkix_pl/system/test_mutex2.c
create mode 100644 nss/cmd/libpkix/pkix_pl/system/test_mutex3.c
create mode 100644 nss/cmd/libpkix/pkix_pl/system/test_object.c
create mode 100644 nss/cmd/libpkix/pkix_pl/system/test_oid.c
create mode 100644 nss/cmd/libpkix/pkix_pl/system/test_rwlock.c
create mode 100644 nss/cmd/libpkix/pkix_pl/system/test_string.c
create mode 100644 nss/cmd/libpkix/pkix_pl/system/test_string2.c
create mode 100755 nss/cmd/libpkix/pkixlibs.mk
create mode 100755 nss/cmd/libpkix/pkixrules.mk
create mode 100644 nss/cmd/libpkix/pkixutil/Makefile
create mode 100644 nss/cmd/libpkix/pkixutil/manifest.mn
create mode 100644 nss/cmd/libpkix/pkixutil/pkixutil.c
create mode 100755 nss/cmd/libpkix/sample_apps/Makefile
create mode 100644 nss/cmd/libpkix/sample_apps/build_chain.c
create mode 100644 nss/cmd/libpkix/sample_apps/dumpcert.c
create mode 100644 nss/cmd/libpkix/sample_apps/dumpcrl.c
create mode 100755 nss/cmd/libpkix/sample_apps/manifest.mn
create mode 100644 nss/cmd/libpkix/sample_apps/validate_chain.c
create mode 100755 nss/cmd/libpkix/testutil/Makefile
create mode 100644 nss/cmd/libpkix/testutil/config.mk
create mode 100755 nss/cmd/libpkix/testutil/manifest.mn
create mode 100644 nss/cmd/libpkix/testutil/pkixutil.def
create mode 100644 nss/cmd/libpkix/testutil/testutil.c
create mode 100644 nss/cmd/libpkix/testutil/testutil.h
create mode 100644 nss/cmd/libpkix/testutil/testutil_nss.c
create mode 100644 nss/cmd/libpkix/testutil/testutil_nss.h
create mode 100644 nss/cmd/listsuites/Makefile
create mode 100644 nss/cmd/listsuites/listsuites.c
create mode 100644 nss/cmd/listsuites/listsuites.gyp
create mode 100644 nss/cmd/listsuites/manifest.mn
create mode 100644 nss/cmd/lowhashtest/Makefile
create mode 100644 nss/cmd/lowhashtest/lowhashtest.c
create mode 100644 nss/cmd/lowhashtest/lowhashtest.gyp
create mode 100644 nss/cmd/lowhashtest/manifest.mn
create mode 100644 nss/cmd/makepqg/Makefile
create mode 100644 nss/cmd/makepqg/makepqg.c
create mode 100644 nss/cmd/makepqg/makepqg.gyp
create mode 100644 nss/cmd/makepqg/manifest.mn
create mode 100644 nss/cmd/makepqg/testit.ksh
create mode 100644 nss/cmd/manifest.mn
create mode 100644 nss/cmd/modutil/Makefile
create mode 100644 nss/cmd/modutil/README
create mode 100644 nss/cmd/modutil/error.h
create mode 100644 nss/cmd/modutil/install-ds.c
create mode 100644 nss/cmd/modutil/install-ds.h
create mode 100644 nss/cmd/modutil/install.c
create mode 100644 nss/cmd/modutil/install.h
create mode 100644 nss/cmd/modutil/installparse.c
create mode 100644 nss/cmd/modutil/installparse.h
create mode 100644 nss/cmd/modutil/installparse.l
create mode 100644 nss/cmd/modutil/installparse.y
create mode 100644 nss/cmd/modutil/instsec.c
create mode 100644 nss/cmd/modutil/lex.Pk11Install_yy.c
create mode 100644 nss/cmd/modutil/manifest.mn
create mode 100644 nss/cmd/modutil/modutil.c
create mode 100644 nss/cmd/modutil/modutil.gyp
create mode 100644 nss/cmd/modutil/modutil.h
create mode 100644 nss/cmd/modutil/pk11.c
create mode 100644 nss/cmd/modutil/pk11jar.html
create mode 100644 nss/cmd/modutil/rules.mk
create mode 100644 nss/cmd/modutil/specification.html
create mode 100644 nss/cmd/mpitests/mpi-test.c
create mode 100644 nss/cmd/mpitests/mpitests.gyp
create mode 100644 nss/cmd/mpitests/test-info.c
create mode 100644 nss/cmd/multinit/Makefile
create mode 100644 nss/cmd/multinit/manifest.mn
create mode 100644 nss/cmd/multinit/multinit.c
create mode 100644 nss/cmd/multinit/multinit.gyp
create mode 100644 nss/cmd/ocspclnt/Makefile
create mode 100644 nss/cmd/ocspclnt/manifest.mn
create mode 100644 nss/cmd/ocspclnt/ocspclnt.c
create mode 100644 nss/cmd/ocspclnt/ocspclnt.gyp
create mode 100644 nss/cmd/ocspresp/Makefile
create mode 100644 nss/cmd/ocspresp/manifest.mn
create mode 100644 nss/cmd/ocspresp/ocspresp.c
create mode 100644 nss/cmd/ocspresp/ocspresp.gyp
create mode 100644 nss/cmd/oidcalc/Makefile
create mode 100644 nss/cmd/oidcalc/manifest.mn
create mode 100644 nss/cmd/oidcalc/oidcalc.c
create mode 100644 nss/cmd/oidcalc/oidcalc.gyp
create mode 100644 nss/cmd/p7content/Makefile
create mode 100644 nss/cmd/p7content/manifest.mn
create mode 100644 nss/cmd/p7content/p7content.c
create mode 100644 nss/cmd/p7content/p7content.gyp
create mode 100644 nss/cmd/p7env/Makefile
create mode 100644 nss/cmd/p7env/manifest.mn
create mode 100644 nss/cmd/p7env/p7env.c
create mode 100644 nss/cmd/p7env/p7env.gyp
create mode 100644 nss/cmd/p7sign/Makefile
create mode 100644 nss/cmd/p7sign/manifest.mn
create mode 100644 nss/cmd/p7sign/p7sign.c
create mode 100644 nss/cmd/p7sign/p7sign.gyp
create mode 100644 nss/cmd/p7verify/Makefile
create mode 100644 nss/cmd/p7verify/manifest.mn
create mode 100644 nss/cmd/p7verify/p7verify.c
create mode 100644 nss/cmd/p7verify/p7verify.gyp
create mode 100644 nss/cmd/perfclient/Makefile
create mode 120000 nss/cmd/perfclient/client_db
create mode 100644 nss/cmd/perfclient/main.c
create mode 100644 nss/cmd/perfclient/manifest.mn
create mode 100644 nss/cmd/perfserver/Makefile
create mode 100644 nss/cmd/perfserver/main.c
create mode 100644 nss/cmd/perfserver/manifest.mn
create mode 120000 nss/cmd/perfserver/server_db
create mode 100644 nss/cmd/pk11ectest/Makefile
create mode 100644 nss/cmd/pk11ectest/manifest.mn
create mode 100644 nss/cmd/pk11ectest/pk11ectest.c
create mode 100644 nss/cmd/pk11ectest/pk11ectest.gyp
create mode 100755 nss/cmd/pk11gcmtest/Makefile
create mode 100644 nss/cmd/pk11gcmtest/manifest.mn
create mode 100644 nss/cmd/pk11gcmtest/pk11gcmtest.c
create mode 100644 nss/cmd/pk11gcmtest/pk11gcmtest.gyp
create mode 100644 nss/cmd/pk11gcmtest/tests/README
create mode 100644 nss/cmd/pk11gcmtest/tests/gcmDecrypt128.rsp
create mode 100644 nss/cmd/pk11gcmtest/tests/gcmDecrypt192.rsp
create mode 100644 nss/cmd/pk11gcmtest/tests/gcmDecrypt256.rsp
create mode 100644 nss/cmd/pk11gcmtest/tests/gcmEncryptExtIV128.rsp
create mode 100644 nss/cmd/pk11gcmtest/tests/gcmEncryptExtIV192.rsp
create mode 100644 nss/cmd/pk11gcmtest/tests/gcmEncryptExtIV256.rsp
create mode 100755 nss/cmd/pk11mode/Makefile
create mode 100644 nss/cmd/pk11mode/manifest.mn
create mode 100644 nss/cmd/pk11mode/pk11mode.c
create mode 100644 nss/cmd/pk11mode/pk11mode.gyp
create mode 100644 nss/cmd/pk11util/Makefile
create mode 100644 nss/cmd/pk11util/manifest.mn
create mode 100644 nss/cmd/pk11util/pk11util.c
create mode 100644 nss/cmd/pk11util/scripts/dosign
create mode 100644 nss/cmd/pk11util/scripts/hssign
create mode 100644 nss/cmd/pk11util/scripts/lcert
create mode 100644 nss/cmd/pk11util/scripts/mechanisms
create mode 100644 nss/cmd/pk11util/scripts/pLabel1
create mode 100644 nss/cmd/pk11util/scripts/pMechanisms
create mode 100644 nss/cmd/pk11util/scripts/pcert
create mode 100644 nss/cmd/pk12util/Makefile
create mode 100644 nss/cmd/pk12util/manifest.mn
create mode 100644 nss/cmd/pk12util/pk12util.c
create mode 100644 nss/cmd/pk12util/pk12util.gyp
create mode 100644 nss/cmd/pk12util/pk12util.h
create mode 100644 nss/cmd/pk1sign/Makefile
create mode 100644 nss/cmd/pk1sign/manifest.mn
create mode 100644 nss/cmd/pk1sign/pk1sign.c
create mode 100644 nss/cmd/pk1sign/pk1sign.gyp
create mode 100644 nss/cmd/pkix-errcodes/Makefile
create mode 100644 nss/cmd/pkix-errcodes/manifest.mn
create mode 100644 nss/cmd/pkix-errcodes/pkix-errcodes.c
create mode 100644 nss/cmd/pkix-errcodes/pkix-errcodes.gyp
create mode 100644 nss/cmd/platlibs.gypi
create mode 100644 nss/cmd/platlibs.mk
create mode 100644 nss/cmd/platrules.mk
create mode 100644 nss/cmd/pp/Makefile
create mode 100644 nss/cmd/pp/manifest.mn
create mode 100644 nss/cmd/pp/pp.c
create mode 100644 nss/cmd/pp/pp.gyp
create mode 100644 nss/cmd/ppcertdata/Makefile
create mode 100644 nss/cmd/ppcertdata/manifest.mn
create mode 100644 nss/cmd/ppcertdata/ppcertdata.c
create mode 100644 nss/cmd/proofgen/.gitignore
create mode 100644 nss/cmd/proofgen/Makefile
create mode 120000 nss/cmd/proofgen/client_db
create mode 100644 nss/cmd/proofgen/main.c
create mode 100644 nss/cmd/proofgen/manifest.mn
create mode 100644 nss/cmd/pwdecrypt/Makefile
create mode 100644 nss/cmd/pwdecrypt/manifest.mn
create mode 100644 nss/cmd/pwdecrypt/pwdecrypt.c
create mode 100644 nss/cmd/pwdecrypt/pwdecrypt.gyp
create mode 100644 nss/cmd/randtrafficClient/Makefile
create mode 120000 nss/cmd/randtrafficClient/client_db
create mode 100644 nss/cmd/randtrafficClient/main.c
create mode 100644 nss/cmd/randtrafficClient/manifest.mn
create mode 100644 nss/cmd/randtrafficServer/Makefile
create mode 100644 nss/cmd/randtrafficServer/main.c
create mode 100644 nss/cmd/randtrafficServer/manifest.mn
create mode 120000 nss/cmd/randtrafficServer/server_db
create mode 100644 nss/cmd/replayClient/.gitignore
create mode 100644 nss/cmd/replayClient/Makefile
create mode 120000 nss/cmd/replayClient/client_db
create mode 100644 nss/cmd/replayClient/main.c
create mode 100644 nss/cmd/replayClient/manifest.mn
create mode 100644 nss/cmd/replayClient/messages.txt
create mode 100644 nss/cmd/replayServer/Makefile
create mode 100644 nss/cmd/replayServer/main.c
create mode 100644 nss/cmd/replayServer/manifest.mn
create mode 120000 nss/cmd/replayServer/server_db
create mode 100644 nss/cmd/rsaperf/Makefile
create mode 100644 nss/cmd/rsaperf/defkey.c
create mode 100644 nss/cmd/rsaperf/manifest.mn
create mode 100644 nss/cmd/rsaperf/rsaperf.c
create mode 100644 nss/cmd/rsaperf/rsaperf.gyp
create mode 100644 nss/cmd/rsapoptst/Makefile
create mode 100644 nss/cmd/rsapoptst/manifest.mn
create mode 100644 nss/cmd/rsapoptst/rsapoptst.c
create mode 100644 nss/cmd/samples/cert
create mode 100644 nss/cmd/samples/cert0
create mode 100644 nss/cmd/samples/cert1
create mode 100644 nss/cmd/samples/cert2
create mode 100644 nss/cmd/samples/pkcs7.ber
create mode 100644 nss/cmd/samples/pkcs7bday.ber
create mode 100644 nss/cmd/samples/pkcs7cnet.ber
create mode 100644 nss/cmd/samples/pkcs7news.ber
create mode 100644 nss/cmd/samples/x509v3.der
create mode 100644 nss/cmd/samples/x509v3.txt
create mode 100644 nss/cmd/sdrtest/Makefile
create mode 100644 nss/cmd/sdrtest/manifest.mn
create mode 100644 nss/cmd/sdrtest/sdrtest.c
create mode 100644 nss/cmd/sdrtest/sdrtest.gyp
create mode 100644 nss/cmd/selfserv/Makefile
create mode 100644 nss/cmd/selfserv/manifest.mn
create mode 100644 nss/cmd/selfserv/selfserv.c
create mode 100644 nss/cmd/selfserv/selfserv.gyp
create mode 100644 nss/cmd/serverProof/.cproject
create mode 100644 nss/cmd/serverProof/.project
create mode 100644 nss/cmd/serverProof/Makefile
create mode 100644 nss/cmd/serverProof/main.c
create mode 100644 nss/cmd/serverProof/manifest.mn
create mode 120000 nss/cmd/serverProof/server_db
create mode 100644 nss/cmd/shlibsign/Makefile
create mode 100644 nss/cmd/shlibsign/mangle/Makefile
create mode 100644 nss/cmd/shlibsign/mangle/mangle.c
create mode 100644 nss/cmd/shlibsign/mangle/mangle.gyp
create mode 100644 nss/cmd/shlibsign/mangle/manifest.mn
create mode 100644 nss/cmd/shlibsign/manifest.mn
create mode 100644 nss/cmd/shlibsign/shlibsign.c
create mode 100644 nss/cmd/shlibsign/shlibsign.gyp
create mode 100644 nss/cmd/shlibsign/sign.cmd
create mode 100644 nss/cmd/shlibsign/sign.sh
create mode 100644 nss/cmd/signtool/Makefile
create mode 100644 nss/cmd/signtool/README
create mode 100644 nss/cmd/signtool/certgen.c
create mode 100644 nss/cmd/signtool/javascript.c
create mode 100644 nss/cmd/signtool/list.c
create mode 100644 nss/cmd/signtool/manifest.mn
create mode 100644 nss/cmd/signtool/sign.c
create mode 100644 nss/cmd/signtool/signtool.c
create mode 100644 nss/cmd/signtool/signtool.gyp
create mode 100644 nss/cmd/signtool/signtool.h
create mode 100644 nss/cmd/signtool/util.c
create mode 100644 nss/cmd/signtool/verify.c
create mode 100644 nss/cmd/signtool/zip.c
create mode 100644 nss/cmd/signtool/zip.h
create mode 100644 nss/cmd/signver/Makefile
create mode 100755 nss/cmd/signver/examples/1/form.pl
create mode 100644 nss/cmd/signver/examples/1/signedForm.html
create mode 100644 nss/cmd/signver/examples/1/signedForm.nt.html
create mode 100755 nss/cmd/signver/examples/1/signedForm.pl
create mode 100644 nss/cmd/signver/manifest.mn
create mode 100644 nss/cmd/signver/pk7print.c
create mode 100644 nss/cmd/signver/signver.c
create mode 100644 nss/cmd/signver/signver.gyp
create mode 100644 nss/cmd/smimetools/Makefile
create mode 100644 nss/cmd/smimetools/cmsutil.c
create mode 100644 nss/cmd/smimetools/manifest.mn
create mode 100644 nss/cmd/smimetools/rules.mk
create mode 100755 nss/cmd/smimetools/smime
create mode 100644 nss/cmd/smimetools/smimetools.gyp
create mode 100644 nss/cmd/ssltap/Makefile
create mode 100644 nss/cmd/ssltap/manifest.mn
create mode 100644 nss/cmd/ssltap/ssltap-manual.html
create mode 100644 nss/cmd/ssltap/ssltap.c
create mode 100644 nss/cmd/ssltap/ssltap.gyp
create mode 100644 nss/cmd/strsclnt/Makefile
create mode 100644 nss/cmd/strsclnt/manifest.mn
create mode 100644 nss/cmd/strsclnt/strsclnt.c
create mode 100644 nss/cmd/strsclnt/strsclnt.gyp
create mode 100644 nss/cmd/symkeyutil/Makefile
create mode 100644 nss/cmd/symkeyutil/manifest.mn
create mode 100644 nss/cmd/symkeyutil/symkey.man
create mode 100644 nss/cmd/symkeyutil/symkeyutil.c
create mode 100644 nss/cmd/symkeyutil/symkeyutil.gyp
create mode 100644 nss/cmd/test/Makefile
create mode 120000 nss/cmd/test/client_db
create mode 100644 nss/cmd/test/main.c
create mode 100644 nss/cmd/test/manifest.mn
create mode 100644 nss/cmd/tests/Makefile
create mode 100644 nss/cmd/tests/baddbdir.c
create mode 100644 nss/cmd/tests/conflict.c
create mode 100644 nss/cmd/tests/dertimetest.c
create mode 100644 nss/cmd/tests/encodeinttest.c
create mode 100644 nss/cmd/tests/manifest.mn
create mode 100644 nss/cmd/tests/nonspr10.c
create mode 100644 nss/cmd/tests/remtest.c
create mode 100644 nss/cmd/tests/secmodtest.c
create mode 100644 nss/cmd/tests/tests.gyp
create mode 100644 nss/cmd/tstclnt/Makefile
create mode 100644 nss/cmd/tstclnt/manifest.mn
create mode 100644 nss/cmd/tstclnt/tstclnt.c
create mode 100644 nss/cmd/tstclnt/tstclnt.gyp
create mode 100644 nss/cmd/verifier/.gitignore
create mode 100644 nss/cmd/verifier/Makefile
create mode 120000 nss/cmd/verifier/client_db
create mode 100644 nss/cmd/verifier/main.c
create mode 100644 nss/cmd/verifier/manifest.mn
create mode 100644 nss/cmd/vfychain/Makefile
create mode 100644 nss/cmd/vfychain/manifest.mn
create mode 100644 nss/cmd/vfychain/vfychain.c
create mode 100644 nss/cmd/vfychain/vfychain.gyp
create mode 100644 nss/cmd/vfyserv/Makefile
create mode 100644 nss/cmd/vfyserv/manifest.mn
create mode 100644 nss/cmd/vfyserv/vfyserv.c
create mode 100644 nss/cmd/vfyserv/vfyserv.gyp
create mode 100644 nss/cmd/vfyserv/vfyserv.h
create mode 100644 nss/cmd/vfyserv/vfyutil.c
create mode 100644 nss/coreconf/AIX.mk
create mode 100644 nss/coreconf/Android.mk
create mode 100644 nss/coreconf/BSD_OS.mk
create mode 100644 nss/coreconf/BeOS.mk
create mode 100644 nss/coreconf/Darwin.mk
create mode 100644 nss/coreconf/FreeBSD.mk
create mode 100644 nss/coreconf/HP-UX.mk
create mode 100644 nss/coreconf/HP-UXA.09.03.mk
create mode 100644 nss/coreconf/HP-UXA.09.07.mk
create mode 100644 nss/coreconf/HP-UXA.09.mk
create mode 100644 nss/coreconf/HP-UXB.10.01.mk
create mode 100644 nss/coreconf/HP-UXB.10.10.mk
create mode 100644 nss/coreconf/HP-UXB.10.20.mk
create mode 100644 nss/coreconf/HP-UXB.10.30.mk
create mode 100644 nss/coreconf/HP-UXB.10.mk
create mode 100644 nss/coreconf/HP-UXB.11.00.mk
create mode 100644 nss/coreconf/HP-UXB.11.11.mk
create mode 100644 nss/coreconf/HP-UXB.11.20.mk
create mode 100644 nss/coreconf/HP-UXB.11.22.mk
create mode 100644 nss/coreconf/HP-UXB.11.23.mk
create mode 100644 nss/coreconf/HP-UXB.11.mk
create mode 100644 nss/coreconf/IRIX.mk
create mode 100644 nss/coreconf/IRIX5.2.mk
create mode 100644 nss/coreconf/IRIX5.3.mk
create mode 100644 nss/coreconf/IRIX5.mk
create mode 100644 nss/coreconf/IRIX6.2.mk
create mode 100644 nss/coreconf/IRIX6.3.mk
create mode 100644 nss/coreconf/IRIX6.5.mk
create mode 100644 nss/coreconf/IRIX6.mk
create mode 100644 nss/coreconf/Linux.mk
create mode 100644 nss/coreconf/Makefile
create mode 100644 nss/coreconf/NCR3.0.mk
create mode 100644 nss/coreconf/NEC4.2.mk
create mode 100644 nss/coreconf/NetBSD.mk
create mode 100644 nss/coreconf/OS2.mk
create mode 100644 nss/coreconf/OSF1.mk
create mode 100644 nss/coreconf/OSF1V2.0.mk
create mode 100644 nss/coreconf/OSF1V3.0.mk
create mode 100644 nss/coreconf/OSF1V3.2.mk
create mode 100644 nss/coreconf/OSF1V4.0.mk
create mode 100644 nss/coreconf/OSF1V4.0B.mk
create mode 100644 nss/coreconf/OSF1V4.0D.mk
create mode 100644 nss/coreconf/OSF1V5.0.mk
create mode 100644 nss/coreconf/OSF1V5.1.mk
create mode 100644 nss/coreconf/OpenBSD.mk
create mode 100644 nss/coreconf/OpenUNIX.mk
create mode 100644 nss/coreconf/QNX.mk
create mode 100644 nss/coreconf/README
create mode 100644 nss/coreconf/RISCOS.mk
create mode 100644 nss/coreconf/ReliantUNIX.mk
create mode 100644 nss/coreconf/ReliantUNIX5.4.mk
create mode 100644 nss/coreconf/SCOOS5.0.mk
create mode 100644 nss/coreconf/SCO_SV3.2.mk
create mode 100644 nss/coreconf/SunOS4.1.3_U1.mk
create mode 100644 nss/coreconf/SunOS5.mk
create mode 100644 nss/coreconf/UNIX.mk
create mode 100644 nss/coreconf/UNIXWARE2.1.mk
create mode 100644 nss/coreconf/WIN32.mk
create mode 100644 nss/coreconf/WIN95.mk
create mode 100644 nss/coreconf/WINNT.mk
create mode 100644 nss/coreconf/Werror.mk
create mode 100644 nss/coreconf/arch.mk
create mode 100644 nss/coreconf/check_cc_clang.py
create mode 100644 nss/coreconf/command.mk
create mode 100644 nss/coreconf/config.gypi
create mode 100644 nss/coreconf/config.mk
create mode 100644 nss/coreconf/coreconf.dep
create mode 100644 nss/coreconf/coreconf.pl
create mode 100755 nss/coreconf/cpdist.pl
create mode 100644 nss/coreconf/detect_host_arch.py
create mode 100644 nss/coreconf/empty.c
create mode 100644 nss/coreconf/fuzz.sh
create mode 100644 nss/coreconf/headers.mk
create mode 100755 nss/coreconf/import.pl
create mode 100644 nss/coreconf/jdk.mk
create mode 100755 nss/coreconf/jniregen.pl
create mode 100644 nss/coreconf/location.mk
create mode 100644 nss/coreconf/mkdepend/Makefile
create mode 100644 nss/coreconf/mkdepend/cppsetup.c
create mode 100644 nss/coreconf/mkdepend/def.h
create mode 100644 nss/coreconf/mkdepend/ifparser.c
create mode 100644 nss/coreconf/mkdepend/ifparser.h
create mode 100644 nss/coreconf/mkdepend/imakemdep.h
create mode 100644 nss/coreconf/mkdepend/include.c
create mode 100644 nss/coreconf/mkdepend/main.c
create mode 100644 nss/coreconf/mkdepend/mkdepend.man
create mode 100644 nss/coreconf/mkdepend/parse.c
create mode 100644 nss/coreconf/mkdepend/pr.c
create mode 100644 nss/coreconf/module.mk
create mode 100644 nss/coreconf/nsinstall/Makefile
create mode 100644 nss/coreconf/nsinstall/nsinstall.c
create mode 100644 nss/coreconf/nsinstall/nsinstall.gyp
create mode 100644 nss/coreconf/nsinstall/pathsub.c
create mode 100644 nss/coreconf/nsinstall/pathsub.h
create mode 100644 nss/coreconf/nsinstall/sunos4.h
create mode 100644 nss/coreconf/nspr.sh
create mode 100755 nss/coreconf/outofdate.pl
create mode 100755 nss/coreconf/precommit.clang-format.sh
create mode 100644 nss/coreconf/prefix.mk
create mode 100755 nss/coreconf/release.pl
create mode 100644 nss/coreconf/rules.mk
create mode 100644 nss/coreconf/ruleset.mk
create mode 100644 nss/coreconf/sanitizers.mk
create mode 100644 nss/coreconf/sanitizers.py
create mode 100644 nss/coreconf/sanitizers.sh
create mode 100644 nss/coreconf/shlibsign.py
create mode 100644 nss/coreconf/source.mk
create mode 100644 nss/coreconf/suffix.mk
create mode 100644 nss/coreconf/tree.mk
create mode 100644 nss/coreconf/version.mk
create mode 100644 nss/coreconf/version.pl
create mode 100644 nss/coreconf/werror.py
create mode 100644 nss/coreconf/zlib.mk
create mode 100644 nss/cpputil/.clang-format
create mode 100644 nss/cpputil/README
create mode 100644 nss/cpputil/cpputil.gyp
create mode 100644 nss/cpputil/dummy_io.cc
create mode 100644 nss/cpputil/dummy_io.h
create mode 100644 nss/cpputil/dummy_io_fwd.cc
create mode 100644 nss/cpputil/scoped_ptrs.h
create mode 100644 nss/doc/.hgignore
create mode 100644 nss/doc/Makefile
create mode 100644 nss/doc/README
create mode 100644 nss/doc/certutil.xml
create mode 100644 nss/doc/cmsutil.xml
create mode 100644 nss/doc/crlutil.xml
create mode 100644 nss/doc/derdump.xml
create mode 100644 nss/doc/html/.hgignore
create mode 100644 nss/doc/html/certutil.html
create mode 100644 nss/doc/html/cmsutil.html
create mode 100644 nss/doc/html/crlutil.html
create mode 100644 nss/doc/html/derdump.html
create mode 100644 nss/doc/html/modutil.html
create mode 100644 nss/doc/html/pk12util.html
create mode 100644 nss/doc/html/pp.html
create mode 100644 nss/doc/html/signtool.html
create mode 100644 nss/doc/html/signver.html
create mode 100644 nss/doc/html/ssltap.html
create mode 100644 nss/doc/html/vfychain.html
create mode 100644 nss/doc/html/vfyserv.html
create mode 100644 nss/doc/modutil.xml
create mode 100644 nss/doc/nroff/certutil.1
create mode 100644 nss/doc/nroff/cmsutil.1
create mode 100644 nss/doc/nroff/crlutil.1
create mode 100644 nss/doc/nroff/derdump.1
create mode 100644 nss/doc/nroff/modutil.1
create mode 100644 nss/doc/nroff/pk12util.1
create mode 100644 nss/doc/nroff/pp.1
create mode 100644 nss/doc/nroff/signtool.1
create mode 100644 nss/doc/nroff/signver.1
create mode 100644 nss/doc/nroff/ssltap.1
create mode 100644 nss/doc/nroff/vfychain.1
create mode 100644 nss/doc/nroff/vfyserv.1
create mode 100644 nss/doc/pk12util.xml
create mode 100644 nss/doc/pp.xml
create mode 100644 nss/doc/signtool.xml
create mode 100644 nss/doc/signver.xml
create mode 100644 nss/doc/ssltap.xml
create mode 100644 nss/doc/vfychain.xml
create mode 100644 nss/doc/vfyserv.xml
create mode 100644 nss/exports.gyp
create mode 100644 nss/external_tests/.clang-format
create mode 100644 nss/external_tests/Makefile
create mode 100644 nss/external_tests/README
create mode 100644 nss/external_tests/common/Makefile
create mode 100644 nss/external_tests/common/gtest.mk
create mode 100644 nss/external_tests/common/gtests.cc
create mode 100644 nss/external_tests/common/manifest.mn
create mode 100644 nss/external_tests/common/scoped_ptrs.h
create mode 100644 nss/external_tests/der_gtest/Makefile
create mode 100644 nss/external_tests/der_gtest/der_getint_unittest.cc
create mode 100644 nss/external_tests/der_gtest/manifest.mn
create mode 100644 nss/external_tests/google_test/Makefile
create mode 100644 nss/external_tests/google_test/gtest/CHANGES
create mode 100644 nss/external_tests/google_test/gtest/CMakeLists.txt
create mode 100644 nss/external_tests/google_test/gtest/CONTRIBUTORS
create mode 100644 nss/external_tests/google_test/gtest/LICENSE
create mode 100644 nss/external_tests/google_test/gtest/Makefile.am
create mode 100644 nss/external_tests/google_test/gtest/README
create mode 100644 nss/external_tests/google_test/gtest/build-aux/.keep
create mode 100644 nss/external_tests/google_test/gtest/cmake/internal_utils.cmake
create mode 100644 nss/external_tests/google_test/gtest/codegear/gtest.cbproj
create mode 100644 nss/external_tests/google_test/gtest/codegear/gtest.groupproj
create mode 100644 nss/external_tests/google_test/gtest/codegear/gtest_all.cc
create mode 100644 nss/external_tests/google_test/gtest/codegear/gtest_link.cc
create mode 100644 nss/external_tests/google_test/gtest/codegear/gtest_main.cbproj
create mode 100644 nss/external_tests/google_test/gtest/codegear/gtest_unittest.cbproj
create mode 100644 nss/external_tests/google_test/gtest/configure.ac
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/gtest-death-test.h
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/gtest-message.h
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/gtest-param-test.h
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/gtest-param-test.h.pump
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/gtest-printers.h
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/gtest-spi.h
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/gtest-test-part.h
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/gtest-typed-test.h
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/gtest.h
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/gtest_pred_impl.h
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/gtest_prod.h
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/internal/gtest-death-test-internal.h
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/internal/gtest-filepath.h
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/internal/gtest-internal.h
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/internal/gtest-linked_ptr.h
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/internal/gtest-param-util-generated.h
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/internal/gtest-param-util-generated.h.pump
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/internal/gtest-param-util.h
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/internal/gtest-port.h
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/internal/gtest-string.h
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/internal/gtest-tuple.h
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/internal/gtest-tuple.h.pump
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/internal/gtest-type-util.h
create mode 100644 nss/external_tests/google_test/gtest/include/gtest/internal/gtest-type-util.h.pump
create mode 100644 nss/external_tests/google_test/gtest/m4/acx_pthread.m4
create mode 100644 nss/external_tests/google_test/gtest/m4/gtest.m4
create mode 100644 nss/external_tests/google_test/gtest/make/Makefile
create mode 100644 nss/external_tests/google_test/gtest/msvc/gtest-md.sln
create mode 100644 nss/external_tests/google_test/gtest/msvc/gtest-md.vcproj
create mode 100644 nss/external_tests/google_test/gtest/msvc/gtest.sln
create mode 100644 nss/external_tests/google_test/gtest/msvc/gtest.vcproj
create mode 100644 nss/external_tests/google_test/gtest/msvc/gtest_main-md.vcproj
create mode 100644 nss/external_tests/google_test/gtest/msvc/gtest_main.vcproj
create mode 100644 nss/external_tests/google_test/gtest/msvc/gtest_prod_test-md.vcproj
create mode 100644 nss/external_tests/google_test/gtest/msvc/gtest_prod_test.vcproj
create mode 100644 nss/external_tests/google_test/gtest/msvc/gtest_unittest-md.vcproj
create mode 100644 nss/external_tests/google_test/gtest/msvc/gtest_unittest.vcproj
create mode 100644 nss/external_tests/google_test/gtest/samples/prime_tables.h
create mode 100644 nss/external_tests/google_test/gtest/samples/sample1.cc
create mode 100644 nss/external_tests/google_test/gtest/samples/sample1.h
create mode 100644 nss/external_tests/google_test/gtest/samples/sample10_unittest.cc
create mode 100644 nss/external_tests/google_test/gtest/samples/sample1_unittest.cc
create mode 100644 nss/external_tests/google_test/gtest/samples/sample2.cc
create mode 100644 nss/external_tests/google_test/gtest/samples/sample2.h
create mode 100644 nss/external_tests/google_test/gtest/samples/sample2_unittest.cc
create mode 100644 nss/external_tests/google_test/gtest/samples/sample3-inl.h
create mode 100644 nss/external_tests/google_test/gtest/samples/sample3_unittest.cc
create mode 100644 nss/external_tests/google_test/gtest/samples/sample4.cc
create mode 100644 nss/external_tests/google_test/gtest/samples/sample4.h
create mode 100644 nss/external_tests/google_test/gtest/samples/sample4_unittest.cc
create mode 100644 nss/external_tests/google_test/gtest/samples/sample5_unittest.cc
create mode 100644 nss/external_tests/google_test/gtest/samples/sample6_unittest.cc
create mode 100644 nss/external_tests/google_test/gtest/samples/sample7_unittest.cc
create mode 100644 nss/external_tests/google_test/gtest/samples/sample8_unittest.cc
create mode 100644 nss/external_tests/google_test/gtest/samples/sample9_unittest.cc
create mode 100644 nss/external_tests/google_test/gtest/scripts/common.py
create mode 100755 nss/external_tests/google_test/gtest/scripts/fuse_gtest_files.py
create mode 100755 nss/external_tests/google_test/gtest/scripts/gen_gtest_pred_impl.py
create mode 100755 nss/external_tests/google_test/gtest/scripts/gtest-config.in
create mode 100755 nss/external_tests/google_test/gtest/scripts/pump.py
create mode 100755 nss/external_tests/google_test/gtest/scripts/release_docs.py
create mode 100644 nss/external_tests/google_test/gtest/scripts/test/Makefile
create mode 100755 nss/external_tests/google_test/gtest/scripts/upload.py
create mode 100755 nss/external_tests/google_test/gtest/scripts/upload_gtest.py
create mode 100644 nss/external_tests/google_test/gtest/src/gtest-all.cc
create mode 100644 nss/external_tests/google_test/gtest/src/gtest-death-test.cc
create mode 100644 nss/external_tests/google_test/gtest/src/gtest-filepath.cc
create mode 100644 nss/external_tests/google_test/gtest/src/gtest-internal-inl.h
create mode 100644 nss/external_tests/google_test/gtest/src/gtest-port.cc
create mode 100644 nss/external_tests/google_test/gtest/src/gtest-printers.cc
create mode 100644 nss/external_tests/google_test/gtest/src/gtest-test-part.cc
create mode 100644 nss/external_tests/google_test/gtest/src/gtest-typed-test.cc
create mode 100644 nss/external_tests/google_test/gtest/src/gtest.cc
create mode 100644 nss/external_tests/google_test/gtest/src/gtest_main.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest-death-test_ex_test.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest-death-test_test.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest-filepath_test.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest-linked_ptr_test.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest-listener_test.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest-message_test.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest-options_test.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest-param-test2_test.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest-param-test_test.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest-param-test_test.h
create mode 100644 nss/external_tests/google_test/gtest/test/gtest-port_test.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest-printers_test.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest-test-part_test.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest-tuple_test.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest-typed-test2_test.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest-typed-test_test.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest-typed-test_test.h
create mode 100644 nss/external_tests/google_test/gtest/test/gtest-unittest-api_test.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_all_test.cc
create mode 100755 nss/external_tests/google_test/gtest/test/gtest_break_on_failure_unittest.py
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_break_on_failure_unittest_.cc
create mode 100755 nss/external_tests/google_test/gtest/test/gtest_catch_exceptions_test.py
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_catch_exceptions_test_.cc
create mode 100755 nss/external_tests/google_test/gtest/test/gtest_color_test.py
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_color_test_.cc
create mode 100755 nss/external_tests/google_test/gtest/test/gtest_env_var_test.py
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_env_var_test_.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_environment_test.cc
create mode 100755 nss/external_tests/google_test/gtest/test/gtest_filter_unittest.py
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_filter_unittest_.cc
create mode 100755 nss/external_tests/google_test/gtest/test/gtest_help_test.py
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_help_test_.cc
create mode 100755 nss/external_tests/google_test/gtest/test/gtest_list_tests_unittest.py
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_list_tests_unittest_.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_main_unittest.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_no_test_unittest.cc
create mode 100755 nss/external_tests/google_test/gtest/test/gtest_output_test.py
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_output_test_.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_output_test_golden_lin.txt
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_pred_impl_unittest.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_premature_exit_test.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_prod_test.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_repeat_test.cc
create mode 100755 nss/external_tests/google_test/gtest/test/gtest_shuffle_test.py
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_shuffle_test_.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_sole_header_test.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_stress_test.cc
create mode 100755 nss/external_tests/google_test/gtest/test/gtest_test_utils.py
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_throw_on_failure_ex_test.cc
create mode 100755 nss/external_tests/google_test/gtest/test/gtest_throw_on_failure_test.py
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_throw_on_failure_test_.cc
create mode 100755 nss/external_tests/google_test/gtest/test/gtest_uninitialized_test.py
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_uninitialized_test_.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_unittest.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_xml_outfile1_test_.cc
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_xml_outfile2_test_.cc
create mode 100755 nss/external_tests/google_test/gtest/test/gtest_xml_outfiles_test.py
create mode 100755 nss/external_tests/google_test/gtest/test/gtest_xml_output_unittest.py
create mode 100644 nss/external_tests/google_test/gtest/test/gtest_xml_output_unittest_.cc
create mode 100755 nss/external_tests/google_test/gtest/test/gtest_xml_test_utils.py
create mode 100644 nss/external_tests/google_test/gtest/test/production.cc
create mode 100644 nss/external_tests/google_test/gtest/test/production.h
create mode 100644 nss/external_tests/google_test/gtest/xcode/Config/DebugProject.xcconfig
create mode 100644 nss/external_tests/google_test/gtest/xcode/Config/FrameworkTarget.xcconfig
create mode 100644 nss/external_tests/google_test/gtest/xcode/Config/General.xcconfig
create mode 100644 nss/external_tests/google_test/gtest/xcode/Config/ReleaseProject.xcconfig
create mode 100644 nss/external_tests/google_test/gtest/xcode/Config/StaticLibraryTarget.xcconfig
create mode 100644 nss/external_tests/google_test/gtest/xcode/Config/TestTarget.xcconfig
create mode 100644 nss/external_tests/google_test/gtest/xcode/Resources/Info.plist
create mode 100644 nss/external_tests/google_test/gtest/xcode/Samples/FrameworkSample/Info.plist
create mode 100644 nss/external_tests/google_test/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj
create mode 100644 nss/external_tests/google_test/gtest/xcode/Samples/FrameworkSample/runtests.sh
create mode 100644 nss/external_tests/google_test/gtest/xcode/Samples/FrameworkSample/widget.cc
create mode 100644 nss/external_tests/google_test/gtest/xcode/Samples/FrameworkSample/widget.h
create mode 100644 nss/external_tests/google_test/gtest/xcode/Samples/FrameworkSample/widget_test.cc
create mode 100644 nss/external_tests/google_test/gtest/xcode/Scripts/runtests.sh
create mode 100644 nss/external_tests/google_test/gtest/xcode/Scripts/versiongenerate.py
create mode 100644 nss/external_tests/google_test/gtest/xcode/gtest.xcodeproj/project.pbxproj
create mode 100644 nss/external_tests/google_test/manifest.mn
create mode 100644 nss/external_tests/manifest.mn
create mode 100644 nss/external_tests/nss_bogo_shim/Makefile
create mode 100644 nss/external_tests/nss_bogo_shim/config.cc
create mode 100644 nss/external_tests/nss_bogo_shim/config.h
create mode 100644 nss/external_tests/nss_bogo_shim/config.json
create mode 100644 nss/external_tests/nss_bogo_shim/manifest.mn
create mode 100644 nss/external_tests/nss_bogo_shim/nss_bogo_shim.cc
create mode 100644 nss/external_tests/nss_bogo_shim/nsskeys.cc
create mode 100644 nss/external_tests/nss_bogo_shim/nsskeys.h
create mode 100644 nss/external_tests/pk11_gtest/Makefile
create mode 100644 nss/external_tests/pk11_gtest/manifest.mn
create mode 100644 nss/external_tests/pk11_gtest/pk11_aeskeywrap_unittest.cc
create mode 100644 nss/external_tests/pk11_gtest/pk11_chacha20poly1305_unittest.cc
create mode 100644 nss/external_tests/pk11_gtest/pk11_pbkdf2_unittest.cc
create mode 100644 nss/external_tests/pk11_gtest/pk11_prf_unittest.cc
create mode 100644 nss/external_tests/pk11_gtest/pk11_rsapss_unittest.cc
create mode 100644 nss/external_tests/ssl_gtest/Makefile
create mode 100644 nss/external_tests/ssl_gtest/databuffer.h
create mode 100644 nss/external_tests/ssl_gtest/gtest_utils.h
create mode 100644 nss/external_tests/ssl_gtest/libssl_internals.c
create mode 100644 nss/external_tests/ssl_gtest/libssl_internals.h
create mode 100644 nss/external_tests/ssl_gtest/manifest.mn
create mode 100644 nss/external_tests/ssl_gtest/ssl_0rtt_unittest.cc
create mode 100644 nss/external_tests/ssl_gtest/ssl_agent_unittest.cc
create mode 100644 nss/external_tests/ssl_gtest/ssl_auth_unittest.cc
create mode 100644 nss/external_tests/ssl_gtest/ssl_cert_ext_unittest.cc
create mode 100644 nss/external_tests/ssl_gtest/ssl_ciphersuite_unittest.cc
create mode 100644 nss/external_tests/ssl_gtest/ssl_damage_unittest.cc
create mode 100644 nss/external_tests/ssl_gtest/ssl_dhe_unittest.cc
create mode 100644 nss/external_tests/ssl_gtest/ssl_drop_unittest.cc
create mode 100644 nss/external_tests/ssl_gtest/ssl_ecdh_unittest.cc
create mode 100644 nss/external_tests/ssl_gtest/ssl_ems_unittest.cc
create mode 100644 nss/external_tests/ssl_gtest/ssl_extension_unittest.cc
create mode 100644 nss/external_tests/ssl_gtest/ssl_gtest.cc
create mode 100644 nss/external_tests/ssl_gtest/ssl_hrr_unittest.cc
create mode 100644 nss/external_tests/ssl_gtest/ssl_loopback_unittest.cc
create mode 100644 nss/external_tests/ssl_gtest/ssl_record_unittest.cc
create mode 100644 nss/external_tests/ssl_gtest/ssl_resumption_unittest.cc
create mode 100644 nss/external_tests/ssl_gtest/ssl_skip_unittest.cc
create mode 100644 nss/external_tests/ssl_gtest/ssl_staticrsa_unittest.cc
create mode 100644 nss/external_tests/ssl_gtest/ssl_v2_client_hello_unittest.cc
create mode 100644 nss/external_tests/ssl_gtest/ssl_version_unittest.cc
create mode 100644 nss/external_tests/ssl_gtest/test_io.cc
create mode 100644 nss/external_tests/ssl_gtest/test_io.h
create mode 100644 nss/external_tests/ssl_gtest/tls_agent.cc
create mode 100644 nss/external_tests/ssl_gtest/tls_agent.h
create mode 100644 nss/external_tests/ssl_gtest/tls_connect.cc
create mode 100644 nss/external_tests/ssl_gtest/tls_connect.h
create mode 100644 nss/external_tests/ssl_gtest/tls_filter.cc
create mode 100644 nss/external_tests/ssl_gtest/tls_filter.h
create mode 100644 nss/external_tests/ssl_gtest/tls_hkdf_unittest.cc
create mode 100644 nss/external_tests/ssl_gtest/tls_parser.cc
create mode 100644 nss/external_tests/ssl_gtest/tls_parser.h
create mode 100644 nss/external_tests/util_gtest/Makefile
create mode 100644 nss/external_tests/util_gtest/manifest.mn
create mode 100644 nss/external_tests/util_gtest/util_utf8_unittest.cc
create mode 100644 nss/fuzz/.clang-format
create mode 100644 nss/fuzz/asn1_mutators.cc
create mode 100644 nss/fuzz/asn1_mutators.h
create mode 100644 nss/fuzz/certDN.options
create mode 100644 nss/fuzz/certDN_target.cc
create mode 100755 nss/fuzz/clone_corpus.sh
create mode 100755 nss/fuzz/clone_libfuzzer.sh
create mode 100644 nss/fuzz/fuzz.gyp
create mode 100755 nss/fuzz/git-copy.sh
create mode 100644 nss/fuzz/mpi-add.options
create mode 100644 nss/fuzz/mpi-addmod.options
create mode 100644 nss/fuzz/mpi-div.options
create mode 100644 nss/fuzz/mpi-expmod.options
create mode 100644 nss/fuzz/mpi-invmod.options
create mode 100644 nss/fuzz/mpi-mod.options
create mode 100644 nss/fuzz/mpi-mulmod.options
create mode 100644 nss/fuzz/mpi-sqr.options
create mode 100644 nss/fuzz/mpi-sqrmod.options
create mode 100644 nss/fuzz/mpi-sub.options
create mode 100644 nss/fuzz/mpi-submod.options
create mode 100644 nss/fuzz/mpi_add_target.cc
create mode 100644 nss/fuzz/mpi_addmod_target.cc
create mode 100644 nss/fuzz/mpi_div_target.cc
create mode 100644 nss/fuzz/mpi_expmod_target.cc
create mode 100644 nss/fuzz/mpi_helper.cc
create mode 100644 nss/fuzz/mpi_helper.h
create mode 100644 nss/fuzz/mpi_invmod_target.cc
create mode 100644 nss/fuzz/mpi_mod_target.cc
create mode 100644 nss/fuzz/mpi_mulmod_target.cc
create mode 100644 nss/fuzz/mpi_sqr_target.cc
create mode 100644 nss/fuzz/mpi_sqrmod_target.cc
create mode 100644 nss/fuzz/mpi_sub_target.cc
create mode 100644 nss/fuzz/mpi_submod_target.cc
create mode 100644 nss/fuzz/pkcs8_target.cc
create mode 100644 nss/fuzz/quickder.options
create mode 100644 nss/fuzz/quickder_target.cc
create mode 100644 nss/fuzz/shared.h
create mode 100644 nss/fuzz/tls-client-no_fuzzer_mode.options
create mode 100644 nss/fuzz/tls-client.options
create mode 100644 nss/fuzz/tls_client_config.cc
create mode 100644 nss/fuzz/tls_client_config.h
create mode 100644 nss/fuzz/tls_client_socket.cc
create mode 100644 nss/fuzz/tls_client_socket.h
create mode 100644 nss/fuzz/tls_client_target.cc
create mode 100644 nss/fuzz/warning.txt
create mode 100644 nss/gtests/.clang-format
create mode 100644 nss/gtests/Makefile
create mode 100644 nss/gtests/README
create mode 100644 nss/gtests/common/Makefile
create mode 100644 nss/gtests/common/gtest.gypi
create mode 100644 nss/gtests/common/gtest.mk
create mode 100644 nss/gtests/common/gtests.cc
create mode 100644 nss/gtests/common/manifest.mn
create mode 100644 nss/gtests/der_gtest/Makefile
create mode 100644 nss/gtests/der_gtest/der_getint_unittest.cc
create mode 100644 nss/gtests/der_gtest/der_gtest.gyp
create mode 100644 nss/gtests/der_gtest/der_private_key_import_unittest.cc
create mode 100644 nss/gtests/der_gtest/manifest.mn
create mode 100644 nss/gtests/freebl_gtest/freebl_gtest.gyp
create mode 100644 nss/gtests/freebl_gtest/kat/Hash_DRBG.rsp
create mode 100644 nss/gtests/freebl_gtest/kat/Hash_DRBG.txt
create mode 100644 nss/gtests/freebl_gtest/mpi_unittest.cc
create mode 100644 nss/gtests/freebl_gtest/prng_kat_unittest.cc
create mode 100644 nss/gtests/google_test/Makefile
create mode 100644 nss/gtests/google_test/google_test.gyp
create mode 100644 nss/gtests/google_test/gtest/CHANGES
create mode 100644 nss/gtests/google_test/gtest/CMakeLists.txt
create mode 100644 nss/gtests/google_test/gtest/CONTRIBUTORS
create mode 100644 nss/gtests/google_test/gtest/LICENSE
create mode 100644 nss/gtests/google_test/gtest/Makefile.am
create mode 100644 nss/gtests/google_test/gtest/README
create mode 100644 nss/gtests/google_test/gtest/build-aux/.keep
create mode 100644 nss/gtests/google_test/gtest/cmake/internal_utils.cmake
create mode 100644 nss/gtests/google_test/gtest/codegear/gtest.cbproj
create mode 100644 nss/gtests/google_test/gtest/codegear/gtest.groupproj
create mode 100644 nss/gtests/google_test/gtest/codegear/gtest_all.cc
create mode 100644 nss/gtests/google_test/gtest/codegear/gtest_link.cc
create mode 100644 nss/gtests/google_test/gtest/codegear/gtest_main.cbproj
create mode 100644 nss/gtests/google_test/gtest/codegear/gtest_unittest.cbproj
create mode 100644 nss/gtests/google_test/gtest/configure.ac
create mode 100644 nss/gtests/google_test/gtest/include/gtest/gtest-death-test.h
create mode 100644 nss/gtests/google_test/gtest/include/gtest/gtest-message.h
create mode 100644 nss/gtests/google_test/gtest/include/gtest/gtest-param-test.h
create mode 100644 nss/gtests/google_test/gtest/include/gtest/gtest-param-test.h.pump
create mode 100644 nss/gtests/google_test/gtest/include/gtest/gtest-printers.h
create mode 100644 nss/gtests/google_test/gtest/include/gtest/gtest-spi.h
create mode 100644 nss/gtests/google_test/gtest/include/gtest/gtest-test-part.h
create mode 100644 nss/gtests/google_test/gtest/include/gtest/gtest-typed-test.h
create mode 100644 nss/gtests/google_test/gtest/include/gtest/gtest.h
create mode 100644 nss/gtests/google_test/gtest/include/gtest/gtest_pred_impl.h
create mode 100644 nss/gtests/google_test/gtest/include/gtest/gtest_prod.h
create mode 100644 nss/gtests/google_test/gtest/include/gtest/internal/gtest-death-test-internal.h
create mode 100644 nss/gtests/google_test/gtest/include/gtest/internal/gtest-filepath.h
create mode 100644 nss/gtests/google_test/gtest/include/gtest/internal/gtest-internal.h
create mode 100644 nss/gtests/google_test/gtest/include/gtest/internal/gtest-linked_ptr.h
create mode 100644 nss/gtests/google_test/gtest/include/gtest/internal/gtest-param-util-generated.h
create mode 100644 nss/gtests/google_test/gtest/include/gtest/internal/gtest-param-util-generated.h.pump
create mode 100644 nss/gtests/google_test/gtest/include/gtest/internal/gtest-param-util.h
create mode 100644 nss/gtests/google_test/gtest/include/gtest/internal/gtest-port.h
create mode 100644 nss/gtests/google_test/gtest/include/gtest/internal/gtest-string.h
create mode 100644 nss/gtests/google_test/gtest/include/gtest/internal/gtest-tuple.h
create mode 100644 nss/gtests/google_test/gtest/include/gtest/internal/gtest-tuple.h.pump
create mode 100644 nss/gtests/google_test/gtest/include/gtest/internal/gtest-type-util.h
create mode 100644 nss/gtests/google_test/gtest/include/gtest/internal/gtest-type-util.h.pump
create mode 100644 nss/gtests/google_test/gtest/m4/acx_pthread.m4
create mode 100644 nss/gtests/google_test/gtest/m4/gtest.m4
create mode 100644 nss/gtests/google_test/gtest/make/Makefile
create mode 100644 nss/gtests/google_test/gtest/msvc/gtest-md.sln
create mode 100644 nss/gtests/google_test/gtest/msvc/gtest-md.vcproj
create mode 100644 nss/gtests/google_test/gtest/msvc/gtest.sln
create mode 100644 nss/gtests/google_test/gtest/msvc/gtest.vcproj
create mode 100644 nss/gtests/google_test/gtest/msvc/gtest_main-md.vcproj
create mode 100644 nss/gtests/google_test/gtest/msvc/gtest_main.vcproj
create mode 100644 nss/gtests/google_test/gtest/msvc/gtest_prod_test-md.vcproj
create mode 100644 nss/gtests/google_test/gtest/msvc/gtest_prod_test.vcproj
create mode 100644 nss/gtests/google_test/gtest/msvc/gtest_unittest-md.vcproj
create mode 100644 nss/gtests/google_test/gtest/msvc/gtest_unittest.vcproj
create mode 100644 nss/gtests/google_test/gtest/samples/prime_tables.h
create mode 100644 nss/gtests/google_test/gtest/samples/sample1.cc
create mode 100644 nss/gtests/google_test/gtest/samples/sample1.h
create mode 100644 nss/gtests/google_test/gtest/samples/sample10_unittest.cc
create mode 100644 nss/gtests/google_test/gtest/samples/sample1_unittest.cc
create mode 100644 nss/gtests/google_test/gtest/samples/sample2.cc
create mode 100644 nss/gtests/google_test/gtest/samples/sample2.h
create mode 100644 nss/gtests/google_test/gtest/samples/sample2_unittest.cc
create mode 100644 nss/gtests/google_test/gtest/samples/sample3-inl.h
create mode 100644 nss/gtests/google_test/gtest/samples/sample3_unittest.cc
create mode 100644 nss/gtests/google_test/gtest/samples/sample4.cc
create mode 100644 nss/gtests/google_test/gtest/samples/sample4.h
create mode 100644 nss/gtests/google_test/gtest/samples/sample4_unittest.cc
create mode 100644 nss/gtests/google_test/gtest/samples/sample5_unittest.cc
create mode 100644 nss/gtests/google_test/gtest/samples/sample6_unittest.cc
create mode 100644 nss/gtests/google_test/gtest/samples/sample7_unittest.cc
create mode 100644 nss/gtests/google_test/gtest/samples/sample8_unittest.cc
create mode 100644 nss/gtests/google_test/gtest/samples/sample9_unittest.cc
create mode 100644 nss/gtests/google_test/gtest/scripts/common.py
create mode 100755 nss/gtests/google_test/gtest/scripts/fuse_gtest_files.py
create mode 100755 nss/gtests/google_test/gtest/scripts/gen_gtest_pred_impl.py
create mode 100755 nss/gtests/google_test/gtest/scripts/gtest-config.in
create mode 100755 nss/gtests/google_test/gtest/scripts/pump.py
create mode 100755 nss/gtests/google_test/gtest/scripts/release_docs.py
create mode 100644 nss/gtests/google_test/gtest/scripts/test/Makefile
create mode 100755 nss/gtests/google_test/gtest/scripts/upload.py
create mode 100755 nss/gtests/google_test/gtest/scripts/upload_gtest.py
create mode 100644 nss/gtests/google_test/gtest/src/gtest-all.cc
create mode 100644 nss/gtests/google_test/gtest/src/gtest-death-test.cc
create mode 100644 nss/gtests/google_test/gtest/src/gtest-filepath.cc
create mode 100644 nss/gtests/google_test/gtest/src/gtest-internal-inl.h
create mode 100644 nss/gtests/google_test/gtest/src/gtest-port.cc
create mode 100644 nss/gtests/google_test/gtest/src/gtest-printers.cc
create mode 100644 nss/gtests/google_test/gtest/src/gtest-test-part.cc
create mode 100644 nss/gtests/google_test/gtest/src/gtest-typed-test.cc
create mode 100644 nss/gtests/google_test/gtest/src/gtest.cc
create mode 100644 nss/gtests/google_test/gtest/src/gtest_main.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest-death-test_ex_test.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest-death-test_test.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest-filepath_test.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest-linked_ptr_test.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest-listener_test.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest-message_test.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest-options_test.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest-param-test2_test.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest-param-test_test.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest-param-test_test.h
create mode 100644 nss/gtests/google_test/gtest/test/gtest-port_test.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest-printers_test.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest-test-part_test.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest-tuple_test.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest-typed-test2_test.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest-typed-test_test.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest-typed-test_test.h
create mode 100644 nss/gtests/google_test/gtest/test/gtest-unittest-api_test.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest_all_test.cc
create mode 100755 nss/gtests/google_test/gtest/test/gtest_break_on_failure_unittest.py
create mode 100644 nss/gtests/google_test/gtest/test/gtest_break_on_failure_unittest_.cc
create mode 100755 nss/gtests/google_test/gtest/test/gtest_catch_exceptions_test.py
create mode 100644 nss/gtests/google_test/gtest/test/gtest_catch_exceptions_test_.cc
create mode 100755 nss/gtests/google_test/gtest/test/gtest_color_test.py
create mode 100644 nss/gtests/google_test/gtest/test/gtest_color_test_.cc
create mode 100755 nss/gtests/google_test/gtest/test/gtest_env_var_test.py
create mode 100644 nss/gtests/google_test/gtest/test/gtest_env_var_test_.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest_environment_test.cc
create mode 100755 nss/gtests/google_test/gtest/test/gtest_filter_unittest.py
create mode 100644 nss/gtests/google_test/gtest/test/gtest_filter_unittest_.cc
create mode 100755 nss/gtests/google_test/gtest/test/gtest_help_test.py
create mode 100644 nss/gtests/google_test/gtest/test/gtest_help_test_.cc
create mode 100755 nss/gtests/google_test/gtest/test/gtest_list_tests_unittest.py
create mode 100644 nss/gtests/google_test/gtest/test/gtest_list_tests_unittest_.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest_main_unittest.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest_no_test_unittest.cc
create mode 100755 nss/gtests/google_test/gtest/test/gtest_output_test.py
create mode 100644 nss/gtests/google_test/gtest/test/gtest_output_test_.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest_output_test_golden_lin.txt
create mode 100644 nss/gtests/google_test/gtest/test/gtest_pred_impl_unittest.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest_premature_exit_test.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest_prod_test.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest_repeat_test.cc
create mode 100755 nss/gtests/google_test/gtest/test/gtest_shuffle_test.py
create mode 100644 nss/gtests/google_test/gtest/test/gtest_shuffle_test_.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest_sole_header_test.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest_stress_test.cc
create mode 100755 nss/gtests/google_test/gtest/test/gtest_test_utils.py
create mode 100644 nss/gtests/google_test/gtest/test/gtest_throw_on_failure_ex_test.cc
create mode 100755 nss/gtests/google_test/gtest/test/gtest_throw_on_failure_test.py
create mode 100644 nss/gtests/google_test/gtest/test/gtest_throw_on_failure_test_.cc
create mode 100755 nss/gtests/google_test/gtest/test/gtest_uninitialized_test.py
create mode 100644 nss/gtests/google_test/gtest/test/gtest_uninitialized_test_.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest_unittest.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest_xml_outfile1_test_.cc
create mode 100644 nss/gtests/google_test/gtest/test/gtest_xml_outfile2_test_.cc
create mode 100755 nss/gtests/google_test/gtest/test/gtest_xml_outfiles_test.py
create mode 100755 nss/gtests/google_test/gtest/test/gtest_xml_output_unittest.py
create mode 100644 nss/gtests/google_test/gtest/test/gtest_xml_output_unittest_.cc
create mode 100755 nss/gtests/google_test/gtest/test/gtest_xml_test_utils.py
create mode 100644 nss/gtests/google_test/gtest/test/production.cc
create mode 100644 nss/gtests/google_test/gtest/test/production.h
create mode 100644 nss/gtests/google_test/gtest/xcode/Config/DebugProject.xcconfig
create mode 100644 nss/gtests/google_test/gtest/xcode/Config/FrameworkTarget.xcconfig
create mode 100644 nss/gtests/google_test/gtest/xcode/Config/General.xcconfig
create mode 100644 nss/gtests/google_test/gtest/xcode/Config/ReleaseProject.xcconfig
create mode 100644 nss/gtests/google_test/gtest/xcode/Config/StaticLibraryTarget.xcconfig
create mode 100644 nss/gtests/google_test/gtest/xcode/Config/TestTarget.xcconfig
create mode 100644 nss/gtests/google_test/gtest/xcode/Resources/Info.plist
create mode 100644 nss/gtests/google_test/gtest/xcode/Samples/FrameworkSample/Info.plist
create mode 100644 nss/gtests/google_test/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj
create mode 100644 nss/gtests/google_test/gtest/xcode/Samples/FrameworkSample/runtests.sh
create mode 100644 nss/gtests/google_test/gtest/xcode/Samples/FrameworkSample/widget.cc
create mode 100644 nss/gtests/google_test/gtest/xcode/Samples/FrameworkSample/widget.h
create mode 100644 nss/gtests/google_test/gtest/xcode/Samples/FrameworkSample/widget_test.cc
create mode 100644 nss/gtests/google_test/gtest/xcode/Scripts/runtests.sh
create mode 100644 nss/gtests/google_test/gtest/xcode/Scripts/versiongenerate.py
create mode 100644 nss/gtests/google_test/gtest/xcode/gtest.xcodeproj/project.pbxproj
create mode 100644 nss/gtests/google_test/manifest.mn
create mode 100644 nss/gtests/manifest.mn
create mode 100644 nss/gtests/nss_bogo_shim/Makefile
create mode 100644 nss/gtests/nss_bogo_shim/config.cc
create mode 100644 nss/gtests/nss_bogo_shim/config.h
create mode 100644 nss/gtests/nss_bogo_shim/config.json
create mode 100644 nss/gtests/nss_bogo_shim/manifest.mn
create mode 100644 nss/gtests/nss_bogo_shim/nss_bogo_shim.cc
create mode 100644 nss/gtests/nss_bogo_shim/nss_bogo_shim.gyp
create mode 100644 nss/gtests/nss_bogo_shim/nsskeys.cc
create mode 100644 nss/gtests/nss_bogo_shim/nsskeys.h
create mode 100644 nss/gtests/pk11_gtest/Makefile
create mode 100644 nss/gtests/pk11_gtest/manifest.mn
create mode 100644 nss/gtests/pk11_gtest/pk11_aeskeywrap_unittest.cc
create mode 100644 nss/gtests/pk11_gtest/pk11_chacha20poly1305_unittest.cc
create mode 100644 nss/gtests/pk11_gtest/pk11_curve25519_unittest.cc
create mode 100644 nss/gtests/pk11_gtest/pk11_ecdsa_unittest.cc
create mode 100644 nss/gtests/pk11_gtest/pk11_ecdsa_vectors.h
create mode 100644 nss/gtests/pk11_gtest/pk11_export_unittest.cc
create mode 100644 nss/gtests/pk11_gtest/pk11_gtest.gyp
create mode 100644 nss/gtests/pk11_gtest/pk11_pbkdf2_unittest.cc
create mode 100644 nss/gtests/pk11_gtest/pk11_prf_unittest.cc
create mode 100644 nss/gtests/pk11_gtest/pk11_prng_unittest.cc
create mode 100644 nss/gtests/pk11_gtest/pk11_rsapss_unittest.cc
create mode 100644 nss/gtests/pk11_gtest/pk11_rsapss_vectors.h
create mode 100644 nss/gtests/pk11_gtest/pk11_signature_test.h
create mode 100644 nss/gtests/ssl_gtest/Makefile
create mode 100644 nss/gtests/ssl_gtest/databuffer.h
create mode 100644 nss/gtests/ssl_gtest/gtest_utils.h
create mode 100644 nss/gtests/ssl_gtest/libssl_internals.c
create mode 100644 nss/gtests/ssl_gtest/libssl_internals.h
create mode 100644 nss/gtests/ssl_gtest/manifest.mn
create mode 100644 nss/gtests/ssl_gtest/ssl_0rtt_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_agent_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_auth_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_cert_ext_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_ciphersuite_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_damage_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_dhe_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_drop_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_ecdh_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_ems_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_exporter_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_extension_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_fragment_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_fuzz_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_gather_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_gtest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_gtest.gyp
create mode 100644 nss/gtests/ssl_gtest/ssl_hrr_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_loopback_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_record_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_resumption_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_skip_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_staticrsa_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_v2_client_hello_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/ssl_version_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/test_io.cc
create mode 100644 nss/gtests/ssl_gtest/test_io.h
create mode 100644 nss/gtests/ssl_gtest/tls_agent.cc
create mode 100644 nss/gtests/ssl_gtest/tls_agent.h
create mode 100644 nss/gtests/ssl_gtest/tls_connect.cc
create mode 100644 nss/gtests/ssl_gtest/tls_connect.h
create mode 100644 nss/gtests/ssl_gtest/tls_filter.cc
create mode 100644 nss/gtests/ssl_gtest/tls_filter.h
create mode 100644 nss/gtests/ssl_gtest/tls_hkdf_unittest.cc
create mode 100644 nss/gtests/ssl_gtest/tls_parser.cc
create mode 100644 nss/gtests/ssl_gtest/tls_parser.h
create mode 100644 nss/gtests/ssl_gtest/tls_protect.cc
create mode 100644 nss/gtests/ssl_gtest/tls_protect.h
create mode 100644 nss/gtests/util_gtest/Makefile
create mode 100644 nss/gtests/util_gtest/manifest.mn
create mode 100644 nss/gtests/util_gtest/util_b64_unittest.cc
create mode 100644 nss/gtests/util_gtest/util_gtest.gyp
create mode 100644 nss/gtests/util_gtest/util_utf8_unittest.cc
create mode 100644 nss/lib/Makefile
create mode 100644 nss/lib/base/Makefile
create mode 100644 nss/lib/base/arena.c
create mode 100644 nss/lib/base/base.gyp
create mode 100644 nss/lib/base/base.h
create mode 100644 nss/lib/base/baset.h
create mode 100644 nss/lib/base/config.mk
create mode 100644 nss/lib/base/error.c
create mode 100644 nss/lib/base/errorval.c
create mode 100644 nss/lib/base/exports.gyp
create mode 100644 nss/lib/base/hash.c
create mode 100644 nss/lib/base/hashops.c
create mode 100644 nss/lib/base/item.c
create mode 100644 nss/lib/base/libc.c
create mode 100644 nss/lib/base/list.c
create mode 100644 nss/lib/base/manifest.mn
create mode 100644 nss/lib/base/nssbase.h
create mode 100644 nss/lib/base/nssbaset.h
create mode 100644 nss/lib/base/tracker.c
create mode 100644 nss/lib/base/utf8.c
create mode 100644 nss/lib/certdb/Makefile
create mode 100644 nss/lib/certdb/alg1485.c
create mode 100644 nss/lib/certdb/cert.h
create mode 100644 nss/lib/certdb/certdb.c
create mode 100644 nss/lib/certdb/certdb.gyp
create mode 100644 nss/lib/certdb/certdb.h
create mode 100644 nss/lib/certdb/certi.h
create mode 100644 nss/lib/certdb/certt.h
create mode 100644 nss/lib/certdb/certv3.c
create mode 100644 nss/lib/certdb/certxutl.c
create mode 100644 nss/lib/certdb/certxutl.h
create mode 100644 nss/lib/certdb/config.mk
create mode 100644 nss/lib/certdb/crl.c
create mode 100644 nss/lib/certdb/exports.gyp
create mode 100644 nss/lib/certdb/genname.c
create mode 100644 nss/lib/certdb/genname.h
create mode 100644 nss/lib/certdb/manifest.mn
create mode 100644 nss/lib/certdb/polcyxtn.c
create mode 100644 nss/lib/certdb/secname.c
create mode 100644 nss/lib/certdb/stanpcertdb.c
create mode 100644 nss/lib/certdb/xauthkid.c
create mode 100644 nss/lib/certdb/xbsconst.c
create mode 100644 nss/lib/certdb/xconst.c
create mode 100644 nss/lib/certdb/xconst.h
create mode 100644 nss/lib/certhigh/Makefile
create mode 100644 nss/lib/certhigh/certhigh.c
create mode 100644 nss/lib/certhigh/certhigh.gyp
create mode 100644 nss/lib/certhigh/certhtml.c
create mode 100644 nss/lib/certhigh/certreq.c
create mode 100644 nss/lib/certhigh/certvfy.c
create mode 100644 nss/lib/certhigh/certvfypkix.c
create mode 100644 nss/lib/certhigh/config.mk
create mode 100644 nss/lib/certhigh/crlv2.c
create mode 100644 nss/lib/certhigh/exports.gyp
create mode 100644 nss/lib/certhigh/manifest.mn
create mode 100644 nss/lib/certhigh/ocsp.c
create mode 100644 nss/lib/certhigh/ocsp.h
create mode 100644 nss/lib/certhigh/ocspi.h
create mode 100644 nss/lib/certhigh/ocspsig.c
create mode 100644 nss/lib/certhigh/ocspt.h
create mode 100644 nss/lib/certhigh/ocspti.h
create mode 100644 nss/lib/certhigh/xcrldist.c
create mode 100644 nss/lib/ckfw/Makefile
create mode 100644 nss/lib/ckfw/builtins/Makefile
create mode 100644 nss/lib/ckfw/builtins/README
create mode 100644 nss/lib/ckfw/builtins/anchor.c
create mode 100644 nss/lib/ckfw/builtins/bfind.c
create mode 100644 nss/lib/ckfw/builtins/binst.c
create mode 100644 nss/lib/ckfw/builtins/bobject.c
create mode 100644 nss/lib/ckfw/builtins/bsession.c
create mode 100644 nss/lib/ckfw/builtins/bslot.c
create mode 100644 nss/lib/ckfw/builtins/btoken.c
create mode 100644 nss/lib/ckfw/builtins/builtins.gyp
create mode 100644 nss/lib/ckfw/builtins/builtins.h
create mode 100644 nss/lib/ckfw/builtins/certdata.perl
create mode 100644 nss/lib/ckfw/builtins/certdata.txt
create mode 100644 nss/lib/ckfw/builtins/ckbiver.c
create mode 100644 nss/lib/ckfw/builtins/config.mk
create mode 100644 nss/lib/ckfw/builtins/constants.c
create mode 100644 nss/lib/ckfw/builtins/exports.gyp
create mode 100644 nss/lib/ckfw/builtins/manifest.mn
create mode 100644 nss/lib/ckfw/builtins/nssckbi.def
create mode 100644 nss/lib/ckfw/builtins/nssckbi.h
create mode 100644 nss/lib/ckfw/builtins/nssckbi.rc
create mode 100644 nss/lib/ckfw/capi/Makefile
create mode 100644 nss/lib/ckfw/capi/README
create mode 100644 nss/lib/ckfw/capi/anchor.c
create mode 100644 nss/lib/ckfw/capi/cfind.c
create mode 100644 nss/lib/ckfw/capi/cinst.c
create mode 100644 nss/lib/ckfw/capi/ckcapi.h
create mode 100644 nss/lib/ckfw/capi/ckcapiver.c
create mode 100644 nss/lib/ckfw/capi/cobject.c
create mode 100644 nss/lib/ckfw/capi/config.mk
create mode 100644 nss/lib/ckfw/capi/constants.c
create mode 100644 nss/lib/ckfw/capi/crsa.c
create mode 100644 nss/lib/ckfw/capi/csession.c
create mode 100644 nss/lib/ckfw/capi/cslot.c
create mode 100644 nss/lib/ckfw/capi/ctoken.c
create mode 100644 nss/lib/ckfw/capi/manifest.mn
create mode 100644 nss/lib/ckfw/capi/nsscapi.def
create mode 100644 nss/lib/ckfw/capi/nsscapi.h
create mode 100644 nss/lib/ckfw/capi/nsscapi.rc
create mode 100644 nss/lib/ckfw/capi/staticobj.c
create mode 100644 nss/lib/ckfw/ck.api
create mode 100644 nss/lib/ckfw/ck.h
create mode 100644 nss/lib/ckfw/ckapi.perl
create mode 100644 nss/lib/ckfw/ckfw.gyp
create mode 100644 nss/lib/ckfw/ckfw.h
create mode 100644 nss/lib/ckfw/ckfwm.h
create mode 100644 nss/lib/ckfw/ckfwtm.h
create mode 100644 nss/lib/ckfw/ckmd.h
create mode 100644 nss/lib/ckfw/ckt.h
create mode 100644 nss/lib/ckfw/config.mk
create mode 100644 nss/lib/ckfw/crypto.c
create mode 100644 nss/lib/ckfw/dbm/Makefile
create mode 100644 nss/lib/ckfw/dbm/anchor.c
create mode 100644 nss/lib/ckfw/dbm/ckdbm.h
create mode 100644 nss/lib/ckfw/dbm/config.mk
create mode 100644 nss/lib/ckfw/dbm/db.c
create mode 100644 nss/lib/ckfw/dbm/find.c
create mode 100644 nss/lib/ckfw/dbm/instance.c
create mode 100644 nss/lib/ckfw/dbm/manifest.mn
create mode 100644 nss/lib/ckfw/dbm/object.c
create mode 100644 nss/lib/ckfw/dbm/session.c
create mode 100644 nss/lib/ckfw/dbm/slot.c
create mode 100644 nss/lib/ckfw/dbm/token.c
create mode 100644 nss/lib/ckfw/exports.gyp
create mode 100644 nss/lib/ckfw/find.c
create mode 100644 nss/lib/ckfw/hash.c
create mode 100644 nss/lib/ckfw/instance.c
create mode 100644 nss/lib/ckfw/manifest.mn
create mode 100644 nss/lib/ckfw/mechanism.c
create mode 100644 nss/lib/ckfw/mutex.c
create mode 100644 nss/lib/ckfw/nssck.api
create mode 100644 nss/lib/ckfw/nssckepv.h
create mode 100644 nss/lib/ckfw/nssckft.h
create mode 100644 nss/lib/ckfw/nssckfw.h
create mode 100644 nss/lib/ckfw/nssckfwc.h
create mode 100644 nss/lib/ckfw/nssckfwt.h
create mode 100644 nss/lib/ckfw/nssckg.h
create mode 100644 nss/lib/ckfw/nssckmdt.h
create mode 100644 nss/lib/ckfw/nssckt.h
create mode 100644 nss/lib/ckfw/nssmkey/Makefile
create mode 100644 nss/lib/ckfw/nssmkey/README
create mode 100644 nss/lib/ckfw/nssmkey/ckmk.h
create mode 100644 nss/lib/ckfw/nssmkey/ckmkver.c
create mode 100644 nss/lib/ckfw/nssmkey/config.mk
create mode 100644 nss/lib/ckfw/nssmkey/manchor.c
create mode 100644 nss/lib/ckfw/nssmkey/manifest.mn
create mode 100644 nss/lib/ckfw/nssmkey/mconstants.c
create mode 100644 nss/lib/ckfw/nssmkey/mfind.c
create mode 100644 nss/lib/ckfw/nssmkey/minst.c
create mode 100644 nss/lib/ckfw/nssmkey/mobject.c
create mode 100644 nss/lib/ckfw/nssmkey/mrsa.c
create mode 100644 nss/lib/ckfw/nssmkey/msession.c
create mode 100644 nss/lib/ckfw/nssmkey/mslot.c
create mode 100644 nss/lib/ckfw/nssmkey/mtoken.c
create mode 100644 nss/lib/ckfw/nssmkey/nssmkey.def
create mode 100644 nss/lib/ckfw/nssmkey/nssmkey.h
create mode 100644 nss/lib/ckfw/nssmkey/staticobj.c
create mode 100644 nss/lib/ckfw/object.c
create mode 100644 nss/lib/ckfw/session.c
create mode 100644 nss/lib/ckfw/sessobj.c
create mode 100644 nss/lib/ckfw/slot.c
create mode 100644 nss/lib/ckfw/token.c
create mode 100644 nss/lib/ckfw/wrap.c
create mode 100644 nss/lib/crmf/Makefile
create mode 100644 nss/lib/crmf/asn1cmn.c
create mode 100644 nss/lib/crmf/challcli.c
create mode 100644 nss/lib/crmf/cmmf.h
create mode 100644 nss/lib/crmf/cmmfasn1.c
create mode 100644 nss/lib/crmf/cmmfchal.c
create mode 100644 nss/lib/crmf/cmmfi.h
create mode 100644 nss/lib/crmf/cmmfit.h
create mode 100644 nss/lib/crmf/cmmfrec.c
create mode 100644 nss/lib/crmf/cmmfresp.c
create mode 100644 nss/lib/crmf/cmmft.h
create mode 100644 nss/lib/crmf/config.mk
create mode 100644 nss/lib/crmf/crmf.gyp
create mode 100644 nss/lib/crmf/crmf.h
create mode 100644 nss/lib/crmf/crmfcont.c
create mode 100644 nss/lib/crmf/crmfdec.c
create mode 100644 nss/lib/crmf/crmfenc.c
create mode 100644 nss/lib/crmf/crmffut.h
create mode 100644 nss/lib/crmf/crmfget.c
create mode 100644 nss/lib/crmf/crmfi.h
create mode 100644 nss/lib/crmf/crmfit.h
create mode 100644 nss/lib/crmf/crmfpop.c
create mode 100644 nss/lib/crmf/crmfreq.c
create mode 100644 nss/lib/crmf/crmft.h
create mode 100644 nss/lib/crmf/crmftmpl.c
create mode 100644 nss/lib/crmf/encutil.c
create mode 100644 nss/lib/crmf/exports.gyp
create mode 100644 nss/lib/crmf/manifest.mn
create mode 100644 nss/lib/crmf/respcli.c
create mode 100644 nss/lib/crmf/respcmn.c
create mode 100644 nss/lib/crmf/servget.c
create mode 100644 nss/lib/cryptohi/Makefile
create mode 100644 nss/lib/cryptohi/config.mk
create mode 100644 nss/lib/cryptohi/cryptohi.gyp
create mode 100644 nss/lib/cryptohi/cryptohi.h
create mode 100644 nss/lib/cryptohi/cryptoht.h
create mode 100644 nss/lib/cryptohi/dsautil.c
create mode 100644 nss/lib/cryptohi/exports.gyp
create mode 100644 nss/lib/cryptohi/key.h
create mode 100644 nss/lib/cryptohi/keyhi.h
create mode 100644 nss/lib/cryptohi/keyi.h
create mode 100644 nss/lib/cryptohi/keyt.h
create mode 100644 nss/lib/cryptohi/keythi.h
create mode 100644 nss/lib/cryptohi/manifest.mn
create mode 100644 nss/lib/cryptohi/sechash.c
create mode 100644 nss/lib/cryptohi/sechash.h
create mode 100644 nss/lib/cryptohi/seckey.c
create mode 100644 nss/lib/cryptohi/secsign.c
create mode 100644 nss/lib/cryptohi/secvfy.c
create mode 100644 nss/lib/dbm/Makefile
create mode 100644 nss/lib/dbm/config/config.mk
create mode 100644 nss/lib/dbm/include/Makefile
create mode 100644 nss/lib/dbm/include/exports.gyp
create mode 100644 nss/lib/dbm/include/extern.h
create mode 100644 nss/lib/dbm/include/hash.h
create mode 100644 nss/lib/dbm/include/hsearch.h
create mode 100644 nss/lib/dbm/include/include.gyp
create mode 100644 nss/lib/dbm/include/manifest.mn
create mode 100644 nss/lib/dbm/include/mcom_db.h
create mode 100644 nss/lib/dbm/include/ncompat.h
create mode 100644 nss/lib/dbm/include/page.h
create mode 100644 nss/lib/dbm/include/queue.h
create mode 100644 nss/lib/dbm/include/search.h
create mode 100644 nss/lib/dbm/include/winfile.h
create mode 100644 nss/lib/dbm/manifest.mn
create mode 100644 nss/lib/dbm/src/Makefile
create mode 100644 nss/lib/dbm/src/config.mk
create mode 100644 nss/lib/dbm/src/db.c
create mode 100644 nss/lib/dbm/src/dirent.c
create mode 100644 nss/lib/dbm/src/dirent.h
create mode 100644 nss/lib/dbm/src/h_bigkey.c
create mode 100644 nss/lib/dbm/src/h_func.c
create mode 100644 nss/lib/dbm/src/h_log2.c
create mode 100644 nss/lib/dbm/src/h_page.c
create mode 100644 nss/lib/dbm/src/hash.c
create mode 100644 nss/lib/dbm/src/hash_buf.c
create mode 100644 nss/lib/dbm/src/manifest.mn
create mode 100644 nss/lib/dbm/src/memmove.c
create mode 100644 nss/lib/dbm/src/mktemp.c
create mode 100644 nss/lib/dbm/src/snprintf.c
create mode 100644 nss/lib/dbm/src/src.gyp
create mode 100644 nss/lib/dbm/src/strerror.c
create mode 100644 nss/lib/dbm/tests/Makefile
create mode 100644 nss/lib/dbm/tests/dbmtest.pkg
create mode 100644 nss/lib/dbm/tests/lots.c
create mode 100644 nss/lib/dev/Makefile
create mode 100644 nss/lib/dev/ckhelper.c
create mode 100644 nss/lib/dev/ckhelper.h
create mode 100644 nss/lib/dev/config.mk
create mode 100644 nss/lib/dev/dev.gyp
create mode 100644 nss/lib/dev/dev.h
create mode 100644 nss/lib/dev/devm.h
create mode 100644 nss/lib/dev/devslot.c
create mode 100644 nss/lib/dev/devt.h
create mode 100644 nss/lib/dev/devtm.h
create mode 100644 nss/lib/dev/devtoken.c
create mode 100644 nss/lib/dev/devutil.c
create mode 100644 nss/lib/dev/exports.gyp
create mode 100644 nss/lib/dev/manifest.mn
create mode 100644 nss/lib/dev/nssdev.h
create mode 100644 nss/lib/dev/nssdevt.h
create mode 100644 nss/lib/freebl/Makefile
create mode 100644 nss/lib/freebl/aeskeywrap.c
create mode 100644 nss/lib/freebl/alg2268.c
create mode 100644 nss/lib/freebl/alghmac.c
create mode 100644 nss/lib/freebl/alghmac.h
create mode 100644 nss/lib/freebl/arcfive.c
create mode 100644 nss/lib/freebl/arcfour-amd64-gas.s
create mode 100644 nss/lib/freebl/arcfour-amd64-masm.asm
create mode 100644 nss/lib/freebl/arcfour-amd64-sun.s
create mode 100644 nss/lib/freebl/arcfour.c
create mode 100644 nss/lib/freebl/blapi.h
create mode 100644 nss/lib/freebl/blapii.h
create mode 100644 nss/lib/freebl/blapit.h
create mode 100644 nss/lib/freebl/blname.c
create mode 100644 nss/lib/freebl/camellia.c
create mode 100644 nss/lib/freebl/camellia.h
create mode 100644 nss/lib/freebl/chacha20.c
create mode 100644 nss/lib/freebl/chacha20.h
create mode 100644 nss/lib/freebl/chacha20_vec.c
create mode 100644 nss/lib/freebl/chacha20poly1305.c
create mode 100644 nss/lib/freebl/chacha20poly1305.h
create mode 100644 nss/lib/freebl/config.mk
create mode 100644 nss/lib/freebl/ctr.c
create mode 100644 nss/lib/freebl/ctr.h
create mode 100644 nss/lib/freebl/cts.c
create mode 100644 nss/lib/freebl/cts.h
create mode 100644 nss/lib/freebl/des.c
create mode 100644 nss/lib/freebl/des.h
create mode 100644 nss/lib/freebl/desblapi.c
create mode 100644 nss/lib/freebl/det_rng.c
create mode 100644 nss/lib/freebl/det_rng.h
create mode 100644 nss/lib/freebl/dh.c
create mode 100644 nss/lib/freebl/drbg.c
create mode 100644 nss/lib/freebl/dsa.c
create mode 100644 nss/lib/freebl/ec.c
create mode 100644 nss/lib/freebl/ec.h
create mode 100644 nss/lib/freebl/ecdecode.c
create mode 100644 nss/lib/freebl/ecl/README
create mode 100644 nss/lib/freebl/ecl/README.FP
create mode 100644 nss/lib/freebl/ecl/curve25519_32.c
create mode 100644 nss/lib/freebl/ecl/curve25519_64.c
create mode 100644 nss/lib/freebl/ecl/ec2.h
create mode 100644 nss/lib/freebl/ecl/ec2_163.c
create mode 100644 nss/lib/freebl/ecl/ec2_193.c
create mode 100644 nss/lib/freebl/ecl/ec2_233.c
create mode 100644 nss/lib/freebl/ecl/ec2_aff.c
create mode 100644 nss/lib/freebl/ecl/ec2_mont.c
create mode 100644 nss/lib/freebl/ecl/ec2_proj.c
create mode 100644 nss/lib/freebl/ecl/ec_naf.c
create mode 100644 nss/lib/freebl/ecl/ecl-curve.h
create mode 100644 nss/lib/freebl/ecl/ecl-exp.h
create mode 100644 nss/lib/freebl/ecl/ecl-priv.h
create mode 100644 nss/lib/freebl/ecl/ecl.c
create mode 100644 nss/lib/freebl/ecl/ecl.h
create mode 100644 nss/lib/freebl/ecl/ecl_curve.c
create mode 100644 nss/lib/freebl/ecl/ecl_gf.c
create mode 100644 nss/lib/freebl/ecl/ecl_mult.c
create mode 100644 nss/lib/freebl/ecl/ecp.h
create mode 100644 nss/lib/freebl/ecl/ecp_192.c
create mode 100644 nss/lib/freebl/ecl/ecp_224.c
create mode 100644 nss/lib/freebl/ecl/ecp_25519.c
create mode 100644 nss/lib/freebl/ecl/ecp_256.c
create mode 100644 nss/lib/freebl/ecl/ecp_256_32.c
create mode 100644 nss/lib/freebl/ecl/ecp_384.c
create mode 100644 nss/lib/freebl/ecl/ecp_521.c
create mode 100644 nss/lib/freebl/ecl/ecp_aff.c
create mode 100644 nss/lib/freebl/ecl/ecp_fp.c
create mode 100644 nss/lib/freebl/ecl/ecp_fp.h
create mode 100644 nss/lib/freebl/ecl/ecp_fp160.c
create mode 100644 nss/lib/freebl/ecl/ecp_fp192.c
create mode 100644 nss/lib/freebl/ecl/ecp_fp224.c
create mode 100644 nss/lib/freebl/ecl/ecp_fpinc.c
create mode 100644 nss/lib/freebl/ecl/ecp_jac.c
create mode 100644 nss/lib/freebl/ecl/ecp_jm.c
create mode 100644 nss/lib/freebl/ecl/ecp_mont.c
create mode 100644 nss/lib/freebl/ecl/tests/ec2_test.c
create mode 100644 nss/lib/freebl/ecl/tests/ec_naft.c
create mode 100644 nss/lib/freebl/ecl/tests/ecp_fpt.c
create mode 100644 nss/lib/freebl/ecl/tests/ecp_test.c
create mode 100644 nss/lib/freebl/ecl/uint128.c
create mode 100644 nss/lib/freebl/ecl/uint128.h
create mode 100644 nss/lib/freebl/exports.gyp
create mode 100644 nss/lib/freebl/fipsfreebl.c
create mode 100644 nss/lib/freebl/freebl.def
create mode 100644 nss/lib/freebl/freebl.gyp
create mode 100644 nss/lib/freebl/freebl.rc
create mode 100644 nss/lib/freebl/freebl_base.gypi
create mode 100644 nss/lib/freebl/freebl_hash.def
create mode 100644 nss/lib/freebl/freebl_hash_vector.def
create mode 100644 nss/lib/freebl/freeblver.c
create mode 100644 nss/lib/freebl/gcm.c
create mode 100644 nss/lib/freebl/gcm.h
create mode 100644 nss/lib/freebl/genload.c
create mode 100644 nss/lib/freebl/hmacct.c
create mode 100644 nss/lib/freebl/hmacct.h
create mode 100644 nss/lib/freebl/intel-aes-x64-masm.asm
create mode 100644 nss/lib/freebl/intel-aes-x86-masm.asm
create mode 100644 nss/lib/freebl/intel-aes.h
create mode 100644 nss/lib/freebl/intel-aes.s
create mode 100644 nss/lib/freebl/intel-gcm-wrap.c
create mode 100644 nss/lib/freebl/intel-gcm-x64-masm.asm
create mode 100644 nss/lib/freebl/intel-gcm-x86-masm.asm
create mode 100644 nss/lib/freebl/intel-gcm.h
create mode 100644 nss/lib/freebl/intel-gcm.s
create mode 100644 nss/lib/freebl/jpake.c
create mode 100644 nss/lib/freebl/ldvector.c
create mode 100644 nss/lib/freebl/loader.c
create mode 100644 nss/lib/freebl/loader.h
create mode 100644 nss/lib/freebl/lowhash_vector.c
create mode 100644 nss/lib/freebl/manifest.mn
create mode 100644 nss/lib/freebl/md2.c
create mode 100644 nss/lib/freebl/md5.c
create mode 100644 nss/lib/freebl/mknewpc2.c
create mode 100644 nss/lib/freebl/mksp.c
create mode 100644 nss/lib/freebl/mpi/Makefile
create mode 100644 nss/lib/freebl/mpi/Makefile.os2
create mode 100644 nss/lib/freebl/mpi/Makefile.win
create mode 100644 nss/lib/freebl/mpi/README
create mode 100755 nss/lib/freebl/mpi/all-tests
create mode 100644 nss/lib/freebl/mpi/doc/LICENSE
create mode 100644 nss/lib/freebl/mpi/doc/LICENSE-MPL
create mode 100644 nss/lib/freebl/mpi/doc/basecvt.pod
create mode 100755 nss/lib/freebl/mpi/doc/build
create mode 100644 nss/lib/freebl/mpi/doc/div.txt
create mode 100644 nss/lib/freebl/mpi/doc/expt.txt
create mode 100644 nss/lib/freebl/mpi/doc/gcd.pod
create mode 100644 nss/lib/freebl/mpi/doc/invmod.pod
create mode 100644 nss/lib/freebl/mpi/doc/isprime.pod
create mode 100644 nss/lib/freebl/mpi/doc/lap.pod
create mode 100644 nss/lib/freebl/mpi/doc/mpi-test.pod
create mode 100644 nss/lib/freebl/mpi/doc/mul.txt
create mode 100644 nss/lib/freebl/mpi/doc/pi.txt
create mode 100644 nss/lib/freebl/mpi/doc/prime.txt
create mode 100644 nss/lib/freebl/mpi/doc/prng.pod
create mode 100644 nss/lib/freebl/mpi/doc/redux.txt
create mode 100644 nss/lib/freebl/mpi/doc/sqrt.txt
create mode 100644 nss/lib/freebl/mpi/doc/square.txt
create mode 100644 nss/lib/freebl/mpi/doc/timing.txt
create mode 100644 nss/lib/freebl/mpi/hpma512.s
create mode 100644 nss/lib/freebl/mpi/hppa20.s
create mode 100644 nss/lib/freebl/mpi/hppatch.adb
create mode 100644 nss/lib/freebl/mpi/logtab.h
create mode 100755 nss/lib/freebl/mpi/make-logtab
create mode 100755 nss/lib/freebl/mpi/make-test-arrays
create mode 100644 nss/lib/freebl/mpi/mdxptest.c
create mode 100644 nss/lib/freebl/mpi/montmulf.c
create mode 100644 nss/lib/freebl/mpi/montmulf.h
create mode 100644 nss/lib/freebl/mpi/montmulf.il
create mode 100644 nss/lib/freebl/mpi/montmulf.s
create mode 100644 nss/lib/freebl/mpi/montmulfv8.il
create mode 100644 nss/lib/freebl/mpi/montmulfv8.s
create mode 100644 nss/lib/freebl/mpi/montmulfv9.il
create mode 100644 nss/lib/freebl/mpi/montmulfv9.s
create mode 100644 nss/lib/freebl/mpi/mp_comba.c
create mode 100644 nss/lib/freebl/mpi/mp_comba_amd64_masm.asm
create mode 100644 nss/lib/freebl/mpi/mp_comba_amd64_sun.s
create mode 100644 nss/lib/freebl/mpi/mp_gf2m-priv.h
create mode 100644 nss/lib/freebl/mpi/mp_gf2m.c
create mode 100644 nss/lib/freebl/mpi/mp_gf2m.h
create mode 100644 nss/lib/freebl/mpi/mpcpucache.c
create mode 100644 nss/lib/freebl/mpi/mpcpucache_amd64.s
create mode 100644 nss/lib/freebl/mpi/mpcpucache_x86.s
create mode 100644 nss/lib/freebl/mpi/mpi-config.h
create mode 100644 nss/lib/freebl/mpi/mpi-priv.h
create mode 100644 nss/lib/freebl/mpi/mpi-test.c
create mode 100644 nss/lib/freebl/mpi/mpi.c
create mode 100644 nss/lib/freebl/mpi/mpi.h
create mode 100644 nss/lib/freebl/mpi/mpi_amd64.c
create mode 100644 nss/lib/freebl/mpi/mpi_amd64_gas.s
create mode 100644 nss/lib/freebl/mpi/mpi_amd64_masm.asm
create mode 100644 nss/lib/freebl/mpi/mpi_amd64_sun.s
create mode 100644 nss/lib/freebl/mpi/mpi_arm.c
create mode 100644 nss/lib/freebl/mpi/mpi_hp.c
create mode 100644 nss/lib/freebl/mpi/mpi_i86pc.s
create mode 100644 nss/lib/freebl/mpi/mpi_mips.s
create mode 100644 nss/lib/freebl/mpi/mpi_sparc.c
create mode 100644 nss/lib/freebl/mpi/mpi_sse2.s
create mode 100644 nss/lib/freebl/mpi/mpi_x86.s
create mode 100644 nss/lib/freebl/mpi/mpi_x86_asm.c
create mode 100644 nss/lib/freebl/mpi/mpi_x86_os2.s
create mode 100644 nss/lib/freebl/mpi/mplogic.c
create mode 100644 nss/lib/freebl/mpi/mplogic.h
create mode 100644 nss/lib/freebl/mpi/mpmontg.c
create mode 100644 nss/lib/freebl/mpi/mpprime.c
create mode 100644 nss/lib/freebl/mpi/mpprime.h
create mode 100644 nss/lib/freebl/mpi/mpv_sparc.c
create mode 100644 nss/lib/freebl/mpi/mpv_sparcv8.s
create mode 100644 nss/lib/freebl/mpi/mpv_sparcv9.s
create mode 100644 nss/lib/freebl/mpi/mpvalpha.c
create mode 100644 nss/lib/freebl/mpi/mulsqr.c
create mode 100755 nss/lib/freebl/mpi/multest
create mode 100644 nss/lib/freebl/mpi/primes.c
create mode 100755 nss/lib/freebl/mpi/stats
create mode 100644 nss/lib/freebl/mpi/target.mk
create mode 100644 nss/lib/freebl/mpi/test-arrays.txt
create mode 100644 nss/lib/freebl/mpi/test-info.c
create mode 100644 nss/lib/freebl/mpi/tests/LICENSE
create mode 100644 nss/lib/freebl/mpi/tests/LICENSE-MPL
create mode 100644 nss/lib/freebl/mpi/tests/mptest-1.c
create mode 100644 nss/lib/freebl/mpi/tests/mptest-2.c
create mode 100644 nss/lib/freebl/mpi/tests/mptest-3.c
create mode 100644 nss/lib/freebl/mpi/tests/mptest-3a.c
create mode 100644 nss/lib/freebl/mpi/tests/mptest-4.c
create mode 100644 nss/lib/freebl/mpi/tests/mptest-4a.c
create mode 100644 nss/lib/freebl/mpi/tests/mptest-4b.c
create mode 100644 nss/lib/freebl/mpi/tests/mptest-5.c
create mode 100644 nss/lib/freebl/mpi/tests/mptest-5a.c
create mode 100644 nss/lib/freebl/mpi/tests/mptest-6.c
create mode 100644 nss/lib/freebl/mpi/tests/mptest-7.c
create mode 100644 nss/lib/freebl/mpi/tests/mptest-8.c
create mode 100644 nss/lib/freebl/mpi/tests/mptest-9.c
create mode 100644 nss/lib/freebl/mpi/tests/mptest-b.c
create mode 100644 nss/lib/freebl/mpi/tests/pi1k.txt
create mode 100644 nss/lib/freebl/mpi/tests/pi2k.txt
create mode 100644 nss/lib/freebl/mpi/tests/pi5k.txt
create mode 100755 nss/lib/freebl/mpi/timetest
create mode 100755 nss/lib/freebl/mpi/types.pl
create mode 100644 nss/lib/freebl/mpi/utils/LICENSE
create mode 100644 nss/lib/freebl/mpi/utils/LICENSE-MPL
create mode 100644 nss/lib/freebl/mpi/utils/PRIMES
create mode 100644 nss/lib/freebl/mpi/utils/README
create mode 100644 nss/lib/freebl/mpi/utils/basecvt.c
create mode 100644 nss/lib/freebl/mpi/utils/bbs_rand.c
create mode 100644 nss/lib/freebl/mpi/utils/bbs_rand.h
create mode 100644 nss/lib/freebl/mpi/utils/bbsrand.c
create mode 100644 nss/lib/freebl/mpi/utils/dec2hex.c
create mode 100644 nss/lib/freebl/mpi/utils/exptmod.c
create mode 100644 nss/lib/freebl/mpi/utils/fact.c
create mode 100644 nss/lib/freebl/mpi/utils/gcd.c
create mode 100644 nss/lib/freebl/mpi/utils/hex2dec.c
create mode 100644 nss/lib/freebl/mpi/utils/identest.c
create mode 100644 nss/lib/freebl/mpi/utils/invmod.c
create mode 100644 nss/lib/freebl/mpi/utils/isprime.c
create mode 100644 nss/lib/freebl/mpi/utils/lap.c
create mode 100644 nss/lib/freebl/mpi/utils/makeprime.c
create mode 100644 nss/lib/freebl/mpi/utils/metime.c
create mode 100644 nss/lib/freebl/mpi/utils/pi.c
create mode 100644 nss/lib/freebl/mpi/utils/primegen.c
create mode 100644 nss/lib/freebl/mpi/utils/prng.c
create mode 100755 nss/lib/freebl/mpi/utils/ptab.pl
create mode 100644 nss/lib/freebl/mpi/utils/sieve.c
create mode 100644 nss/lib/freebl/mpi/vis_32.il
create mode 100644 nss/lib/freebl/mpi/vis_64.il
create mode 100644 nss/lib/freebl/mpi/vis_proto.h
create mode 100644 nss/lib/freebl/nsslowhash.c
create mode 100644 nss/lib/freebl/nsslowhash.h
create mode 100644 nss/lib/freebl/os2_rand.c
create mode 100644 nss/lib/freebl/poly1305-donna-x64-sse2-incremental-source.c
create mode 100644 nss/lib/freebl/poly1305.c
create mode 100644 nss/lib/freebl/poly1305.h
create mode 100644 nss/lib/freebl/pqg.c
create mode 100644 nss/lib/freebl/pqg.h
create mode 100644 nss/lib/freebl/rawhash.c
create mode 100644 nss/lib/freebl/ret_cr16.s
create mode 100644 nss/lib/freebl/rijndael.c
create mode 100644 nss/lib/freebl/rijndael.h
create mode 100644 nss/lib/freebl/rijndael32.tab
create mode 100644 nss/lib/freebl/rijndael_tables.c
create mode 100644 nss/lib/freebl/rsa.c
create mode 100644 nss/lib/freebl/rsapkcs.c
create mode 100644 nss/lib/freebl/secmpi.h
create mode 100644 nss/lib/freebl/secrng.h
create mode 100644 nss/lib/freebl/seed.c
create mode 100644 nss/lib/freebl/seed.h
create mode 100644 nss/lib/freebl/sha-fast-amd64-sun.s
create mode 100644 nss/lib/freebl/sha256.h
create mode 100644 nss/lib/freebl/sha512.c
create mode 100644 nss/lib/freebl/sha_fast.c
create mode 100644 nss/lib/freebl/sha_fast.h
create mode 100644 nss/lib/freebl/shsign.h
create mode 100644 nss/lib/freebl/shvfy.c
create mode 100644 nss/lib/freebl/stubs.c
create mode 100644 nss/lib/freebl/stubs.h
create mode 100644 nss/lib/freebl/sysrand.c
create mode 100644 nss/lib/freebl/tlsprfalg.c
create mode 100644 nss/lib/freebl/unix_rand.c
create mode 100644 nss/lib/freebl/win_rand.c
create mode 100644 nss/lib/jar/Makefile
create mode 100644 nss/lib/jar/config.mk
create mode 100644 nss/lib/jar/exports.gyp
create mode 100644 nss/lib/jar/jar-ds.c
create mode 100644 nss/lib/jar/jar-ds.h
create mode 100644 nss/lib/jar/jar.c
create mode 100644 nss/lib/jar/jar.gyp
create mode 100644 nss/lib/jar/jar.h
create mode 100644 nss/lib/jar/jarfile.c
create mode 100644 nss/lib/jar/jarfile.h
create mode 100644 nss/lib/jar/jarint.c
create mode 100644 nss/lib/jar/jarint.h
create mode 100644 nss/lib/jar/jarnav.c
create mode 100644 nss/lib/jar/jarsign.c
create mode 100644 nss/lib/jar/jarver.c
create mode 100644 nss/lib/jar/jzconf.h
create mode 100644 nss/lib/jar/jzlib.h
create mode 100644 nss/lib/jar/manifest.mn
create mode 100755 nss/lib/libpkix/Makefile
create mode 100755 nss/lib/libpkix/config.mk
create mode 100755 nss/lib/libpkix/include/Makefile
create mode 100755 nss/lib/libpkix/include/config.mk
create mode 100644 nss/lib/libpkix/include/exports.gyp
create mode 100644 nss/lib/libpkix/include/include.gyp
create mode 100755 nss/lib/libpkix/include/manifest.mn
create mode 100755 nss/lib/libpkix/include/pkix.h
create mode 100755 nss/lib/libpkix/include/pkix_certsel.h
create mode 100755 nss/lib/libpkix/include/pkix_certstore.h
create mode 100755 nss/lib/libpkix/include/pkix_checker.h
create mode 100755 nss/lib/libpkix/include/pkix_crlsel.h
create mode 100755 nss/lib/libpkix/include/pkix_errorstrings.h
create mode 100755 nss/lib/libpkix/include/pkix_params.h
create mode 100755 nss/lib/libpkix/include/pkix_pl_pki.h
create mode 100755 nss/lib/libpkix/include/pkix_pl_system.h
create mode 100755 nss/lib/libpkix/include/pkix_results.h
create mode 100755 nss/lib/libpkix/include/pkix_revchecker.h
create mode 100755 nss/lib/libpkix/include/pkix_sample_modules.h
create mode 100755 nss/lib/libpkix/include/pkix_util.h
create mode 100755 nss/lib/libpkix/include/pkixt.h
create mode 100755 nss/lib/libpkix/manifest.mn
create mode 100755 nss/lib/libpkix/pkix/Makefile
create mode 100755 nss/lib/libpkix/pkix/certsel/Makefile
create mode 100644 nss/lib/libpkix/pkix/certsel/certsel.gyp
create mode 100755 nss/lib/libpkix/pkix/certsel/config.mk
create mode 100644 nss/lib/libpkix/pkix/certsel/exports.gyp
create mode 100755 nss/lib/libpkix/pkix/certsel/manifest.mn
create mode 100755 nss/lib/libpkix/pkix/certsel/pkix_certselector.c
create mode 100755 nss/lib/libpkix/pkix/certsel/pkix_certselector.h
create mode 100755 nss/lib/libpkix/pkix/certsel/pkix_comcertselparams.c
create mode 100755 nss/lib/libpkix/pkix/certsel/pkix_comcertselparams.h
create mode 100755 nss/lib/libpkix/pkix/checker/Makefile
create mode 100644 nss/lib/libpkix/pkix/checker/checker.gyp
create mode 100755 nss/lib/libpkix/pkix/checker/config.mk
create mode 100644 nss/lib/libpkix/pkix/checker/exports.gyp
create mode 100755 nss/lib/libpkix/pkix/checker/manifest.mn
create mode 100755 nss/lib/libpkix/pkix/checker/pkix_basicconstraintschecker.c
create mode 100755 nss/lib/libpkix/pkix/checker/pkix_basicconstraintschecker.h
create mode 100755 nss/lib/libpkix/pkix/checker/pkix_certchainchecker.c
create mode 100755 nss/lib/libpkix/pkix/checker/pkix_certchainchecker.h
create mode 100644 nss/lib/libpkix/pkix/checker/pkix_crlchecker.c
create mode 100644 nss/lib/libpkix/pkix/checker/pkix_crlchecker.h
create mode 100644 nss/lib/libpkix/pkix/checker/pkix_ekuchecker.c
create mode 100644 nss/lib/libpkix/pkix/checker/pkix_ekuchecker.h
create mode 100755 nss/lib/libpkix/pkix/checker/pkix_expirationchecker.c
create mode 100755 nss/lib/libpkix/pkix/checker/pkix_expirationchecker.h
create mode 100755 nss/lib/libpkix/pkix/checker/pkix_namechainingchecker.c
create mode 100755 nss/lib/libpkix/pkix/checker/pkix_namechainingchecker.h
create mode 100755 nss/lib/libpkix/pkix/checker/pkix_nameconstraintschecker.c
create mode 100755 nss/lib/libpkix/pkix/checker/pkix_nameconstraintschecker.h
create mode 100644 nss/lib/libpkix/pkix/checker/pkix_ocspchecker.c
create mode 100644 nss/lib/libpkix/pkix/checker/pkix_ocspchecker.h
create mode 100755 nss/lib/libpkix/pkix/checker/pkix_policychecker.c
create mode 100755 nss/lib/libpkix/pkix/checker/pkix_policychecker.h
create mode 100755 nss/lib/libpkix/pkix/checker/pkix_revocationchecker.c
create mode 100755 nss/lib/libpkix/pkix/checker/pkix_revocationchecker.h
create mode 100644 nss/lib/libpkix/pkix/checker/pkix_revocationmethod.c
create mode 100644 nss/lib/libpkix/pkix/checker/pkix_revocationmethod.h
create mode 100755 nss/lib/libpkix/pkix/checker/pkix_signaturechecker.c
create mode 100755 nss/lib/libpkix/pkix/checker/pkix_signaturechecker.h
create mode 100755 nss/lib/libpkix/pkix/checker/pkix_targetcertchecker.c
create mode 100755 nss/lib/libpkix/pkix/checker/pkix_targetcertchecker.h
create mode 100755 nss/lib/libpkix/pkix/config.mk
create mode 100755 nss/lib/libpkix/pkix/crlsel/Makefile
create mode 100755 nss/lib/libpkix/pkix/crlsel/config.mk
create mode 100644 nss/lib/libpkix/pkix/crlsel/crlsel.gyp
create mode 100644 nss/lib/libpkix/pkix/crlsel/exports.gyp
create mode 100755 nss/lib/libpkix/pkix/crlsel/manifest.mn
create mode 100755 nss/lib/libpkix/pkix/crlsel/pkix_comcrlselparams.c
create mode 100755 nss/lib/libpkix/pkix/crlsel/pkix_comcrlselparams.h
create mode 100755 nss/lib/libpkix/pkix/crlsel/pkix_crlselector.c
create mode 100755 nss/lib/libpkix/pkix/crlsel/pkix_crlselector.h
create mode 100755 nss/lib/libpkix/pkix/manifest.mn
create mode 100755 nss/lib/libpkix/pkix/params/Makefile
create mode 100755 nss/lib/libpkix/pkix/params/config.mk
create mode 100644 nss/lib/libpkix/pkix/params/exports.gyp
create mode 100755 nss/lib/libpkix/pkix/params/manifest.mn
create mode 100644 nss/lib/libpkix/pkix/params/params.gyp
create mode 100755 nss/lib/libpkix/pkix/params/pkix_procparams.c
create mode 100755 nss/lib/libpkix/pkix/params/pkix_procparams.h
create mode 100755 nss/lib/libpkix/pkix/params/pkix_resourcelimits.c
create mode 100755 nss/lib/libpkix/pkix/params/pkix_resourcelimits.h
create mode 100755 nss/lib/libpkix/pkix/params/pkix_trustanchor.c
create mode 100755 nss/lib/libpkix/pkix/params/pkix_trustanchor.h
create mode 100755 nss/lib/libpkix/pkix/params/pkix_valparams.c
create mode 100755 nss/lib/libpkix/pkix/params/pkix_valparams.h
create mode 100755 nss/lib/libpkix/pkix/results/Makefile
create mode 100755 nss/lib/libpkix/pkix/results/config.mk
create mode 100644 nss/lib/libpkix/pkix/results/exports.gyp
create mode 100755 nss/lib/libpkix/pkix/results/manifest.mn
create mode 100755 nss/lib/libpkix/pkix/results/pkix_buildresult.c
create mode 100755 nss/lib/libpkix/pkix/results/pkix_buildresult.h
create mode 100755 nss/lib/libpkix/pkix/results/pkix_policynode.c
create mode 100755 nss/lib/libpkix/pkix/results/pkix_policynode.h
create mode 100755 nss/lib/libpkix/pkix/results/pkix_valresult.c
create mode 100755 nss/lib/libpkix/pkix/results/pkix_valresult.h
create mode 100755 nss/lib/libpkix/pkix/results/pkix_verifynode.c
create mode 100755 nss/lib/libpkix/pkix/results/pkix_verifynode.h
create mode 100644 nss/lib/libpkix/pkix/results/results.gyp
create mode 100755 nss/lib/libpkix/pkix/store/Makefile
create mode 100755 nss/lib/libpkix/pkix/store/config.mk
create mode 100644 nss/lib/libpkix/pkix/store/exports.gyp
create mode 100755 nss/lib/libpkix/pkix/store/manifest.mn
create mode 100755 nss/lib/libpkix/pkix/store/pkix_store.c
create mode 100755 nss/lib/libpkix/pkix/store/pkix_store.h
create mode 100644 nss/lib/libpkix/pkix/store/store.gyp
create mode 100755 nss/lib/libpkix/pkix/top/Makefile
create mode 100755 nss/lib/libpkix/pkix/top/config.mk
create mode 100644 nss/lib/libpkix/pkix/top/exports.gyp
create mode 100755 nss/lib/libpkix/pkix/top/manifest.mn
create mode 100755 nss/lib/libpkix/pkix/top/pkix_build.c
create mode 100755 nss/lib/libpkix/pkix/top/pkix_build.h
create mode 100755 nss/lib/libpkix/pkix/top/pkix_lifecycle.c
create mode 100755 nss/lib/libpkix/pkix/top/pkix_lifecycle.h
create mode 100755 nss/lib/libpkix/pkix/top/pkix_validate.c
create mode 100755 nss/lib/libpkix/pkix/top/pkix_validate.h
create mode 100644 nss/lib/libpkix/pkix/top/top.gyp
create mode 100755 nss/lib/libpkix/pkix/util/Makefile
create mode 100755 nss/lib/libpkix/pkix/util/config.mk
create mode 100644 nss/lib/libpkix/pkix/util/exports.gyp
create mode 100755 nss/lib/libpkix/pkix/util/manifest.mn
create mode 100755 nss/lib/libpkix/pkix/util/pkix_error.c
create mode 100755 nss/lib/libpkix/pkix/util/pkix_error.h
create mode 100644 nss/lib/libpkix/pkix/util/pkix_errpaths.c
create mode 100755 nss/lib/libpkix/pkix/util/pkix_list.c
create mode 100755 nss/lib/libpkix/pkix/util/pkix_list.h
create mode 100644 nss/lib/libpkix/pkix/util/pkix_logger.c
create mode 100644 nss/lib/libpkix/pkix/util/pkix_logger.h
create mode 100755 nss/lib/libpkix/pkix/util/pkix_tools.c
create mode 100755 nss/lib/libpkix/pkix/util/pkix_tools.h
create mode 100644 nss/lib/libpkix/pkix/util/util.gyp
create mode 100755 nss/lib/libpkix/pkix_pl_nss/Makefile
create mode 100755 nss/lib/libpkix/pkix_pl_nss/config.mk
create mode 100755 nss/lib/libpkix/pkix_pl_nss/manifest.mn
create mode 100755 nss/lib/libpkix/pkix_pl_nss/module/Makefile
create mode 100755 nss/lib/libpkix/pkix_pl_nss/module/config.mk
create mode 100644 nss/lib/libpkix/pkix_pl_nss/module/exports.gyp
create mode 100755 nss/lib/libpkix/pkix_pl_nss/module/manifest.mn
create mode 100644 nss/lib/libpkix/pkix_pl_nss/module/module.gyp
create mode 100644 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.h
create mode 100755 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_colcertstore.c
create mode 100755 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_colcertstore.h
create mode 100755 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapcertstore.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapcertstore.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapdefaultclient.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapdefaultclient.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldaprequest.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldaprequest.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapresponse.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapresponse.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapt.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldaptemplates.c
create mode 100755 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_nsscontext.c
create mode 100755 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_nsscontext.h
create mode 100755 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_pk11certstore.c
create mode 100755 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_pk11certstore.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.h
create mode 100755 nss/lib/libpkix/pkix_pl_nss/pki/Makefile
create mode 100755 nss/lib/libpkix/pkix_pl_nss/pki/config.mk
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/exports.gyp
create mode 100755 nss/lib/libpkix/pkix_pl_nss/pki/manifest.mn
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pki.gyp
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_basicconstraints.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_basicconstraints.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyinfo.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyinfo.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicymap.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicymap.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyqualifier.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyqualifier.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crlentry.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crlentry.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_date.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_date.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_generalname.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_generalname.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_nameconstraints.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_nameconstraints.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_publickey.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_publickey.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_x500name.c
create mode 100644 nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_x500name.h
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/Makefile
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/config.mk
create mode 100644 nss/lib/libpkix/pkix_pl_nss/system/exports.gyp
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/manifest.mn
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bigint.c
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bigint.h
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bytearray.c
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bytearray.h
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_common.c
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_common.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_error.c
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_hashtable.c
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_hashtable.h
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.h
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mem.c
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mem.h
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_monitorlock.c
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_monitorlock.h
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mutex.c
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mutex.h
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.c
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.h
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_oid.c
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_oid.h
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_primhash.c
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_primhash.h
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_rwlock.c
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_rwlock.h
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_string.c
create mode 100755 nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_string.h
create mode 100644 nss/lib/libpkix/pkix_pl_nss/system/system.gyp
create mode 100644 nss/lib/manifest.mn
create mode 100644 nss/lib/nss/Makefile
create mode 100644 nss/lib/nss/config.mk
create mode 100644 nss/lib/nss/exports.gyp
create mode 100644 nss/lib/nss/manifest.mn
create mode 100644 nss/lib/nss/nss.def
create mode 100644 nss/lib/nss/nss.gyp
create mode 100644 nss/lib/nss/nss.h
create mode 100644 nss/lib/nss/nss.rc
create mode 100644 nss/lib/nss/nssinit.c
create mode 100644 nss/lib/nss/nssoptions.c
create mode 100644 nss/lib/nss/nssoptions.h
create mode 100644 nss/lib/nss/nssrenam.h
create mode 100644 nss/lib/nss/nssver.c
create mode 100644 nss/lib/nss/pkixpriv.def
create mode 100644 nss/lib/nss/utilwrap.c
create mode 100644 nss/lib/pk11wrap/Makefile
create mode 100644 nss/lib/pk11wrap/config.mk
create mode 100644 nss/lib/pk11wrap/debug_module.c
create mode 100644 nss/lib/pk11wrap/dev3hack.c
create mode 100644 nss/lib/pk11wrap/dev3hack.h
create mode 100644 nss/lib/pk11wrap/exports.gyp
create mode 100644 nss/lib/pk11wrap/manifest.mn
create mode 100644 nss/lib/pk11wrap/pk11akey.c
create mode 100644 nss/lib/pk11wrap/pk11auth.c
create mode 100644 nss/lib/pk11wrap/pk11cert.c
create mode 100644 nss/lib/pk11wrap/pk11cxt.c
create mode 100644 nss/lib/pk11wrap/pk11err.c
create mode 100644 nss/lib/pk11wrap/pk11func.h
create mode 100644 nss/lib/pk11wrap/pk11kea.c
create mode 100644 nss/lib/pk11wrap/pk11list.c
create mode 100644 nss/lib/pk11wrap/pk11load.c
create mode 100644 nss/lib/pk11wrap/pk11mech.c
create mode 100644 nss/lib/pk11wrap/pk11merge.c
create mode 100644 nss/lib/pk11wrap/pk11nobj.c
create mode 100644 nss/lib/pk11wrap/pk11obj.c
create mode 100644 nss/lib/pk11wrap/pk11pars.c
create mode 100644 nss/lib/pk11wrap/pk11pbe.c
create mode 100644 nss/lib/pk11wrap/pk11pk12.c
create mode 100644 nss/lib/pk11wrap/pk11pqg.c
create mode 100644 nss/lib/pk11wrap/pk11pqg.h
create mode 100644 nss/lib/pk11wrap/pk11priv.h
create mode 100644 nss/lib/pk11wrap/pk11pub.h
create mode 100644 nss/lib/pk11wrap/pk11sdr.c
create mode 100644 nss/lib/pk11wrap/pk11sdr.h
create mode 100644 nss/lib/pk11wrap/pk11skey.c
create mode 100644 nss/lib/pk11wrap/pk11slot.c
create mode 100644 nss/lib/pk11wrap/pk11util.c
create mode 100644 nss/lib/pk11wrap/pk11wrap.gyp
create mode 100644 nss/lib/pk11wrap/secmod.h
create mode 100644 nss/lib/pk11wrap/secmodi.h
create mode 100644 nss/lib/pk11wrap/secmodt.h
create mode 100644 nss/lib/pk11wrap/secmodti.h
create mode 100644 nss/lib/pk11wrap/secpkcs5.h
create mode 100644 nss/lib/pkcs12/Makefile
create mode 100644 nss/lib/pkcs12/config.mk
create mode 100644 nss/lib/pkcs12/exports.gyp
create mode 100644 nss/lib/pkcs12/manifest.mn
create mode 100644 nss/lib/pkcs12/p12.h
create mode 100644 nss/lib/pkcs12/p12creat.c
create mode 100644 nss/lib/pkcs12/p12d.c
create mode 100644 nss/lib/pkcs12/p12dec.c
create mode 100644 nss/lib/pkcs12/p12e.c
create mode 100644 nss/lib/pkcs12/p12exp.c
create mode 100644 nss/lib/pkcs12/p12local.c
create mode 100644 nss/lib/pkcs12/p12local.h
create mode 100644 nss/lib/pkcs12/p12plcy.c
create mode 100644 nss/lib/pkcs12/p12plcy.h
create mode 100644 nss/lib/pkcs12/p12t.h
create mode 100644 nss/lib/pkcs12/p12tmpl.c
create mode 100644 nss/lib/pkcs12/pkcs12.gyp
create mode 100644 nss/lib/pkcs12/pkcs12.h
create mode 100644 nss/lib/pkcs12/pkcs12t.h
create mode 100644 nss/lib/pkcs7/Makefile
create mode 100644 nss/lib/pkcs7/certread.c
create mode 100644 nss/lib/pkcs7/config.mk
create mode 100644 nss/lib/pkcs7/exports.gyp
create mode 100644 nss/lib/pkcs7/manifest.mn
create mode 100644 nss/lib/pkcs7/p7common.c
create mode 100644 nss/lib/pkcs7/p7create.c
create mode 100644 nss/lib/pkcs7/p7decode.c
create mode 100644 nss/lib/pkcs7/p7encode.c
create mode 100644 nss/lib/pkcs7/p7local.c
create mode 100644 nss/lib/pkcs7/p7local.h
create mode 100644 nss/lib/pkcs7/pkcs7.gyp
create mode 100644 nss/lib/pkcs7/pkcs7t.h
create mode 100644 nss/lib/pkcs7/secmime.c
create mode 100644 nss/lib/pkcs7/secmime.h
create mode 100644 nss/lib/pkcs7/secpkcs7.h
create mode 100644 nss/lib/pki/Makefile
create mode 100644 nss/lib/pki/asymmkey.c
create mode 100644 nss/lib/pki/certdecode.c
create mode 100644 nss/lib/pki/certificate.c
create mode 100644 nss/lib/pki/config.mk
create mode 100644 nss/lib/pki/cryptocontext.c
create mode 100644 nss/lib/pki/doc/standiag.png
create mode 100644 nss/lib/pki/doc/standoc.html
create mode 100644 nss/lib/pki/exports.gyp
create mode 100644 nss/lib/pki/manifest.mn
create mode 100644 nss/lib/pki/nsspki.h
create mode 100644 nss/lib/pki/nsspkit.h
create mode 100644 nss/lib/pki/pki.gyp
create mode 100644 nss/lib/pki/pki.h
create mode 100644 nss/lib/pki/pki3hack.c
create mode 100644 nss/lib/pki/pki3hack.h
create mode 100644 nss/lib/pki/pkibase.c
create mode 100644 nss/lib/pki/pkim.h
create mode 100644 nss/lib/pki/pkistore.c
create mode 100644 nss/lib/pki/pkistore.h
create mode 100644 nss/lib/pki/pkit.h
create mode 100644 nss/lib/pki/pkitm.h
create mode 100644 nss/lib/pki/symmkey.c
create mode 100644 nss/lib/pki/tdcache.c
create mode 100644 nss/lib/pki/trustdomain.c
create mode 100644 nss/lib/smime/Makefile
create mode 100644 nss/lib/smime/cms.h
create mode 100644 nss/lib/smime/cmsarray.c
create mode 100644 nss/lib/smime/cmsasn1.c
create mode 100644 nss/lib/smime/cmsattr.c
create mode 100644 nss/lib/smime/cmscinfo.c
create mode 100644 nss/lib/smime/cmscipher.c
create mode 100644 nss/lib/smime/cmsdecode.c
create mode 100644 nss/lib/smime/cmsdigdata.c
create mode 100644 nss/lib/smime/cmsdigest.c
create mode 100644 nss/lib/smime/cmsencdata.c
create mode 100644 nss/lib/smime/cmsencode.c
create mode 100644 nss/lib/smime/cmsenvdata.c
create mode 100644 nss/lib/smime/cmslocal.h
create mode 100644 nss/lib/smime/cmsmessage.c
create mode 100644 nss/lib/smime/cmspubkey.c
create mode 100644 nss/lib/smime/cmsrecinfo.c
create mode 100644 nss/lib/smime/cmsreclist.c
create mode 100644 nss/lib/smime/cmsreclist.h
create mode 100644 nss/lib/smime/cmssigdata.c
create mode 100644 nss/lib/smime/cmssiginfo.c
create mode 100644 nss/lib/smime/cmst.h
create mode 100644 nss/lib/smime/cmsudf.c
create mode 100644 nss/lib/smime/cmsutil.c
create mode 100644 nss/lib/smime/config.mk
create mode 100644 nss/lib/smime/exports.gyp
create mode 100644 nss/lib/smime/manifest.mn
create mode 100644 nss/lib/smime/smime.def
create mode 100644 nss/lib/smime/smime.gyp
create mode 100644 nss/lib/smime/smime.h
create mode 100644 nss/lib/smime/smime.rc
create mode 100644 nss/lib/smime/smimemessage.c
create mode 100644 nss/lib/smime/smimesym.c
create mode 100644 nss/lib/smime/smimeutil.c
create mode 100644 nss/lib/smime/smimever.c
create mode 100644 nss/lib/softoken/Makefile
create mode 100644 nss/lib/softoken/config.mk
create mode 100644 nss/lib/softoken/exports.gyp
create mode 100644 nss/lib/softoken/fipsaudt.c
create mode 100644 nss/lib/softoken/fipstest.c
create mode 100644 nss/lib/softoken/fipstokn.c
create mode 100644 nss/lib/softoken/jpakesftk.c
create mode 100644 nss/lib/softoken/legacydb/Makefile
create mode 100644 nss/lib/softoken/legacydb/cdbhdl.h
create mode 100644 nss/lib/softoken/legacydb/config.mk
create mode 100644 nss/lib/softoken/legacydb/dbmshim.c
create mode 100644 nss/lib/softoken/legacydb/keydb.c
create mode 100644 nss/lib/softoken/legacydb/keydbi.h
create mode 100644 nss/lib/softoken/legacydb/legacydb.gyp
create mode 100644 nss/lib/softoken/legacydb/lgattr.c
create mode 100644 nss/lib/softoken/legacydb/lgcreate.c
create mode 100644 nss/lib/softoken/legacydb/lgdb.h
create mode 100644 nss/lib/softoken/legacydb/lgdestroy.c
create mode 100644 nss/lib/softoken/legacydb/lgfind.c
create mode 100644 nss/lib/softoken/legacydb/lgfips.c
create mode 100644 nss/lib/softoken/legacydb/lginit.c
create mode 100644 nss/lib/softoken/legacydb/lgutil.c
create mode 100644 nss/lib/softoken/legacydb/lowcert.c
create mode 100644 nss/lib/softoken/legacydb/lowkey.c
create mode 100644 nss/lib/softoken/legacydb/lowkeyi.h
create mode 100644 nss/lib/softoken/legacydb/lowkeyti.h
create mode 100644 nss/lib/softoken/legacydb/manifest.mn
create mode 100644 nss/lib/softoken/legacydb/nssdbm.def
create mode 100644 nss/lib/softoken/legacydb/nssdbm.rc
create mode 100644 nss/lib/softoken/legacydb/pcert.h
create mode 100644 nss/lib/softoken/legacydb/pcertdb.c
create mode 100644 nss/lib/softoken/legacydb/pcertt.h
create mode 100644 nss/lib/softoken/legacydb/pk11db.c
create mode 100644 nss/lib/softoken/lgglue.c
create mode 100644 nss/lib/softoken/lgglue.h
create mode 100644 nss/lib/softoken/lowkey.c
create mode 100644 nss/lib/softoken/lowkeyi.h
create mode 100644 nss/lib/softoken/lowkeyti.h
create mode 100644 nss/lib/softoken/lowpbe.c
create mode 100644 nss/lib/softoken/lowpbe.h
create mode 100644 nss/lib/softoken/manifest.mn
create mode 100644 nss/lib/softoken/padbuf.c
create mode 100644 nss/lib/softoken/pkcs11.c
create mode 100644 nss/lib/softoken/pkcs11c.c
create mode 100644 nss/lib/softoken/pkcs11i.h
create mode 100644 nss/lib/softoken/pkcs11ni.h
create mode 100644 nss/lib/softoken/pkcs11u.c
create mode 100644 nss/lib/softoken/sdb.c
create mode 100644 nss/lib/softoken/sdb.h
create mode 100644 nss/lib/softoken/sftkdb.c
create mode 100644 nss/lib/softoken/sftkdb.h
create mode 100644 nss/lib/softoken/sftkdbt.h
create mode 100644 nss/lib/softoken/sftkdbti.h
create mode 100644 nss/lib/softoken/sftkhmac.c
create mode 100644 nss/lib/softoken/sftkpars.c
create mode 100644 nss/lib/softoken/sftkpars.h
create mode 100644 nss/lib/softoken/sftkpwd.c
create mode 100644 nss/lib/softoken/softkver.c
create mode 100644 nss/lib/softoken/softkver.h
create mode 100644 nss/lib/softoken/softoken.gyp
create mode 100644 nss/lib/softoken/softoken.h
create mode 100644 nss/lib/softoken/softokn.def
create mode 100644 nss/lib/softoken/softokn.rc
create mode 100644 nss/lib/softoken/softoknt.h
create mode 100644 nss/lib/softoken/tlsprf.c
create mode 100644 nss/lib/sqlite/Makefile
create mode 100644 nss/lib/sqlite/README
create mode 100644 nss/lib/sqlite/config.mk
create mode 100644 nss/lib/sqlite/exports.gyp
create mode 100644 nss/lib/sqlite/manifest.mn
create mode 100644 nss/lib/sqlite/sqlite.def
create mode 100644 nss/lib/sqlite/sqlite.gyp
create mode 100644 nss/lib/sqlite/sqlite3.c
create mode 100644 nss/lib/sqlite/sqlite3.h
create mode 100644 nss/lib/ssl/Makefile
create mode 100644 nss/lib/ssl/SSLerrs.h
create mode 100644 nss/lib/ssl/authcert.c
create mode 100644 nss/lib/ssl/cmpcert.c
create mode 100644 nss/lib/ssl/config.mk
create mode 100644 nss/lib/ssl/derive.c
create mode 100644 nss/lib/ssl/dhe-param.c
create mode 100644 nss/lib/ssl/dtlscon.c
create mode 100644 nss/lib/ssl/exports.gyp
create mode 100644 nss/lib/ssl/manifest.mn
create mode 100644 nss/lib/ssl/notes.txt
create mode 100644 nss/lib/ssl/os2_err.c
create mode 100644 nss/lib/ssl/os2_err.h
create mode 100644 nss/lib/ssl/preenc.h
create mode 100644 nss/lib/ssl/prelib.c
create mode 100644 nss/lib/ssl/ssl.def
create mode 100644 nss/lib/ssl/ssl.gyp
create mode 100644 nss/lib/ssl/ssl.h
create mode 100644 nss/lib/ssl/ssl.rc
create mode 100644 nss/lib/ssl/ssl3con.c
create mode 100644 nss/lib/ssl/ssl3ecc.c
create mode 100644 nss/lib/ssl/ssl3ext.c
create mode 100644 nss/lib/ssl/ssl3ext.h
create mode 100644 nss/lib/ssl/ssl3exthandle.c
create mode 100644 nss/lib/ssl/ssl3exthandle.h
create mode 100644 nss/lib/ssl/ssl3gthr.c
create mode 100644 nss/lib/ssl/ssl3prot.h
create mode 100644 nss/lib/ssl/sslauth.c
create mode 100644 nss/lib/ssl/sslcert.c
create mode 100644 nss/lib/ssl/sslcert.h
create mode 100644 nss/lib/ssl/sslcon.c
create mode 100644 nss/lib/ssl/ssldef.c
create mode 100644 nss/lib/ssl/sslenum.c
create mode 100644 nss/lib/ssl/sslerr.c
create mode 100644 nss/lib/ssl/sslerr.h
create mode 100644 nss/lib/ssl/sslerrstrs.c
create mode 100644 nss/lib/ssl/sslgrp.c
create mode 100644 nss/lib/ssl/sslimpl.h
create mode 100644 nss/lib/ssl/sslinfo.c
create mode 100644 nss/lib/ssl/sslinit.c
create mode 100644 nss/lib/ssl/sslmutex.c
create mode 100644 nss/lib/ssl/sslmutex.h
create mode 100644 nss/lib/ssl/sslnonce.c
create mode 100644 nss/lib/ssl/sslproto.h
create mode 100644 nss/lib/ssl/sslreveal.c
create mode 100644 nss/lib/ssl/sslsecur.c
create mode 100644 nss/lib/ssl/sslsnce.c
create mode 100644 nss/lib/ssl/sslsock.c
create mode 100644 nss/lib/ssl/sslt.h
create mode 100644 nss/lib/ssl/ssltrace.c
create mode 100644 nss/lib/ssl/sslver.c
create mode 100644 nss/lib/ssl/tls13con.c
create mode 100644 nss/lib/ssl/tls13con.h
create mode 100644 nss/lib/ssl/tls13exthandle.c
create mode 100644 nss/lib/ssl/tls13exthandle.h
create mode 100644 nss/lib/ssl/tls13hkdf.c
create mode 100644 nss/lib/ssl/tls13hkdf.h
create mode 100644 nss/lib/ssl/tlsproof.c
create mode 100644 nss/lib/ssl/tlsproof.h
create mode 100644 nss/lib/ssl/tlsproofstr.h
create mode 100644 nss/lib/ssl/unix_err.c
create mode 100644 nss/lib/ssl/unix_err.h
create mode 100644 nss/lib/ssl/win32err.c
create mode 100644 nss/lib/ssl/win32err.h
create mode 100644 nss/lib/sysinit/Makefile
create mode 100644 nss/lib/sysinit/config.mk
create mode 100644 nss/lib/sysinit/manifest.mn
create mode 100644 nss/lib/sysinit/nsssysinit.c
create mode 100644 nss/lib/sysinit/sysinit.gyp
create mode 100644 nss/lib/util/Makefile
create mode 100644 nss/lib/util/SECerrs.h
create mode 100644 nss/lib/util/base64.h
create mode 100644 nss/lib/util/ciferfam.h
create mode 100644 nss/lib/util/config.mk
create mode 100644 nss/lib/util/derdec.c
create mode 100644 nss/lib/util/derenc.c
create mode 100644 nss/lib/util/dersubr.c
create mode 100644 nss/lib/util/dertime.c
create mode 100644 nss/lib/util/eccutil.h
create mode 100644 nss/lib/util/errstrs.c
create mode 100644 nss/lib/util/exports.gyp
create mode 100644 nss/lib/util/hasht.h
create mode 100644 nss/lib/util/manifest.mn
create mode 100644 nss/lib/util/nssb64.h
create mode 100644 nss/lib/util/nssb64d.c
create mode 100644 nss/lib/util/nssb64e.c
create mode 100644 nss/lib/util/nssb64t.h
create mode 100644 nss/lib/util/nssilckt.h
create mode 100644 nss/lib/util/nssilock.c
create mode 100644 nss/lib/util/nssilock.h
create mode 100644 nss/lib/util/nsslocks.h
create mode 100644 nss/lib/util/nssrwlk.c
create mode 100644 nss/lib/util/nssrwlk.h
create mode 100644 nss/lib/util/nssrwlkt.h
create mode 100644 nss/lib/util/nssutil.def
create mode 100644 nss/lib/util/nssutil.h
create mode 100644 nss/lib/util/nssutil.rc
create mode 100644 nss/lib/util/oidstring.c
create mode 100644 nss/lib/util/pkcs11.h
create mode 100644 nss/lib/util/pkcs11f.h
create mode 100644 nss/lib/util/pkcs11n.h
create mode 100644 nss/lib/util/pkcs11p.h
create mode 100644 nss/lib/util/pkcs11t.h
create mode 100644 nss/lib/util/pkcs11u.h
create mode 100644 nss/lib/util/pkcs1sig.c
create mode 100644 nss/lib/util/pkcs1sig.h
create mode 100644 nss/lib/util/portreg.c
create mode 100644 nss/lib/util/portreg.h
create mode 100644 nss/lib/util/quickder.c
create mode 100644 nss/lib/util/secalgid.c
create mode 100644 nss/lib/util/secasn1.h
create mode 100644 nss/lib/util/secasn1d.c
create mode 100644 nss/lib/util/secasn1e.c
create mode 100644 nss/lib/util/secasn1t.h
create mode 100644 nss/lib/util/secasn1u.c
create mode 100644 nss/lib/util/seccomon.h
create mode 100644 nss/lib/util/secder.h
create mode 100644 nss/lib/util/secdert.h
create mode 100644 nss/lib/util/secdig.c
create mode 100644 nss/lib/util/secdig.h
create mode 100644 nss/lib/util/secdigt.h
create mode 100644 nss/lib/util/secerr.h
create mode 100644 nss/lib/util/secitem.c
create mode 100644 nss/lib/util/secitem.h
create mode 100644 nss/lib/util/secload.c
create mode 100644 nss/lib/util/secoid.c
create mode 100644 nss/lib/util/secoid.h
create mode 100644 nss/lib/util/secoidt.h
create mode 100644 nss/lib/util/secplcy.c
create mode 100644 nss/lib/util/secplcy.h
create mode 100644 nss/lib/util/secport.c
create mode 100644 nss/lib/util/secport.h
create mode 100644 nss/lib/util/sectime.c
create mode 100644 nss/lib/util/templates.c
create mode 100644 nss/lib/util/utf8.c
create mode 100644 nss/lib/util/util.gyp
create mode 100644 nss/lib/util/utilmod.c
create mode 100644 nss/lib/util/utilmodt.h
create mode 100644 nss/lib/util/utilpars.c
create mode 100644 nss/lib/util/utilpars.h
create mode 100644 nss/lib/util/utilparst.h
create mode 100644 nss/lib/util/utilrename.h
create mode 100644 nss/lib/util/verref.h
create mode 100644 nss/lib/zlib/Makefile
create mode 100644 nss/lib/zlib/README
create mode 100644 nss/lib/zlib/README.nss
create mode 100644 nss/lib/zlib/adler32.c
create mode 100644 nss/lib/zlib/compress.c
create mode 100644 nss/lib/zlib/config.mk
create mode 100644 nss/lib/zlib/crc32.c
create mode 100644 nss/lib/zlib/crc32.h
create mode 100644 nss/lib/zlib/deflate.c
create mode 100644 nss/lib/zlib/deflate.h
create mode 100644 nss/lib/zlib/example.c
create mode 100644 nss/lib/zlib/exports.gyp
create mode 100644 nss/lib/zlib/gzclose.c
create mode 100644 nss/lib/zlib/gzguts.h
create mode 100644 nss/lib/zlib/gzlib.c
create mode 100644 nss/lib/zlib/gzread.c
create mode 100644 nss/lib/zlib/gzwrite.c
create mode 100644 nss/lib/zlib/infback.c
create mode 100644 nss/lib/zlib/inffast.c
create mode 100644 nss/lib/zlib/inffast.h
create mode 100644 nss/lib/zlib/inffixed.h
create mode 100644 nss/lib/zlib/inflate.c
create mode 100644 nss/lib/zlib/inflate.h
create mode 100644 nss/lib/zlib/inftrees.c
create mode 100644 nss/lib/zlib/inftrees.h
create mode 100644 nss/lib/zlib/manifest.mn
create mode 100644 nss/lib/zlib/minigzip.c
create mode 100644 nss/lib/zlib/patches/prune-zlib.sh
create mode 100644 nss/lib/zlib/trees.c
create mode 100644 nss/lib/zlib/trees.h
create mode 100644 nss/lib/zlib/uncompr.c
create mode 100644 nss/lib/zlib/zconf.h
create mode 100644 nss/lib/zlib/zlib.gyp
create mode 100644 nss/lib/zlib/zlib.h
create mode 100644 nss/lib/zlib/zutil.c
create mode 100644 nss/lib/zlib/zutil.h
create mode 100644 nss/manifest.mn
create mode 100644 nss/nss-tool/.clang-format
create mode 100644 nss/nss-tool/common/argparse.cc
create mode 100644 nss/nss-tool/common/argparse.h
create mode 100644 nss/nss-tool/common/util.cc
create mode 100644 nss/nss-tool/common/util.h
create mode 100644 nss/nss-tool/db/dbtool.cc
create mode 100644 nss/nss-tool/db/dbtool.h
create mode 100644 nss/nss-tool/nss_tool.cc
create mode 100644 nss/nss-tool/nss_tool.gyp
create mode 100644 nss/nss.gyp
create mode 100644 nss/pkg/Makefile
create mode 100644 nss/pkg/linux/Makefile
create mode 100644 nss/pkg/linux/sun-nss.spec
create mode 100644 nss/pkg/pkg-config/nss-config.in
create mode 100644 nss/pkg/pkg-config/nss.pc.in
create mode 100644 nss/pkg/solaris/Makefile
create mode 100755 nss/pkg/solaris/Makefile-devl.com
create mode 100755 nss/pkg/solaris/Makefile-devl.targ
create mode 100755 nss/pkg/solaris/Makefile-tlsu.com
create mode 100755 nss/pkg/solaris/Makefile-tlsu.targ
create mode 100644 nss/pkg/solaris/Makefile.com
create mode 100644 nss/pkg/solaris/Makefile.targ
create mode 100644 nss/pkg/solaris/SUNWtls/Makefile
create mode 100644 nss/pkg/solaris/SUNWtls/pkgdepend
create mode 100644 nss/pkg/solaris/SUNWtls/pkginfo.tmpl
create mode 100644 nss/pkg/solaris/SUNWtls/prototype_com
create mode 100644 nss/pkg/solaris/SUNWtls/prototype_i386
create mode 100644 nss/pkg/solaris/SUNWtls/prototype_sparc
create mode 100755 nss/pkg/solaris/SUNWtlsd/Makefile
create mode 100755 nss/pkg/solaris/SUNWtlsd/pkgdepend
create mode 100755 nss/pkg/solaris/SUNWtlsd/pkginfo.tmpl
create mode 100755 nss/pkg/solaris/SUNWtlsd/prototype
create mode 100755 nss/pkg/solaris/SUNWtlsu/Makefile
create mode 100755 nss/pkg/solaris/SUNWtlsu/pkgdepend
create mode 100755 nss/pkg/solaris/SUNWtlsu/pkginfo.tmpl
create mode 100755 nss/pkg/solaris/SUNWtlsu/prototype_com
create mode 100644 nss/pkg/solaris/SUNWtlsu/prototype_i386
create mode 100644 nss/pkg/solaris/SUNWtlsu/prototype_sparc
create mode 100644 nss/pkg/solaris/bld_awk_pkginfo.ksh
create mode 100644 nss/pkg/solaris/common_files/copyright
create mode 100644 nss/pkg/solaris/proto64.mk
create mode 100644 nss/readme.md
create mode 100644 nss/tests/README.txt
create mode 100755 nss/tests/all.sh
create mode 100755 nss/tests/bogo/bogo.sh
create mode 100755 nss/tests/cert/cert.sh
create mode 100644 nss/tests/cert/certext.txt
create mode 100755 nss/tests/chains/chains.sh
create mode 100755 nss/tests/chains/ocspd-config/ocspd-certs.sh
create mode 100644 nss/tests/chains/ocspd-config/ocspd.conf.template
create mode 100644 nss/tests/chains/ocspd-config/readme
create mode 100644 nss/tests/chains/scenarios/aia.cfg
create mode 100644 nss/tests/chains/scenarios/anypolicy.cfg
create mode 100644 nss/tests/chains/scenarios/anypolicywithlevel.cfg
create mode 100644 nss/tests/chains/scenarios/bridge.cfg
create mode 100644 nss/tests/chains/scenarios/bridgewithaia.cfg
create mode 100644 nss/tests/chains/scenarios/bridgewithhalfaia.cfg
create mode 100644 nss/tests/chains/scenarios/bridgewithpolicyextensionandmapping.cfg
create mode 100644 nss/tests/chains/scenarios/crldp.cfg
create mode 100644 nss/tests/chains/scenarios/dsa.cfg
create mode 100644 nss/tests/chains/scenarios/explicitPolicy.cfg
create mode 100644 nss/tests/chains/scenarios/extension.cfg
create mode 100644 nss/tests/chains/scenarios/extension2.cfg
create mode 100644 nss/tests/chains/scenarios/mapping.cfg
create mode 100644 nss/tests/chains/scenarios/mapping2.cfg
create mode 100644 nss/tests/chains/scenarios/megabridge_3_2.cfg
create mode 100644 nss/tests/chains/scenarios/method.cfg
create mode 100644 nss/tests/chains/scenarios/nameconstraints.cfg
create mode 100644 nss/tests/chains/scenarios/ocsp.cfg
create mode 100644 nss/tests/chains/scenarios/ocspd.cfg
create mode 100644 nss/tests/chains/scenarios/realcerts.cfg
create mode 100644 nss/tests/chains/scenarios/revoc.cfg
create mode 100644 nss/tests/chains/scenarios/scenarios
create mode 100644 nss/tests/chains/scenarios/trustanchors.cfg
create mode 100755 nss/tests/cipher/cipher.sh
create mode 100644 nss/tests/cipher/cipher.txt
create mode 100644 nss/tests/cipher/dsa.txt
create mode 100644 nss/tests/cipher/gcm.txt
create mode 100644 nss/tests/cipher/hash.txt
create mode 100755 nss/tests/cipher/performance.sh
create mode 100644 nss/tests/cipher/rsa.txt
create mode 100644 nss/tests/cipher/symmkey.txt
create mode 100755 nss/tests/clean_tbx
create mode 100644 nss/tests/cmdtests/cmdtests.sh
create mode 100644 nss/tests/common/Makefile
create mode 100755 nss/tests/common/cleanup.sh
create mode 100644 nss/tests/common/init.sh
create mode 100644 nss/tests/common/parsegtestreport.sed
create mode 100644 nss/tests/common/results_header.html
create mode 100755 nss/tests/core_watch
create mode 100644 nss/tests/crmf/crmf.sh
create mode 100755 nss/tests/dbtests/dbtests.sh
create mode 100755 nss/tests/dbupgrade/dbupgrade.sh
create mode 100755 nss/tests/dll_version.sh
create mode 100644 nss/tests/doc/clean.gif
create mode 100755 nss/tests/doc/nssqa.txt
create mode 100644 nss/tests/doc/platform_specific_problems
create mode 100755 nss/tests/doc/qa_wrapper.html
create mode 100644 nss/tests/dummy/dummy.sh
create mode 100755 nss/tests/ec/ec.sh
create mode 100755 nss/tests/ec/ecperf.sh
create mode 100644 nss/tests/ec/ectest.sh
create mode 100755 nss/tests/fips/fips.sh
create mode 100755 nss/tests/gtests/gtests.sh
create mode 100644 nss/tests/header
create mode 100755 nss/tests/interop/interop.sh
create mode 100644 nss/tests/iopr/cert_iopr.sh
create mode 100644 nss/tests/iopr/ocsp_iopr.sh
create mode 100644 nss/tests/iopr/server_scr/apache_unix.cfg
create mode 100644 nss/tests/iopr/server_scr/cert_gen.sh
create mode 100644 nss/tests/iopr/server_scr/cipher.list
create mode 100644 nss/tests/iopr/server_scr/client.cgi
create mode 100644 nss/tests/iopr/server_scr/config
create mode 100644 nss/tests/iopr/server_scr/iis_windows.cfg
create mode 100644 nss/tests/iopr/server_scr/iopr_server.cfg
create mode 100644 nss/tests/iopr/server_scr/sslreq.dat
create mode 100644 nss/tests/iopr/ssl_iopr.sh
create mode 100755 nss/tests/jss_dll_version.sh
create mode 100755 nss/tests/jssdir
create mode 100755 nss/tests/jssqa
create mode 100644 nss/tests/libpkix/cert_trust.map
create mode 100644 nss/tests/libpkix/certs/BrAirWaysBadSig.cert
create mode 100755 nss/tests/libpkix/certs/CertificatePoliciesCritical.crt
create mode 100644 nss/tests/libpkix/certs/GoodCACert.crt
create mode 100644 nss/tests/libpkix/certs/NameConstraints.ca.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.dcissallowed.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.dcissblocked.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.dcisscopy.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.intermediate.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.intermediate2.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.intermediate3.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.intermediate4.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.intermediate5.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.intermediate6.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.ncca.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.server1.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.server10.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.server11.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.server12.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.server13.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.server14.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.server15.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.server16.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.server17.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.server2.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.server3.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.server4.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.server5.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.server6.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.server7.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.server8.cert
create mode 100644 nss/tests/libpkix/certs/NameConstraints.server9.cert
create mode 100644 nss/tests/libpkix/certs/OCSPCA1.cert
create mode 100644 nss/tests/libpkix/certs/OCSPCA1.p12
create mode 100644 nss/tests/libpkix/certs/OCSPCA2.cert
create mode 100644 nss/tests/libpkix/certs/OCSPCA2.p12
create mode 100644 nss/tests/libpkix/certs/OCSPCA3.cert
create mode 100644 nss/tests/libpkix/certs/OCSPCA3.p12
create mode 100644 nss/tests/libpkix/certs/OCSPEE11.cert
create mode 100644 nss/tests/libpkix/certs/OCSPEE12.cert
create mode 100644 nss/tests/libpkix/certs/OCSPEE13.cert
create mode 100644 nss/tests/libpkix/certs/OCSPEE14.cert
create mode 100644 nss/tests/libpkix/certs/OCSPEE15.cert
create mode 100644 nss/tests/libpkix/certs/OCSPEE21.cert
create mode 100644 nss/tests/libpkix/certs/OCSPEE22.cert
create mode 100644 nss/tests/libpkix/certs/OCSPEE23.cert
create mode 100644 nss/tests/libpkix/certs/OCSPEE31.cert
create mode 100644 nss/tests/libpkix/certs/OCSPEE32.cert
create mode 100644 nss/tests/libpkix/certs/OCSPEE33.cert
create mode 100644 nss/tests/libpkix/certs/OCSPRoot.cert
create mode 100644 nss/tests/libpkix/certs/OCSPRoot.p12
create mode 100644 nss/tests/libpkix/certs/PayPalEE.cert
create mode 100644 nss/tests/libpkix/certs/PayPalICA.cert
create mode 100644 nss/tests/libpkix/certs/PayPalRootCA.cert
create mode 100644 nss/tests/libpkix/certs/TestCA.ca.cert
create mode 100644 nss/tests/libpkix/certs/TestUser50.cert
create mode 100644 nss/tests/libpkix/certs/TestUser51.cert
create mode 100644 nss/tests/libpkix/certs/TrustAnchorRootCertificate.crt
create mode 100644 nss/tests/libpkix/certs/ValidCertificatePathTest1EE.crt
create mode 100755 nss/tests/libpkix/certs/anchor2dsa
create mode 100755 nss/tests/libpkix/certs/crldiff.crl
create mode 100755 nss/tests/libpkix/certs/crlgood.crl
create mode 100755 nss/tests/libpkix/certs/extKeyUsage/codeSigningEKUCert
create mode 100755 nss/tests/libpkix/certs/extKeyUsage/multiEKUCert
create mode 100755 nss/tests/libpkix/certs/extKeyUsage/noEKUCert
create mode 100755 nss/tests/libpkix/certs/generalName/altNameDnCert
create mode 100755 nss/tests/libpkix/certs/generalName/altNameDnCert_diff
create mode 100755 nss/tests/libpkix/certs/generalName/altNameDnsCert
create mode 100755 nss/tests/libpkix/certs/generalName/altNameDnsCert_diff
create mode 100755 nss/tests/libpkix/certs/generalName/altNameEdiCert
create mode 100755 nss/tests/libpkix/certs/generalName/altNameEdiCert_diff
create mode 100755 nss/tests/libpkix/certs/generalName/altNameIpCert
create mode 100755 nss/tests/libpkix/certs/generalName/altNameIpCert_diff
create mode 100755 nss/tests/libpkix/certs/generalName/altNameNoneCert
create mode 100755 nss/tests/libpkix/certs/generalName/altNameOidCert
create mode 100755 nss/tests/libpkix/certs/generalName/altNameOidCert_diff
create mode 100755 nss/tests/libpkix/certs/generalName/altNameOtherCert
create mode 100755 nss/tests/libpkix/certs/generalName/altNameOtherCert_diff
create mode 100755 nss/tests/libpkix/certs/generalName/altNameRfc822Cert
create mode 100755 nss/tests/libpkix/certs/generalName/altNameRfc822Cert_diff
create mode 100755 nss/tests/libpkix/certs/generalName/altNameRfc822DnsCert
create mode 100755 nss/tests/libpkix/certs/generalName/altNameUriCert
create mode 100755 nss/tests/libpkix/certs/generalName/altNameUriCert_diff
create mode 100755 nss/tests/libpkix/certs/generalName/altNameX400Cert
create mode 100755 nss/tests/libpkix/certs/generalName/altNameX400Cert_diff
create mode 100755 nss/tests/libpkix/certs/hanfeiyu2hanfeiyu
create mode 100755 nss/tests/libpkix/certs/hy2hc-bc
create mode 100755 nss/tests/libpkix/certs/hy2hy-bc0
create mode 100755 nss/tests/libpkix/certs/issuer-hanfei.crl
create mode 100755 nss/tests/libpkix/certs/issuer-none.crl
create mode 100755 nss/tests/libpkix/certs/keyIdentifier/authKeyIDCert
create mode 100755 nss/tests/libpkix/certs/keyIdentifier/subjKeyIDCert
create mode 100755 nss/tests/libpkix/certs/keyUsage/decipherOnlyCert
create mode 100755 nss/tests/libpkix/certs/keyUsage/encipherOnlyCert
create mode 100755 nss/tests/libpkix/certs/keyUsage/multiKeyUsagesCert
create mode 100755 nss/tests/libpkix/certs/keyUsage/noKeyUsagesCert
create mode 100755 nss/tests/libpkix/certs/make-ca-u50-u51
create mode 100755 nss/tests/libpkix/certs/make-nc
create mode 100755 nss/tests/libpkix/certs/noExtensionsCert
create mode 100755 nss/tests/libpkix/certs/nss2alice
create mode 100755 nss/tests/libpkix/certs/publicKey/dsaWithParams
create mode 100755 nss/tests/libpkix/certs/publicKey/dsaWithoutParams
create mode 100755 nss/tests/libpkix/certs/publicKey/labs2yassir
create mode 100755 nss/tests/libpkix/certs/publicKey/yassir2labs
create mode 100755 nss/tests/libpkix/certs/sun2sun
create mode 100755 nss/tests/libpkix/certs/yassir2bcn
create mode 100755 nss/tests/libpkix/certs/yassir2yassir
create mode 100644 nss/tests/libpkix/common/libpkix_init.sh
create mode 100644 nss/tests/libpkix/common/libpkix_init_nist.sh
create mode 100755 nss/tests/libpkix/libpkix.sh
create mode 100755 nss/tests/libpkix/pkix_pl_tests/module/cert8.db
create mode 100755 nss/tests/libpkix/pkix_pl_tests/module/key3.db
create mode 100755 nss/tests/libpkix/pkix_pl_tests/module/rev_data/local/crldiff.crl
create mode 100755 nss/tests/libpkix/pkix_pl_tests/module/rev_data/local/crlgood.crl
create mode 100755 nss/tests/libpkix/pkix_pl_tests/module/rev_data/local/issuer-hanfei.crl
create mode 100755 nss/tests/libpkix/pkix_pl_tests/module/rev_data/local/issuer-none.crl
create mode 100755 nss/tests/libpkix/pkix_pl_tests/module/rev_data/test_eku_all.crt
create mode 100755 nss/tests/libpkix/pkix_pl_tests/module/rev_data/test_eku_allbutcodesigningEE.crt
create mode 100755 nss/tests/libpkix/pkix_pl_tests/module/rev_data/test_eku_clientauth.crt
create mode 100755 nss/tests/libpkix/pkix_pl_tests/module/rev_data/test_eku_clientauthEE.crt
create mode 100755 nss/tests/libpkix/pkix_pl_tests/module/rev_data/test_eku_codesigning_clientauth.crt
create mode 100755 nss/tests/libpkix/pkix_pl_tests/module/runPLTests.sh
create mode 100755 nss/tests/libpkix/pkix_pl_tests/module/secmod.db
create mode 100755 nss/tests/libpkix/pkix_pl_tests/pki/rev_data/local/README
create mode 100755 nss/tests/libpkix/pkix_pl_tests/pki/rev_data/local/crldiff.crl
create mode 100755 nss/tests/libpkix/pkix_pl_tests/pki/rev_data/local/crlgood.crl
create mode 100755 nss/tests/libpkix/pkix_pl_tests/pki/rev_data/local/issuer-hanfei.crl
create mode 100755 nss/tests/libpkix/pkix_pl_tests/pki/rev_data/local/issuer-none.crl
create mode 100755 nss/tests/libpkix/pkix_pl_tests/pki/runPLTests.sh
create mode 100755 nss/tests/libpkix/pkix_pl_tests/runPLTests.sh
create mode 100755 nss/tests/libpkix/pkix_pl_tests/system/runPLTests.sh
create mode 100755 nss/tests/libpkix/pkix_tests/certsel/keyUsage
create mode 100755 nss/tests/libpkix/pkix_tests/certsel/runTests.sh
create mode 100755 nss/tests/libpkix/pkix_tests/checker/runTests.sh
create mode 100755 nss/tests/libpkix/pkix_tests/crlsel/runTests.sh
create mode 100755 nss/tests/libpkix/pkix_tests/params/runTests.sh
create mode 100755 nss/tests/libpkix/pkix_tests/results/runTests.sh
create mode 100755 nss/tests/libpkix/pkix_tests/runTests.sh
create mode 100755 nss/tests/libpkix/pkix_tests/store/runTests.sh
create mode 100644 nss/tests/libpkix/pkix_tests/top/anchorcert.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/backtracking/signature/greg.crl
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/backtracking/signature/greg2yassir_badsig.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/backtracking/signature/jes.crl
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/backtracking/signature/jes2greg.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/backtracking/signature/jes2jes.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/backtracking/signature/jes2labs.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/backtracking/signature/labs.crl
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/backtracking/signature/labs2yassir.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/backtracking/signature/yassir.crl
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/backtracking/signature/yassir2hanfei.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/multi_path/signature/fail/greg.crl
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/multi_path/signature/fail/greg2yassir.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/multi_path/signature/fail/jes.crl
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/multi_path/signature/fail/jes2greg.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/multi_path/signature/fail/jes2jes.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/multi_path/signature/fail/jes2labs.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/multi_path/signature/fail/labs.crl
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/multi_path/signature/fail/labs2yassir.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/multi_path/signature/fail/yassir.crl
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/multi_path/signature/fail/yassir2hanfei.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/multi_path/signature/pass/greg.crl
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/multi_path/signature/pass/greg2yassir.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/multi_path/signature/pass/jes.crl
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/multi_path/signature/pass/jes2greg.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/multi_path/signature/pass/jes2jes.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/multi_path/signature/pass/jes2labs.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/multi_path/signature/pass/labs.crl
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/multi_path/signature/pass/labs2yassir.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/multi_path/signature/pass/yassir.crl
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/multi_path/signature/pass/yassir2hanfei.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/single_path/signature/fail/greg.crl
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/single_path/signature/fail/greg2yassir_badsig.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/single_path/signature/fail/jes.crl
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/single_path/signature/fail/jes2greg.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/single_path/signature/fail/jes2jes.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/single_path/signature/fail/yassir.crl
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/single_path/signature/fail/yassir2hanfei.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/single_path/signature/pass/greg.crl
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/single_path/signature/pass/greg2yassir.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/single_path/signature/pass/jes.crl
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/single_path/signature/pass/jes2greg.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/single_path/signature/pass/jes2jes.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/single_path/signature/pass/yassir.crl
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/single_path/signature/pass/yassir2hanfei.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/test1/greg2yassir.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/test1/jes2greg.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/test1/jes2jes.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/test1/jes2labs.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/test1/labs2yassir.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/test1/yassir2hanfei.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/test1/yassir2richard.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/test2/jes2greg.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/test2/jes2jes.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/test2/jes2labs.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/test2/labs2yassir.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/test2/nelson2yassir.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/test2/yassir2hanfei.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/test2/yassir2richard.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/test3/jes2greg.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/test3/jes2jes.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/test3/jes2labs.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/test3/labs2yassir.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/test3/nelson2yassir.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/build_data/test3/yassir2hanfei.crt
create mode 100644 nss/tests/libpkix/pkix_tests/top/cert8.db
create mode 100644 nss/tests/libpkix/pkix_tests/top/goodcert.crt
create mode 100644 nss/tests/libpkix/pkix_tests/top/key3.db
create mode 100755 nss/tests/libpkix/pkix_tests/top/rev_data/crlchecker/chem.crl
create mode 100755 nss/tests/libpkix/pkix_tests/top/rev_data/crlchecker/chem2prof.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/rev_data/crlchecker/phy2prof.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/rev_data/crlchecker/phys.crl
create mode 100755 nss/tests/libpkix/pkix_tests/top/rev_data/crlchecker/prof.crl
create mode 100755 nss/tests/libpkix/pkix_tests/top/rev_data/crlchecker/prof2test.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/rev_data/crlchecker/sci.crl
create mode 100755 nss/tests/libpkix/pkix_tests/top/rev_data/crlchecker/sci2chem.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/rev_data/crlchecker/sci2phy.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/rev_data/crlchecker/sci2sci.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/rev_data/crlchecker/test.crl
create mode 100644 nss/tests/libpkix/pkix_tests/top/revokedcert.crt
create mode 100755 nss/tests/libpkix/pkix_tests/top/runTests.sh
create mode 100644 nss/tests/libpkix/pkix_tests/top/secmod.db
create mode 100755 nss/tests/libpkix/pkix_tests/util/runTests.sh
create mode 100755 nss/tests/libpkix/runTests.sh
create mode 100755 nss/tests/libpkix/sample_apps/README
create mode 100755 nss/tests/libpkix/sample_apps/cert8.db
create mode 100755 nss/tests/libpkix/sample_apps/key3.db
create mode 100755 nss/tests/libpkix/sample_apps/runPerf.sh
create mode 100755 nss/tests/libpkix/sample_apps/secmod.db
create mode 100644 nss/tests/libpkix/vfychain_test.lst
create mode 100644 nss/tests/lowhash/lowhash.sh
create mode 100644 nss/tests/memleak/ignored
create mode 100755 nss/tests/memleak/memleak.sh
create mode 100644 nss/tests/memleak/sslreq.dat
create mode 100755 nss/tests/merge/merge.sh
create mode 100755 nss/tests/mksymlinks
create mode 100644 nss/tests/mpi/mpi.sh
create mode 100755 nss/tests/multinit/multinit.sh
create mode 100644 nss/tests/multinit/multinit.txt
create mode 100755 nss/tests/nssdir
create mode 100755 nss/tests/nsspath
create mode 100755 nss/tests/nssqa
create mode 100644 nss/tests/ocsp/ocsp.sh
create mode 100755 nss/tests/path_uniq
create mode 100755 nss/tests/perf/perf.sh
create mode 100644 nss/tests/pkcs11/netscape/suites/security/ssl/cert7.db
create mode 100644 nss/tests/pkcs11/netscape/suites/security/ssl/key3.db
create mode 100755 nss/tests/pkits/pkits.sh
create mode 100644 nss/tests/platformlist
create mode 100644 nss/tests/platformlist.tbx
create mode 100755 nss/tests/qa_stage
create mode 100755 nss/tests/qa_stat
create mode 100755 nss/tests/qaclean
create mode 100644 nss/tests/remote/Makefile
create mode 100644 nss/tests/remote/manifest.mn
create mode 100755 nss/tests/run_niscc.sh
create mode 100755 nss/tests/sdr/sdr.sh
create mode 100644 nss/tests/set_environment
create mode 100644 nss/tests/smime/alice.txt
create mode 100644 nss/tests/smime/bob.txt
create mode 100755 nss/tests/smime/smime.sh
create mode 100755 nss/tests/ssl/ssl.sh
create mode 100755 nss/tests/ssl/ssl_dist_stress.sh
create mode 100644 nss/tests/ssl/sslauth.txt
create mode 100644 nss/tests/ssl/sslcov.txt
create mode 100644 nss/tests/ssl/sslpolicy.txt
create mode 100644 nss/tests/ssl/sslreq.dat
create mode 100644 nss/tests/ssl/sslreq.txt
create mode 100644 nss/tests/ssl/sslstress.txt
create mode 100755 nss/tests/ssl_gtests/ssl_gtests.sh
create mode 100644 nss/tests/tools/sign.html
create mode 100644 nss/tests/tools/signjs.html
create mode 100644 nss/tests/tools/tools.sh
create mode 100755 nss/trademarks.txt
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..244ef3f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,30 @@
+# TLS-N implementation for NSS
+
+This is the prototype [TLS-N](https://tls-n.org) implementation based on Mozilla's [NSS](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS) library.
+
+## Main Library
+The main library file can be found inside (nss/lib/ssl/tlsproof.c). Here the most important functions are:
+
+``` tlsproof_addMessageToProof ```
+This function adds a record to the evidence calculation.
+
+``` SSL_TLSProofRequestProof ```
+The requester calls this function to trigger the evidence request.
+
+``` tlsproof_handleMessageRequest ```
+The function used by the generator to finalize the evidence.
+
+``` tlsproof_handleMessageResponse ```
+Uses the supplied evidence to create a proof according to the user's wishes.
+
+``` SSL_TLSProofCheckProof ```
+Verifies a given proof.
+
+### Test Applications
+We have also provided multiple test applications, such as:
+* A standalone [verifier](nss/cmd/verifier) that verifies proofs.
+* A [client](nss/cmd/randtrafficClient) and [server](randtrafficServer) application to test TLS-N with a specified amount of random traffic.
+* A [bechmarking](nss/cmd/benchmark) app for TLS-N.
+
+#### Test-CA
+For testing purposes we provide a Test CA with a test certiface for ```tls-n.testserver```. The certificate store has an empty password. You have to resolve this hostname accordingly in DNS.
diff --git a/ca/cert_creation.sh b/ca/cert_creation.sh
new file mode 100644
index 0000000..2e283d0
--- /dev/null
+++ b/ca/cert_creation.sh
@@ -0,0 +1,20 @@
+ps -ef > noise.txt
+date >> noise.txt
+mkdir server_db
+cd server_db
+certutil -N --empty-password -d .
+echo -e "5\n6\n7\ny\ny\n\ny\n" | certutil -S -s "CN=TLS-N Root CA" -k ec -q secp256r1 -n tlsproofca -x -t "C,C,C" -1 -2 -d . -z ../noise.txt # 5,6,7,y,y,,y
+ps -ef > ../noise.txt
+date >> ../noise.txt
+date "+%N" >> ../noise.txt
+certutil -R -k ec -q secp256r1 -s "CN=tls-n.testserver,O=TLS-N,C=NN" -d . -u V -a -f pwd.txt -o cert.req -z ../noise.txt
+openssl req -in cert.req -out cert.req2 -outform DER
+certutil -C -i cert.req2 -o server.crt -c tlsproofca -f pwd.txt -d .
+certutil -A -n tlsproofserver.com -t "u,u,u" -i server.crt -f pwd.txt -d .
+cd ..
+mkdir client_db
+cp server_db/* client_db
+cd client_db
+certutil -D -d . -f pwd.txt -n tls-n.testserver
+cd ..
+
diff --git a/ca/client_db/cert.req b/ca/client_db/cert.req
new file mode 100644
index 0000000..39fe947
--- /dev/null
+++ b/ca/client_db/cert.req
@@ -0,0 +1,18 @@
+
+Certificate request generated by Netscape certutil
+Phone: (not specified)
+
+Common Name: tls-n.testserver
+Email: (not specified)
+Organization: TLS-N
+State: (not specified)
+Country: NN
+
+-----BEGIN NEW CERTIFICATE REQUEST-----
+MIH0MIGaAgEAMDgxCzAJBgNVBAYTAk5OMQ4wDAYDVQQKEwVUTFMtTjEZMBcGA1UE
+AxMQdGxzLW4udGVzdHNlcnZlcjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKTR
+iNOt2VpeI+llhXEmHXzmAvuhv/OmnbPsDkfI+/HO3EJUVv1E/ad6UWPm/7cSAm20
+BsVLe95KJ42mPvKMgxWgADAKBggqhkjOPQQDAgNJADBGAiEAwG4kqlSisqkKl1St
+nsBYQYKNPIXD/W0tx3pworFZt+MCIQDn72ZDAAmqs3rH/+ScIT934Z0Vcc4J9kpc
+C4IdQnqXeQ==
+-----END NEW CERTIFICATE REQUEST-----
diff --git a/ca/client_db/cert.req2 b/ca/client_db/cert.req2
new file mode 100644
index 0000000000000000000000000000000000000000..931eda0c8a70ef10383f0e0304270bbdc3018708
GIT binary patch
literal 247
zcmXqL{9@2Ji;0oJz`~H*fRl|ml!Z;0$s=(xD|F;V<Ro-$OTBlQ-KU;r
z(FF_!Tu>8Pn3nlD
ofl8jgPjhDAT(!CC`2Qz!6z$6&&J`^@$N9}GhPz4DscL#907IEu$p8QV
literal 0
HcmV?d00001
diff --git a/ca/client_db/cert8.db b/ca/client_db/cert8.db
new file mode 100644
index 0000000000000000000000000000000000000000..20deb33a9a72b08b2bff61a61640aeccab3b3d90
GIT binary patch
literal 65536
zcmeI)eN0tl9KiACoO8MN%ByuDEuv&N%M$k-Fe?L&m{2N1LnLy|rgzuT6mDMbSVNhi
z=Bn9Zy4L1PFB2kw00IagfB*srAbb1VKs;#A}
zgg6jD009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**
z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q58#1l)!Yn(zn_Tw3`?!0%sN=?hf(0u#Od
zav>g7`Te`wHYLi@<^wX(Y0PsNp19(Ix#@*tiv0fInCEj1`HUGON7!9Xk6u`4#>-f{
z5$%Zz-)BB3M@7bsR1>6EObq%egOMrR>ft56K;`TH3K1=Ot#<2>wc7GpTFy_|E3(S6
z#%Cp{GF&?h@EimXKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL
zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1P~Z@0kbWQ$yEuJt~s?9PM;JvG&Ci*$zV=JP}$xGAhn|TCGfGm>HAJN%QTdY2Iw!
z`I_Y`(&Kc6SD-*Vtm{0lAD
z|2Xl(wBnM!>3ut@U-EW`4&JYqH#xtawfx7KkG)@?)3a`Mk{s}A#tb3z^;B^&I5P92
zu_gDdFK8}a)>!}Q&dk}rHoy5>ZowxN-5>8;oUCs7>SXEmswdC49-cR4^R+!)2da;L
z*V^H#E~?vKFrnjgTgq*awSUPYw}Vh>|FoGRMg<{X)?T_5gpC~oSNb1=@YJM?fkCjF
zLyR08xjjGc_^vsnH8ZjO$kzc>j9q-MaFg4<28+q^hVhF|IbGBGK^0v9^`x8mBjPwS0E@
zd|uj_mcy}Sp<{8&_ck{)r5sGU5ee@?mE^y>O*syl$sgGWAm-La0BTJC1^`11GlqDg
z`c@wry!+<2s3z*W$97%dbrC=S0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**
x5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5cod|`~#|^N|yit
literal 0
HcmV?d00001
diff --git a/ca/client_db/key3.db b/ca/client_db/key3.db
new file mode 100644
index 0000000000000000000000000000000000000000..00ad06f85e8e1705911bed599d036873fdf7dcc1
GIT binary patch
literal 16384
zcmeI%TQJm77y$6IH*I$N|C@%2B9}-?s5Da{H7lY?JLHl{?QW>CELP;QE?Guq8Iht^
zle>~>iqs@zbXnExh$&;Ii#y9sF6m-6v`Y`Y^w0xMGv7CJ=KJQHGv}Q7J$?siXtNMP
zM1;s~2rXBYh>j3JmDB@Ke-*0rxe3x-o?Ai`b)6d`=v8HPsQ0MHq6c;UJ&S%XTnGXn
z00JNY0w4eaAOHd&00JNY0{@Eu6;0va@nO6cuf#9oo_IDEhh<~45Fh{oAOHd&00JNY
z0w4eaAOHd&u)qQ&)km{cQoWU#2F*OxIrZBz0-Zu2S?Q3q>^3T+!
z-7@%8{3E|>pGEShUTY$2;woK~Y@2D;Ttv(071T$I6MQ?d6D~ol)#t_zwfJzG$tADT
z+N(N``WegpQ^HL3;s%Jy!p6^K1=R}7NunH=zT4;FIn9_Zk705KX78^c2G?jjb&dVt
zvLU0)enOP2?Ob3Ic&xPbGjCMJZ>m4qAvk7N6v*YVSzHS~iyJ}GA|!5!SRNV6(aobg
z!&@Isni)`prs#Jun~u%bK2?kA+Pid2UcDU-3uW>7QM~Yz7MxT5oFI~?e>nd%FNBC1
zaV0j6DY5^hV*&330T2KI5C8!X009sH0T2KI5CDO{68LkY;hgYZ?6=I=CcDVWiK_e}
z@6BE=E%S|rGwJc64A!R5gPccCYG*J7v>)ldZ>-8b$)$Xzm|J%+fPUhn5cdR~QX45mPRH5EGe}5K*zJ
zJ%yHYijhGVKV~^s(RbA-dQP;A4DI)0B!(=x;9#VGM
zzPNGNTX4X3%xg^#-B6}A(6J0f2crsmj}ZxgS5
s&)!Lzv}1Qo%H5|IxSIpVg8&GC00@8p2!H?xfB*=900@8p2>g42pQWadM*si-
literal 0
HcmV?d00001
diff --git a/ca/client_db/secmod.db b/ca/client_db/secmod.db
new file mode 100644
index 0000000000000000000000000000000000000000..b6e81ca751dff9ba46a094715f7b4f507fbc7a6c
GIT binary patch
literal 16384
zcmeI&u}Z^07{Kw*R!RqnE^Zx$77N%-690cmD-&dD;yhx4R^%UjVIGMyr;p?7OktxbiVaCawueF+*`>)B|M7MeD
zYuESU8?DA^IGOuuF^j{}G$r(EGT5l&HVnU4bE(AETYqw$Pfd1i=24N%$|TR~755JR
nxxMu5RZngE5x@Q3$C5w*0R#|0009ILKmY**5I_Kd|1R(eN?b*1
literal 0
HcmV?d00001
diff --git a/ca/client_db/server.crt b/ca/client_db/server.crt
new file mode 100644
index 0000000000000000000000000000000000000000..55a697de4dd0f14e2c2bc165d75881be0d4a6060
GIT binary patch
literal 325
zcmXqLVstcUe7=C0iIItkm0{J{*&+s9Y#dr`9_MUXn3)VD48;sY*qB3En1y*me1diT
z6oT^eOB9?P4dldm4b2TK3=ND7jm!*9qCi|jLpT>G!)?F`(#a;wLo3-^CsHh1$IKKB#9Kc2he6cYB=U473>
zy?2@2r=Dg}WUn!MG8niqDKfk+5ip*v5+*pwXJ1I+x@9pdjQwBjt9a|^Ge7Uyyp3tn
pKqUvxM=UAResOwFsMVYwYwm8YI(Y5$b@r;D37dR$uHQH-3jmk5Y~BC>
literal 0
HcmV?d00001
diff --git a/ca/noise.txt b/ca/noise.txt
new file mode 100644
index 0000000..167604b
--- /dev/null
+++ b/ca/noise.txt
@@ -0,0 +1,250 @@
+UID PID PPID C STIME TTY TIME CMD
+root 1 0 0 Jul21 ? 00:00:25 /sbin/init
+root 2 0 0 Jul21 ? 00:00:00 [kthreadd]
+root 4 2 0 Jul21 ? 00:00:00 [kworker/0:0H]
+root 6 2 0 Jul21 ? 00:00:00 [mm_percpu_wq]
+root 7 2 0 Jul21 ? 00:00:36 [ksoftirqd/0]
+root 8 2 0 Jul21 ? 00:10:34 [rcu_preempt]
+root 9 2 0 Jul21 ? 00:00:00 [rcu_sched]
+root 10 2 0 Jul21 ? 00:00:00 [rcu_bh]
+root 11 2 0 Jul21 ? 00:00:01 [migration/0]
+root 12 2 0 Jul21 ? 00:00:06 [watchdog/0]
+root 13 2 0 Jul21 ? 00:00:00 [cpuhp/0]
+root 14 2 0 Jul21 ? 00:00:00 [cpuhp/1]
+root 15 2 0 Jul21 ? 00:00:05 [watchdog/1]
+root 16 2 0 Jul21 ? 00:00:01 [migration/1]
+root 17 2 0 Jul21 ? 00:00:03 [ksoftirqd/1]
+root 19 2 0 Jul21 ? 00:00:00 [kworker/1:0H]
+root 20 2 0 Jul21 ? 00:00:00 [cpuhp/2]
+root 21 2 0 Jul21 ? 00:00:06 [watchdog/2]
+root 22 2 0 Jul21 ? 00:00:01 [migration/2]
+root 23 2 0 Jul21 ? 00:00:03 [ksoftirqd/2]
+root 25 2 0 Jul21 ? 00:00:00 [kworker/2:0H]
+root 26 2 0 Jul21 ? 00:00:00 [cpuhp/3]
+root 27 2 0 Jul21 ? 00:00:06 [watchdog/3]
+root 28 2 0 Jul21 ? 00:00:01 [migration/3]
+root 29 2 0 Jul21 ? 00:00:01 [ksoftirqd/3]
+root 31 2 0 Jul21 ? 00:00:00 [kworker/3:0H]
+root 32 2 0 Jul21 ? 00:00:00 [kdevtmpfs]
+root 33 2 0 Jul21 ? 00:00:00 [netns]
+root 36 2 0 Jul21 ? 00:00:02 [khungtaskd]
+root 37 2 0 Jul21 ? 00:00:00 [oom_reaper]
+root 38 2 0 Jul21 ? 00:00:00 [writeback]
+root 39 2 0 Jul21 ? 00:00:00 [kcompactd0]
+root 40 2 0 Jul21 ? 00:00:00 [ksmd]
+root 41 2 0 Jul21 ? 00:08:49 [khugepaged]
+root 42 2 0 Jul21 ? 00:00:00 [crypto]
+root 43 2 0 Jul21 ? 00:00:00 [kintegrityd]
+root 44 2 0 Jul21 ? 00:00:00 [bioset]
+root 45 2 0 Jul21 ? 00:00:00 [kblockd]
+root 46 2 0 Jul21 ? 00:00:00 [devfreq_wq]
+root 47 2 0 Jul21 ? 00:00:00 [watchdogd]
+root 49 2 0 Jul21 ? 00:04:05 [kswapd0]
+root 50 2 0 Jul21 ? 00:00:00 [bioset]
+root 63 2 0 Jul21 ? 00:00:00 [kthrotld]
+root 64 2 0 Jul21 ? 00:00:00 [ipv6_addrconf]
+root 104 2 0 Jul21 ? 00:00:00 [ata_sff]
+root 143 2 0 Jul21 ? 00:00:00 [scsi_eh_0]
+root 144 2 0 Jul21 ? 00:00:00 [scsi_tmf_0]
+root 145 2 0 Jul21 ? 00:00:00 [scsi_eh_1]
+root 146 2 0 Jul21 ? 00:00:00 [scsi_tmf_1]
+root 147 2 0 Jul21 ? 00:00:00 [scsi_eh_2]
+root 148 2 0 Jul21 ? 00:00:00 [scsi_tmf_2]
+root 149 2 0 Jul21 ? 00:00:00 [scsi_eh_3]
+root 150 2 0 Jul21 ? 00:00:00 [scsi_tmf_3]
+root 151 2 0 Jul21 ? 00:00:00 [scsi_eh_4]
+root 152 2 0 Jul21 ? 00:00:00 [scsi_tmf_4]
+root 153 2 0 Jul21 ? 00:00:00 [scsi_eh_5]
+root 154 2 0 Jul21 ? 00:00:00 [scsi_tmf_5]
+root 162 2 0 Jul21 ? 00:00:00 [bioset]
+root 166 2 0 Jul21 ? 00:02:18 [kworker/0:1H]
+root 186 2 0 Jul21 ? 00:00:00 [kdmflush]
+root 188 2 0 Jul21 ? 00:00:00 [bioset]
+root 189 2 0 Jul21 ? 00:00:00 [kcryptd_io]
+root 190 2 0 Jul21 ? 00:00:00 [kcryptd]
+root 191 2 0 Jul21 ? 00:02:23 [dmcrypt_write]
+root 193 2 0 Jul21 ? 00:00:00 [bioset]
+root 199 2 0 Jul21 ? 00:00:00 [kdmflush]
+root 200 2 0 Jul21 ? 00:00:00 [bioset]
+root 204 2 0 Jul21 ? 00:00:00 [kdmflush]
+root 205 2 0 Jul21 ? 00:00:00 [bioset]
+root 208 2 0 Jul21 ? 00:00:00 [kdmflush]
+root 212 2 0 Jul21 ? 00:00:00 [bioset]
+root 223 2 0 Jul21 ? 00:00:02 [kworker/2:1H]
+root 238 2 0 Jul21 ? 00:00:17 [jbd2/dm-2-8]
+root 239 2 0 Jul21 ? 00:00:00 [ext4-rsv-conver]
+root 262 1 0 Jul21 ? 00:00:41 /usr/lib/systemd/systemd-journald
+root 270 2 0 Jul21 ? 00:00:00 [ktpacpid]
+root 273 2 0 Jul21 ? 00:00:03 [kworker/1:1H]
+root 274 2 0 Jul21 ? 00:00:00 [iprt-VBoxWQueue]
+root 276 2 0 Jul21 ? 00:00:02 [kworker/3:1H]
+root 277 1 0 Jul21 ? 00:00:04 /usr/lib/systemd/systemd-udevd
+root 278 2 0 Jul21 ? 00:00:01 [iprt-VBoxTscThr]
+root 331 2 0 Jul21 ? 00:00:00 [acpi_thermal_pm]
+root 480 2 0 Jul21 ? 00:00:00 [ext4-rsv-conver]
+root 505 2 0 Jul21 ? 00:00:00 [cfg80211]
+root 529 2 0 Jul21 ? 01:56:15 [irq/36-iwlwifi]
+root 568 2 0 Jul21 ? 00:00:00 [i915/signal:0]
+root 569 2 0 Jul21 ? 00:00:00 [i915/signal:1]
+root 576 2 0 Jul21 ? 00:00:00 [i915/signal:2]
+hubert 658 31866 0 Aug04 ? 00:00:06 /usr/lib/opera/opera --type=renderer --field-trial-handle=1 --primordial-pipe-token=289E0D52C0B48B885CD429EE8688F4B6 --lang=en-US --disable-client-side-phishing-detection --enable-offline-auto-reload --enable-offline-auto-reload-visible-only --enable-pinch --num-raster-threads=2 --enable-main-frame-before-activation --content-image-texture-target=0,0,3553;0,1,3553;0,2,3553;0,3,3553;0,4,3553;0,5,3553;0,6,3553;0,7,3553;0,8,3553;0,9,3553;0,10,3553;0,11,3553;0,12,3553;0,13,3553;0,14,3553;0,15,3553;0,16,3553;1,0,3553;1,1,3553;1,2,3553;1,3,3553;1,4,3553;1,5,3553;1,6,3553;1,7,3553;1,8,3553;1,9,3553;1,10,3553;1,11,3553;1,12,3553;1,13,3553;1,14,3553;1,15,3553;1,16,3553;2,0,3553;2,1,3553;2,2,3553;2,3,3553;2,4,3553;2,5,3553;2,6,3553;2,7,3553;2,8,3553;2,9,3553;2,10,3553;2,11,3553;2,12,3553;2,13,3553;2,14,3553;2,15,3553;2,16,3553;3,0,3553;3,1,3553;3,2,3553;3,3,3553;3,4,3553;3,5,3553;3,6,3553;3,7,3553;3,8,3553;3,9,3553;3,10,3553;3,11,3553;3,12,3553;3,13,3553;3,
+root 741 1 0 Jul21 ? 00:00:00 /usr/bin/lvmetad -f
+root 1105 2 0 Jul21 ? 00:00:41 [jbd2/dm-3-8]
+root 1106 2 0 Jul21 ? 00:00:00 [ext4-rsv-conver]
+root 1114 1 0 Jul21 ? 00:03:49 /usr/bin/thinkfan -n -s5 -q
+root 1115 1 0 Jul21 ? 00:00:06 /usr/bin/crond -n
+dbus 1116 1 0 Jul21 ? 00:15:11 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
+root 1119 1 0 Jul21 ? 00:27:54 /usr/bin/python2 -O /usr/share/wicd/daemon/wicd-daemon.py --no-daemon
+root 1121 1 0 Jul21 ? 00:01:00 /usr/bin/acpid --foreground --netlink
+root 1123 1 0 Jul21 ? 00:00:04 /usr/lib/systemd/systemd-logind
+root 1125 1 0 Jul21 ? 00:00:32 /usr/bin/syslog-ng -F
+root 1592 1 0 Jul21 ? 01:09:59 /usr/bin/dockerd -H fd://
+root 1595 1 0 Jul21 ? 00:00:00 /usr/bin/sshd -D
+root 1600 2 0 Jul21 ? 00:05:17 [kworker/u17:0]
+root 1610 1 0 Jul21 tty1 00:00:00 /sbin/agetty --noclear tty1 linux
+root 1611 1 0 Jul21 ? 00:00:00 /usr/bin/slim -nodaemon
+root 1660 1611 0 Jul21 tty7 04:42:03 /usr/lib/xorg-server/Xorg -nolisten tcp vt07 -auth /var/run/slim.auth
+root 1678 2 0 Jul21 ? 00:00:21 [kworker/u17:1]
+root 1715 1119 0 Jul21 ? 00:12:10 /usr/bin/python2 -O /usr/share/wicd/daemon/monitor.py
+hubert 2066 1 0 Jul21 ? 00:00:10 /usr/lib/systemd/systemd --user
+hubert 2067 2066 0 Jul21 ? 00:00:00 (sd-pam)
+hubert 2078 1611 0 Jul21 ? 00:02:49 i3
+hubert 2085 2066 0 Jul21 ? 00:00:07 /usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation
+hubert 2087 1 0 Jul21 ? 00:00:02 gnome-keyring-daemon
+hubert 2094 1 0 Jul21 ? 00:00:55 xfce4-clipman
+hubert 2102 1 0 Jul21 ? 00:01:00 orage
+hubert 2119 1 0 Jul21 ? 00:01:05 i3bar --bar_id=bar-0 --socket=/run/user/1000/i3/ipc-socket.2078
+hubert 2123 2119 0 Jul21 ? 00:05:15 i3status
+hubert 2128 2066 0 Jul21 ? 00:00:00 /usr/lib/at-spi2-core/at-spi-bus-launcher
+hubert 2134 2128 0 Jul21 ? 00:00:28 /usr/bin/dbus-daemon --config-file=/usr/share/defaults/at-spi2/accessibility.conf --nofork --print-address 3
+hubert 2140 2066 0 Jul21 ? 00:00:00 /usr/lib/xfce4/xfconf/xfconfd
+hubert 2145 2066 0 Jul21 ? 00:01:44 /usr/lib/at-spi2-core/at-spi2-registryd --use-gnome-session
+hubert 2210 2066 0 Jul21 ? 00:00:06 /usr/lib/GConf/gconfd-2
+hubert 2414 2066 0 Jul21 ? 00:01:16 /usr/bin/gpg-agent --supervised
+hubert 3483 1 0 Aug03 ? 00:00:01 xterm
+hubert 3500 3483 0 Aug03 pts/10 00:00:02 zsh
+hubert 4605 1 0 Aug05 ? 00:00:29 evince /tmp/mozilla_hubert0/paper.pdf
+hubert 5333 11028 0 12:13 pts/22 00:03:29 node /home/hubert/.node_modules/bin/truffle-testrpc
+hubert 5704 1 0 Aug04 ? 00:00:00 /bin/zsh
+hubert 5717 5704 0 Aug04 ? 00:45:14 /usr/lib/thunderbird/thunderbird
+hubert 6344 31866 0 12:43 ? 00:00:40 /usr/lib/opera/opera --type=renderer --field-trial-handle=1 --primordial-pipe-token=81CA01159608F846CD9C203772B048B5 --lang=en-US --disable-client-side-phishing-detection --enable-offline-auto-reload --enable-offline-auto-reload-visible-only --enable-pinch --num-raster-threads=2 --enable-main-frame-before-activation --content-image-texture-target=0,0,3553;0,1,3553;0,2,3553;0,3,3553;0,4,3553;0,5,3553;0,6,3553;0,7,3553;0,8,3553;0,9,3553;0,10,3553;0,11,3553;0,12,3553;0,13,3553;0,14,3553;0,15,3553;0,16,3553;1,0,3553;1,1,3553;1,2,3553;1,3,3553;1,4,3553;1,5,3553;1,6,3553;1,7,3553;1,8,3553;1,9,3553;1,10,3553;1,11,3553;1,12,3553;1,13,3553;1,14,3553;1,15,3553;1,16,3553;2,0,3553;2,1,3553;2,2,3553;2,3,3553;2,4,3553;2,5,3553;2,6,3553;2,7,3553;2,8,3553;2,9,3553;2,10,3553;2,11,3553;2,12,3553;2,13,3553;2,14,3553;2,15,3553;2,16,3553;3,0,3553;3,1,3553;3,2,3553;3,3,3553;3,4,3553;3,5,3553;3,6,3553;3,7,3553;3,8,3553;3,9,3553;3,10,3553;3,11,3553;3,12,3553;3,13,3553;3,
+hubert 6835 27197 0 Aug07 pts/6 00:00:19 vi main.tex
+root 9355 2 0 Aug09 ? 00:00:06 [kworker/3:0]
+hubert 9443 1 0 Aug07 ? 00:00:01 xterm
+hubert 9460 9443 0 Aug07 pts/4 00:00:00 zsh
+hubert 9561 1 0 Aug03 ? 00:00:00 xterm
+hubert 9578 9561 0 Aug03 pts/7 00:00:00 zsh
+hubert 9748 31866 0 14:26 ? 00:00:25 /usr/lib/opera/opera --type=renderer --field-trial-handle=1 --primordial-pipe-token=BD83BF238B871A07F2908BCCA3D20319 --lang=en-US --disable-client-side-phishing-detection --enable-offline-auto-reload --enable-offline-auto-reload-visible-only --enable-pinch --num-raster-threads=2 --enable-main-frame-before-activation --content-image-texture-target=0,0,3553;0,1,3553;0,2,3553;0,3,3553;0,4,3553;0,5,3553;0,6,3553;0,7,3553;0,8,3553;0,9,3553;0,10,3553;0,11,3553;0,12,3553;0,13,3553;0,14,3553;0,15,3553;0,16,3553;1,0,3553;1,1,3553;1,2,3553;1,3,3553;1,4,3553;1,5,3553;1,6,3553;1,7,3553;1,8,3553;1,9,3553;1,10,3553;1,11,3553;1,12,3553;1,13,3553;1,14,3553;1,15,3553;1,16,3553;2,0,3553;2,1,3553;2,2,3553;2,3,3553;2,4,3553;2,5,3553;2,6,3553;2,7,3553;2,8,3553;2,9,3553;2,10,3553;2,11,3553;2,12,3553;2,13,3553;2,14,3553;2,15,3553;2,16,3553;3,0,3553;3,1,3553;3,2,3553;3,3,3553;3,4,3553;3,5,3553;3,6,3553;3,7,3553;3,8,3553;3,9,3553;3,10,3553;3,11,3553;3,12,3553;3,13,3553;3,
+hubert 9767 31866 0 14:26 ? 00:01:24 /usr/lib/opera/opera --type=renderer --field-trial-handle=1 --primordial-pipe-token=F6D7C3BABECDB0E552584085A2C9F235 --lang=en-US --disable-client-side-phishing-detection --enable-offline-auto-reload --enable-offline-auto-reload-visible-only --enable-pinch --num-raster-threads=2 --enable-main-frame-before-activation --content-image-texture-target=0,0,3553;0,1,3553;0,2,3553;0,3,3553;0,4,3553;0,5,3553;0,6,3553;0,7,3553;0,8,3553;0,9,3553;0,10,3553;0,11,3553;0,12,3553;0,13,3553;0,14,3553;0,15,3553;0,16,3553;1,0,3553;1,1,3553;1,2,3553;1,3,3553;1,4,3553;1,5,3553;1,6,3553;1,7,3553;1,8,3553;1,9,3553;1,10,3553;1,11,3553;1,12,3553;1,13,3553;1,14,3553;1,15,3553;1,16,3553;2,0,3553;2,1,3553;2,2,3553;2,3,3553;2,4,3553;2,5,3553;2,6,3553;2,7,3553;2,8,3553;2,9,3553;2,10,3553;2,11,3553;2,12,3553;2,13,3553;2,14,3553;2,15,3553;2,16,3553;3,0,3553;3,1,3553;3,2,3553;3,3,3553;3,4,3553;3,5,3553;3,6,3553;3,7,3553;3,8,3553;3,9,3553;3,10,3553;3,11,3553;3,12,3553;3,13,3553;3,
+hubert 10088 9460 0 Aug07 pts/4 00:00:00 vi fig_reorderingattack.tex
+hubert 10409 1 0 Jul31 ? 00:00:00 xterm
+hubert 10426 10409 0 Jul31 pts/3 00:00:00 zsh
+hubert 10463 10426 0 Jul31 pts/3 00:00:00 vi false_positives.txt
+hubert 10630 1 0 Jul28 ? 00:00:01 xterm
+hubert 10637 10630 0 Jul28 pts/21 00:00:00 zsh
+hubert 11011 1 0 Jul28 ? 00:00:01 xterm
+hubert 11028 11011 0 Jul28 pts/22 00:00:00 zsh
+hubert 13195 1 0 Jul28 ? 00:00:00 xterm
+hubert 13212 13195 0 Jul28 pts/2 00:00:00 zsh
+hubert 13265 13212 0 Jul28 pts/2 00:00:00 vi imported/ethereum/Wallet.sol
+hubert 14464 1 0 Jul28 ? 00:00:01 xterm
+hubert 14481 14464 0 Jul28 pts/23 00:00:00 zsh
+root 14578 2 0 Aug08 ? 00:00:00 [irq/32-mei_me]
+root 14579 2 0 Aug08 ? 00:00:00 [irq/16-mmc0]
+hubert 14995 2066 0 Jul24 ? 00:00:00 /usr/lib/dconf/dconf-service
+root 15058 2 0 17:01 ? 00:00:00 [kworker/1:1]
+hubert 15879 1 0 Jul24 ? 00:00:12 xterm
+hubert 15896 15879 0 Jul24 pts/5 00:00:02 zsh
+root 16071 1 0 Aug08 ? 00:01:53 dhcpcd
+hubert 16132 1 0 Aug08 ? 00:00:40 xterm
+hubert 16139 16132 0 Aug08 pts/13 00:00:00 zsh
+hubert 16550 1 0 17:39 ? 00:00:01 xterm
+hubert 16568 16550 0 17:39 pts/0 00:00:02 zsh
+hubert 16875 14481 0 Jul28 pts/23 00:00:08 node /home/hubert/.node_modules/bin/truffle console
+hubert 17622 31866 0 Aug09 ? 00:00:17 /usr/lib/opera/opera --type=renderer --field-trial-handle=1 --primordial-pipe-token=053D905D833EC7568B19D51B18A3835D --lang=en-US --disable-client-side-phishing-detection --enable-offline-auto-reload --enable-offline-auto-reload-visible-only --enable-pinch --num-raster-threads=2 --enable-main-frame-before-activation --content-image-texture-target=0,0,3553;0,1,3553;0,2,3553;0,3,3553;0,4,3553;0,5,3553;0,6,3553;0,7,3553;0,8,3553;0,9,3553;0,10,3553;0,11,3553;0,12,3553;0,13,3553;0,14,3553;0,15,3553;0,16,3553;1,0,3553;1,1,3553;1,2,3553;1,3,3553;1,4,3553;1,5,3553;1,6,3553;1,7,3553;1,8,3553;1,9,3553;1,10,3553;1,11,3553;1,12,3553;1,13,3553;1,14,3553;1,15,3553;1,16,3553;2,0,3553;2,1,3553;2,2,3553;2,3,3553;2,4,3553;2,5,3553;2,6,3553;2,7,3553;2,8,3553;2,9,3553;2,10,3553;2,11,3553;2,12,3553;2,13,3553;2,14,3553;2,15,3553;2,16,3553;3,0,3553;3,1,3553;3,2,3553;3,3,3553;3,4,3553;3,5,3553;3,6,3553;3,7,3553;3,8,3553;3,9,3553;3,10,3553;3,11,3553;3,12,3553;3,13,3553;3,
+hubert 17832 1 0 Aug08 ? 00:00:00 xterm
+hubert 17849 17832 0 Aug08 pts/9 00:00:00 zsh
+hubert 17867 17849 0 Aug08 pts/9 00:00:00 vi fallback_and_more.sol
+hubert 18298 1 0 Aug08 ? 00:00:00 xterm
+hubert 18315 18298 0 Aug08 pts/16 00:00:00 zsh
+hubert 18345 1 0 Aug09 ? 00:00:04 xterm
+hubert 18362 18345 0 Aug09 pts/19 00:00:02 zsh
+hubert 18415 18315 0 Aug08 pts/16 00:00:47 evince CES_full-2003-2.pdf
+hubert 18906 10637 0 Jul28 pts/21 00:00:00 vi Reservation.sol
+root 19010 1592 0 Aug03 ? 00:17:34 docker-containerd -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/containerd --shim docker-containerd-shim --runtime docker-runc
+hubert 19469 31866 0 Aug09 ? 00:00:26 /usr/lib/opera/opera --type=renderer --field-trial-handle=1 --primordial-pipe-token=E019B288BCD40AA097039098D1899850 --lang=en-US --disable-client-side-phishing-detection --enable-offline-auto-reload --enable-offline-auto-reload-visible-only --enable-pinch --num-raster-threads=2 --enable-main-frame-before-activation --content-image-texture-target=0,0,3553;0,1,3553;0,2,3553;0,3,3553;0,4,3553;0,5,3553;0,6,3553;0,7,3553;0,8,3553;0,9,3553;0,10,3553;0,11,3553;0,12,3553;0,13,3553;0,14,3553;0,15,3553;0,16,3553;1,0,3553;1,1,3553;1,2,3553;1,3,3553;1,4,3553;1,5,3553;1,6,3553;1,7,3553;1,8,3553;1,9,3553;1,10,3553;1,11,3553;1,12,3553;1,13,3553;1,14,3553;1,15,3553;1,16,3553;2,0,3553;2,1,3553;2,2,3553;2,3,3553;2,4,3553;2,5,3553;2,6,3553;2,7,3553;2,8,3553;2,9,3553;2,10,3553;2,11,3553;2,12,3553;2,13,3553;2,14,3553;2,15,3553;2,16,3553;3,0,3553;3,1,3553;3,2,3553;3,3,3553;3,4,3553;3,5,3553;3,6,3553;3,7,3553;3,8,3553;3,9,3553;3,10,3553;3,11,3553;3,12,3553;3,13,3553;3,
+root 19522 1 0 Jul22 ? 00:00:36 /usr/lib/upower/upowerd
+hubert 19927 1 0 Jul24 ? 00:00:01 xterm
+hubert 19945 19927 0 Jul24 pts/8 00:00:01 zsh
+hubert 19959 1 0 Aug09 ? 00:00:05 xterm
+hubert 19976 19959 0 Aug09 pts/1 00:00:03 zsh
+root 21015 2 0 21:09 ? 00:00:05 [kworker/u16:2]
+hubert 21085 1 0 21:10 ? 00:00:00 xterm
+hubert 21102 21085 0 21:10 pts/14 00:00:00 zsh
+hubert 21668 31866 0 21:28 ? 00:00:15 /usr/lib/opera/opera --type=renderer --field-trial-handle=1 --primordial-pipe-token=66CFEC1C291E00B21A6FD059C0C8CAFF --lang=en-US --disable-client-side-phishing-detection --enable-offline-auto-reload --enable-offline-auto-reload-visible-only --enable-pinch --num-raster-threads=2 --enable-main-frame-before-activation --content-image-texture-target=0,0,3553;0,1,3553;0,2,3553;0,3,3553;0,4,3553;0,5,3553;0,6,3553;0,7,3553;0,8,3553;0,9,3553;0,10,3553;0,11,3553;0,12,3553;0,13,3553;0,14,3553;0,15,3553;0,16,3553;1,0,3553;1,1,3553;1,2,3553;1,3,3553;1,4,3553;1,5,3553;1,6,3553;1,7,3553;1,8,3553;1,9,3553;1,10,3553;1,11,3553;1,12,3553;1,13,3553;1,14,3553;1,15,3553;1,16,3553;2,0,3553;2,1,3553;2,2,3553;2,3,3553;2,4,3553;2,5,3553;2,6,3553;2,7,3553;2,8,3553;2,9,3553;2,10,3553;2,11,3553;2,12,3553;2,13,3553;2,14,3553;2,15,3553;2,16,3553;3,0,3553;3,1,3553;3,2,3553;3,3,3553;3,4,3553;3,5,3553;3,6,3553;3,7,3553;3,8,3553;3,9,3553;3,10,3553;3,11,3553;3,12,3553;3,13,3553;3,
+root 21852 2 0 21:31 ? 00:00:00 [kworker/2:0]
+hubert 21954 1 0 21:32 ? 00:00:00 xterm
+hubert 21971 21954 0 21:32 pts/11 00:00:00 zsh
+hubert 22135 1 0 Aug04 ? 00:01:44 evince main.pdf
+hubert 22139 2066 0 Aug04 ? 00:00:00 /usr/lib/evince/evinced
+root 22752 2 0 Aug04 ? 00:00:00 [bioset]
+hubert 23037 16139 3 22:05 pts/13 00:02:43 mplayer -noar -nojoystick -nolirc -fs -loop 0 /home/hubert/mukke/miles_children.mp3
+hubert 23500 31866 0 Aug04 ? 00:01:08 /usr/lib/opera/opera --type=renderer --field-trial-handle=1 --primordial-pipe-token=001F8195543E36AEC0F84D5FC220A82E --lang=en-US --disable-client-side-phishing-detection --enable-offline-auto-reload --enable-offline-auto-reload-visible-only --enable-pinch --num-raster-threads=2 --enable-main-frame-before-activation --content-image-texture-target=0,0,3553;0,1,3553;0,2,3553;0,3,3553;0,4,3553;0,5,3553;0,6,3553;0,7,3553;0,8,3553;0,9,3553;0,10,3553;0,11,3553;0,12,3553;0,13,3553;0,14,3553;0,15,3553;0,16,3553;1,0,3553;1,1,3553;1,2,3553;1,3,3553;1,4,3553;1,5,3553;1,6,3553;1,7,3553;1,8,3553;1,9,3553;1,10,3553;1,11,3553;1,12,3553;1,13,3553;1,14,3553;1,15,3553;1,16,3553;2,0,3553;2,1,3553;2,2,3553;2,3,3553;2,4,3553;2,5,3553;2,6,3553;2,7,3553;2,8,3553;2,9,3553;2,10,3553;2,11,3553;2,12,3553;2,13,3553;2,14,3553;2,15,3553;2,16,3553;3,0,3553;3,1,3553;3,2,3553;3,3,3553;3,4,3553;3,5,3553;3,6,3553;3,7,3553;3,8,3553;3,9,3553;3,10,3553;3,11,3553;3,12,3553;3,13,3553;3,
+hubert 24040 1 0 Aug07 ? 00:00:00 /bin/zsh
+hubert 24043 24040 8 Aug07 ? 07:01:53 /usr/lib/firefox/firefox
+hubert 24160 1 0 Aug07 ? 00:00:00 /bin/zsh
+hubert 24164 24160 0 Aug07 ? 00:00:00 /usr/lib/eclipse/eclipse
+hubert 24165 24164 3 Aug07 ? 02:31:10 /usr/bin/java -Dosgi.requiredJavaVersion=1.8 -Dosgi.instance.area.default=@user.home/eclipse-workspace -XX:+UseG1GC -XX:+UseStringDeduplication -Dosgi.requiredJavaVersion=1.8 -Xms256m -Xmx1024m -jar /usr/lib/eclipse//plugins/org.eclipse.equinox.launcher_1.4.0.v20161219-1356.jar -os linux -ws gtk -arch x86_64 -showsplash /usr/lib/eclipse//plugins/org.eclipse.epp.package.common_4.7.0.20170620-1800/splash.bmp -launcher /usr/lib/eclipse/eclipse -name Eclipse --launcher.library /usr/lib/eclipse//plugins/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.1.500.v20170531-1133/eclipse_1624.so -startup /usr/lib/eclipse//plugins/org.eclipse.equinox.launcher_1.4.0.v20161219-1356.jar --launcher.appendVmargs -exitdata 11440014 -product org.eclipse.epp.package.java.product -vm /usr/bin/java -vmargs -Dosgi.requiredJavaVersion=1.8 -Dosgi.instance.area.default=@user.home/eclipse-workspace -XX:+UseG1GC -XX:+UseStringDeduplication -Dosgi.requiredJavaVersion=1.8 -Xms256m -Xmx1024m -jar /usr/lib/eclipse//plugins/org.eclipse.equinox.launcher_1.4.0.v20161219-1356.jar
+hubert 24219 19976 0 22:21 pts/1 00:00:00 vi README.md
+root 24564 2 0 22:33 ? 00:00:02 [kworker/0:0]
+hubert 24614 31866 4 22:35 ? 00:02:14 /usr/lib/opera/opera --type=renderer --field-trial-handle=1 --primordial-pipe-token=CB478A87C4D17F08CB28A14B889B0DB9 --lang=en-US --disable-client-side-phishing-detection --enable-offline-auto-reload --enable-offline-auto-reload-visible-only --enable-pinch --num-raster-threads=2 --enable-main-frame-before-activation --content-image-texture-target=0,0,3553;0,1,3553;0,2,3553;0,3,3553;0,4,3553;0,5,3553;0,6,3553;0,7,3553;0,8,3553;0,9,3553;0,10,3553;0,11,3553;0,12,3553;0,13,3553;0,14,3553;0,15,3553;0,16,3553;1,0,3553;1,1,3553;1,2,3553;1,3,3553;1,4,3553;1,5,3553;1,6,3553;1,7,3553;1,8,3553;1,9,3553;1,10,3553;1,11,3553;1,12,3553;1,13,3553;1,14,3553;1,15,3553;1,16,3553;2,0,3553;2,1,3553;2,2,3553;2,3,3553;2,4,3553;2,5,3553;2,6,3553;2,7,3553;2,8,3553;2,9,3553;2,10,3553;2,11,3553;2,12,3553;2,13,3553;2,14,3553;2,15,3553;2,16,3553;3,0,3553;3,1,3553;3,2,3553;3,3,3553;3,4,3553;3,5,3553;3,6,3553;3,7,3553;3,8,3553;3,9,3553;3,10,3553;3,11,3553;3,12,3553;3,13,3553;3,
+root 24902 2 0 22:43 ? 00:00:02 [kworker/u16:4]
+hubert 24910 31866 1 22:43 ? 00:00:38 /usr/lib/opera/opera --type=renderer --field-trial-handle=1 --primordial-pipe-token=039D355B2BEABA43E8F3BF515D291D93 --lang=en-US --disable-client-side-phishing-detection --enable-offline-auto-reload --enable-offline-auto-reload-visible-only --enable-pinch --num-raster-threads=2 --enable-main-frame-before-activation --content-image-texture-target=0,0,3553;0,1,3553;0,2,3553;0,3,3553;0,4,3553;0,5,3553;0,6,3553;0,7,3553;0,8,3553;0,9,3553;0,10,3553;0,11,3553;0,12,3553;0,13,3553;0,14,3553;0,15,3553;0,16,3553;1,0,3553;1,1,3553;1,2,3553;1,3,3553;1,4,3553;1,5,3553;1,6,3553;1,7,3553;1,8,3553;1,9,3553;1,10,3553;1,11,3553;1,12,3553;1,13,3553;1,14,3553;1,15,3553;1,16,3553;2,0,3553;2,1,3553;2,2,3553;2,3,3553;2,4,3553;2,5,3553;2,6,3553;2,7,3553;2,8,3553;2,9,3553;2,10,3553;2,11,3553;2,12,3553;2,13,3553;2,14,3553;2,15,3553;2,16,3553;3,0,3553;3,1,3553;3,2,3553;3,3,3553;3,4,3553;3,5,3553;3,6,3553;3,7,3553;3,8,3553;3,9,3553;3,10,3553;3,11,3553;3,12,3553;3,13,3553;3,
+hubert 25149 1 0 Aug09 ? 00:00:00 /bin/zsh
+hubert 25152 25149 0 Aug09 ? 00:00:47 evince
+hubert 25168 1 0 Aug09 ? 00:00:10 xterm
+hubert 25185 25168 0 Aug09 pts/17 00:00:00 zsh
+hubert 25209 1 0 Aug07 ? 00:00:00 /usr/lib/webkit2gtk-4.0/WebKitNetworkProcess 150
+root 25340 2 0 22:52 ? 00:00:01 [kworker/u16:5]
+root 25643 2 0 22:57 ? 00:00:00 [kworker/0:2]
+root 25644 2 0 22:57 ? 00:00:00 [kworker/2:2]
+root 25783 2 0 23:00 ? 00:00:01 [kworker/u16:1]
+hubert 26069 1 0 23:04 ? 00:00:00 xterm
+hubert 26086 26069 0 23:04 pts/15 00:00:00 zsh
+hubert 26140 1 0 Aug07 ? 00:00:03 /usr/lib/webkit2gtk-4.0/WebKitWebProcess 160
+hubert 26276 31866 18 23:08 ? 00:03:05 /usr/lib/opera/opera --type=renderer --field-trial-handle=1 --primordial-pipe-token=FF9838BC3C7B81643EC2018E40955224 --lang=en-US --disable-client-side-phishing-detection --enable-offline-auto-reload --enable-offline-auto-reload-visible-only --enable-pinch --num-raster-threads=2 --enable-main-frame-before-activation --content-image-texture-target=0,0,3553;0,1,3553;0,2,3553;0,3,3553;0,4,3553;0,5,3553;0,6,3553;0,7,3553;0,8,3553;0,9,3553;0,10,3553;0,11,3553;0,12,3553;0,13,3553;0,14,3553;0,15,3553;0,16,3553;1,0,3553;1,1,3553;1,2,3553;1,3,3553;1,4,3553;1,5,3553;1,6,3553;1,7,3553;1,8,3553;1,9,3553;1,10,3553;1,11,3553;1,12,3553;1,13,3553;1,14,3553;1,15,3553;1,16,3553;2,0,3553;2,1,3553;2,2,3553;2,3,3553;2,4,3553;2,5,3553;2,6,3553;2,7,3553;2,8,3553;2,9,3553;2,10,3553;2,11,3553;2,12,3553;2,13,3553;2,14,3553;2,15,3553;2,16,3553;3,0,3553;3,1,3553;3,2,3553;3,3,3553;3,4,3553;3,5,3553;3,6,3553;3,7,3553;3,8,3553;3,9,3553;3,10,3553;3,11,3553;3,12,3553;3,13,3553;3,
+root 26323 2 0 23:09 ? 00:00:01 [kworker/u16:7]
+hubert 26351 31866 0 23:11 ? 00:00:05 /usr/lib/opera/opera --type=renderer --field-trial-handle=1 --primordial-pipe-token=FD05C72A42976CBC6B85103EFAE1B437 --lang=en-US --disable-client-side-phishing-detection --enable-offline-auto-reload --enable-offline-auto-reload-visible-only --enable-pinch --num-raster-threads=2 --enable-main-frame-before-activation --content-image-texture-target=0,0,3553;0,1,3553;0,2,3553;0,3,3553;0,4,3553;0,5,3553;0,6,3553;0,7,3553;0,8,3553;0,9,3553;0,10,3553;0,11,3553;0,12,3553;0,13,3553;0,14,3553;0,15,3553;0,16,3553;1,0,3553;1,1,3553;1,2,3553;1,3,3553;1,4,3553;1,5,3553;1,6,3553;1,7,3553;1,8,3553;1,9,3553;1,10,3553;1,11,3553;1,12,3553;1,13,3553;1,14,3553;1,15,3553;1,16,3553;2,0,3553;2,1,3553;2,2,3553;2,3,3553;2,4,3553;2,5,3553;2,6,3553;2,7,3553;2,8,3553;2,9,3553;2,10,3553;2,11,3553;2,12,3553;2,13,3553;2,14,3553;2,15,3553;2,16,3553;3,0,3553;3,1,3553;3,2,3553;3,3,3553;3,4,3553;3,5,3553;3,6,3553;3,7,3553;3,8,3553;3,9,3553;3,10,3553;3,11,3553;3,12,3553;3,13,3553;3,
+root 26389 2 0 23:12 ? 00:00:00 [kworker/1:2]
+root 26430 2 0 23:13 ? 00:00:00 [kworker/3:1]
+hubert 26621 16568 0 23:19 pts/0 00:00:00 vi cert_creation.sh
+hubert 26691 1 0 23:22 ? 00:00:00 xterm
+hubert 26708 26691 0 23:22 pts/18 00:00:00 zsh
+hubert 26795 21102 0 23:23 pts/14 00:00:00 man certutil
+hubert 26807 26795 0 23:23 pts/14 00:00:00 less
+hubert 26915 26708 0 23:25 pts/18 00:00:00 ps -ef
+hubert 27179 1 0 Aug04 ? 00:00:04 xterm
+hubert 27197 27179 0 Aug04 pts/6 00:00:00 zsh
+hubert 27775 1 0 Jul28 ? 00:00:39 xterm
+hubert 27792 27775 0 Jul28 pts/12 00:00:01 zsh
+root 27952 2 0 Jul28 ? 00:00:00 [bioset]
+hubert 28132 24043 0 Aug09 ? 00:00:41 /usr/bin/evince /tmp/mozilla_hubert0/p1197-dowling.pdf
+root 31079 2 0 Jul24 ? 00:00:00 [dio/dm-3]
+polkitd 31448 1 0 Jul25 ? 00:00:50 /usr/lib/polkit-1/polkitd --no-debug
+root 31476 1 0 Jul25 ? 00:01:17 /usr/bin/cupsd -l
+colord 31477 1 0 Jul25 ? 00:00:00 /usr/lib/colord/colord
+hubert 31643 31866 0 Aug04 ? 00:00:07 /usr/lib/opera/opera --type=renderer --field-trial-handle=1 --primordial-pipe-token=DC1172410C70C0F58E75E6D62CFFDEAD --lang=en-US --disable-client-side-phishing-detection --enable-offline-auto-reload --enable-offline-auto-reload-visible-only --enable-pinch --num-raster-threads=2 --enable-main-frame-before-activation --content-image-texture-target=0,0,3553;0,1,3553;0,2,3553;0,3,3553;0,4,3553;0,5,3553;0,6,3553;0,7,3553;0,8,3553;0,9,3553;0,10,3553;0,11,3553;0,12,3553;0,13,3553;0,14,3553;0,15,3553;0,16,3553;1,0,3553;1,1,3553;1,2,3553;1,3,3553;1,4,3553;1,5,3553;1,6,3553;1,7,3553;1,8,3553;1,9,3553;1,10,3553;1,11,3553;1,12,3553;1,13,3553;1,14,3553;1,15,3553;1,16,3553;2,0,3553;2,1,3553;2,2,3553;2,3,3553;2,4,3553;2,5,3553;2,6,3553;2,7,3553;2,8,3553;2,9,3553;2,10,3553;2,11,3553;2,12,3553;2,13,3553;2,14,3553;2,15,3553;2,16,3553;3,0,3553;3,1,3553;3,2,3553;3,3,3553;3,4,3553;3,5,3553;3,6,3553;3,7,3553;3,8,3553;3,9,3553;3,10,3553;3,11,3553;3,12,3553;3,13,3553;3,
+hubert 31858 1 0 Jul24 ? 00:00:00 /bin/zsh
+hubert 31861 31858 3 Jul24 ? 13:46:37 /usr/lib/opera/opera
+hubert 31863 31861 0 Jul24 ? 00:00:00 /usr/lib/opera/opera_sandbox /usr/lib/opera/opera --type=zygote
+hubert 31864 31863 0 Jul24 ? 00:00:00 /usr/lib/opera/opera --type=zygote
+hubert 31866 31864 0 Jul24 ? 00:00:00 /usr/lib/opera/opera --type=zygote
+hubert 31934 31861 0 Jul24 ? 02:22:40 /usr/lib/opera/opera --type=gpu-process --field-trial-handle=1 --supports-dual-gpus=false --gpu-driver-bug-workarounds=1,7,8,10,24,30,63,68,76 --disable-gl-extensions=GL_ARB_timer_query GL_EXT_timer_query GL_KHR_blend_equation_advanced GL_KHR_blend_equation_advanced_coherent --disable-webrtc-hw-encoding --gpu-vendor-id=0x8086 --gpu-device-id=0x0126 --gpu-driver-vendor=Mesa --gpu-driver-version=17.1.4 --gpu-driver-date --service-request-channel-token=D475D44CA403ED1AC8789FEE92E3D5F7
+hubert 31937 31934 0 Jul24 ? 00:00:00 /usr/lib/opera/opera --type=gpu-broker
+hubert 31969 31866 0 Jul24 ? 00:00:05 /usr/lib/opera/opera --type=renderer --field-trial-handle=1 --primordial-pipe-token=F2861656839C6C74836DBB94F63A6E9C --lang=en-US --disable-client-side-phishing-detection --enable-offline-auto-reload --enable-offline-auto-reload-visible-only --enable-pinch --num-raster-threads=2 --enable-main-frame-before-activation --content-image-texture-target=0,0,3553;0,1,3553;0,2,3553;0,3,3553;0,4,3553;0,5,3553;0,6,3553;0,7,3553;0,8,3553;0,9,3553;0,10,3553;0,11,3553;0,12,3553;0,13,3553;0,14,3553;0,15,3553;0,16,3553;1,0,3553;1,1,3553;1,2,3553;1,3,3553;1,4,3553;1,5,3553;1,6,3553;1,7,3553;1,8,3553;1,9,3553;1,10,3553;1,11,3553;1,12,3553;1,13,3553;1,14,3553;1,15,3553;1,16,3553;2,0,3553;2,1,3553;2,2,3553;2,3,3553;2,4,3553;2,5,3553;2,6,3553;2,7,3553;2,8,3553;2,9,3553;2,10,3553;2,11,3553;2,12,3553;2,13,3553;2,14,3553;2,15,3553;2,16,3553;3,0,3553;3,1,3553;3,2,3553;3,3,3553;3,4,3553;3,5,3553;3,6,3553;3,7,3553;3,8,3553;3,9,3553;3,10,3553;3,11,3553;3,12,3553;3,13,3553;3,
+hubert 31980 31866 0 Jul24 ? 00:00:10 /usr/lib/opera/opera --type=renderer --field-trial-handle=1 --primordial-pipe-token=637D81672AEE9F862B863C3CD30E68D1 --lang=en-US --disable-client-side-phishing-detection --enable-offline-auto-reload --enable-offline-auto-reload-visible-only --enable-pinch --num-raster-threads=2 --enable-main-frame-before-activation --content-image-texture-target=0,0,3553;0,1,3553;0,2,3553;0,3,3553;0,4,3553;0,5,3553;0,6,3553;0,7,3553;0,8,3553;0,9,3553;0,10,3553;0,11,3553;0,12,3553;0,13,3553;0,14,3553;0,15,3553;0,16,3553;1,0,3553;1,1,3553;1,2,3553;1,3,3553;1,4,3553;1,5,3553;1,6,3553;1,7,3553;1,8,3553;1,9,3553;1,10,3553;1,11,3553;1,12,3553;1,13,3553;1,14,3553;1,15,3553;1,16,3553;2,0,3553;2,1,3553;2,2,3553;2,3,3553;2,4,3553;2,5,3553;2,6,3553;2,7,3553;2,8,3553;2,9,3553;2,10,3553;2,11,3553;2,12,3553;2,13,3553;2,14,3553;2,15,3553;2,16,3553;3,0,3553;3,1,3553;3,2,3553;3,3,3553;3,4,3553;3,5,3553;3,6,3553;3,7,3553;3,8,3553;3,9,3553;3,10,3553;3,11,3553;3,12,3553;3,13,3553;3,
+hubert 32021 31866 0 Jul24 ? 00:01:07 /usr/lib/opera/opera --type=renderer --field-trial-handle=1 --primordial-pipe-token=13C3244006EB0927FBB3DA60803441AF --lang=en-US --disable-client-side-phishing-detection --enable-offline-auto-reload --enable-offline-auto-reload-visible-only --enable-pinch --num-raster-threads=2 --enable-main-frame-before-activation --content-image-texture-target=0,0,3553;0,1,3553;0,2,3553;0,3,3553;0,4,3553;0,5,3553;0,6,3553;0,7,3553;0,8,3553;0,9,3553;0,10,3553;0,11,3553;0,12,3553;0,13,3553;0,14,3553;0,15,3553;0,16,3553;1,0,3553;1,1,3553;1,2,3553;1,3,3553;1,4,3553;1,5,3553;1,6,3553;1,7,3553;1,8,3553;1,9,3553;1,10,3553;1,11,3553;1,12,3553;1,13,3553;1,14,3553;1,15,3553;1,16,3553;2,0,3553;2,1,3553;2,2,3553;2,3,3553;2,4,3553;2,5,3553;2,6,3553;2,7,3553;2,8,3553;2,9,3553;2,10,3553;2,11,3553;2,12,3553;2,13,3553;2,14,3553;2,15,3553;2,16,3553;3,0,3553;3,1,3553;3,2,3553;3,3,3553;3,4,3553;3,5,3553;3,6,3553;3,7,3553;3,8,3553;3,9,3553;3,10,3553;3,11,3553;3,12,3553;3,13,3553;3,
+hubert 32081 31866 1 Jul24 ? 04:29:26 /usr/lib/opera/opera --type=renderer --field-trial-handle=1 --primordial-pipe-token=B912F73C8CF5743F2E6305E6A45CB54C --lang=en-US --disable-client-side-phishing-detection --enable-offline-auto-reload --enable-offline-auto-reload-visible-only --enable-pinch --num-raster-threads=2 --enable-main-frame-before-activation --content-image-texture-target=0,0,3553;0,1,3553;0,2,3553;0,3,3553;0,4,3553;0,5,3553;0,6,3553;0,7,3553;0,8,3553;0,9,3553;0,10,3553;0,11,3553;0,12,3553;0,13,3553;0,14,3553;0,15,3553;0,16,3553;1,0,3553;1,1,3553;1,2,3553;1,3,3553;1,4,3553;1,5,3553;1,6,3553;1,7,3553;1,8,3553;1,9,3553;1,10,3553;1,11,3553;1,12,3553;1,13,3553;1,14,3553;1,15,3553;1,16,3553;2,0,3553;2,1,3553;2,2,3553;2,3,3553;2,4,3553;2,5,3553;2,6,3553;2,7,3553;2,8,3553;2,9,3553;2,10,3553;2,11,3553;2,12,3553;2,13,3553;2,14,3553;2,15,3553;2,16,3553;3,0,3553;3,1,3553;3,2,3553;3,3,3553;3,4,3553;3,5,3553;3,6,3553;3,7,3553;3,8,3553;3,9,3553;3,10,3553;3,11,3553;3,12,3553;3,13,3553;3,
+hubert 32124 31866 1 Jul24 ? 06:13:22 /usr/lib/opera/opera --type=renderer --field-trial-handle=1 --primordial-pipe-token=01234742489C6A487EC763DD784F8EBE --lang=en-US --extension-process --disable-client-side-phishing-detection --enable-offline-auto-reload --enable-offline-auto-reload-visible-only --enable-pinch --num-raster-threads=2 --enable-main-frame-before-activation --content-image-texture-target=0,0,3553;0,1,3553;0,2,3553;0,3,3553;0,4,3553;0,5,3553;0,6,3553;0,7,3553;0,8,3553;0,9,3553;0,10,3553;0,11,3553;0,12,3553;0,13,3553;0,14,3553;0,15,3553;0,16,3553;1,0,3553;1,1,3553;1,2,3553;1,3,3553;1,4,3553;1,5,3553;1,6,3553;1,7,3553;1,8,3553;1,9,3553;1,10,3553;1,11,3553;1,12,3553;1,13,3553;1,14,3553;1,15,3553;1,16,3553;2,0,3553;2,1,3553;2,2,3553;2,3,3553;2,4,3553;2,5,3553;2,6,3553;2,7,3553;2,8,3553;2,9,3553;2,10,3553;2,11,3553;2,12,3553;2,13,3553;2,14,3553;2,15,3553;2,16,3553;3,0,3553;3,1,3553;3,2,3553;3,3,3553;3,4,3553;3,5,3553;3,6,3553;3,7,3553;3,8,3553;3,9,3553;3,10,3553;3,11,3553;3,
+Thu Aug 10 23:25:53 CEST 2017
+047155232
diff --git a/ca/server_db/cert.req b/ca/server_db/cert.req
new file mode 100644
index 0000000..39fe947
--- /dev/null
+++ b/ca/server_db/cert.req
@@ -0,0 +1,18 @@
+
+Certificate request generated by Netscape certutil
+Phone: (not specified)
+
+Common Name: tls-n.testserver
+Email: (not specified)
+Organization: TLS-N
+State: (not specified)
+Country: NN
+
+-----BEGIN NEW CERTIFICATE REQUEST-----
+MIH0MIGaAgEAMDgxCzAJBgNVBAYTAk5OMQ4wDAYDVQQKEwVUTFMtTjEZMBcGA1UE
+AxMQdGxzLW4udGVzdHNlcnZlcjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKTR
+iNOt2VpeI+llhXEmHXzmAvuhv/OmnbPsDkfI+/HO3EJUVv1E/ad6UWPm/7cSAm20
+BsVLe95KJ42mPvKMgxWgADAKBggqhkjOPQQDAgNJADBGAiEAwG4kqlSisqkKl1St
+nsBYQYKNPIXD/W0tx3pworFZt+MCIQDn72ZDAAmqs3rH/+ScIT934Z0Vcc4J9kpc
+C4IdQnqXeQ==
+-----END NEW CERTIFICATE REQUEST-----
diff --git a/ca/server_db/cert.req2 b/ca/server_db/cert.req2
new file mode 100644
index 0000000000000000000000000000000000000000..931eda0c8a70ef10383f0e0304270bbdc3018708
GIT binary patch
literal 247
zcmXqL{9@2Ji;0oJz`~H*fRl|ml!Z;0$s=(xD|F;V<Ro-$OTBlQ-KU;r
z(FF_!Tu>8Pn3nlD
ofl8jgPjhDAT(!CC`2Qz!6z$6&&J`^@$N9}GhPz4DscL#907IEu$p8QV
literal 0
HcmV?d00001
diff --git a/ca/server_db/cert8.db b/ca/server_db/cert8.db
new file mode 100644
index 0000000000000000000000000000000000000000..20deb33a9a72b08b2bff61a61640aeccab3b3d90
GIT binary patch
literal 65536
zcmeI)eN0tl9KiACoO8MN%ByuDEuv&N%M$k-Fe?L&m{2N1LnLy|rgzuT6mDMbSVNhi
z=Bn9Zy4L1PFB2kw00IagfB*srAbb1VKs;#A}
zgg6jD009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**
z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q58#1l)!Yn(zn_Tw3`?!0%sN=?hf(0u#Od
zav>g7`Te`wHYLi@<^wX(Y0PsNp19(Ix#@*tiv0fInCEj1`HUGON7!9Xk6u`4#>-f{
z5$%Zz-)BB3M@7bsR1>6EObq%egOMrR>ft56K;`TH3K1=Ot#<2>wc7GpTFy_|E3(S6
z#%Cp{GF&?h@EimXKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL
zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1P~Z@0kbWQ$yEuJt~s?9PM;JvG&Ci*$zV=JP}$xGAhn|TCGfGm>HAJN%QTdY2Iw!
z`I_Y`(&Kc6SD-*Vtm{0lAD
z|2Xl(wBnM!>3ut@U-EW`4&JYqH#xtawfx7KkG)@?)3a`Mk{s}A#tb3z^;B^&I5P92
zu_gDdFK8}a)>!}Q&dk}rHoy5>ZowxN-5>8;oUCs7>SXEmswdC49-cR4^R+!)2da;L
z*V^H#E~?vKFrnjgTgq*awSUPYw}Vh>|FoGRMg<{X)?T_5gpC~oSNb1=@YJM?fkCjF
zLyR08xjjGc_^vsnH8ZjO$kzc>j9q-MaFg4<28+q^hVhF|IbGBGK^0v9^`x8mBjPwS0E@
zd|uj_mcy}Sp<{8&_ck{)r5sGU5ee@?mE^y>O*syl$sgGWAm-La0BTJC1^`11GlqDg
z`c@wry!+<2s3z*W$97%dbrC=S0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**
x5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5cod|`~#|^N|yit
literal 0
HcmV?d00001
diff --git a/ca/server_db/key3.db b/ca/server_db/key3.db
new file mode 100644
index 0000000000000000000000000000000000000000..00ad06f85e8e1705911bed599d036873fdf7dcc1
GIT binary patch
literal 16384
zcmeI%TQJm77y$6IH*I$N|C@%2B9}-?s5Da{H7lY?JLHl{?QW>CELP;QE?Guq8Iht^
zle>~>iqs@zbXnExh$&;Ii#y9sF6m-6v`Y`Y^w0xMGv7CJ=KJQHGv}Q7J$?siXtNMP
zM1;s~2rXBYh>j3JmDB@Ke-*0rxe3x-o?Ai`b)6d`=v8HPsQ0MHq6c;UJ&S%XTnGXn
z00JNY0w4eaAOHd&00JNY0{@Eu6;0va@nO6cuf#9oo_IDEhh<~45Fh{oAOHd&00JNY
z0w4eaAOHd&u)qQ&)km{cQoWU#2F*OxIrZBz0-Zu2S?Q3q>^3T+!
z-7@%8{3E|>pGEShUTY$2;woK~Y@2D;Ttv(071T$I6MQ?d6D~ol)#t_zwfJzG$tADT
z+N(N``WegpQ^HL3;s%Jy!p6^K1=R}7NunH=zT4;FIn9_Zk705KX78^c2G?jjb&dVt
zvLU0)enOP2?Ob3Ic&xPbGjCMJZ>m4qAvk7N6v*YVSzHS~iyJ}GA|!5!SRNV6(aobg
z!&@Isni)`prs#Jun~u%bK2?kA+Pid2UcDU-3uW>7QM~Yz7MxT5oFI~?e>nd%FNBC1
zaV0j6DY5^hV*&330T2KI5C8!X009sH0T2KI5CDO{68LkY;hgYZ?6=I=CcDVWiK_e}
z@6BE=E%S|rGwJc64A!R5gPccCYG*J7v>)ldZ>-8b$)$Xzm|J%+fPUhn5cdR~QX45mPRH5EGe}5K*zJ
zJ%yHYijhGVKV~^s(RbA-dQP;A4DI)0B!(=x;9#VGM
zzPNGNTX4X3%xg^#-B6}A(6J0f2crsmj}ZxgS5
s&)!Lzv}1Qo%H5|IxSIpVg8&GC00@8p2!H?xfB*=900@8p2>g42pQWadM*si-
literal 0
HcmV?d00001
diff --git a/ca/server_db/secmod.db b/ca/server_db/secmod.db
new file mode 100644
index 0000000000000000000000000000000000000000..b6e81ca751dff9ba46a094715f7b4f507fbc7a6c
GIT binary patch
literal 16384
zcmeI&u}Z^07{Kw*R!RqnE^Zx$77N%-690cmD-&dD;yhx4R^%UjVIGMyr;p?7OktxbiVaCawueF+*`>)B|M7MeD
zYuESU8?DA^IGOuuF^j{}G$r(EGT5l&HVnU4bE(AETYqw$Pfd1i=24N%$|TR~755JR
nxxMu5RZngE5x@Q3$C5w*0R#|0009ILKmY**5I_Kd|1R(eN?b*1
literal 0
HcmV?d00001
diff --git a/ca/server_db/server.crt b/ca/server_db/server.crt
new file mode 100644
index 0000000000000000000000000000000000000000..55a697de4dd0f14e2c2bc165d75881be0d4a6060
GIT binary patch
literal 325
zcmXqLVstcUe7=C0iIItkm0{J{*&+s9Y#dr`9_MUXn3)VD48;sY*qB3En1y*me1diT
z6oT^eOB9?P4dldm4b2TK3=ND7jm!*9qCi|jLpT>G!)?F`(#a;wLo3-^CsHh1$IKKB#9Kc2he6cYB=U473>
zy?2@2r=Dg}WUn!MG8niqDKfk+5ip*v5+*pwXJ1I+x@9pdjQwBjt9a|^Ge7Uyyp3tn
pKqUvxM=UAResOwFsMVYwYwm8YI(Y5$b@r;D37dR$uHQH-3jmk5Y~BC>
literal 0
HcmV?d00001
diff --git a/nss/.clang-format b/nss/.clang-format
new file mode 100644
index 0000000..b90d52f
--- /dev/null
+++ b/nss/.clang-format
@@ -0,0 +1,65 @@
+---
+Language: Cpp
+# BasedOnStyle: Mozilla
+AccessModifierOffset: -2
+AlignAfterOpenBracket: true
+AlignEscapedNewlinesLeft: false
+AlignOperands: true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: All
+AlwaysBreakAfterDefinitionReturnType: true
+AlwaysBreakTemplateDeclarations: false
+AlwaysBreakBeforeMultilineStrings: false
+BreakBeforeBinaryOperators: false
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+BinPackParameters: true
+BinPackArguments: true
+ColumnLimit: 0
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerIndentWidth: 4
+DerivePointerAlignment: true
+ExperimentalAutoDetectBinPacking: false
+IndentCaseLabels: true
+IndentWrappedFunctionNames: false
+IndentFunctionDeclarationAfterType: false
+MaxEmptyLinesToKeep: 1
+KeepEmptyLinesAtTheStartOfBlocks: true
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: true
+ObjCSpaceBeforeProtocolList: false
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakString: 1000
+PenaltyBreakFirstLessLess: 120
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 200
+PointerAlignment: Right
+SpacesBeforeTrailingComments: 1
+Cpp11BracedListStyle: false
+Standard: Cpp03
+IndentWidth: 4
+TabWidth: 8
+UseTab: Never
+BreakBeforeBraces: Linux
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+SpacesInAngles: false
+SpaceInEmptyParentheses: false
+SpacesInCStyleCastParentheses: false
+SpaceAfterCStyleCast: false
+SpacesInContainerLiterals: true
+SpaceBeforeAssignmentOperators: true
+ContinuationIndentWidth: 4
+CommentPragmas: '^ IWYU pragma:'
+ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
+SpaceBeforeParens: ControlStatements
+DisableFormat: false
+SortIncludes: false
+...
diff --git a/nss/.gitignore b/nss/.gitignore
new file mode 100644
index 0000000..079fcae
--- /dev/null
+++ b/nss/.gitignore
@@ -0,0 +1,20 @@
+*~
+*.swp
+*OPT.OBJ/
+*DBG.OBJ/
+*DBG.OBJD/
+out/*
+*.pyc
+*.bak
+*.out
+*.rej
+*.patch
+GPATH
+GRTAGS
+GTAGS
+#*
+.#*
+.ycm_extra_conf.py*
+fuzz/libFuzzer/*
+fuzz/corpus
+fuzz/out
diff --git a/nss/.hg_archival.txt b/nss/.hg_archival.txt
new file mode 100644
index 0000000..cfd7283
--- /dev/null
+++ b/nss/.hg_archival.txt
@@ -0,0 +1,4 @@
+repo: 9949429068caa6bb8827a8ceeaa7c605d722f47f
+node: 127d10a77798396fdb659231040bb4b57ec16dc5
+branch: NSS_3_30_BRANCH
+tag: NSS_3_30_1_RTM
diff --git a/nss/.hgignore b/nss/.hgignore
new file mode 100644
index 0000000..a8d626e
--- /dev/null
+++ b/nss/.hgignore
@@ -0,0 +1,20 @@
+syntax: glob
+*~
+*OPT.OBJ/*
+*DBG.OBJ/*
+*DBG.OBJD/*
+out/*
+*.pyc
+*.bak
+*.out
+*.rej
+*.patch
+GPATH
+GRTAGS
+GTAGS
+#*
+.#*
+.ycm_extra_conf.py*
+fuzz/libFuzzer/*
+fuzz/corpus
+fuzz/out
diff --git a/nss/.taskcluster.yml b/nss/.taskcluster.yml
new file mode 100644
index 0000000..9d56c9b
--- /dev/null
+++ b/nss/.taskcluster.yml
@@ -0,0 +1,89 @@
+---
+version: 0
+metadata:
+ name: "NSS Continuous Integration"
+ description: "The Taskcluster task graph for the NSS tree"
+ owner: "mozilla-taskcluster-maintenance@mozilla.com"
+ source: {{{source}}}
+
+scopes:
+ # Note the below scopes are insecure however these get overriden on the server
+ # side to whatever scopes are set by mozilla-taskcluster.
+ - queue:*
+ - docker-worker:*
+ - scheduler:*
+
+# Available mustache parameters (see the mozilla-taskcluster source):
+#
+# - owner: push user (email address)
+# - source: URL of this YAML file
+# - url: repository URL
+# - project: alias for the destination repository (basename of
+# the repo url)
+# - level: SCM level of the destination repository
+# (1 = try, 3 = core)
+# - revision: (short) hg revision of the head of the push
+# - revision_hash: (long) hg revision of the head of the push
+# - comment: comment of the push
+# - pushlog_id: id in the pushlog table of the repository
+#
+# and functions:
+# - as_slugid: convert a label into a slugId
+# - from_now: generate a timestamp at a fixed offset from now
+
+tasks:
+ - taskId: '{{#as_slugid}}decision task{{/as_slugid}}'
+ reruns: 3
+ task:
+ created: '{{now}}'
+ deadline: '{{#from_now}}1 day{{/from_now}}'
+ expires: '{{#from_now}}14 days{{/from_now}}'
+
+ metadata:
+ owner: mozilla-taskcluster-maintenance@mozilla.com
+ source: {{{source}}}
+ name: "NSS Decision Task"
+ description: |
+ The task that creates all of the other tasks in the task graph
+
+ workerType: "hg-worker"
+ provisionerId: "aws-provisioner-v1"
+
+ tags:
+ createdForUser: {{owner}}
+
+ routes:
+ - "tc-treeherder-stage.v2.{{project}}.{{revision}}.{{pushlog_id}}"
+ - "tc-treeherder.v2.{{project}}.{{revision}}.{{pushlog_id}}"
+
+ payload:
+ image: ttaubert/nss-decision:0.0.2
+
+ env:
+ TC_OWNER: {{owner}}
+ TC_SOURCE: {{{source}}}
+ TC_PROJECT: {{project}}
+ TC_COMMENT: '{{comment}}'
+ NSS_PUSHLOG_ID: '{{pushlog_id}}'
+ NSS_HEAD_REPOSITORY: '{{{url}}}'
+ NSS_HEAD_REVISION: '{{revision}}'
+
+ maxRunTime: 1800
+
+ command:
+ - bash
+ - -cx
+ - >
+ bin/checkout.sh &&
+ nss/automation/taskcluster/scripts/extend_task_graph.sh
+
+ features:
+ taskclusterProxy: true
+
+ extra:
+ treeherder:
+ symbol: D
+ build:
+ platform: nss-decision
+ machine:
+ platform: nss-decision
diff --git a/nss/COPYING b/nss/COPYING
new file mode 100644
index 0000000..212af5b
--- /dev/null
+++ b/nss/COPYING
@@ -0,0 +1,403 @@
+NSS is available under the Mozilla Public License, version 2, a copy of which
+is below.
+
+Note on GPL Compatibility
+-------------------------
+
+The MPL 2, section 3.3, permits you to combine NSS with code under the GNU
+General Public License (GPL) version 2, or any later version of that
+license, to make a Larger Work, and distribute the result under the GPL.
+The only condition is that you must also make NSS, and any changes you
+have made to it, available to recipients under the terms of the MPL 2 also.
+
+Anyone who receives the combined code from you does not have to continue
+to dual licence in this way, and may, if they wish, distribute under the
+terms of either of the two licences - either the MPL alone or the GPL
+alone. However, we discourage people from distributing copies of NSS under
+the GPL alone, because it means that any improvements they make cannot be
+reincorporated into the main version of NSS. There is never a need to do
+this for license compatibility reasons.
+
+Note on LGPL Compatibility
+--------------------------
+
+The above also applies to combining MPLed code in a single library with
+code under the GNU Lesser General Public License (LGPL) version 2.1, or
+any later version of that license. If the LGPLed code and the MPLed code
+are not in the same library, then the copyleft coverage of the two
+licences does not overlap, so no issues arise.
+
+
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+ means each individual or legal entity that creates, contributes to
+ the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+ means the combination of the Contributions of others (if any) used
+ by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+ means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+ means Source Code Form to which the initial Contributor has attached
+ the notice in Exhibit A, the Executable Form of such Source Code
+ Form, and Modifications of such Source Code Form, in each case
+ including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+ means
+
+ (a) that the initial Contributor has attached the notice described
+ in Exhibit B to the Covered Software; or
+
+ (b) that the Covered Software was made available under the terms of
+ version 1.1 or earlier of the License, but not also under the
+ terms of a Secondary License.
+
+1.6. "Executable Form"
+ means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+ means a work that combines Covered Software with other material, in
+ a separate file or files, that is not Covered Software.
+
+1.8. "License"
+ means this document.
+
+1.9. "Licensable"
+ means having the right to grant, to the maximum extent possible,
+ whether at the time of the initial grant or subsequently, any and
+ all of the rights conveyed by this License.
+
+1.10. "Modifications"
+ means any of the following:
+
+ (a) any file in Source Code Form that results from an addition to,
+ deletion from, or modification of the contents of Covered
+ Software; or
+
+ (b) any new file in Source Code Form that contains any Covered
+ Software.
+
+1.11. "Patent Claims" of a Contributor
+ means any patent claim(s), including without limitation, method,
+ process, and apparatus claims, in any patent Licensable by such
+ Contributor that would be infringed, but for the grant of the
+ License, by the making, using, selling, offering for sale, having
+ made, import, or transfer of either its Contributions or its
+ Contributor Version.
+
+1.12. "Secondary License"
+ means either the GNU General Public License, Version 2.0, the GNU
+ Lesser General Public License, Version 2.1, the GNU Affero General
+ Public License, Version 3.0, or any later versions of those
+ licenses.
+
+1.13. "Source Code Form"
+ means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+ means an individual or a legal entity exercising rights under this
+ License. For legal entities, "You" includes any entity that
+ controls, is controlled by, or is under common control with You. For
+ purposes of this definition, "control" means (a) the power, direct
+ or indirect, to cause the direction or management of such entity,
+ whether by contract or otherwise, or (b) ownership of more than
+ fifty percent (50%) of the outstanding shares or beneficial
+ ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+ Licensable by such Contributor to use, reproduce, make available,
+ modify, display, perform, distribute, and otherwise exploit its
+ Contributions, either on an unmodified basis, with Modifications, or
+ as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+ for sale, have made, import, and otherwise transfer either its
+ Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+ or
+
+(b) for infringements caused by: (i) Your and any other third party's
+ modifications of Covered Software, or (ii) the combination of its
+ Contributions with other software (except as part of its Contributor
+ Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+ its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+ Form, as described in Section 3.1, and You must inform recipients of
+ the Executable Form how they can obtain a copy of such Source Code
+ Form by reasonable means in a timely manner, at a charge no more
+ than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+ License, or sublicense it under different terms, provided that the
+ license for the Executable Form does not attempt to limit or alter
+ the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+* *
+* 6. Disclaimer of Warranty *
+* ------------------------- *
+* *
+* Covered Software is provided under this License on an "as is" *
+* basis, without warranty of any kind, either expressed, implied, or *
+* statutory, including, without limitation, warranties that the *
+* Covered Software is free of defects, merchantable, fit for a *
+* particular purpose or non-infringing. The entire risk as to the *
+* quality and performance of the Covered Software is with You. *
+* Should any Covered Software prove defective in any respect, You *
+* (not any Contributor) assume the cost of any necessary servicing, *
+* repair, or correction. This disclaimer of warranty constitutes an *
+* essential part of this License. No use of any Covered Software is *
+* authorized under this License except under this disclaimer. *
+* *
+************************************************************************
+
+************************************************************************
+* *
+* 7. Limitation of Liability *
+* -------------------------- *
+* *
+* Under no circumstances and under no legal theory, whether tort *
+* (including negligence), contract, or otherwise, shall any *
+* Contributor, or anyone who distributes Covered Software as *
+* permitted above, be liable to You for any direct, indirect, *
+* special, incidental, or consequential damages of any character *
+* including, without limitation, damages for lost profits, loss of *
+* goodwill, work stoppage, computer failure or malfunction, or any *
+* and all other commercial damages or losses, even if such party *
+* shall have been informed of the possibility of such damages. This *
+* limitation of liability shall not apply to liability for death or *
+* personal injury resulting from such party's negligence to the *
+* extent applicable law prohibits such limitation. Some *
+* jurisdictions do not allow the exclusion or limitation of *
+* incidental or consequential damages, so this exclusion and *
+* limitation may not apply to You. *
+* *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+ This Source Code Form is subject to the terms of the Mozilla Public
+ License, v. 2.0. If a copy of the MPL was not distributed with this
+ file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+ This Source Code Form is "Incompatible With Secondary Licenses", as
+ defined by the Mozilla Public License, v. 2.0.
diff --git a/nss/Makefile b/nss/Makefile
new file mode 100644
index 0000000..a24c4ca
--- /dev/null
+++ b/nss/Makefile
@@ -0,0 +1,159 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+ifdef NSS_DISABLE_GTESTS
+DIRS := $(filter-out gtests,$(DIRS))
+endif
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+nss_build_all: build_nspr all latest
+
+nss_clean_all: clobber_nspr clobber
+
+NSPR_CONFIG_STATUS = $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME)/config.status
+NSPR_CONFIGURE = $(CORE_DEPTH)/../nspr/configure
+
+#
+# Translate coreconf build options to NSPR configure options.
+#
+
+ifeq ($(OS_TARGET),Android)
+NSPR_CONFIGURE_OPTS += --with-android-ndk=$(ANDROID_NDK) \
+ --target=$(ANDROID_PREFIX) \
+ --with-android-version=$(OS_TARGET_RELEASE) \
+ --with-android-toolchain=$(ANDROID_TOOLCHAIN) \
+ --with-android-platform=$(ANDROID_SYSROOT)
+endif
+ifdef BUILD_OPT
+NSPR_CONFIGURE_OPTS += --disable-debug --enable-optimize
+endif
+ifdef USE_X32
+NSPR_CONFIGURE_OPTS += --enable-x32
+endif
+ifdef USE_64
+NSPR_CONFIGURE_OPTS += --enable-64bit
+endif
+ifeq ($(OS_TARGET),WIN95)
+NSPR_CONFIGURE_OPTS += --enable-win32-target=WIN95
+endif
+ifdef USE_DEBUG_RTL
+NSPR_CONFIGURE_OPTS += --enable-debug-rtl
+endif
+ifdef USE_STATIC_RTL
+NSPR_CONFIGURE_OPTS += --enable-static-rtl
+endif
+ifdef NS_USE_GCC
+NSPR_CONFIGURE_ENV = CC=gcc CXX=g++
+endif
+ifdef CC
+NSPR_CONFIGURE_ENV = CC=$(CC)
+endif
+ifdef CCC
+NSPR_CONFIGURE_ENV += CXX=$(CCC)
+endif
+# Remove -arch definitions. NSPR can't handle that.
+NSPR_CONFIGURE_ENV := $(filter-out -arch x86_64,$(NSPR_CONFIGURE_ENV))
+NSPR_CONFIGURE_ENV := $(filter-out -arch i386,$(NSPR_CONFIGURE_ENV))
+NSPR_CONFIGURE_ENV := $(filter-out -arch ppc,$(NSPR_CONFIGURE_ENV))
+
+#
+# Some pwd commands on Windows (for example, the pwd
+# command in Cygwin) return a pathname that begins
+# with a (forward) slash. When such a pathname is
+# passed to Windows build tools (for example, cl), it
+# is mistaken as a command-line option. If that is the case,
+# we use a relative pathname as NSPR's prefix on Windows.
+#
+
+USEABSPATH="YES"
+ifeq (,$(filter-out WIN%,$(OS_TARGET)))
+ifeq (,$(findstring :,$(shell pwd)))
+USEABSPATH="NO"
+endif
+endif
+ifeq ($(USEABSPATH),"YES")
+NSPR_PREFIX = $(shell pwd)/../dist/$(OBJDIR_NAME)
+else
+NSPR_PREFIX = $$(topsrcdir)/../dist/$(OBJDIR_NAME)
+endif
+
+ifndef NSS_GYP_PREFIX
+$(NSPR_CONFIG_STATUS): $(NSPR_CONFIGURE)
+ mkdir -p $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME)
+ cd $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME) ; \
+ $(NSPR_CONFIGURE_ENV) sh ../configure \
+ $(NSPR_CONFIGURE_OPTS) \
+ --with-dist-prefix='$(NSPR_PREFIX)' \
+ --with-dist-includedir='$(NSPR_PREFIX)/include'
+else
+$(NSPR_CONFIG_STATUS): $(NSPR_CONFIGURE)
+ mkdir -p $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME)
+ cd $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME) ; \
+ $(NSPR_CONFIGURE_ENV) sh ../configure \
+ $(NSPR_CONFIGURE_OPTS) \
+ --prefix='$(NSS_GYP_PREFIX)'
+endif
+
+build_nspr: $(NSPR_CONFIG_STATUS)
+ $(MAKE) -C $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME)
+
+install_nspr: build_nspr
+ $(MAKE) -C $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME) install
+
+clobber_nspr: $(NSPR_CONFIG_STATUS)
+ $(MAKE) -C $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME) clobber
+
+build_docs:
+ $(MAKE) -C $(CORE_DEPTH)/doc
+
+clean_docs:
+ $(MAKE) -C $(CORE_DEPTH)/doc clean
+
+nss_RelEng_bld: import all
+
+package:
+ $(MAKE) -C pkg publish
+
+latest:
+ echo $(OBJDIR_NAME) > $(CORE_DEPTH)/../dist/latest
+
diff --git a/nss/automation/buildbot-slave/bbenv-example.sh b/nss/automation/buildbot-slave/bbenv-example.sh
new file mode 100644
index 0000000..c76e5d6
--- /dev/null
+++ b/nss/automation/buildbot-slave/bbenv-example.sh
@@ -0,0 +1,67 @@
+#! /bin/bash
+
+# Each buildbot-slave requires a bbenv.sh file that defines
+# machine specific variables. This is an example file.
+
+
+HOST=$(hostname | cut -d. -f1)
+export HOST
+
+# if your machine's IP isn't registered in DNS,
+# you must set appropriate environment variables
+# that can be resolved locally.
+# For example, if localhost.localdomain works on your system, set:
+#HOST=localhost
+#DOMSUF=localdomain
+#export DOMSUF
+
+ARCH=$(uname -s)
+
+ulimit -c unlimited 2> /dev/null
+
+export NSPR_LOG_MODULES="pkix:1"
+
+#export JAVA_HOME_32=
+#export JAVA_HOME_64=
+
+#enable if you have PKITS data
+#export PKITS_DATA=$HOME/pkits/data/
+
+NSS_BUILD_TARGET="clean nss_build_all"
+JSS_BUILD_TARGET="clean all"
+
+MAKE=gmake
+AWK=awk
+PATCH=patch
+
+if [ "${ARCH}" = "SunOS" ]; then
+ AWK=nawk
+ PATCH=gpatch
+ ARCH=SunOS/$(uname -p)
+fi
+
+if [ "${ARCH}" = "Linux" -a -f /etc/system-release ]; then
+ VERSION=`sed -e 's; release ;;' -e 's; (.*)$;;' -e 's;Red Hat Enterprise Linux Server;RHEL;' -e 's;Red Hat Enterprise Linux Workstation;RHEL;' /etc/system-release`
+ ARCH=Linux/${VERSION}
+ echo ${ARCH}
+fi
+
+PROCESSOR=$(uname -p)
+if [ "${PROCESSOR}" = "ppc64" ]; then
+ ARCH="${ARCH}/ppc64"
+fi
+if [ "${PROCESSOR}" = "powerpc" ]; then
+ ARCH="${ARCH}/ppc"
+fi
+
+PORT_64_DBG=8543
+PORT_64_OPT=8544
+PORT_32_DBG=8545
+PORT_32_OPT=8546
+
+if [ "${NSS_TESTS}" = "memleak" ]; then
+ PORT_64_DBG=8547
+ PORT_64_OPT=8548
+ PORT_32_DBG=8549
+ PORT_32_OPT=8550
+fi
diff --git a/nss/automation/buildbot-slave/build.sh b/nss/automation/buildbot-slave/build.sh
new file mode 100755
index 0000000..7f1a960
--- /dev/null
+++ b/nss/automation/buildbot-slave/build.sh
@@ -0,0 +1,414 @@
+#! /bin/bash
+
+# Ensure a failure of the first command inside a pipe
+# won't be hidden by commands later in the pipe.
+# (e.g. as in ./dosomething | grep)
+
+set -o pipefail
+
+proc_args()
+{
+ while [ -n "$1" ]; do
+ OPT=$(echo $1 | cut -d= -f1)
+ VAL=$(echo $1 | cut -d= -f2)
+
+ case $OPT in
+ "--build-nss")
+ BUILD_NSS=1
+ ;;
+ "--test-nss")
+ TEST_NSS=1
+ ;;
+ "--build-jss")
+ BUILD_JSS=1
+ ;;
+ "--test-jss")
+ TEST_JSS=1
+ ;;
+ "--memtest")
+ NSS_TESTS="memleak"
+ export NSS_TESTS
+ ;;
+ "--nojsssign")
+ NO_JSS_SIGN=1
+ ;;
+ *)
+ echo "Usage: $0 ..."
+ echo " --memtest - run the memory leak tests"
+ echo " --nojsssign - try to sign jss"
+ echo " --build-nss"
+ echo " --build-jss"
+ echo " --test-nss"
+ echo " --test-jss"
+ exit 1
+ ;;
+ esac
+
+ shift
+ done
+}
+
+set_env()
+{
+ TOPDIR=$(pwd)
+ HGDIR=$(pwd)$(echo "/hg")
+ OUTPUTDIR=$(pwd)$(echo "/output")
+ LOG_ALL="${OUTPUTDIR}/all.log"
+ LOG_TMP="${OUTPUTDIR}/tmp.log"
+
+ echo "hello" |grep --line-buffered hello >/dev/null 2>&1
+ [ $? -eq 0 ] && GREP_BUFFER="--line-buffered"
+}
+
+print_log()
+{
+ DATE=$(date "+TB [%Y-%m-%d %H:%M:%S]")
+ echo "${DATE} $*"
+ echo "${DATE} $*" >> ${LOG_ALL}
+}
+
+print_result()
+{
+ TESTNAME=$1
+ RET=$2
+ EXP=$3
+
+ if [ ${RET} -eq ${EXP} ]; then
+ print_log "${TESTNAME} PASSED"
+ else
+ print_log "${TESTNAME} FAILED"
+ fi
+}
+
+print_env()
+{
+ print_log "######## Environment variables ########"
+
+ uname -a | tee -a ${LOG_ALL}
+ if [ -e "/etc/redhat-release" ]; then
+ cat "/etc/redhat-release" | tee -a ${LOG_ALL}
+ fi
+ # don't print the MAIL command, it might contain a password
+ env | grep -v "^MAIL=" | tee -a ${LOG_ALL}
+}
+
+set_cycle()
+{
+ BITS=$1
+ OPT=$2
+
+ if [ "${BITS}" = "64" ]; then
+ USE_64=1
+ JAVA_HOME=${JAVA_HOME_64}
+ PORT_DBG=${PORT_64_DBG}
+ PORT_OPT=${PORT_64_OPT}
+ else
+ USE_64=
+ JAVA_HOME=${JAVA_HOME_32}
+ PORT_DBG=${PORT_32_DBG}
+ PORT_OPT=${PORT_32_OPT}
+ fi
+ export USE_64
+ export JAVA_HOME
+
+ BUILD_OPT=
+ if [ "${OPT}" = "OPT" ]; then
+ BUILD_OPT=1
+ XPCLASS=xpclass.jar
+ PORT=${PORT_OPT}
+ else
+ BUILD_OPT=
+ XPCLASS=xpclass_dbg.jar
+ PORT=${PORT_DBG}
+ fi
+ export BUILD_OPT
+
+ PORT_JSS_SERVER=$(expr ${PORT} + 20)
+ PORT_JSSE_SERVER=$(expr ${PORT} + 40)
+
+ export PORT
+ export PORT_JSS_SERVER
+ export PORT_JSSE_SERVER
+}
+
+build_nss()
+{
+ print_log "######## NSS - build - ${BITS} bits - ${OPT} ########"
+
+ print_log "$ cd ${HGDIR}/nss"
+ cd ${HGDIR}/nss
+
+ print_log "$ ${MAKE} ${NSS_BUILD_TARGET}"
+ #${MAKE} ${NSS_BUILD_TARGET} 2>&1 | tee -a ${LOG_ALL} | grep ${GREP_BUFFER} "^${MAKE}"
+ ${MAKE} ${NSS_BUILD_TARGET} 2>&1 | tee -a ${LOG_ALL}
+ RET=$?
+ print_result "NSS - build - ${BITS} bits - ${OPT}" ${RET} 0
+
+ if [ ${RET} -eq 0 ]; then
+ return 0
+ else
+ tail -100 ${LOG_ALL}
+ return ${RET}
+ fi
+}
+
+build_jss()
+{
+ print_log "######## JSS - build - ${BITS} bits - ${OPT} ########"
+
+ print_log "$ cd ${HGDIR}/jss"
+ cd ${HGDIR}/jss
+
+ print_log "$ ${MAKE} ${JSS_BUILD_TARGET}"
+ #${MAKE} ${JSS_BUILD_TARGET} 2>&1 | tee -a ${LOG_ALL} | grep ${GREP_BUFFER} "^${MAKE}"
+ ${MAKE} ${JSS_BUILD_TARGET} 2>&1 | tee -a ${LOG_ALL}
+ RET=$?
+ print_result "JSS build - ${BITS} bits - ${OPT}" ${RET} 0
+ [ ${RET} -eq 0 ] || return ${RET}
+
+ print_log "$ cd ${HGDIR}/dist"
+ cd ${HGDIR}/dist
+
+ if [ -z "${NO_JSS_SIGN}" ]; then
+ print_log "cat ${TOPDIR}/keystore.pw | ${JAVA_HOME}/bin/jarsigner -keystore ${TOPDIR}/keystore -internalsf ${XPCLASS} jssdsa"
+ cat ${TOPDIR}/keystore.pw | ${JAVA_HOME}/bin/jarsigner -keystore ${TOPDIR}/keystore -internalsf ${XPCLASS} jssdsa >> ${LOG_ALL} 2>&1
+ RET=$?
+ print_result "JSS - sign JAR files - ${BITS} bits - ${OPT}" ${RET} 0
+ [ ${RET} -eq 0 ] || return ${RET}
+ fi
+ print_log "${JAVA_HOME}/bin/jarsigner -verify -certs ${XPCLASS}"
+ ${JAVA_HOME}/bin/jarsigner -verify -certs ${XPCLASS} >> ${LOG_ALL} 2>&1
+ RET=$?
+ print_result "JSS - verify JAR files - ${BITS} bits - ${OPT}" ${RET} 0
+ [ ${RET} -eq 0 ] || return ${RET}
+
+ return 0
+}
+
+test_nss()
+{
+ print_log "######## NSS - tests - ${BITS} bits - ${OPT} ########"
+
+ if [ "${OS_TARGET}" = "Android" ]; then
+ print_log "$ cd ${HGDIR}/nss/tests/remote"
+ cd ${HGDIR}/nss/tests/remote
+ print_log "$ make test_android"
+ make test_android 2>&1 | tee ${LOG_TMP} | grep ${GREP_BUFFER} ": #"
+ OUTPUTFILE=${HGDIR}/tests_results/security/*.1/output.log
+ else
+ print_log "$ cd ${HGDIR}/nss/tests"
+ cd ${HGDIR}/nss/tests
+ print_log "$ ./all.sh"
+ ./all.sh 2>&1 | tee ${LOG_TMP} | egrep ${GREP_BUFFER} ": #|^\[.{10}\] "
+ OUTPUTFILE=${LOG_TMP}
+ fi
+
+ cat ${LOG_TMP} >> ${LOG_ALL}
+ tail -n2 ${HGDIR}/tests_results/security/*.1/results.html | grep END_OF_TEST >> ${LOG_ALL}
+ RET=$?
+
+ print_log "######## details of detected failures (if any) ########"
+ grep -B50 FAILED ${OUTPUTFILE}
+ [ $? -eq 1 ] || RET=1
+
+ print_result "NSS - tests - ${BITS} bits - ${OPT}" ${RET} 0
+ return ${RET}
+}
+
+test_jss()
+{
+ print_log "######## JSS - tests - ${BITS} bits - ${OPT} ########"
+
+ print_log "$ cd ${HGDIR}/jss"
+ cd ${HGDIR}/jss
+
+ print_log "$ ${MAKE} platform"
+ PLATFORM=$(${MAKE} platform)
+ print_log "PLATFORM=${PLATFORM}"
+
+ print_log "$ cd ${HGDIR}/jss/org/mozilla/jss/tests"
+ cd ${HGDIR}/jss/org/mozilla/jss/tests
+
+ print_log "$ perl all.pl dist ${HGDIR}/dist/${PLATFORM}"
+ perl all.pl dist ${HGDIR}/dist/${PLATFORM} 2>&1 | tee ${LOG_TMP}
+ cat ${LOG_TMP} >> ${LOG_ALL}
+
+ tail -n2 ${LOG_TMP} | grep JSSTEST_RATE > /dev/null
+ RET=$?
+
+ grep FAIL ${LOG_TMP}
+ [ $? -eq 1 ] || RET=1
+
+ print_result "JSS - tests - ${BITS} bits - ${OPT}" ${RET} 0
+ return ${RET}
+}
+
+create_objdir_dist_link()
+{
+ # compute relevant 'dist' OBJDIR_NAME subdirectory names for JSS and NSS
+ OS_TARGET=`uname -s`
+ OS_RELEASE=`uname -r | sed 's/-.*//' | sed 's/-.*//' | cut -d . -f1,2`
+ CPU_TAG=_`uname -m`
+ # OBJDIR_NAME_COMPILER appears to be defined for NSS but not JSS
+ OBJDIR_NAME_COMPILER=_cc
+ LIBC_TAG=_glibc
+ IMPL_STRATEGY=_PTH
+ if [ "${RUN_BITS}" = "64" ]; then
+ OBJDIR_TAG=_${RUN_BITS}_${RUN_OPT}.OBJ
+ else
+ OBJDIR_TAG=_${RUN_OPT}.OBJ
+ fi
+
+ # define NSS_OBJDIR_NAME
+ NSS_OBJDIR_NAME=${OS_TARGET}${OS_RELEASE}${CPU_TAG}${OBJDIR_NAME_COMPILER}
+ NSS_OBJDIR_NAME=${NSS_OBJDIR_NAME}${LIBC_TAG}${IMPL_STRATEGY}${OBJDIR_TAG}
+ print_log "create_objdir_dist_link(): NSS_OBJDIR_NAME='${NSS_OBJDIR_NAME}'"
+
+ # define JSS_OBJDIR_NAME
+ JSS_OBJDIR_NAME=${OS_TARGET}${OS_RELEASE}${CPU_TAG}
+ JSS_OBJDIR_NAME=${JSS_OBJDIR_NAME}${LIBC_TAG}${IMPL_STRATEGY}${OBJDIR_TAG}
+ print_log "create_objdir_dist_link(): JSS_OBJDIR_NAME='${JSS_OBJDIR_NAME}'"
+
+ if [ -e "${HGDIR}/dist/${NSS_OBJDIR_NAME}" ]; then
+ SOURCE=${HGDIR}/dist/${NSS_OBJDIR_NAME}
+ TARGET=${HGDIR}/dist/${JSS_OBJDIR_NAME}
+ ln -s ${SOURCE} ${TARGET} >/dev/null 2>&1
+ fi
+}
+
+build_and_test()
+{
+ if [ -n "${BUILD_NSS}" ]; then
+ build_nss
+ [ $? -eq 0 ] || return 1
+ fi
+
+ if [ -n "${TEST_NSS}" ]; then
+ test_nss
+ [ $? -eq 0 ] || return 1
+ fi
+
+ if [ -n "${BUILD_JSS}" ]; then
+ create_objdir_dist_link
+ build_jss
+ [ $? -eq 0 ] || return 1
+ fi
+
+ if [ -n "${TEST_JSS}" ]; then
+ test_jss
+ [ $? -eq 0 ] || return 1
+ fi
+
+ return 0
+}
+
+run_cycle()
+{
+ print_env
+ build_and_test
+ RET=$?
+
+ grep ^TinderboxPrint ${LOG_ALL}
+
+ return ${RET}
+}
+
+prepare()
+{
+ rm -rf ${OUTPUTDIR}.oldest >/dev/null 2>&1
+ mv ${OUTPUTDIR}.older ${OUTPUTDIR}.oldest >/dev/null 2>&1
+ mv ${OUTPUTDIR}.old ${OUTPUTDIR}.older >/dev/null 2>&1
+ mv ${OUTPUTDIR}.last ${OUTPUTDIR}.old >/dev/null 2>&1
+ mv ${OUTPUTDIR} ${OUTPUTDIR}.last >/dev/null 2>&1
+ mkdir -p ${OUTPUTDIR}
+
+ # Remove temporary test files from previous jobs, that weren't cleaned up
+ # by move_results(), e.g. caused by unexpected interruptions.
+ rm -rf ${HGDIR}/tests_results/
+
+ cd ${HGDIR}/nss
+
+ if [ -n "${FEWER_STRESS_ITERATIONS}" ]; then
+ sed -i 's/-c_1000_/-c_500_/g' tests/ssl/sslstress.txt
+ fi
+
+ return 0
+}
+
+move_results()
+{
+ cd ${HGDIR}
+ if [ -n "${TEST_NSS}" ]; then
+ mv -f tests_results ${OUTPUTDIR}
+ fi
+ tar -c -z --dereference -f ${OUTPUTDIR}/dist.tgz dist
+ rm -rf dist
+}
+
+run_all()
+{
+ set_cycle ${BITS} ${OPT}
+ prepare
+ run_cycle
+ RESULT=$?
+ print_log "### result of run_cycle is ${RESULT}"
+ move_results
+ return ${RESULT}
+}
+
+main()
+{
+ VALID=0
+ RET=1
+
+ for BITS in 32 64; do
+ echo ${RUN_BITS} | grep ${BITS} > /dev/null
+ [ $? -eq 0 ] || continue
+ for OPT in DBG OPT; do
+ echo ${RUN_OPT} | grep ${OPT} > /dev/null
+ [ $? -eq 0 ] || continue
+
+ VALID=1
+ set_env
+ run_all
+ RET=$?
+ print_log "### result of run_all is ${RET}"
+ done
+ done
+
+ if [ ${VALID} -ne 1 ]; then
+ echo "Need to set valid bits/opt values."
+ return 1
+ fi
+
+ return ${RET}
+}
+
+#function killallsub()
+#{
+# FINAL_RET=$?
+# for proc in `jobs -p`
+# do
+# kill -9 $proc
+# done
+# return ${FINAL_RET}
+#}
+#trap killallsub EXIT
+
+#IS_RUNNING_FILE="./build-is-running"
+
+#if [ -a $IS_RUNNING_FILE ]; then
+# echo "exiting, because old job is still running"
+# exit 1
+#fi
+
+#touch $IS_RUNNING_FILE
+
+echo "tinderbox args: $0 $@"
+. ${ENVVARS}
+proc_args "$@"
+main
+
+#RET=$?
+#rm $IS_RUNNING_FILE
+#exit ${RET}
diff --git a/nss/automation/buildbot-slave/reboot.bat b/nss/automation/buildbot-slave/reboot.bat
new file mode 100644
index 0000000..c6a5c7b
--- /dev/null
+++ b/nss/automation/buildbot-slave/reboot.bat
@@ -0,0 +1,6 @@
+IF EXIST ..\buildbot-is-building (
+ del ..\buildbot-is-building
+ shutdown /r /t 0
+
+ timeout /t 120
+)
diff --git a/nss/automation/buildbot-slave/startbuild.bat b/nss/automation/buildbot-slave/startbuild.bat
new file mode 100644
index 0000000..ba06834
--- /dev/null
+++ b/nss/automation/buildbot-slave/startbuild.bat
@@ -0,0 +1,14 @@
+echo running > ..\buildbot-is-building
+
+echo running: "%MOZILLABUILD%\msys\bin\bash" -c "hg/nss/automation/buildbot-slave/build.sh %*"
+"%MOZILLABUILD%\msys\bin\bash" -c "hg/nss/automation/buildbot-slave/build.sh %*"
+
+if %errorlevel% neq 0 (
+ set EXITCODE=1
+) else (
+ set EXITCODE=0
+)
+
+del ..\buildbot-is-building
+
+exit /b %EXITCODE%
diff --git a/nss/automation/ossfuzz/build.sh b/nss/automation/ossfuzz/build.sh
new file mode 100755
index 0000000..04dca18
--- /dev/null
+++ b/nss/automation/ossfuzz/build.sh
@@ -0,0 +1,57 @@
+#!/bin/bash -eu
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+################################################################################
+
+# List of targets disabled for oss-fuzz.
+declare -A disabled=([pkcs8]=1)
+
+# List of targets we want to fuzz in TLS and non-TLS mode.
+declare -A tls_targets=([tls-client]=1)
+
+# Helper function that copies a fuzzer binary and its seed corpus.
+copy_fuzzer()
+{
+ local fuzzer=$1
+ local name=$2
+
+ # Copy the binary.
+ cp ../dist/Debug/bin/$fuzzer $OUT/$name
+
+ # Zip and copy the corpus, if any.
+ if [ -d "$SRC/nss-corpus/$name" ]; then
+ zip $OUT/${name}_seed_corpus.zip $SRC/nss-corpus/$name/*
+ else
+ zip $OUT/${name}_seed_corpus.zip $SRC/nss-corpus/*/*
+ fi
+}
+
+# Copy libFuzzer options
+cp fuzz/*.options $OUT/
+
+# Build the library (non-TLS fuzzing mode).
+CXX="$CXX -stdlib=libc++" LDFLAGS="$CFLAGS" \
+ ./build.sh -c -v --fuzz=oss --fuzz --disable-tests
+
+# Copy fuzzing targets.
+for fuzzer in $(find ../dist/Debug/bin -name "nssfuzz-*" -printf "%f\n"); do
+ name=${fuzzer:8}
+ if [ -z "${disabled[$name]:-}" ]; then
+ [ -n "${tls_targets[$name]:-}" ] && name="${name}-no_fuzzer_mode"
+ copy_fuzzer $fuzzer $name
+ fi
+done
+
+# Build the library again (TLS fuzzing mode).
+CXX="$CXX -stdlib=libc++" LDFLAGS="$CFLAGS" \
+ ./build.sh -c -v --fuzz=oss --fuzz=tls --disable-tests
+
+# Copy dual mode targets in TLS mode.
+for name in "${!tls_targets[@]}"; do
+ if [ -z "${disabled[$name]:-}" ]; then
+ copy_fuzzer nssfuzz-$name $name
+ fi
+done
diff --git a/nss/automation/release/nss-release-helper.py b/nss/automation/release/nss-release-helper.py
new file mode 100644
index 0000000..a7b4088
--- /dev/null
+++ b/nss/automation/release/nss-release-helper.py
@@ -0,0 +1,250 @@
+#!/usr/bin/python
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import os
+import sys
+import datetime
+import shutil
+import glob
+from optparse import OptionParser
+from subprocess import check_call
+
+nssutil_h = "lib/util/nssutil.h"
+softkver_h = "lib/softoken/softkver.h"
+nss_h = "lib/nss/nss.h"
+nssckbi_h = "lib/ckfw/builtins/nssckbi.h"
+
+def check_call_noisy(cmd, *args, **kwargs):
+ print "Executing command:", cmd
+ check_call(cmd, *args, **kwargs)
+
+o = OptionParser(usage="client.py [options] remove_beta | set_beta | print_library_versions | print_root_ca_version | set_root_ca_version | set_version_to_minor_release | set_version_to_patch_release | set_release_candidate_number | set_4_digit_release_number | create_nss_release_archive")
+
+try:
+ options, args = o.parse_args()
+ action = args[0]
+except IndexError:
+ o.print_help()
+ sys.exit(2)
+
+def exit_with_failure(what):
+ print "failure: ", what
+ sys.exit(2)
+
+def check_files_exist():
+ if (not os.path.exists(nssutil_h) or not os.path.exists(softkver_h)
+ or not os.path.exists(nss_h) or not os.path.exists(nssckbi_h)):
+ exit_with_failure("cannot find expected header files, must run from inside NSS hg directory")
+
+def sed_inplace(sed_expression, filename):
+ backup_file = filename + '.tmp'
+ check_call_noisy(["sed", "-i.tmp", sed_expression, filename])
+ os.remove(backup_file)
+
+def toggle_beta_status(is_beta):
+ check_files_exist()
+ if (is_beta):
+ print "adding Beta status to version numbers"
+ sed_inplace('s/^\(#define *NSSUTIL_VERSION *\"[0-9.]\+\)\" *$/\\1 Beta\"/', nssutil_h)
+ sed_inplace('s/^\(#define *NSSUTIL_BETA *\)PR_FALSE *$/\\1PR_TRUE/', nssutil_h)
+ sed_inplace('s/^\(#define *SOFTOKEN_VERSION *\"[0-9.]\+\" *SOFTOKEN_ECC_STRING\) *$/\\1 \" Beta"/', softkver_h)
+ sed_inplace('s/^\(#define *SOFTOKEN_BETA *\)PR_FALSE *$/\\1PR_TRUE/', softkver_h)
+ sed_inplace('s/^\(#define *NSS_VERSION *\"[0-9.]\+\" *_NSS_CUSTOMIZED\) *$/\\1 \" Beta"/', nss_h)
+ sed_inplace('s/^\(#define *NSS_BETA *\)PR_FALSE *$/\\1PR_TRUE/', nss_h)
+ else:
+ print "removing Beta status from version numbers"
+ sed_inplace('s/^\(#define *NSSUTIL_VERSION *\"[0-9.]\+\) *Beta\" *$/\\1\"/', nssutil_h)
+ sed_inplace('s/^\(#define *NSSUTIL_BETA *\)PR_TRUE *$/\\1PR_FALSE/', nssutil_h)
+ sed_inplace('s/^\(#define *SOFTOKEN_VERSION *\"[0-9.]\+\" *SOFTOKEN_ECC_STRING\) *\" *Beta\" *$/\\1/', softkver_h)
+ sed_inplace('s/^\(#define *SOFTOKEN_BETA *\)PR_TRUE *$/\\1PR_FALSE/', softkver_h)
+ sed_inplace('s/^\(#define *NSS_VERSION *\"[0-9.]\+\" *_NSS_CUSTOMIZED\) *\" *Beta\" *$/\\1/', nss_h)
+ sed_inplace('s/^\(#define *NSS_BETA *\)PR_TRUE *$/\\1PR_FALSE/', nss_h)
+ print "please run 'hg stat' and 'hg diff' to verify the files have been verified correctly"
+
+def print_beta_versions():
+ check_call_noisy(["egrep", "#define *NSSUTIL_VERSION|#define *NSSUTIL_BETA", nssutil_h])
+ check_call_noisy(["egrep", "#define *SOFTOKEN_VERSION|#define *SOFTOKEN_BETA", softkver_h])
+ check_call_noisy(["egrep", "#define *NSS_VERSION|#define *NSS_BETA", nss_h])
+
+def remove_beta_status():
+ print "--- removing beta flags. Existing versions were:"
+ print_beta_versions()
+ toggle_beta_status(False)
+ print "--- finished modifications, new versions are:"
+ print_beta_versions()
+
+def set_beta_status():
+ print "--- adding beta flags. Existing versions were:"
+ print_beta_versions()
+ toggle_beta_status(True)
+ print "--- finished modifications, new versions are:"
+ print_beta_versions()
+
+def print_library_versions():
+ check_files_exist()
+ check_call_noisy(["egrep", "#define *NSSUTIL_VERSION|#define NSSUTIL_VMAJOR|#define *NSSUTIL_VMINOR|#define *NSSUTIL_VPATCH|#define *NSSUTIL_VBUILD|#define *NSSUTIL_BETA", nssutil_h])
+ check_call_noisy(["egrep", "#define *SOFTOKEN_VERSION|#define SOFTOKEN_VMAJOR|#define *SOFTOKEN_VMINOR|#define *SOFTOKEN_VPATCH|#define *SOFTOKEN_VBUILD|#define *SOFTOKEN_BETA", softkver_h])
+ check_call_noisy(["egrep", "#define *NSS_VERSION|#define NSS_VMAJOR|#define *NSS_VMINOR|#define *NSS_VPATCH|#define *NSS_VBUILD|#define *NSS_BETA", nss_h])
+
+def print_root_ca_version():
+ check_files_exist()
+ check_call_noisy(["grep", "define *NSS_BUILTINS_LIBRARY_VERSION", nssckbi_h])
+
+
+def ensure_arguments_after_action(how_many, usage):
+ if (len(sys.argv) != (2+how_many)):
+ exit_with_failure("incorrect number of arguments, expected parameters are:\n" + usage)
+
+def set_major_versions(major):
+ sed_inplace('s/^\(#define *NSSUTIL_VMAJOR *\).*$/\\1' + major + '/', nssutil_h)
+ sed_inplace('s/^\(#define *SOFTOKEN_VMAJOR *\).*$/\\1' + major + '/', softkver_h)
+ sed_inplace('s/^\(#define *NSS_VMAJOR *\).*$/\\1' + major + '/', nss_h)
+
+def set_minor_versions(minor):
+ sed_inplace('s/^\(#define *NSSUTIL_VMINOR *\).*$/\\1' + minor + '/', nssutil_h)
+ sed_inplace('s/^\(#define *SOFTOKEN_VMINOR *\).*$/\\1' + minor + '/', softkver_h)
+ sed_inplace('s/^\(#define *NSS_VMINOR *\).*$/\\1' + minor + '/', nss_h)
+
+def set_patch_versions(patch):
+ sed_inplace('s/^\(#define *NSSUTIL_VPATCH *\).*$/\\1' + patch + '/', nssutil_h)
+ sed_inplace('s/^\(#define *SOFTOKEN_VPATCH *\).*$/\\1' + patch + '/', softkver_h)
+ sed_inplace('s/^\(#define *NSS_VPATCH *\).*$/\\1' + patch + '/', nss_h)
+
+def set_build_versions(build):
+ sed_inplace('s/^\(#define *NSSUTIL_VBUILD *\).*$/\\1' + build + '/', nssutil_h)
+ sed_inplace('s/^\(#define *SOFTOKEN_VBUILD *\).*$/\\1' + build + '/', softkver_h)
+ sed_inplace('s/^\(#define *NSS_VBUILD *\).*$/\\1' + build + '/', nss_h)
+
+def set_full_lib_versions(version):
+ sed_inplace('s/^\(#define *NSSUTIL_VERSION *\"\)\([0-9.]\+\)\(.*\)$/\\1' + version + '\\3/', nssutil_h)
+ sed_inplace('s/^\(#define *SOFTOKEN_VERSION *\"\)\([0-9.]\+\)\(.*\)$/\\1' + version + '\\3/', softkver_h)
+ sed_inplace('s/^\(#define *NSS_VERSION *\"\)\([0-9.]\+\)\(.*\)$/\\1' + version + '\\3/', nss_h)
+
+def set_root_ca_version():
+ ensure_arguments_after_action(2, "major_version minor_version")
+ major = args[1].strip()
+ minor = args[2].strip()
+ version = major + '.' + minor
+ sed_inplace('s/^\(#define *NSS_BUILTINS_LIBRARY_VERSION *\"\).*$/\\1' + version + '/', nssckbi_h)
+ sed_inplace('s/^\(#define *NSS_BUILTINS_LIBRARY_VERSION_MAJOR *\).*$/\\1' + major + '/', nssckbi_h)
+ sed_inplace('s/^\(#define *NSS_BUILTINS_LIBRARY_VERSION_MINOR *\).*$/\\1' + minor + '/', nssckbi_h)
+
+def set_all_lib_versions(version, major, minor, patch, build):
+ set_full_lib_versions(version)
+ set_major_versions(major)
+ set_minor_versions(minor)
+ set_patch_versions(patch)
+ set_build_versions(build)
+
+def set_version_to_minor_release():
+ ensure_arguments_after_action(2, "major_version minor_version")
+ major = args[1].strip()
+ minor = args[2].strip()
+ version = major + '.' + minor
+ patch = "0"
+ build = "0"
+ set_all_lib_versions(version, major, minor, patch, build)
+
+def set_version_to_patch_release():
+ ensure_arguments_after_action(3, "major_version minor_version patch_release")
+ major = args[1].strip()
+ minor = args[2].strip()
+ patch = args[3].strip()
+ version = major + '.' + minor + '.' + patch
+ build = "0"
+ set_all_lib_versions(version, major, minor, patch, build)
+
+def set_release_candidate_number():
+ ensure_arguments_after_action(1, "release_candidate_number")
+ build = args[1].strip()
+ set_build_versions(build)
+
+def set_4_digit_release_number():
+ ensure_arguments_after_action(4, "major_version minor_version patch_release 4th_digit_release_number")
+ major = args[1].strip()
+ minor = args[2].strip()
+ patch = args[3].strip()
+ build = args[4].strip()
+ version = major + '.' + minor + '.' + patch + '.' + build
+ set_all_lib_versions(version, major, minor, patch, build)
+
+def create_nss_release_archive():
+ ensure_arguments_after_action(4, "nss_release_version nss_hg_release_tag nspr_release_version path_to_stage_directory")
+ nssrel = args[1].strip() #e.g. 3.19.3
+ nssreltag = args[2].strip() #e.g. NSS_3_19_3_RTM
+ nsprrel = args[3].strip() #e.g. 4.10.8
+ stagedir = args[4].strip() #e.g. ../stage
+
+ nspr_tar = "nspr-" + nsprrel + ".tar.gz"
+ nsprtar_with_path= stagedir + "/v" + nsprrel + "/src/" + nspr_tar
+ if (not os.path.exists(nsprtar_with_path)):
+ exit_with_failure("cannot find nspr archive at expected location " + nsprtar_with_path)
+
+ nss_stagedir= stagedir + "/" + nssreltag + "/src"
+ if (os.path.exists(nss_stagedir)):
+ exit_with_failure("nss stage directory already exists: " + nss_stagedir)
+
+ nss_tar = "nss-" + nssrel + ".tar.gz"
+
+ check_call_noisy(["mkdir", "-p", nss_stagedir])
+ check_call_noisy(["hg", "archive", "-r", nssreltag, "--prefix=nss-" + nssrel + "/nss",
+ stagedir + "/" + nssreltag + "/src/" + nss_tar, "-X", ".hgtags"])
+ check_call_noisy(["tar", "-xz", "-C", nss_stagedir, "-f", nsprtar_with_path])
+ print "changing to directory " + nss_stagedir
+ os.chdir(nss_stagedir)
+ check_call_noisy(["tar", "-xz", "-f", nss_tar])
+ check_call_noisy(["mv", "-i", "nspr-" + nsprrel + "/nspr", "nss-" + nssrel + "/"])
+ check_call_noisy(["rmdir", "nspr-" + nsprrel])
+
+ nss_nspr_tar = "nss-" + nssrel + "-with-nspr-" + nsprrel + ".tar.gz"
+
+ check_call_noisy(["tar", "-cz", "--remove-files", "-f", nss_nspr_tar, "nss-" + nssrel])
+ check_call("sha1sum " + nss_tar + " " + nss_nspr_tar + " > SHA1SUMS", shell=True)
+ check_call("sha256sum " + nss_tar + " " + nss_nspr_tar + " > SHA256SUMS", shell=True)
+ print "created directory " + nss_stagedir + " with files:"
+ check_call_noisy(["ls", "-l"])
+
+if action in ('remove_beta'):
+ remove_beta_status()
+
+elif action in ('set_beta'):
+ set_beta_status()
+
+elif action in ('print_library_versions'):
+ print_library_versions()
+
+elif action in ('print_root_ca_version'):
+ print_root_ca_version()
+
+elif action in ('set_root_ca_version'):
+ set_root_ca_version()
+
+# x.y version number - 2 parameters
+elif action in ('set_version_to_minor_release'):
+ set_version_to_minor_release()
+
+# x.y.z version number - 3 parameters
+elif action in ('set_version_to_patch_release'):
+ set_version_to_patch_release()
+
+# change the release candidate number, usually increased by one,
+# usually if previous release candiate had a bug
+# 1 parameter
+elif action in ('set_release_candidate_number'):
+ set_release_candidate_number()
+
+# use the build/release candiate number in the identifying version number
+# 4 parameters
+elif action in ('set_4_digit_release_number'):
+ set_4_digit_release_number()
+
+elif action in ('create_nss_release_archive'):
+ create_nss_release_archive()
+
+else:
+ o.print_help()
+ sys.exit(2)
+
+sys.exit(0)
diff --git a/nss/automation/taskcluster/docker-aarch64/Dockerfile b/nss/automation/taskcluster/docker-aarch64/Dockerfile
new file mode 100644
index 0000000..cd58278
--- /dev/null
+++ b/nss/automation/taskcluster/docker-aarch64/Dockerfile
@@ -0,0 +1,30 @@
+FROM franziskus/xenial:aarch64
+MAINTAINER Franziskus Kiefer
+
+RUN useradd -d /home/worker -s /bin/bash -m worker
+WORKDIR /home/worker
+
+# Add build and test scripts.
+ADD bin /home/worker/bin
+RUN chmod +x /home/worker/bin/*
+
+# Install dependencies.
+ADD setup.sh /tmp/setup.sh
+RUN bash /tmp/setup.sh
+
+# Change user.
+USER worker
+
+# Env variables.
+ENV HOME /home/worker
+ENV SHELL /bin/bash
+ENV USER worker
+ENV LOGNAME worker
+ENV HOSTNAME taskcluster-worker
+ENV LANG en_US.UTF-8
+ENV LC_ALL en_US.UTF-8
+ENV HOST localhost
+ENV DOMSUF localdomain
+
+# Set a default command for debugging.
+CMD ["/bin/bash", "--login"]
diff --git a/nss/automation/taskcluster/docker-aarch64/bin/checkout.sh b/nss/automation/taskcluster/docker-aarch64/bin/checkout.sh
new file mode 100755
index 0000000..9167f6b
--- /dev/null
+++ b/nss/automation/taskcluster/docker-aarch64/bin/checkout.sh
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+
+set -v -e -x
+
+if [ $(id -u) = 0 ]; then
+ # Drop privileges by re-running this script.
+ exec su worker $0
+fi
+
+# Default values for testing.
+REVISION=${NSS_HEAD_REVISION:-default}
+REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss}
+
+# Clone NSS.
+for i in 0 2 5; do
+ sleep $i
+ hg clone -r $REVISION $REPOSITORY nss && exit 0
+ rm -rf nss
+done
+exit 1
diff --git a/nss/automation/taskcluster/docker-aarch64/setup.sh b/nss/automation/taskcluster/docker-aarch64/setup.sh
new file mode 100755
index 0000000..b137a50
--- /dev/null
+++ b/nss/automation/taskcluster/docker-aarch64/setup.sh
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+
+set -v -e -x
+
+export DEBIAN_FRONTEND=noninteractive
+
+apt-get -y update
+apt-get -y install software-properties-common
+
+# Add more repos
+add-apt-repository "deb http://ports.ubuntu.com/ xenial main restricted universe multiverse"
+add-apt-repository "deb http://ports.ubuntu.com/ xenial-security main restricted universe multiverse"
+add-apt-repository "deb http://ports.ubuntu.com/ xenial-updates main restricted universe multiverse"
+add-apt-repository "deb http://ports.ubuntu.com/ xenial-backports main restricted universe multiverse"
+
+# Update.
+apt-get -y update
+apt-get -y dist-upgrade
+
+apt_packages=()
+apt_packages+=('build-essential')
+apt_packages+=('ca-certificates')
+apt_packages+=('curl')
+apt_packages+=('zlib1g-dev')
+apt_packages+=('ninja-build')
+apt_packages+=('gyp')
+apt_packages+=('mercurial')
+
+# Install packages.
+apt-get install -y --no-install-recommends ${apt_packages[@]}
+
+locale-gen en_US.UTF-8
+dpkg-reconfigure locales
+
+# Cleanup.
+rm -rf ~/.ccache ~/.cache
+apt-get autoremove -y
+apt-get clean
+apt-get autoclean
+rm $0
diff --git a/nss/automation/taskcluster/docker-arm/Dockerfile b/nss/automation/taskcluster/docker-arm/Dockerfile
new file mode 100644
index 0000000..9a7e502
--- /dev/null
+++ b/nss/automation/taskcluster/docker-arm/Dockerfile
@@ -0,0 +1,27 @@
+FROM armv7/armhf-ubuntu:16.04
+MAINTAINER Franziskus Kiefer
+
+RUN useradd -d /home/worker -s /bin/bash -m worker
+WORKDIR /home/worker
+
+# Add build and test scripts.
+ADD bin /home/worker/bin
+RUN chmod +x /home/worker/bin/*
+
+# Install dependencies.
+ADD setup.sh /tmp/setup.sh
+RUN bash /tmp/setup.sh
+
+# Env variables.
+ENV HOME /home/worker
+ENV SHELL /bin/bash
+ENV USER worker
+ENV LOGNAME worker
+ENV HOSTNAME taskcluster-worker
+ENV LANG en_US.UTF-8
+ENV LC_ALL en_US.UTF-8
+ENV HOST localhost
+ENV DOMSUF localdomain
+
+# Set a default command for debugging.
+CMD ["/bin/bash", "--login"]
diff --git a/nss/automation/taskcluster/docker-arm/bin/checkout.sh b/nss/automation/taskcluster/docker-arm/bin/checkout.sh
new file mode 100755
index 0000000..4b89128
--- /dev/null
+++ b/nss/automation/taskcluster/docker-arm/bin/checkout.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+
+set -v -e -x
+
+if [ $(id -u) = 0 ]; then
+ # set up fake uname
+ if [ ! -f /bin/uname-real ]; then
+ mv /bin/uname /bin/uname-real
+ ln -s /home/worker/bin/uname.sh /bin/uname
+ fi
+ # Drop privileges by re-running this script.
+ exec su worker $0
+fi
+
+# Default values for testing.
+REVISION=${NSS_HEAD_REVISION:-default}
+REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss}
+
+# Clone NSS.
+for i in 0 2 5; do
+ sleep $i
+ hg clone -r $REVISION $REPOSITORY nss && exit 0
+ rm -rf nss
+done
+exit 1
diff --git a/nss/automation/taskcluster/docker-arm/bin/uname.sh b/nss/automation/taskcluster/docker-arm/bin/uname.sh
new file mode 100755
index 0000000..61ad13c
--- /dev/null
+++ b/nss/automation/taskcluster/docker-arm/bin/uname.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+args=`getopt rmvs $*`
+set -- $args
+for i
+do
+ if [ "$i" == "-v" ]; then
+ /bin/uname-real -v
+ fi
+ if [ "$i" == "-r" ]; then
+ echo "4.4.16-v7+"
+ fi
+ if [ "$i" == "-m" ]; then
+ echo "armv7l"
+ fi
+ if [ "$i" == "-s" ]; then
+ echo "Linux"
+ fi
+done
\ No newline at end of file
diff --git a/nss/automation/taskcluster/docker-arm/setup.sh b/nss/automation/taskcluster/docker-arm/setup.sh
new file mode 100755
index 0000000..42d66a4
--- /dev/null
+++ b/nss/automation/taskcluster/docker-arm/setup.sh
@@ -0,0 +1,35 @@
+#!/usr/bin/env bash
+
+set -v -e -x
+
+export DEBIAN_FRONTEND=noninteractive
+
+# Update.
+apt-get -y update
+apt-get -y dist-upgrade
+
+apt_packages=()
+apt_packages+=('build-essential')
+apt_packages+=('ca-certificates')
+apt_packages+=('curl')
+apt_packages+=('python-dev')
+apt_packages+=('python-pip')
+apt_packages+=('python-setuptools')
+apt_packages+=('zlib1g-dev')
+
+# Install packages.
+apt-get install -y --no-install-recommends ${apt_packages[@]}
+
+# Latest Mercurial.
+pip install --upgrade pip
+pip install Mercurial
+
+locale-gen en_US.UTF-8
+dpkg-reconfigure locales
+
+# Cleanup.
+rm -rf ~/.ccache ~/.cache
+apt-get autoremove -y
+apt-get clean
+apt-get autoclean
+rm $0
diff --git a/nss/automation/taskcluster/docker-decision/Dockerfile b/nss/automation/taskcluster/docker-decision/Dockerfile
new file mode 100644
index 0000000..35777c0
--- /dev/null
+++ b/nss/automation/taskcluster/docker-decision/Dockerfile
@@ -0,0 +1,27 @@
+FROM ubuntu:16.04
+MAINTAINER Tim Taubert
+
+RUN useradd -d /home/worker -s /bin/bash -m worker
+WORKDIR /home/worker
+
+# Add build and test scripts.
+ADD bin /home/worker/bin
+RUN chmod +x /home/worker/bin/*
+
+# Install dependencies.
+ADD setup.sh /tmp/setup.sh
+RUN bash /tmp/setup.sh
+
+# Env variables.
+ENV HOME /home/worker
+ENV SHELL /bin/bash
+ENV USER worker
+ENV LOGNAME worker
+ENV HOSTNAME taskcluster-worker
+ENV LANG en_US.UTF-8
+ENV LC_ALL en_US.UTF-8
+ENV HOST localhost
+ENV DOMSUF localdomain
+
+# Set a default command for debugging.
+CMD ["/bin/bash", "--login"]
diff --git a/nss/automation/taskcluster/docker-decision/bin/checkout.sh b/nss/automation/taskcluster/docker-decision/bin/checkout.sh
new file mode 100644
index 0000000..9167f6b
--- /dev/null
+++ b/nss/automation/taskcluster/docker-decision/bin/checkout.sh
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+
+set -v -e -x
+
+if [ $(id -u) = 0 ]; then
+ # Drop privileges by re-running this script.
+ exec su worker $0
+fi
+
+# Default values for testing.
+REVISION=${NSS_HEAD_REVISION:-default}
+REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss}
+
+# Clone NSS.
+for i in 0 2 5; do
+ sleep $i
+ hg clone -r $REVISION $REPOSITORY nss && exit 0
+ rm -rf nss
+done
+exit 1
diff --git a/nss/automation/taskcluster/docker-decision/setup.sh b/nss/automation/taskcluster/docker-decision/setup.sh
new file mode 100644
index 0000000..e5a6d20
--- /dev/null
+++ b/nss/automation/taskcluster/docker-decision/setup.sh
@@ -0,0 +1,31 @@
+#!/usr/bin/env bash
+
+set -v -e -x
+
+# Update packages.
+export DEBIAN_FRONTEND=noninteractive
+apt-get -y update && apt-get -y upgrade
+
+# Need those to install newer packages below.
+apt-get install -y --no-install-recommends apt-utils curl ca-certificates
+
+# Latest Mercurial.
+apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 41BD8711B1F0EC2B0D85B91CF59CE3A8323293EE
+echo "deb http://ppa.launchpad.net/mercurial-ppa/releases/ubuntu xenial main" > /etc/apt/sources.list.d/mercurial.list
+
+# Install packages.
+apt-get -y update && apt-get install -y --no-install-recommends mercurial
+
+# Latest Node.JS.
+curl -sL https://deb.nodesource.com/setup_6.x | bash -
+apt-get install -y --no-install-recommends nodejs
+
+locale-gen en_US.UTF-8
+dpkg-reconfigure locales
+
+# Cleanup.
+rm -rf ~/.ccache ~/.cache
+apt-get autoremove -y
+apt-get clean
+apt-get autoclean
+rm $0
diff --git a/nss/automation/taskcluster/docker-fuzz/Dockerfile b/nss/automation/taskcluster/docker-fuzz/Dockerfile
new file mode 100644
index 0000000..254f166
--- /dev/null
+++ b/nss/automation/taskcluster/docker-fuzz/Dockerfile
@@ -0,0 +1,33 @@
+FROM ubuntu:16.04
+MAINTAINER Tim Taubert
+
+RUN useradd -d /home/worker -s /bin/bash -m worker
+WORKDIR /home/worker
+
+# Add build and test scripts.
+ADD bin /home/worker/bin
+RUN chmod +x /home/worker/bin/*
+
+# Install dependencies.
+ADD setup.sh /tmp/setup.sh
+RUN bash /tmp/setup.sh
+
+# Change user.
+USER worker
+
+# Env variables.
+ENV HOME /home/worker
+ENV SHELL /bin/bash
+ENV USER worker
+ENV LOGNAME worker
+ENV HOSTNAME taskcluster-worker
+ENV LANG en_US.UTF-8
+ENV LC_ALL en_US.UTF-8
+ENV HOST localhost
+ENV DOMSUF localdomain
+
+# LLVM 4.0
+ENV PATH "${PATH}:/home/worker/third_party/llvm-build/Release+Asserts/bin/"
+
+# Set a default command for debugging.
+CMD ["/bin/bash", "--login"]
diff --git a/nss/automation/taskcluster/docker-fuzz/bin/checkout.sh b/nss/automation/taskcluster/docker-fuzz/bin/checkout.sh
new file mode 100644
index 0000000..9167f6b
--- /dev/null
+++ b/nss/automation/taskcluster/docker-fuzz/bin/checkout.sh
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+
+set -v -e -x
+
+if [ $(id -u) = 0 ]; then
+ # Drop privileges by re-running this script.
+ exec su worker $0
+fi
+
+# Default values for testing.
+REVISION=${NSS_HEAD_REVISION:-default}
+REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss}
+
+# Clone NSS.
+for i in 0 2 5; do
+ sleep $i
+ hg clone -r $REVISION $REPOSITORY nss && exit 0
+ rm -rf nss
+done
+exit 1
diff --git a/nss/automation/taskcluster/docker-fuzz/setup.sh b/nss/automation/taskcluster/docker-fuzz/setup.sh
new file mode 100644
index 0000000..899ad7d
--- /dev/null
+++ b/nss/automation/taskcluster/docker-fuzz/setup.sh
@@ -0,0 +1,48 @@
+#!/usr/bin/env bash
+
+set -v -e -x
+
+# Update packages.
+export DEBIAN_FRONTEND=noninteractive
+apt-get -y update && apt-get -y upgrade
+
+# Need this to add keys for PPAs below.
+apt-get install -y --no-install-recommends apt-utils
+
+apt_packages=()
+apt_packages+=('build-essential')
+apt_packages+=('ca-certificates')
+apt_packages+=('curl')
+apt_packages+=('git')
+apt_packages+=('gyp')
+apt_packages+=('libssl-dev')
+apt_packages+=('ninja-build')
+apt_packages+=('pkg-config')
+apt_packages+=('zlib1g-dev')
+
+# Latest Mercurial.
+apt_packages+=('mercurial')
+apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 41BD8711B1F0EC2B0D85B91CF59CE3A8323293EE
+echo "deb http://ppa.launchpad.net/mercurial-ppa/releases/ubuntu xenial main" > /etc/apt/sources.list.d/mercurial.list
+
+# Install packages.
+apt-get -y update
+apt-get install -y --no-install-recommends ${apt_packages[@]}
+
+# Install LLVM/clang-4.0.
+mkdir clang-tmp
+git clone -n --depth 1 https://chromium.googlesource.com/chromium/src/tools/clang clang-tmp/clang
+git -C clang-tmp/clang checkout HEAD scripts/update.py
+clang-tmp/clang/scripts/update.py
+rm -fr clang-tmp
+
+# Generate locales.
+locale-gen en_US.UTF-8
+dpkg-reconfigure locales
+
+# Cleanup.
+rm -rf ~/.ccache ~/.cache
+apt-get autoremove -y
+apt-get clean
+apt-get autoclean
+rm $0
diff --git a/nss/automation/taskcluster/docker/Dockerfile b/nss/automation/taskcluster/docker/Dockerfile
new file mode 100644
index 0000000..8a2256d
--- /dev/null
+++ b/nss/automation/taskcluster/docker/Dockerfile
@@ -0,0 +1,33 @@
+FROM ubuntu:16.04
+MAINTAINER Tim Taubert
+
+RUN useradd -d /home/worker -s /bin/bash -m worker
+WORKDIR /home/worker
+
+# Add build and test scripts.
+ADD bin /home/worker/bin
+RUN chmod +x /home/worker/bin/*
+
+# Install dependencies.
+ADD setup.sh /tmp/setup.sh
+RUN bash /tmp/setup.sh
+
+# Change user.
+USER worker
+
+# Env variables.
+ENV HOME /home/worker
+ENV SHELL /bin/bash
+ENV USER worker
+ENV LOGNAME worker
+ENV HOSTNAME taskcluster-worker
+ENV LANG en_US.UTF-8
+ENV LC_ALL en_US.UTF-8
+ENV HOST localhost
+ENV DOMSUF localdomain
+
+# Rust + Go
+ENV PATH "${PATH}:/home/worker/.cargo/bin/:/usr/lib/go-1.6/bin"
+
+# Set a default command for debugging.
+CMD ["/bin/bash", "--login"]
diff --git a/nss/automation/taskcluster/docker/bin/checkout.sh b/nss/automation/taskcluster/docker/bin/checkout.sh
new file mode 100644
index 0000000..9167f6b
--- /dev/null
+++ b/nss/automation/taskcluster/docker/bin/checkout.sh
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+
+set -v -e -x
+
+if [ $(id -u) = 0 ]; then
+ # Drop privileges by re-running this script.
+ exec su worker $0
+fi
+
+# Default values for testing.
+REVISION=${NSS_HEAD_REVISION:-default}
+REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss}
+
+# Clone NSS.
+for i in 0 2 5; do
+ sleep $i
+ hg clone -r $REVISION $REPOSITORY nss && exit 0
+ rm -rf nss
+done
+exit 1
diff --git a/nss/automation/taskcluster/docker/setup.sh b/nss/automation/taskcluster/docker/setup.sh
new file mode 100644
index 0000000..bead035
--- /dev/null
+++ b/nss/automation/taskcluster/docker/setup.sh
@@ -0,0 +1,66 @@
+#!/usr/bin/env bash
+
+set -v -e -x
+
+# Update packages.
+export DEBIAN_FRONTEND=noninteractive
+apt-get -y update && apt-get -y upgrade
+
+# Need this to add keys for PPAs below.
+apt-get install -y --no-install-recommends apt-utils
+
+apt_packages=()
+apt_packages+=('build-essential')
+apt_packages+=('ca-certificates')
+apt_packages+=('curl')
+apt_packages+=('npm')
+apt_packages+=('git')
+apt_packages+=('golang-1.6')
+apt_packages+=('ninja-build')
+apt_packages+=('pkg-config')
+apt_packages+=('zlib1g-dev')
+
+# 32-bit builds
+apt_packages+=('lib32z1-dev')
+apt_packages+=('gcc-multilib')
+apt_packages+=('g++-multilib')
+
+# ct-verif and sanitizers
+apt_packages+=('valgrind')
+
+# Latest Mercurial.
+apt_packages+=('mercurial')
+apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 41BD8711B1F0EC2B0D85B91CF59CE3A8323293EE
+echo "deb http://ppa.launchpad.net/mercurial-ppa/releases/ubuntu xenial main" > /etc/apt/sources.list.d/mercurial.list
+
+# gcc 4.8 and 6
+apt_packages+=('g++-6')
+apt_packages+=('g++-4.8')
+apt_packages+=('g++-6-multilib')
+apt_packages+=('g++-4.8-multilib')
+apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 60C317803A41BA51845E371A1E9377A2BA9EF27F
+echo "deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu xenial main" > /etc/apt/sources.list.d/toolchain.list
+
+# Install packages.
+apt-get -y update
+apt-get install -y --no-install-recommends ${apt_packages[@]}
+
+# 32-bit builds
+ln -s /usr/include/x86_64-linux-gnu/zconf.h /usr/include
+
+# Install clang-3.9 into /usr/local/.
+# FIXME: verify signature
+curl -L http://releases.llvm.org/3.9.1/clang+llvm-3.9.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz | tar xJv -C /usr/local --strip-components=1
+
+# Install latest Rust (stable).
+su worker -c "curl https://sh.rustup.rs -sSf | sh -s -- -y"
+
+locale-gen en_US.UTF-8
+dpkg-reconfigure locales
+
+# Cleanup.
+rm -rf ~/.ccache ~/.cache
+apt-get autoremove -y
+apt-get clean
+apt-get autoclean
+rm $0
diff --git a/nss/automation/taskcluster/graph/npm-shrinkwrap.json b/nss/automation/taskcluster/graph/npm-shrinkwrap.json
new file mode 100644
index 0000000..b805bb8
--- /dev/null
+++ b/nss/automation/taskcluster/graph/npm-shrinkwrap.json
@@ -0,0 +1,1643 @@
+{
+ "name": "decision-task",
+ "version": "0.0.1",
+ "dependencies": {
+ "amqplib": {
+ "version": "0.4.2",
+ "from": "amqplib@>=0.4.1 <0.5.0",
+ "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.4.2.tgz",
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "from": "isarray@0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
+ },
+ "readable-stream": {
+ "version": "1.1.14",
+ "from": "readable-stream@>=1.0.0 <2.0.0 >=1.1.9",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz"
+ }
+ }
+ },
+ "ansi-regex": {
+ "version": "2.0.0",
+ "from": "ansi-regex@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz"
+ },
+ "ansi-styles": {
+ "version": "2.2.1",
+ "from": "ansi-styles@>=2.1.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz"
+ },
+ "anymatch": {
+ "version": "1.3.0",
+ "from": "anymatch@>=1.3.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.0.tgz"
+ },
+ "argparse": {
+ "version": "1.0.9",
+ "from": "argparse@>=1.0.7 <2.0.0",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz"
+ },
+ "arr-diff": {
+ "version": "2.0.0",
+ "from": "arr-diff@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz"
+ },
+ "arr-flatten": {
+ "version": "1.0.1",
+ "from": "arr-flatten@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.0.1.tgz"
+ },
+ "array-find-index": {
+ "version": "1.0.2",
+ "from": "array-find-index@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz"
+ },
+ "array-uniq": {
+ "version": "1.0.3",
+ "from": "array-uniq@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz"
+ },
+ "array-unique": {
+ "version": "0.2.1",
+ "from": "array-unique@>=0.2.1 <0.3.0",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz"
+ },
+ "arrify": {
+ "version": "1.0.1",
+ "from": "arrify@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz"
+ },
+ "asap": {
+ "version": "1.0.0",
+ "from": "asap@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-1.0.0.tgz"
+ },
+ "asn1": {
+ "version": "0.2.3",
+ "from": "asn1@>=0.2.3 <0.3.0",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz"
+ },
+ "assert-plus": {
+ "version": "0.2.0",
+ "from": "assert-plus@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz"
+ },
+ "async": {
+ "version": "2.1.1",
+ "from": "async@*",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.1.1.tgz"
+ },
+ "async-each": {
+ "version": "1.0.1",
+ "from": "async-each@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz"
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "from": "asynckit@>=0.4.0 <0.5.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz"
+ },
+ "aws-sign2": {
+ "version": "0.6.0",
+ "from": "aws-sign2@>=0.6.0 <0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz"
+ },
+ "aws4": {
+ "version": "1.5.0",
+ "from": "aws4@>=1.2.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.5.0.tgz"
+ },
+ "babel-cli": {
+ "version": "6.16.0",
+ "from": "babel-cli@>=6.14.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.16.0.tgz"
+ },
+ "babel-code-frame": {
+ "version": "6.16.0",
+ "from": "babel-code-frame@>=6.16.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.16.0.tgz"
+ },
+ "babel-compile": {
+ "version": "2.0.0",
+ "from": "babel-compile@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/babel-compile/-/babel-compile-2.0.0.tgz"
+ },
+ "babel-core": {
+ "version": "6.17.0",
+ "from": "babel-core@>=6.16.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.17.0.tgz"
+ },
+ "babel-generator": {
+ "version": "6.17.0",
+ "from": "babel-generator@>=6.17.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.17.0.tgz"
+ },
+ "babel-helper-call-delegate": {
+ "version": "6.8.0",
+ "from": "babel-helper-call-delegate@>=6.8.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.8.0.tgz"
+ },
+ "babel-helper-define-map": {
+ "version": "6.9.0",
+ "from": "babel-helper-define-map@>=6.9.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.9.0.tgz"
+ },
+ "babel-helper-function-name": {
+ "version": "6.8.0",
+ "from": "babel-helper-function-name@>=6.8.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.8.0.tgz"
+ },
+ "babel-helper-get-function-arity": {
+ "version": "6.8.0",
+ "from": "babel-helper-get-function-arity@>=6.8.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.8.0.tgz"
+ },
+ "babel-helper-hoist-variables": {
+ "version": "6.8.0",
+ "from": "babel-helper-hoist-variables@>=6.8.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.8.0.tgz"
+ },
+ "babel-helper-optimise-call-expression": {
+ "version": "6.8.0",
+ "from": "babel-helper-optimise-call-expression@>=6.8.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.8.0.tgz"
+ },
+ "babel-helper-regex": {
+ "version": "6.9.0",
+ "from": "babel-helper-regex@>=6.8.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.9.0.tgz"
+ },
+ "babel-helper-remap-async-to-generator": {
+ "version": "6.16.2",
+ "from": "babel-helper-remap-async-to-generator@>=6.16.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.16.2.tgz"
+ },
+ "babel-helper-replace-supers": {
+ "version": "6.16.0",
+ "from": "babel-helper-replace-supers@>=6.14.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.16.0.tgz"
+ },
+ "babel-helpers": {
+ "version": "6.16.0",
+ "from": "babel-helpers@>=6.16.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.16.0.tgz"
+ },
+ "babel-messages": {
+ "version": "6.8.0",
+ "from": "babel-messages@>=6.8.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.8.0.tgz"
+ },
+ "babel-plugin-check-es2015-constants": {
+ "version": "6.8.0",
+ "from": "babel-plugin-check-es2015-constants@>=6.3.13 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.8.0.tgz"
+ },
+ "babel-plugin-syntax-async-functions": {
+ "version": "6.13.0",
+ "from": "babel-plugin-syntax-async-functions@>=6.8.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz"
+ },
+ "babel-plugin-transform-async-to-generator": {
+ "version": "6.16.0",
+ "from": "babel-plugin-transform-async-to-generator@>=6.8.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.16.0.tgz"
+ },
+ "babel-plugin-transform-es2015-arrow-functions": {
+ "version": "6.8.0",
+ "from": "babel-plugin-transform-es2015-arrow-functions@>=6.3.13 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.8.0.tgz"
+ },
+ "babel-plugin-transform-es2015-block-scoped-functions": {
+ "version": "6.8.0",
+ "from": "babel-plugin-transform-es2015-block-scoped-functions@>=6.3.13 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.8.0.tgz"
+ },
+ "babel-plugin-transform-es2015-block-scoping": {
+ "version": "6.15.0",
+ "from": "babel-plugin-transform-es2015-block-scoping@>=6.14.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.15.0.tgz"
+ },
+ "babel-plugin-transform-es2015-classes": {
+ "version": "6.14.0",
+ "from": "babel-plugin-transform-es2015-classes@>=6.14.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.14.0.tgz"
+ },
+ "babel-plugin-transform-es2015-computed-properties": {
+ "version": "6.8.0",
+ "from": "babel-plugin-transform-es2015-computed-properties@>=6.3.13 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.8.0.tgz"
+ },
+ "babel-plugin-transform-es2015-destructuring": {
+ "version": "6.16.0",
+ "from": "babel-plugin-transform-es2015-destructuring@>=6.16.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.16.0.tgz"
+ },
+ "babel-plugin-transform-es2015-duplicate-keys": {
+ "version": "6.8.0",
+ "from": "babel-plugin-transform-es2015-duplicate-keys@>=6.6.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.8.0.tgz"
+ },
+ "babel-plugin-transform-es2015-for-of": {
+ "version": "6.8.0",
+ "from": "babel-plugin-transform-es2015-for-of@>=6.6.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.8.0.tgz"
+ },
+ "babel-plugin-transform-es2015-function-name": {
+ "version": "6.9.0",
+ "from": "babel-plugin-transform-es2015-function-name@>=6.9.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.9.0.tgz"
+ },
+ "babel-plugin-transform-es2015-literals": {
+ "version": "6.8.0",
+ "from": "babel-plugin-transform-es2015-literals@>=6.3.13 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.8.0.tgz"
+ },
+ "babel-plugin-transform-es2015-modules-amd": {
+ "version": "6.8.0",
+ "from": "babel-plugin-transform-es2015-modules-amd@>=6.8.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.8.0.tgz"
+ },
+ "babel-plugin-transform-es2015-modules-commonjs": {
+ "version": "6.16.0",
+ "from": "babel-plugin-transform-es2015-modules-commonjs@>=6.16.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.16.0.tgz"
+ },
+ "babel-plugin-transform-es2015-modules-systemjs": {
+ "version": "6.14.0",
+ "from": "babel-plugin-transform-es2015-modules-systemjs@>=6.14.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.14.0.tgz"
+ },
+ "babel-plugin-transform-es2015-modules-umd": {
+ "version": "6.12.0",
+ "from": "babel-plugin-transform-es2015-modules-umd@>=6.12.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.12.0.tgz"
+ },
+ "babel-plugin-transform-es2015-object-super": {
+ "version": "6.8.0",
+ "from": "babel-plugin-transform-es2015-object-super@>=6.3.13 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.8.0.tgz"
+ },
+ "babel-plugin-transform-es2015-parameters": {
+ "version": "6.17.0",
+ "from": "babel-plugin-transform-es2015-parameters@>=6.16.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.17.0.tgz"
+ },
+ "babel-plugin-transform-es2015-shorthand-properties": {
+ "version": "6.8.0",
+ "from": "babel-plugin-transform-es2015-shorthand-properties@>=6.3.13 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.8.0.tgz"
+ },
+ "babel-plugin-transform-es2015-spread": {
+ "version": "6.8.0",
+ "from": "babel-plugin-transform-es2015-spread@>=6.3.13 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.8.0.tgz"
+ },
+ "babel-plugin-transform-es2015-sticky-regex": {
+ "version": "6.8.0",
+ "from": "babel-plugin-transform-es2015-sticky-regex@>=6.3.13 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.8.0.tgz"
+ },
+ "babel-plugin-transform-es2015-template-literals": {
+ "version": "6.8.0",
+ "from": "babel-plugin-transform-es2015-template-literals@>=6.6.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.8.0.tgz"
+ },
+ "babel-plugin-transform-es2015-typeof-symbol": {
+ "version": "6.8.0",
+ "from": "babel-plugin-transform-es2015-typeof-symbol@>=6.6.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.8.0.tgz"
+ },
+ "babel-plugin-transform-es2015-unicode-regex": {
+ "version": "6.11.0",
+ "from": "babel-plugin-transform-es2015-unicode-regex@>=6.3.13 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.11.0.tgz"
+ },
+ "babel-plugin-transform-regenerator": {
+ "version": "6.16.1",
+ "from": "babel-plugin-transform-regenerator@>=6.16.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.16.1.tgz"
+ },
+ "babel-plugin-transform-runtime": {
+ "version": "6.15.0",
+ "from": "babel-plugin-transform-runtime@>=6.9.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.15.0.tgz"
+ },
+ "babel-plugin-transform-strict-mode": {
+ "version": "6.11.3",
+ "from": "babel-plugin-transform-strict-mode@>=6.8.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.11.3.tgz"
+ },
+ "babel-polyfill": {
+ "version": "6.16.0",
+ "from": "babel-polyfill@>=6.16.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.16.0.tgz"
+ },
+ "babel-preset-es2015": {
+ "version": "6.16.0",
+ "from": "babel-preset-es2015@>=6.9.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.16.0.tgz"
+ },
+ "babel-preset-taskcluster": {
+ "version": "3.0.0",
+ "from": "babel-preset-taskcluster@>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-taskcluster/-/babel-preset-taskcluster-3.0.0.tgz"
+ },
+ "babel-register": {
+ "version": "6.16.3",
+ "from": "babel-register@>=6.16.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.16.3.tgz"
+ },
+ "babel-runtime": {
+ "version": "6.11.6",
+ "from": "babel-runtime@>=6.11.6 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.11.6.tgz"
+ },
+ "babel-template": {
+ "version": "6.16.0",
+ "from": "babel-template@>=6.16.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.16.0.tgz"
+ },
+ "babel-traverse": {
+ "version": "6.16.0",
+ "from": "babel-traverse@>=6.16.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.16.0.tgz"
+ },
+ "babel-types": {
+ "version": "6.16.0",
+ "from": "babel-types@>=6.16.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.16.0.tgz"
+ },
+ "babylon": {
+ "version": "6.11.6",
+ "from": "babylon@>=6.11.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.11.6.tgz"
+ },
+ "balanced-match": {
+ "version": "0.4.2",
+ "from": "balanced-match@>=0.4.1 <0.5.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz"
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.0",
+ "from": "bcrypt-pbkdf@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.0.tgz"
+ },
+ "bin-version": {
+ "version": "1.0.4",
+ "from": "bin-version@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/bin-version/-/bin-version-1.0.4.tgz"
+ },
+ "bin-version-check": {
+ "version": "2.1.0",
+ "from": "bin-version-check@>=2.1.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-2.1.0.tgz"
+ },
+ "binary-extensions": {
+ "version": "1.7.0",
+ "from": "binary-extensions@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.7.0.tgz"
+ },
+ "bitsyntax": {
+ "version": "0.0.4",
+ "from": "bitsyntax@>=0.0.4 <0.1.0",
+ "resolved": "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.0.4.tgz"
+ },
+ "bl": {
+ "version": "1.1.2",
+ "from": "bl@>=1.1.2 <1.2.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz",
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.0.6",
+ "from": "readable-stream@>=2.0.5 <2.1.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz"
+ }
+ }
+ },
+ "boom": {
+ "version": "2.10.1",
+ "from": "boom@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz"
+ },
+ "brace-expansion": {
+ "version": "1.1.6",
+ "from": "brace-expansion@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz"
+ },
+ "braces": {
+ "version": "1.8.5",
+ "from": "braces@>=1.8.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz"
+ },
+ "buffer-more-ints": {
+ "version": "0.0.2",
+ "from": "buffer-more-ints@0.0.2",
+ "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-0.0.2.tgz"
+ },
+ "buffer-shims": {
+ "version": "1.0.0",
+ "from": "buffer-shims@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz"
+ },
+ "builtin-modules": {
+ "version": "1.1.1",
+ "from": "builtin-modules@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz"
+ },
+ "camelcase": {
+ "version": "2.1.1",
+ "from": "camelcase@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz"
+ },
+ "camelcase-keys": {
+ "version": "2.1.0",
+ "from": "camelcase-keys@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz"
+ },
+ "caseless": {
+ "version": "0.11.0",
+ "from": "caseless@>=0.11.0 <0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz"
+ },
+ "chalk": {
+ "version": "1.1.1",
+ "from": "chalk@1.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.1.tgz"
+ },
+ "chokidar": {
+ "version": "1.6.0",
+ "from": "chokidar@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.6.0.tgz"
+ },
+ "combined-stream": {
+ "version": "1.0.5",
+ "from": "combined-stream@>=1.0.5 <1.1.0",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz"
+ },
+ "commander": {
+ "version": "2.9.0",
+ "from": "commander@>=2.8.1 <3.0.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz"
+ },
+ "component-emitter": {
+ "version": "1.2.1",
+ "from": "component-emitter@>=1.2.0 <1.3.0",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz"
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "from": "concat-map@0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
+ },
+ "convert-source-map": {
+ "version": "1.3.0",
+ "from": "convert-source-map@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.3.0.tgz"
+ },
+ "cookiejar": {
+ "version": "2.0.6",
+ "from": "cookiejar@2.0.6",
+ "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.0.6.tgz"
+ },
+ "core-js": {
+ "version": "2.4.1",
+ "from": "core-js@>=2.4.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz"
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "from": "core-util-is@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
+ },
+ "cryptiles": {
+ "version": "2.0.5",
+ "from": "cryptiles@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz"
+ },
+ "currently-unhandled": {
+ "version": "0.4.1",
+ "from": "currently-unhandled@>=0.4.1 <0.5.0",
+ "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz"
+ },
+ "dashdash": {
+ "version": "1.14.0",
+ "from": "dashdash@>=1.12.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.0.tgz",
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "from": "assert-plus@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
+ }
+ }
+ },
+ "debug": {
+ "version": "2.2.0",
+ "from": "debug@>=2.1.1 <3.0.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz"
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "from": "decamelize@>=1.1.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz"
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "from": "delayed-stream@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
+ },
+ "detect-indent": {
+ "version": "3.0.1",
+ "from": "detect-indent@>=3.0.1 <4.0.0",
+ "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-3.0.1.tgz"
+ },
+ "ecc-jsbn": {
+ "version": "0.1.1",
+ "from": "ecc-jsbn@>=0.1.1 <0.2.0",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz"
+ },
+ "error-ex": {
+ "version": "1.3.0",
+ "from": "error-ex@>=1.2.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.0.tgz"
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "from": "escape-string-regexp@>=1.0.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
+ },
+ "esprima": {
+ "version": "2.7.3",
+ "from": "esprima@>=2.6.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz"
+ },
+ "esutils": {
+ "version": "2.0.2",
+ "from": "esutils@>=2.0.2 <3.0.0",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz"
+ },
+ "eventsource": {
+ "version": "0.1.6",
+ "from": "eventsource@>=0.1.6 <0.2.0",
+ "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz"
+ },
+ "expand-brackets": {
+ "version": "0.1.5",
+ "from": "expand-brackets@>=0.1.4 <0.2.0",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz"
+ },
+ "expand-range": {
+ "version": "1.8.2",
+ "from": "expand-range@>=1.8.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz"
+ },
+ "extend": {
+ "version": "3.0.0",
+ "from": "extend@>=3.0.0 <3.1.0",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz"
+ },
+ "extglob": {
+ "version": "0.3.2",
+ "from": "extglob@>=0.3.1 <0.4.0",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz"
+ },
+ "extsprintf": {
+ "version": "1.0.2",
+ "from": "extsprintf@1.0.2",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz"
+ },
+ "faye-websocket": {
+ "version": "0.11.0",
+ "from": "faye-websocket@>=0.11.0 <0.12.0",
+ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.0.tgz"
+ },
+ "filename-regex": {
+ "version": "2.0.0",
+ "from": "filename-regex@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.0.tgz"
+ },
+ "fill-range": {
+ "version": "2.2.3",
+ "from": "fill-range@>=2.1.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz"
+ },
+ "find-up": {
+ "version": "1.1.2",
+ "from": "find-up@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+ "dependencies": {
+ "path-exists": {
+ "version": "2.1.0",
+ "from": "path-exists@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz"
+ }
+ }
+ },
+ "find-versions": {
+ "version": "1.2.1",
+ "from": "find-versions@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-1.2.1.tgz"
+ },
+ "flatmap": {
+ "version": "0.0.3",
+ "from": "flatmap@0.0.3",
+ "resolved": "https://registry.npmjs.org/flatmap/-/flatmap-0.0.3.tgz"
+ },
+ "for-in": {
+ "version": "0.1.6",
+ "from": "for-in@>=0.1.5 <0.2.0",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.6.tgz"
+ },
+ "for-own": {
+ "version": "0.1.4",
+ "from": "for-own@>=0.1.3 <0.2.0",
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.4.tgz"
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "from": "forever-agent@>=0.6.1 <0.7.0",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz"
+ },
+ "form-data": {
+ "version": "2.0.0",
+ "from": "form-data@>=2.0.0 <2.1.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.0.0.tgz"
+ },
+ "formidable": {
+ "version": "1.0.17",
+ "from": "formidable@>=1.0.14 <1.1.0",
+ "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.0.17.tgz"
+ },
+ "fs-readdir-recursive": {
+ "version": "0.1.2",
+ "from": "fs-readdir-recursive@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-0.1.2.tgz"
+ },
+ "fs-walk": {
+ "version": "0.0.1",
+ "from": "fs-walk@0.0.1",
+ "resolved": "https://registry.npmjs.org/fs-walk/-/fs-walk-0.0.1.tgz"
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "from": "fs.realpath@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
+ },
+ "generate-function": {
+ "version": "2.0.0",
+ "from": "generate-function@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz"
+ },
+ "generate-object-property": {
+ "version": "1.2.0",
+ "from": "generate-object-property@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz"
+ },
+ "get-stdin": {
+ "version": "4.0.1",
+ "from": "get-stdin@>=4.0.1 <5.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz"
+ },
+ "getpass": {
+ "version": "0.1.6",
+ "from": "getpass@>=0.1.1 <0.2.0",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz",
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "from": "assert-plus@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
+ }
+ }
+ },
+ "glob": {
+ "version": "5.0.15",
+ "from": "glob@>=5.0.5 <6.0.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz"
+ },
+ "glob-base": {
+ "version": "0.3.0",
+ "from": "glob-base@>=0.3.0 <0.4.0",
+ "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz"
+ },
+ "glob-parent": {
+ "version": "2.0.0",
+ "from": "glob-parent@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz"
+ },
+ "globals": {
+ "version": "8.18.0",
+ "from": "globals@>=8.3.0 <9.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-8.18.0.tgz"
+ },
+ "graceful-fs": {
+ "version": "4.1.9",
+ "from": "graceful-fs@>=4.1.2 <5.0.0",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.9.tgz"
+ },
+ "graceful-readlink": {
+ "version": "1.0.1",
+ "from": "graceful-readlink@>=1.0.0",
+ "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz"
+ },
+ "har-validator": {
+ "version": "2.0.6",
+ "from": "har-validator@>=2.0.6 <2.1.0",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz"
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "from": "has-ansi@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz"
+ },
+ "hawk": {
+ "version": "3.1.3",
+ "from": "hawk@>=3.1.3 <3.2.0",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz"
+ },
+ "hoek": {
+ "version": "2.16.3",
+ "from": "hoek@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz"
+ },
+ "home-or-tmp": {
+ "version": "1.0.0",
+ "from": "home-or-tmp@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-1.0.0.tgz"
+ },
+ "hosted-git-info": {
+ "version": "2.1.5",
+ "from": "hosted-git-info@>=2.1.4 <3.0.0",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.1.5.tgz"
+ },
+ "http-signature": {
+ "version": "1.1.1",
+ "from": "http-signature@>=1.1.0 <1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz"
+ },
+ "indent-string": {
+ "version": "2.1.0",
+ "from": "indent-string@>=2.1.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
+ "dependencies": {
+ "repeating": {
+ "version": "2.0.1",
+ "from": "repeating@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz"
+ }
+ }
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "from": "inflight@>=1.0.4 <2.0.0",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz"
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "from": "inherits@>=2.0.1 <3.0.0",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz"
+ },
+ "intersect": {
+ "version": "1.0.1",
+ "from": "intersect@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/intersect/-/intersect-1.0.1.tgz"
+ },
+ "invariant": {
+ "version": "2.2.1",
+ "from": "invariant@>=2.2.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.1.tgz"
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "from": "is-arrayish@>=0.2.1 <0.3.0",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz"
+ },
+ "is-binary-path": {
+ "version": "1.0.1",
+ "from": "is-binary-path@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz"
+ },
+ "is-buffer": {
+ "version": "1.1.4",
+ "from": "is-buffer@>=1.0.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.4.tgz"
+ },
+ "is-builtin-module": {
+ "version": "1.0.0",
+ "from": "is-builtin-module@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz"
+ },
+ "is-dotfile": {
+ "version": "1.0.2",
+ "from": "is-dotfile@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.2.tgz"
+ },
+ "is-equal-shallow": {
+ "version": "0.1.3",
+ "from": "is-equal-shallow@>=0.1.3 <0.2.0",
+ "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz"
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "from": "is-extendable@>=0.1.1 <0.2.0",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz"
+ },
+ "is-extglob": {
+ "version": "1.0.0",
+ "from": "is-extglob@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz"
+ },
+ "is-finite": {
+ "version": "1.0.2",
+ "from": "is-finite@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz"
+ },
+ "is-glob": {
+ "version": "2.0.1",
+ "from": "is-glob@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz"
+ },
+ "is-my-json-valid": {
+ "version": "2.15.0",
+ "from": "is-my-json-valid@>=2.12.4 <3.0.0",
+ "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz"
+ },
+ "is-number": {
+ "version": "2.1.0",
+ "from": "is-number@>=2.1.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz"
+ },
+ "is-posix-bracket": {
+ "version": "0.1.1",
+ "from": "is-posix-bracket@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz"
+ },
+ "is-primitive": {
+ "version": "2.0.0",
+ "from": "is-primitive@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz"
+ },
+ "is-property": {
+ "version": "1.0.2",
+ "from": "is-property@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz"
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "from": "is-typedarray@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz"
+ },
+ "is-utf8": {
+ "version": "0.2.1",
+ "from": "is-utf8@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz"
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "from": "isarray@1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
+ },
+ "isobject": {
+ "version": "2.1.0",
+ "from": "isobject@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz"
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "from": "isstream@>=0.1.2 <0.2.0",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz"
+ },
+ "jodid25519": {
+ "version": "1.0.2",
+ "from": "jodid25519@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz"
+ },
+ "js-tokens": {
+ "version": "2.0.0",
+ "from": "js-tokens@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-2.0.0.tgz"
+ },
+ "js-yaml": {
+ "version": "3.6.1",
+ "from": "js-yaml@>=3.6.1 <4.0.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.6.1.tgz"
+ },
+ "jsbn": {
+ "version": "0.1.0",
+ "from": "jsbn@>=0.1.0 <0.2.0",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.0.tgz"
+ },
+ "jsesc": {
+ "version": "1.3.0",
+ "from": "jsesc@>=1.3.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz"
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "from": "json-schema@0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz"
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "from": "json-stringify-safe@>=5.0.1 <5.1.0",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz"
+ },
+ "json3": {
+ "version": "3.3.2",
+ "from": "json3@>=3.3.2 <4.0.0",
+ "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz"
+ },
+ "json5": {
+ "version": "0.4.0",
+ "from": "json5@>=0.4.0 <0.5.0",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-0.4.0.tgz"
+ },
+ "jsonpointer": {
+ "version": "4.0.0",
+ "from": "jsonpointer@>=4.0.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.0.tgz"
+ },
+ "jsprim": {
+ "version": "1.3.1",
+ "from": "jsprim@>=1.2.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.3.1.tgz"
+ },
+ "kind-of": {
+ "version": "3.0.4",
+ "from": "kind-of@>=3.0.2 <4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.0.4.tgz"
+ },
+ "load-json-file": {
+ "version": "1.1.0",
+ "from": "load-json-file@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz"
+ },
+ "lodash": {
+ "version": "4.16.4",
+ "from": "lodash@>=4.2.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.16.4.tgz"
+ },
+ "log-symbols": {
+ "version": "1.0.2",
+ "from": "log-symbols@>=1.0.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz"
+ },
+ "loose-envify": {
+ "version": "1.2.0",
+ "from": "loose-envify@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.2.0.tgz",
+ "dependencies": {
+ "js-tokens": {
+ "version": "1.0.3",
+ "from": "js-tokens@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-1.0.3.tgz"
+ }
+ }
+ },
+ "loud-rejection": {
+ "version": "1.6.0",
+ "from": "loud-rejection@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz"
+ },
+ "map-obj": {
+ "version": "1.0.1",
+ "from": "map-obj@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz"
+ },
+ "meow": {
+ "version": "3.7.0",
+ "from": "meow@>=3.5.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz"
+ },
+ "merge": {
+ "version": "1.2.0",
+ "from": "merge@>=1.2.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.0.tgz"
+ },
+ "methods": {
+ "version": "1.1.2",
+ "from": "methods@>=1.1.1 <1.2.0",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz"
+ },
+ "micromatch": {
+ "version": "2.3.11",
+ "from": "micromatch@>=2.1.5 <3.0.0",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz"
+ },
+ "mime": {
+ "version": "1.3.4",
+ "from": "mime@1.3.4",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz"
+ },
+ "mime-db": {
+ "version": "1.24.0",
+ "from": "mime-db@>=1.24.0 <1.25.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.24.0.tgz"
+ },
+ "mime-types": {
+ "version": "2.1.12",
+ "from": "mime-types@>=2.1.7 <2.2.0",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.12.tgz"
+ },
+ "minimatch": {
+ "version": "3.0.3",
+ "from": "minimatch@>=3.0.2 <4.0.0",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz"
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "from": "minimist@>=1.2.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz"
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "from": "mkdirp@>=0.5.1 <0.6.0",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.8",
+ "from": "minimist@0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz"
+ }
+ }
+ },
+ "ms": {
+ "version": "0.7.1",
+ "from": "ms@0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
+ },
+ "node-uuid": {
+ "version": "1.4.7",
+ "from": "node-uuid@>=1.4.7 <1.5.0",
+ "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz"
+ },
+ "normalize-package-data": {
+ "version": "2.3.5",
+ "from": "normalize-package-data@>=2.3.4 <3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.5.tgz"
+ },
+ "normalize-path": {
+ "version": "2.0.1",
+ "from": "normalize-path@>=2.0.1 <3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.0.1.tgz"
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "from": "number-is-nan@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz"
+ },
+ "oauth-sign": {
+ "version": "0.8.2",
+ "from": "oauth-sign@>=0.8.1 <0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz"
+ },
+ "object-assign": {
+ "version": "4.1.0",
+ "from": "object-assign@>=4.0.1 <5.0.0",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz"
+ },
+ "object.omit": {
+ "version": "2.0.0",
+ "from": "object.omit@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.0.tgz"
+ },
+ "once": {
+ "version": "1.4.0",
+ "from": "once@>=1.3.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz"
+ },
+ "original": {
+ "version": "1.0.0",
+ "from": "original@>=0.0.5",
+ "resolved": "https://registry.npmjs.org/original/-/original-1.0.0.tgz",
+ "dependencies": {
+ "url-parse": {
+ "version": "1.0.5",
+ "from": "url-parse@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.0.5.tgz"
+ }
+ }
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "from": "os-tmpdir@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz"
+ },
+ "output-file-sync": {
+ "version": "1.1.2",
+ "from": "output-file-sync@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz"
+ },
+ "parse-glob": {
+ "version": "3.0.4",
+ "from": "parse-glob@>=3.0.4 <4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz"
+ },
+ "parse-json": {
+ "version": "2.2.0",
+ "from": "parse-json@>=2.2.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz"
+ },
+ "path-exists": {
+ "version": "1.0.0",
+ "from": "path-exists@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-1.0.0.tgz"
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "from": "path-is-absolute@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz"
+ },
+ "path-type": {
+ "version": "1.1.0",
+ "from": "path-type@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz"
+ },
+ "pify": {
+ "version": "2.3.0",
+ "from": "pify@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz"
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "from": "pinkie@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz"
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "from": "pinkie-promise@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz"
+ },
+ "preserve": {
+ "version": "0.2.0",
+ "from": "preserve@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz"
+ },
+ "private": {
+ "version": "0.1.6",
+ "from": "private@>=0.1.6 <0.2.0",
+ "resolved": "https://registry.npmjs.org/private/-/private-0.1.6.tgz"
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "from": "process-nextick-args@>=1.0.6 <1.1.0",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz"
+ },
+ "promise": {
+ "version": "6.1.0",
+ "from": "promise@>=6.1.0 <7.0.0",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-6.1.0.tgz"
+ },
+ "qs": {
+ "version": "6.2.1",
+ "from": "qs@>=6.2.0 <6.3.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.1.tgz"
+ },
+ "querystringify": {
+ "version": "0.0.4",
+ "from": "querystringify@>=0.0.0 <0.1.0",
+ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-0.0.4.tgz"
+ },
+ "randomatic": {
+ "version": "1.1.5",
+ "from": "randomatic@>=1.1.3 <2.0.0",
+ "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.5.tgz"
+ },
+ "read-pkg": {
+ "version": "1.1.0",
+ "from": "read-pkg@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz"
+ },
+ "read-pkg-up": {
+ "version": "1.0.1",
+ "from": "read-pkg-up@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz"
+ },
+ "readable-stream": {
+ "version": "2.1.5",
+ "from": "readable-stream@>=2.0.2 <3.0.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz"
+ },
+ "readdirp": {
+ "version": "2.1.0",
+ "from": "readdirp@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz"
+ },
+ "redent": {
+ "version": "1.0.0",
+ "from": "redent@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz"
+ },
+ "reduce-component": {
+ "version": "1.0.1",
+ "from": "reduce-component@1.0.1",
+ "resolved": "https://registry.npmjs.org/reduce-component/-/reduce-component-1.0.1.tgz"
+ },
+ "regenerate": {
+ "version": "1.3.1",
+ "from": "regenerate@>=1.2.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.1.tgz"
+ },
+ "regenerator-runtime": {
+ "version": "0.9.5",
+ "from": "regenerator-runtime@>=0.9.5 <0.10.0",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.9.5.tgz"
+ },
+ "regex-cache": {
+ "version": "0.4.3",
+ "from": "regex-cache@>=0.4.2 <0.5.0",
+ "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz"
+ },
+ "regexpu-core": {
+ "version": "2.0.0",
+ "from": "regexpu-core@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz"
+ },
+ "regjsgen": {
+ "version": "0.2.0",
+ "from": "regjsgen@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz"
+ },
+ "regjsparser": {
+ "version": "0.1.5",
+ "from": "regjsparser@>=0.1.4 <0.2.0",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
+ "dependencies": {
+ "jsesc": {
+ "version": "0.5.0",
+ "from": "jsesc@>=0.5.0 <0.6.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz"
+ }
+ }
+ },
+ "repeat-element": {
+ "version": "1.1.2",
+ "from": "repeat-element@>=1.1.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz"
+ },
+ "repeat-string": {
+ "version": "1.5.4",
+ "from": "repeat-string@>=1.5.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.5.4.tgz"
+ },
+ "repeating": {
+ "version": "1.1.3",
+ "from": "repeating@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/repeating/-/repeating-1.1.3.tgz"
+ },
+ "request": {
+ "version": "2.75.0",
+ "from": "request@>=2.65.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.75.0.tgz"
+ },
+ "requires-port": {
+ "version": "1.0.0",
+ "from": "requires-port@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz"
+ },
+ "rimraf": {
+ "version": "2.5.4",
+ "from": "rimraf@>=2.4.3 <3.0.0",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz",
+ "dependencies": {
+ "glob": {
+ "version": "7.1.1",
+ "from": "glob@>=7.0.5 <8.0.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz"
+ }
+ }
+ },
+ "semver": {
+ "version": "4.3.6",
+ "from": "semver@>=4.0.3 <5.0.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz"
+ },
+ "semver-regex": {
+ "version": "1.0.0",
+ "from": "semver-regex@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-1.0.0.tgz"
+ },
+ "semver-truncate": {
+ "version": "1.1.2",
+ "from": "semver-truncate@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-1.1.2.tgz",
+ "dependencies": {
+ "semver": {
+ "version": "5.3.0",
+ "from": "semver@>=5.3.0 <6.0.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz"
+ }
+ }
+ },
+ "set-immediate-shim": {
+ "version": "1.0.1",
+ "from": "set-immediate-shim@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz"
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "from": "shebang-regex@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz"
+ },
+ "signal-exit": {
+ "version": "3.0.1",
+ "from": "signal-exit@>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.1.tgz"
+ },
+ "slash": {
+ "version": "1.0.0",
+ "from": "slash@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz"
+ },
+ "slugid": {
+ "version": "1.1.0",
+ "from": "slugid@>=1.1.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/slugid/-/slugid-1.1.0.tgz"
+ },
+ "sntp": {
+ "version": "1.0.9",
+ "from": "sntp@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz"
+ },
+ "sockjs-client": {
+ "version": "1.1.1",
+ "from": "sockjs-client@>=1.0.3 <2.0.0",
+ "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.1.tgz"
+ },
+ "source-map": {
+ "version": "0.5.6",
+ "from": "source-map@>=0.5.0 <0.6.0",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz"
+ },
+ "source-map-support": {
+ "version": "0.4.3",
+ "from": "source-map-support@>=0.4.2 <0.5.0",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.3.tgz"
+ },
+ "spdx-correct": {
+ "version": "1.0.2",
+ "from": "spdx-correct@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz"
+ },
+ "spdx-expression-parse": {
+ "version": "1.0.4",
+ "from": "spdx-expression-parse@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz"
+ },
+ "spdx-license-ids": {
+ "version": "1.2.2",
+ "from": "spdx-license-ids@>=1.0.2 <2.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz"
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "from": "sprintf-js@>=1.0.2 <1.1.0",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz"
+ },
+ "sshpk": {
+ "version": "1.10.1",
+ "from": "sshpk@>=1.7.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.10.1.tgz",
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "from": "assert-plus@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
+ }
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "from": "string_decoder@>=0.10.0 <0.11.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
+ },
+ "stringstream": {
+ "version": "0.0.5",
+ "from": "stringstream@>=0.0.4 <0.1.0",
+ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz"
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "from": "strip-ansi@>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz"
+ },
+ "strip-bom": {
+ "version": "2.0.0",
+ "from": "strip-bom@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz"
+ },
+ "strip-indent": {
+ "version": "1.0.1",
+ "from": "strip-indent@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz"
+ },
+ "superagent": {
+ "version": "1.7.2",
+ "from": "superagent@>=1.7.0 <1.8.0",
+ "resolved": "https://registry.npmjs.org/superagent/-/superagent-1.7.2.tgz",
+ "dependencies": {
+ "async": {
+ "version": "0.9.2",
+ "from": "async@>=0.9.0 <0.10.0",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz"
+ },
+ "combined-stream": {
+ "version": "0.0.7",
+ "from": "combined-stream@>=0.0.4 <0.1.0",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz"
+ },
+ "delayed-stream": {
+ "version": "0.0.5",
+ "from": "delayed-stream@0.0.5",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz"
+ },
+ "form-data": {
+ "version": "0.2.0",
+ "from": "form-data@0.2.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz"
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "from": "isarray@0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
+ },
+ "mime-db": {
+ "version": "1.12.0",
+ "from": "mime-db@>=1.12.0 <1.13.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz"
+ },
+ "mime-types": {
+ "version": "2.0.14",
+ "from": "mime-types@>=2.0.3 <2.1.0",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz"
+ },
+ "qs": {
+ "version": "2.3.3",
+ "from": "qs@2.3.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz"
+ },
+ "readable-stream": {
+ "version": "1.0.27-1",
+ "from": "readable-stream@1.0.27-1",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.27-1.tgz"
+ }
+ }
+ },
+ "superagent-hawk": {
+ "version": "0.0.6",
+ "from": "superagent-hawk@>=0.0.6 <0.0.7",
+ "resolved": "https://registry.npmjs.org/superagent-hawk/-/superagent-hawk-0.0.6.tgz",
+ "dependencies": {
+ "boom": {
+ "version": "0.4.2",
+ "from": "boom@>=0.4.0 <0.5.0",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz"
+ },
+ "cryptiles": {
+ "version": "0.2.2",
+ "from": "cryptiles@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz"
+ },
+ "hawk": {
+ "version": "1.0.0",
+ "from": "hawk@>=1.0.0 <1.1.0",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.0.0.tgz"
+ },
+ "hoek": {
+ "version": "0.9.1",
+ "from": "hoek@>=0.9.0 <0.10.0",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz"
+ },
+ "qs": {
+ "version": "0.6.6",
+ "from": "qs@>=0.6.6 <0.7.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-0.6.6.tgz"
+ },
+ "sntp": {
+ "version": "0.2.4",
+ "from": "sntp@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz"
+ }
+ }
+ },
+ "superagent-promise": {
+ "version": "0.2.0",
+ "from": "superagent-promise@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/superagent-promise/-/superagent-promise-0.2.0.tgz"
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "from": "supports-color@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz"
+ },
+ "taskcluster-client": {
+ "version": "1.4.0",
+ "from": "taskcluster-client@>=1.2.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/taskcluster-client/-/taskcluster-client-1.4.0.tgz",
+ "dependencies": {
+ "hawk": {
+ "version": "2.3.1",
+ "from": "hawk@>=2.3.1 <3.0.0",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-2.3.1.tgz"
+ },
+ "lodash": {
+ "version": "3.10.1",
+ "from": "lodash@>=3.6.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz"
+ }
+ }
+ },
+ "to-fast-properties": {
+ "version": "1.0.2",
+ "from": "to-fast-properties@>=1.0.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.2.tgz"
+ },
+ "tough-cookie": {
+ "version": "2.3.1",
+ "from": "tough-cookie@>=2.3.0 <2.4.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.1.tgz"
+ },
+ "trim-newlines": {
+ "version": "1.0.0",
+ "from": "trim-newlines@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz"
+ },
+ "tunnel-agent": {
+ "version": "0.4.3",
+ "from": "tunnel-agent@>=0.4.1 <0.5.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz"
+ },
+ "tweetnacl": {
+ "version": "0.14.3",
+ "from": "tweetnacl@>=0.14.0 <0.15.0",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.3.tgz"
+ },
+ "url-join": {
+ "version": "0.0.1",
+ "from": "url-join@>=0.0.1 <0.0.2",
+ "resolved": "https://registry.npmjs.org/url-join/-/url-join-0.0.1.tgz"
+ },
+ "url-parse": {
+ "version": "1.1.6",
+ "from": "url-parse@>=1.1.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.1.6.tgz"
+ },
+ "user-home": {
+ "version": "1.1.1",
+ "from": "user-home@>=1.1.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz"
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "from": "util-deprecate@>=1.0.1 <1.1.0",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
+ },
+ "uuid": {
+ "version": "2.0.3",
+ "from": "uuid@>=2.0.1 <3.0.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz"
+ },
+ "v8flags": {
+ "version": "2.0.11",
+ "from": "v8flags@>=2.0.10 <3.0.0",
+ "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.0.11.tgz"
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.1",
+ "from": "validate-npm-package-license@>=3.0.1 <4.0.0",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz"
+ },
+ "verror": {
+ "version": "1.3.6",
+ "from": "verror@1.3.6",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz"
+ },
+ "websocket-driver": {
+ "version": "0.6.5",
+ "from": "websocket-driver@>=0.5.1",
+ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz"
+ },
+ "websocket-extensions": {
+ "version": "0.1.1",
+ "from": "websocket-extensions@>=0.1.1",
+ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.1.tgz"
+ },
+ "when": {
+ "version": "3.6.4",
+ "from": "when@>=3.6.2 <3.7.0",
+ "resolved": "https://registry.npmjs.org/when/-/when-3.6.4.tgz"
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "from": "wrappy@>=1.0.0 <2.0.0",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
+ },
+ "xtend": {
+ "version": "4.0.1",
+ "from": "xtend@>=4.0.0 <5.0.0",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz"
+ }
+ }
+}
diff --git a/nss/automation/taskcluster/graph/package.json b/nss/automation/taskcluster/graph/package.json
new file mode 100644
index 0000000..d866ade
--- /dev/null
+++ b/nss/automation/taskcluster/graph/package.json
@@ -0,0 +1,24 @@
+{
+ "name": "decision-task",
+ "version": "0.0.1",
+ "private": true,
+ "author": "Tim Taubert ",
+ "description": "Decision Task for NSS",
+ "scripts": {
+ "compile": "babel-compile -p taskcluster src:lib",
+ "install": "npm run compile"
+ },
+ "dependencies": {
+ "babel-cli": "^6.14.0",
+ "babel-compile": "^2.0.0",
+ "babel-preset-taskcluster": "^3.0.0",
+ "babel-runtime": "^6.11.6",
+ "flatmap": "0.0.3",
+ "intersect": "^1.0.1",
+ "js-yaml": "^3.6.1",
+ "merge": "^1.2.0",
+ "minimist": "^1.2.0",
+ "slugid": "^1.1.0",
+ "taskcluster-client": "^1.2.1"
+ }
+}
diff --git a/nss/automation/taskcluster/graph/src/context_hash.js b/nss/automation/taskcluster/graph/src/context_hash.js
new file mode 100644
index 0000000..f0a2e9a
--- /dev/null
+++ b/nss/automation/taskcluster/graph/src/context_hash.js
@@ -0,0 +1,43 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import fs from "fs";
+import path from "path";
+import crypto from "crypto";
+import flatmap from "flatmap";
+
+// Compute the SHA-256 digest.
+function sha256(data) {
+ let hash = crypto.createHash("sha256");
+ hash.update(data);
+ return hash.digest("hex");
+}
+
+// Recursively collect a list of all files of a given directory.
+function collectFilesInDirectory(dir) {
+ return flatmap(fs.readdirSync(dir), entry => {
+ let entry_path = path.join(dir, entry);
+
+ if (fs.lstatSync(entry_path).isDirectory()) {
+ return collectFilesInDirectory(entry_path);
+ }
+
+ return [entry_path];
+ });
+}
+
+// Compute a context hash for the given context path.
+export default function (context_path) {
+ let root = path.join(__dirname, "../../../..");
+ let dir = path.join(root, context_path);
+ let files = collectFilesInDirectory(dir).sort();
+ let hashes = files.map(file => {
+ return sha256(file + "|" + fs.readFileSync(file, "utf-8"));
+ });
+
+ // Generate a new prefix every month to ensure the image stays buildable.
+ let now = new Date();
+ let prefix = `${now.getUTCFullYear()}-${now.getUTCMonth() + 1}:`;
+ return sha256(prefix + hashes.join(","));
+}
diff --git a/nss/automation/taskcluster/graph/src/extend.js b/nss/automation/taskcluster/graph/src/extend.js
new file mode 100644
index 0000000..e0db085
--- /dev/null
+++ b/nss/automation/taskcluster/graph/src/extend.js
@@ -0,0 +1,601 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import merge from "./merge";
+import * as queue from "./queue";
+
+const LINUX_IMAGE = {name: "linux", path: "automation/taskcluster/docker"};
+const FUZZ_IMAGE = {name: "fuzz", path: "automation/taskcluster/docker-fuzz"};
+
+const WINDOWS_CHECKOUT_CMD =
+ "bash -c \"hg clone -r $NSS_HEAD_REVISION $NSS_HEAD_REPOSITORY nss || " +
+ "(sleep 2; hg clone -r $NSS_HEAD_REVISION $NSS_HEAD_REPOSITORY nss) || " +
+ "(sleep 5; hg clone -r $NSS_HEAD_REVISION $NSS_HEAD_REPOSITORY nss)\"";
+
+/*****************************************************************************/
+
+queue.filter(task => {
+ if (task.group == "Builds") {
+ // Remove extra builds on {A,UB}San and ARM.
+ if (task.collection == "asan" || task.platform == "aarch64") {
+ return false;
+ }
+
+ // Remove extra builds w/o libpkix for non-linux64-debug.
+ if (task.symbol == "noLibpkix" &&
+ (task.platform != "linux64" || task.collection != "debug")) {
+ return false;
+ }
+
+ // Make modular builds only on Linux x64.
+ if (task.symbol == "modular" && task.platform != "linux64") {
+ return false;
+ }
+ }
+
+ if (task.tests == "bogo" || task.tests == "interop") {
+ // No windows
+ if (task.platform == "windows2012-64") {
+ return false;
+ }
+
+ // No ARM; TODO: enable
+ if (task.platform == "aarch64") {
+ return false;
+ }
+ }
+
+ // GYP builds with -Ddisable_libpkix=1 by default.
+ if ((task.collection == "gyp" || task.collection == "asan"
+ || task.platform == "aarch64") && task.tests == "chains") {
+ return false;
+ }
+
+ return true;
+});
+
+queue.map(task => {
+ if (task.collection == "asan") {
+ // CRMF and FIPS tests still leak, unfortunately.
+ if (task.tests == "crmf" || task.tests == "fips") {
+ task.env.ASAN_OPTIONS = "detect_leaks=0";
+ }
+ }
+
+ // Windows is slow.
+ if (task.platform == "windows2012-64" && task.tests == "chains") {
+ task.maxRunTime = 7200;
+ }
+
+ return task;
+});
+
+/*****************************************************************************/
+
+export default async function main() {
+ await scheduleLinux("Linux 32 (opt)", {
+ env: {BUILD_OPT: "1"},
+ platform: "linux32",
+ image: LINUX_IMAGE
+ });
+
+ await scheduleLinux("Linux 32 (debug)", {
+ platform: "linux32",
+ collection: "debug",
+ image: LINUX_IMAGE
+ });
+
+ await scheduleLinux("Linux 64 (opt)", {
+ env: {USE_64: "1", BUILD_OPT: "1"},
+ platform: "linux64",
+ image: LINUX_IMAGE
+ });
+
+ await scheduleLinux("Linux 64 (debug)", {
+ env: {USE_64: "1"},
+ platform: "linux64",
+ collection: "debug",
+ image: LINUX_IMAGE
+ });
+
+ await scheduleLinux("Linux 64 (debug, gyp)", {
+ command: [
+ "/bin/bash",
+ "-c",
+ "bin/checkout.sh && nss/automation/taskcluster/scripts/build_gyp.sh"
+ ],
+ platform: "linux64",
+ collection: "gyp",
+ image: LINUX_IMAGE
+ });
+
+ await scheduleLinux("Linux 64 (GYP, ASan, debug)", {
+ command: [
+ "/bin/bash",
+ "-c",
+ "bin/checkout.sh && nss/automation/taskcluster/scripts/build_gyp.sh -g -v --ubsan --asan"
+ ],
+ env: {
+ UBSAN_OPTIONS: "print_stacktrace=1",
+ NSS_DISABLE_ARENA_FREE_LIST: "1",
+ NSS_DISABLE_UNLOAD: "1",
+ CC: "clang",
+ CCC: "clang++",
+ },
+ platform: "linux64",
+ collection: "asan",
+ image: LINUX_IMAGE
+ });
+
+ await scheduleWindows("Windows 2012 64 (opt)", {
+ env: {BUILD_OPT: "1"}
+ });
+
+ await scheduleWindows("Windows 2012 64 (debug)", {
+ collection: "debug"
+ });
+
+ await scheduleFuzzing();
+
+ await scheduleTestBuilds();
+
+ await scheduleTools();
+
+ let aarch64_base = {
+ image: "franziskus/nss-aarch64-ci",
+ provisioner: "localprovisioner",
+ workerType: "nss-aarch64",
+ platform: "aarch64",
+ maxRunTime: 7200
+ };
+
+ await scheduleLinux("Linux AArch64 (debug)",
+ merge({
+ command: [
+ "/bin/bash",
+ "-c",
+ "bin/checkout.sh && nss/automation/taskcluster/scripts/build_gyp.sh"
+ ],
+ collection: "debug",
+ }, aarch64_base)
+ );
+
+ await scheduleLinux("Linux AArch64 (opt)",
+ merge({
+ command: [
+ "/bin/bash",
+ "-c",
+ "bin/checkout.sh && nss/automation/taskcluster/scripts/build_gyp.sh --opt"
+ ],
+ collection: "opt",
+ }, aarch64_base)
+ );
+}
+
+/*****************************************************************************/
+
+async function scheduleLinux(name, base) {
+ // Build base definition.
+ let build_base = merge({
+ command: [
+ "/bin/bash",
+ "-c",
+ "bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh"
+ ],
+ artifacts: {
+ public: {
+ expires: 24 * 7,
+ type: "directory",
+ path: "/home/worker/artifacts"
+ }
+ },
+ kind: "build",
+ symbol: "B"
+ }, base);
+
+ // The task that builds NSPR+NSS.
+ let task_build = queue.scheduleTask(merge(build_base, {name}));
+
+ // The task that generates certificates.
+ let task_cert = queue.scheduleTask(merge(build_base, {
+ name: "Certificates",
+ command: [
+ "/bin/bash",
+ "-c",
+ "bin/checkout.sh && nss/automation/taskcluster/scripts/gen_certs.sh"
+ ],
+ parent: task_build,
+ symbol: "Certs"
+ }));
+
+ // Schedule tests.
+ scheduleTests(task_build, task_cert, merge(base, {
+ command: [
+ "/bin/bash",
+ "-c",
+ "bin/checkout.sh && nss/automation/taskcluster/scripts/run_tests.sh"
+ ]
+ }));
+
+ // Extra builds.
+ let extra_base = merge({group: "Builds"}, build_base);
+ queue.scheduleTask(merge(extra_base, {
+ name: `${name} w/ clang-3.9`,
+ env: {
+ CC: "clang",
+ CCC: "clang++",
+ },
+ symbol: "clang-3.9"
+ }));
+
+ queue.scheduleTask(merge(extra_base, {
+ name: `${name} w/ gcc-4.8`,
+ env: {
+ CC: "gcc-4.8",
+ CCC: "g++-4.8"
+ },
+ symbol: "gcc-4.8"
+ }));
+
+ queue.scheduleTask(merge(extra_base, {
+ name: `${name} w/ gcc-6.1`,
+ env: {
+ CC: "gcc-6",
+ CCC: "g++-6"
+ },
+ symbol: "gcc-6.1"
+ }));
+
+ queue.scheduleTask(merge(extra_base, {
+ name: `${name} w/ NSS_DISABLE_LIBPKIX=1`,
+ env: {NSS_DISABLE_LIBPKIX: "1"},
+ symbol: "noLibpkix"
+ }));
+
+ queue.scheduleTask(merge(extra_base, {
+ name: `${name} w/ modular builds`,
+ env: {NSS_BUILD_MODULAR: "1"},
+ symbol: "modular"
+ }));
+
+ return queue.submit();
+}
+
+/*****************************************************************************/
+
+function scheduleFuzzingRun(base, name, target, max_len, symbol = null, corpus = null) {
+ const MAX_FUZZ_TIME = 300;
+
+ queue.scheduleTask(merge(base, {
+ name,
+ command: [
+ "/bin/bash",
+ "-c",
+ "bin/checkout.sh && nss/automation/taskcluster/scripts/fuzz.sh " +
+ `${target} nss/fuzz/corpus/${corpus || target} ` +
+ `-max_total_time=${MAX_FUZZ_TIME} ` +
+ `-max_len=${max_len}`
+ ],
+ symbol: symbol || name
+ }));
+}
+
+async function scheduleFuzzing() {
+ let base = {
+ env: {
+ ASAN_OPTIONS: "allocator_may_return_null=1",
+ UBSAN_OPTIONS: "print_stacktrace=1",
+ NSS_DISABLE_ARENA_FREE_LIST: "1",
+ NSS_DISABLE_UNLOAD: "1",
+ CC: "clang",
+ CCC: "clang++"
+ },
+ features: ["allowPtrace"],
+ platform: "linux64",
+ collection: "fuzz",
+ image: FUZZ_IMAGE
+ };
+
+ // Build base definition.
+ let build_base = merge({
+ command: [
+ "/bin/bash",
+ "-c",
+ "bin/checkout.sh && " +
+ "nss/automation/taskcluster/scripts/build_gyp.sh -g -v --fuzz"
+ ],
+ artifacts: {
+ public: {
+ expires: 24 * 7,
+ type: "directory",
+ path: "/home/worker/artifacts"
+ }
+ },
+ kind: "build",
+ symbol: "B"
+ }, base);
+
+ // The task that builds NSPR+NSS.
+ let task_build = queue.scheduleTask(merge(build_base, {
+ name: "Linux x64 (debug, fuzz)"
+ }));
+
+ // The task that builds NSPR+NSS (TLS fuzzing mode).
+ let task_build_tls = queue.scheduleTask(merge(build_base, {
+ name: "Linux x64 (debug, TLS fuzz)",
+ symbol: "B",
+ group: "TLS",
+ command: [
+ "/bin/bash",
+ "-c",
+ "bin/checkout.sh && " +
+ "nss/automation/taskcluster/scripts/build_gyp.sh -g -v --fuzz=tls"
+ ],
+ }));
+
+ // Schedule tests.
+ queue.scheduleTask(merge(base, {
+ parent: task_build_tls,
+ name: "Gtests",
+ command: [
+ "/bin/bash",
+ "-c",
+ "bin/checkout.sh && nss/automation/taskcluster/scripts/run_tests.sh"
+ ],
+ env: {GTESTFILTER: "*Fuzz*"},
+ tests: "ssl_gtests gtests",
+ cycle: "standard",
+ symbol: "Gtest",
+ kind: "test"
+ }));
+
+ // Schedule fuzzing runs.
+ let run_base = merge(base, {parent: task_build, kind: "test"});
+ scheduleFuzzingRun(run_base, "CertDN", "certDN", 4096);
+ scheduleFuzzingRun(run_base, "QuickDER", "quickder", 10000);
+
+ // Schedule MPI fuzzing runs.
+ let mpi_base = merge(run_base, {group: "MPI"});
+ let mpi_names = ["add", "addmod", "div", "expmod", "mod", "mulmod", "sqr",
+ "sqrmod", "sub", "submod"];
+ for (let name of mpi_names) {
+ scheduleFuzzingRun(mpi_base, `MPI (${name})`, `mpi-${name}`, 4096, name);
+ }
+ scheduleFuzzingRun(mpi_base, `MPI (invmod)`, `mpi-invmod`, 256, "invmod");
+
+ // Schedule TLS fuzzing runs (non-fuzzing mode).
+ let tls_base = merge(run_base, {group: "TLS"});
+ scheduleFuzzingRun(tls_base, "TLS Client", "tls-client", 20000, "client-nfm",
+ "tls-client-no_fuzzer_mode");
+
+ // Schedule TLS fuzzing runs (fuzzing mode).
+ let tls_fm_base = merge(tls_base, {parent: task_build_tls});
+ scheduleFuzzingRun(tls_fm_base, "TLS Client", "tls-client", 20000, "client");
+
+ return queue.submit();
+}
+
+/*****************************************************************************/
+
+async function scheduleTestBuilds() {
+ let base = {
+ platform: "linux64",
+ collection: "gyp",
+ group: "Test",
+ image: LINUX_IMAGE
+ };
+
+ // Build base definition.
+ let build = merge({
+ command: [
+ "/bin/bash",
+ "-c",
+ "bin/checkout.sh && " +
+ "nss/automation/taskcluster/scripts/build_gyp.sh -g -v --test --ct-verif"
+ ],
+ artifacts: {
+ public: {
+ expires: 24 * 7,
+ type: "directory",
+ path: "/home/worker/artifacts"
+ }
+ },
+ kind: "build",
+ symbol: "B",
+ name: "Linux 64 (debug, gyp, test)"
+ }, base);
+
+ // The task that builds NSPR+NSS.
+ let task_build = queue.scheduleTask(build);
+
+ // Schedule tests.
+ queue.scheduleTask(merge(base, {
+ parent: task_build,
+ name: "mpi",
+ command: [
+ "/bin/bash",
+ "-c",
+ "bin/checkout.sh && nss/automation/taskcluster/scripts/run_tests.sh"
+ ],
+ tests: "mpi",
+ cycle: "standard",
+ symbol: "mpi",
+ kind: "test"
+ }));
+
+ return queue.submit();
+}
+
+
+/*****************************************************************************/
+
+async function scheduleWindows(name, base) {
+ base = merge(base, {
+ workerType: "nss-win2012r2",
+ platform: "windows2012-64",
+ env: {
+ PATH: "c:\\mozilla-build\\python;c:\\mozilla-build\\msys\\local\\bin;" +
+ "c:\\mozilla-build\\7zip;c:\\mozilla-build\\info-zip;" +
+ "c:\\mozilla-build\\python\\Scripts;c:\\mozilla-build\\yasm;" +
+ "c:\\mozilla-build\\msys\\bin;c:\\Windows\\system32;" +
+ "c:\\mozilla-build\\upx391w;c:\\mozilla-build\\moztools-x64\\bin;" +
+ "c:\\mozilla-build\\wget",
+ DOMSUF: "localdomain",
+ HOST: "localhost",
+ USE_64: "1"
+ }
+ });
+
+ // Build base definition.
+ let build_base = merge(base, {
+ command: [
+ WINDOWS_CHECKOUT_CMD,
+ "bash -c nss/automation/taskcluster/windows/build.sh"
+ ],
+ artifacts: [{
+ expires: 24 * 7,
+ type: "directory",
+ path: "public\\build"
+ }],
+ kind: "build",
+ symbol: "B"
+ });
+
+ // The task that builds NSPR+NSS.
+ let task_build = queue.scheduleTask(merge(build_base, {name}));
+
+ // The task that generates certificates.
+ let task_cert = queue.scheduleTask(merge(build_base, {
+ name: "Certificates",
+ command: [
+ WINDOWS_CHECKOUT_CMD,
+ "bash -c nss/automation/taskcluster/windows/gen_certs.sh"
+ ],
+ parent: task_build,
+ symbol: "Certs"
+ }));
+
+ // Schedule tests.
+ scheduleTests(task_build, task_cert, merge(base, {
+ command: [
+ WINDOWS_CHECKOUT_CMD,
+ "bash -c nss/automation/taskcluster/windows/run_tests.sh"
+ ]
+ }));
+
+ return queue.submit();
+}
+
+/*****************************************************************************/
+
+function scheduleTests(task_build, task_cert, test_base) {
+ test_base = merge({kind: "test"}, test_base);
+
+ // Schedule tests that do NOT need certificates.
+ let no_cert_base = merge(test_base, {parent: task_build});
+ queue.scheduleTask(merge(no_cert_base, {
+ name: "Gtests", symbol: "Gtest", tests: "ssl_gtests gtests", cycle: "standard"
+ }));
+ queue.scheduleTask(merge(no_cert_base, {
+ name: "Bogo tests", symbol: "Bogo", tests: "bogo", cycle: "standard"
+ }));
+ queue.scheduleTask(merge(no_cert_base, {
+ name: "Interop tests", symbol: "Interop", tests: "interop", cycle: "standard"
+ }));
+ queue.scheduleTask(merge(no_cert_base, {
+ name: "Chains tests", symbol: "Chains", tests: "chains"
+ }));
+ queue.scheduleTask(merge(no_cert_base, {
+ name: "Cipher tests", symbol: "Cipher", tests: "cipher"
+ }));
+ queue.scheduleTask(merge(no_cert_base, {
+ name: "EC tests", symbol: "EC", tests: "ec"
+ }));
+ queue.scheduleTask(merge(no_cert_base, {
+ name: "Lowhash tests", symbol: "Lowhash", tests: "lowhash"
+ }));
+ queue.scheduleTask(merge(no_cert_base, {
+ name: "SDR tests", symbol: "SDR", tests: "sdr"
+ }));
+
+ // Schedule tests that need certificates.
+ let cert_base = merge(test_base, {parent: task_cert});
+ queue.scheduleTask(merge(cert_base, {
+ name: "CRMF tests", symbol: "CRMF", tests: "crmf"
+ }));
+ queue.scheduleTask(merge(cert_base, {
+ name: "DB tests", symbol: "DB", tests: "dbtests"
+ }));
+ queue.scheduleTask(merge(cert_base, {
+ name: "FIPS tests", symbol: "FIPS", tests: "fips"
+ }));
+ queue.scheduleTask(merge(cert_base, {
+ name: "Merge tests", symbol: "Merge", tests: "merge"
+ }));
+ queue.scheduleTask(merge(cert_base, {
+ name: "S/MIME tests", symbol: "SMIME", tests: "smime"
+ }));
+ queue.scheduleTask(merge(cert_base, {
+ name: "Tools tests", symbol: "Tools", tests: "tools"
+ }));
+
+ // SSL tests, need certificates too.
+ let ssl_base = merge(cert_base, {tests: "ssl", group: "SSL"});
+ queue.scheduleTask(merge(ssl_base, {
+ name: "SSL tests (standard)", symbol: "standard", cycle: "standard"
+ }));
+ queue.scheduleTask(merge(ssl_base, {
+ name: "SSL tests (pkix)", symbol: "pkix", cycle: "pkix"
+ }));
+ queue.scheduleTask(merge(ssl_base, {
+ name: "SSL tests (sharedb)", symbol: "sharedb", cycle: "sharedb"
+ }));
+ queue.scheduleTask(merge(ssl_base, {
+ name: "SSL tests (upgradedb)", symbol: "upgradedb", cycle: "upgradedb"
+ }));
+}
+
+/*****************************************************************************/
+
+async function scheduleTools() {
+ let base = {
+ image: LINUX_IMAGE,
+ platform: "nss-tools",
+ kind: "test"
+ };
+
+ queue.scheduleTask(merge(base, {
+ symbol: "clang-format-3.9",
+ name: "clang-format-3.9",
+ command: [
+ "/bin/bash",
+ "-c",
+ "bin/checkout.sh && nss/automation/taskcluster/scripts/run_clang_format.sh"
+ ]
+ }));
+
+ queue.scheduleTask(merge(base, {
+ symbol: "scan-build-3.9",
+ name: "scan-build-3.9",
+ env: {
+ USE_64: "1",
+ CC: "clang",
+ CCC: "clang++",
+ },
+ artifacts: {
+ public: {
+ expires: 24 * 7,
+ type: "directory",
+ path: "/home/worker/artifacts"
+ }
+ },
+ command: [
+ "/bin/bash",
+ "-c",
+ "bin/checkout.sh && nss/automation/taskcluster/scripts/run_scan_build.sh"
+ ]
+ }));
+
+ return queue.submit();
+}
diff --git a/nss/automation/taskcluster/graph/src/image_builder.js b/nss/automation/taskcluster/graph/src/image_builder.js
new file mode 100644
index 0000000..bc90e02
--- /dev/null
+++ b/nss/automation/taskcluster/graph/src/image_builder.js
@@ -0,0 +1,62 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import * as queue from "./queue";
+import context_hash from "./context_hash";
+import taskcluster from "taskcluster-client";
+
+async function taskHasImageArtifact(taskId) {
+ let queue = new taskcluster.Queue();
+ let {artifacts} = await queue.listLatestArtifacts(taskId);
+ return artifacts.some(artifact => artifact.name == "public/image.tar");
+}
+
+async function findTaskWithImageArtifact(ns) {
+ let index = new taskcluster.Index();
+ let {taskId} = await index.findTask(ns);
+ let has_image = await taskHasImageArtifact(taskId);
+ return has_image ? taskId : null;
+}
+
+export async function findTask({name, path}) {
+ let hash = await context_hash(path);
+ let ns = `docker.images.v1.${process.env.TC_PROJECT}.${name}.hash.${hash}`;
+ return findTaskWithImageArtifact(ns).catch(() => null);
+}
+
+export async function buildTask({name, path}) {
+ let hash = await context_hash(path);
+ let ns = `docker.images.v1.${process.env.TC_PROJECT}.${name}.hash.${hash}`;
+
+ return {
+ name: "Image Builder",
+ image: "taskcluster/image_builder:0.1.5",
+ routes: ["index." + ns],
+ env: {
+ HEAD_REPOSITORY: process.env.NSS_HEAD_REPOSITORY,
+ BASE_REPOSITORY: process.env.NSS_HEAD_REPOSITORY,
+ HEAD_REV: process.env.NSS_HEAD_REVISION,
+ HEAD_REF: process.env.NSS_HEAD_REVISION,
+ PROJECT: process.env.TC_PROJECT,
+ CONTEXT_PATH: path,
+ HASH: hash
+ },
+ artifacts: {
+ "public/image.tar": {
+ type: "file",
+ expires: 24 * 90,
+ path: "/artifacts/image.tar"
+ }
+ },
+ command: [
+ "/bin/bash",
+ "-c",
+ "/home/worker/bin/build_image.sh"
+ ],
+ platform: "nss-decision",
+ features: ["dind"],
+ kind: "build",
+ symbol: "I"
+ };
+}
diff --git a/nss/automation/taskcluster/graph/src/index.js b/nss/automation/taskcluster/graph/src/index.js
new file mode 100644
index 0000000..4153e1b
--- /dev/null
+++ b/nss/automation/taskcluster/graph/src/index.js
@@ -0,0 +1,14 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import * as try_syntax from "./try_syntax";
+import extend from "./extend";
+
+// Init try syntax filter.
+if (process.env.TC_PROJECT == "nss-try") {
+ try_syntax.initFilter();
+}
+
+// Extend the task graph.
+extend().catch(console.error);
diff --git a/nss/automation/taskcluster/graph/src/merge.js b/nss/automation/taskcluster/graph/src/merge.js
new file mode 100644
index 0000000..17043dd
--- /dev/null
+++ b/nss/automation/taskcluster/graph/src/merge.js
@@ -0,0 +1,10 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import {recursive as merge} from "merge";
+
+// We always want to clone.
+export default function (...args) {
+ return merge(true, ...args);
+}
diff --git a/nss/automation/taskcluster/graph/src/queue.js b/nss/automation/taskcluster/graph/src/queue.js
new file mode 100644
index 0000000..b78c54d
--- /dev/null
+++ b/nss/automation/taskcluster/graph/src/queue.js
@@ -0,0 +1,248 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import {clone} from "merge";
+import merge from "./merge";
+import slugid from "slugid";
+import taskcluster from "taskcluster-client";
+import * as image_builder from "./image_builder";
+
+let maps = [];
+let filters = [];
+
+let tasks = new Map();
+let image_tasks = new Map();
+
+let queue = new taskcluster.Queue({
+ baseUrl: "http://taskcluster/queue/v1"
+});
+
+function fromNow(hours) {
+ let d = new Date();
+ d.setHours(d.getHours() + (hours|0));
+ return d.toJSON();
+}
+
+function parseRoutes(routes) {
+ return [
+ `tc-treeherder.v2.${process.env.TC_PROJECT}.${process.env.NSS_HEAD_REVISION}.${process.env.NSS_PUSHLOG_ID}`,
+ ...routes
+ ];
+}
+
+function parseFeatures(list) {
+ return list.reduce((map, feature) => {
+ map[feature] = true;
+ return map;
+ }, {});
+}
+
+function parseArtifacts(artifacts) {
+ let copy = clone(artifacts);
+ Object.keys(copy).forEach(key => {
+ copy[key].expires = fromNow(copy[key].expires);
+ });
+ return copy;
+}
+
+function parseCollection(name) {
+ let collection = {};
+ collection[name] = true;
+ return collection;
+}
+
+function parseTreeherder(def) {
+ let treeherder = {
+ build: {
+ platform: def.platform
+ },
+ machine: {
+ platform: def.platform
+ },
+ symbol: def.symbol,
+ jobKind: def.kind
+ };
+
+ if (def.group) {
+ treeherder.groupSymbol = def.group;
+ }
+
+ if (def.collection) {
+ treeherder.collection = parseCollection(def.collection);
+ }
+
+ if (def.tier) {
+ treeherder.tier = def.tier;
+ }
+
+ return treeherder;
+}
+
+function convertTask(def) {
+ let scopes = [];
+ let dependencies = [];
+
+ let env = merge({
+ NSS_HEAD_REPOSITORY: process.env.NSS_HEAD_REPOSITORY,
+ NSS_HEAD_REVISION: process.env.NSS_HEAD_REVISION
+ }, def.env || {});
+
+ if (def.parent) {
+ dependencies.push(def.parent);
+ env.TC_PARENT_TASK_ID = def.parent;
+ }
+
+ if (def.tests) {
+ env.NSS_TESTS = def.tests;
+ }
+
+ if (def.cycle) {
+ env.NSS_CYCLES = def.cycle;
+ }
+
+ let payload = {
+ env,
+ command: def.command,
+ maxRunTime: def.maxRunTime || 3600
+ };
+
+ if (def.image) {
+ payload.image = def.image;
+ }
+
+ if (def.artifacts) {
+ payload.artifacts = parseArtifacts(def.artifacts);
+ }
+
+ if (def.features) {
+ payload.features = parseFeatures(def.features);
+
+ if (payload.features.allowPtrace) {
+ scopes.push("docker-worker:feature:allowPtrace");
+ }
+ }
+
+ return {
+ provisionerId: def.provisioner || "aws-provisioner-v1",
+ workerType: def.workerType || "hg-worker",
+ schedulerId: "task-graph-scheduler",
+
+ scopes,
+ created: fromNow(0),
+ deadline: fromNow(24),
+
+ dependencies,
+ routes: parseRoutes(def.routes || []),
+
+ metadata: {
+ name: def.name,
+ description: def.name,
+ owner: process.env.TC_OWNER,
+ source: process.env.TC_SOURCE
+ },
+
+ payload,
+
+ extra: {
+ treeherder: parseTreeherder(def)
+ }
+ };
+}
+
+export function map(fun) {
+ maps.push(fun);
+}
+
+export function filter(fun) {
+ filters.push(fun);
+}
+
+export function scheduleTask(def) {
+ let taskId = slugid.v4();
+ tasks.set(taskId, merge({}, def));
+ return taskId;
+}
+
+export async function submit() {
+ let promises = new Map();
+
+ for (let [taskId, task] of tasks) {
+ // Allow filtering tasks before we schedule them.
+ if (!filters.every(filter => filter(task))) {
+ continue;
+ }
+
+ // Allow changing tasks before we schedule them.
+ maps.forEach(map => { task = map(merge({}, task)) });
+
+ let log_id = `${task.name} @ ${task.platform}[${task.collection || "opt"}]`;
+ console.log(`+ Submitting ${log_id}.`);
+
+ let parent = task.parent;
+
+ // Convert the task definition.
+ task = await convertTask(task);
+
+ // Convert the docker image definition.
+ let image_def = task.payload.image;
+ if (image_def && image_def.hasOwnProperty("path")) {
+ let key = `${image_def.name}:${image_def.path}`;
+ let data = {};
+
+ // Check the cache first.
+ if (image_tasks.has(key)) {
+ data = image_tasks.get(key);
+ } else {
+ data.taskId = await image_builder.findTask(image_def);
+ data.isPending = !data.taskId;
+
+ // No task found.
+ if (data.isPending) {
+ let image_task = await image_builder.buildTask(image_def);
+
+ // Schedule a new image builder task immediately.
+ data.taskId = slugid.v4();
+
+ try {
+ await queue.createTask(data.taskId, convertTask(image_task));
+ } catch (e) {
+ console.error("! FAIL: Scheduling image builder task failed.");
+ continue; /* Skip this task on failure. */
+ }
+ }
+
+ // Store in cache.
+ image_tasks.set(key, data);
+ }
+
+ if (data.isPending) {
+ task.dependencies.push(data.taskId);
+ }
+
+ task.payload.image = {
+ path: "public/image.tar",
+ taskId: data.taskId,
+ type: "task-image"
+ };
+ }
+
+ // Wait for the parent task to be created before scheduling dependants.
+ let predecessor = parent ? promises.get(parent) : Promise.resolve();
+
+ promises.set(taskId, predecessor.then(() => {
+ // Schedule the task.
+ return queue.createTask(taskId, task).catch(err => {
+ console.error(`! FAIL: Scheduling ${log_id} failed.`, err);
+ });
+ }));
+ }
+
+ // Wait for all requests to finish.
+ if (promises.length) {
+ await Promise.all([...promises.values()]);
+ console.log("=== Total:", promises.length, "tasks. ===");
+ }
+
+ tasks.clear();
+}
diff --git a/nss/automation/taskcluster/graph/src/try_syntax.js b/nss/automation/taskcluster/graph/src/try_syntax.js
new file mode 100644
index 0000000..e5203e7
--- /dev/null
+++ b/nss/automation/taskcluster/graph/src/try_syntax.js
@@ -0,0 +1,153 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import * as queue from "./queue";
+import intersect from "intersect";
+import parse_args from "minimist";
+
+function parseOptions(opts) {
+ opts = parse_args(opts.split(/\s+/), {
+ default: {build: "do", platform: "all", unittests: "none", tools: "none"},
+ alias: {b: "build", p: "platform", u: "unittests", t: "tools", e: "extra-builds"},
+ string: ["build", "platform", "unittests", "tools", "extra-builds"]
+ });
+
+ // Parse build types (d=debug, o=opt).
+ let builds = intersect(opts.build.split(""), ["d", "o"]);
+
+ // If the given value is nonsense default to debug and opt builds.
+ if (builds.length == 0) {
+ builds = ["d", "o"];
+ }
+
+ // Parse platforms.
+ let allPlatforms = ["linux", "linux64", "linux64-asan", "win64",
+ "linux64-gyp", "linux64-fuzz", "aarch64"];
+ let platforms = intersect(opts.platform.split(/\s*,\s*/), allPlatforms);
+
+ // If the given value is nonsense or "none" default to all platforms.
+ if (platforms.length == 0 && opts.platform != "none") {
+ platforms = allPlatforms;
+ }
+
+ // Parse unit tests.
+ let aliases = {"gtests": "gtest"};
+ let allUnitTests = ["bogo", "crmf", "chains", "cipher", "db", "ec", "fips",
+ "gtest", "interop", "lowhash", "merge", "sdr", "smime", "tools",
+ "ssl", "mpi", "scert", "spki"];
+ let unittests = intersect(opts.unittests.split(/\s*,\s*/).map(t => {
+ return aliases[t] || t;
+ }), allUnitTests);
+
+ // If the given value is "all" run all tests.
+ // If it's nonsense then don't run any tests.
+ if (opts.unittests == "all") {
+ unittests = allUnitTests;
+ } else if (unittests.length == 0) {
+ unittests = [];
+ }
+
+ // Parse tools.
+ let allTools = ["clang-format", "scan-build"];
+ let tools = intersect(opts.tools.split(/\s*,\s*/), allTools);
+
+ // If the given value is "all" run all tools.
+ // If it's nonsense then don't run any tools.
+ if (opts.tools == "all") {
+ tools = allTools;
+ } else if (tools.length == 0) {
+ tools = [];
+ }
+
+ return {
+ builds: builds,
+ platforms: platforms,
+ unittests: unittests,
+ extra: (opts.e == "all"),
+ tools: tools
+ };
+}
+
+function filter(opts) {
+ return function (task) {
+ // Filter tools. We can immediately return here as those
+ // are not affected by platform or build type selectors.
+ if (task.platform == "nss-tools") {
+ return opts.tools.some(tool => {
+ return task.symbol.toLowerCase().startsWith(tool);
+ });
+ }
+
+ // Filter unit tests.
+ if (task.tests) {
+ let found = opts.unittests.some(test => {
+ // TODO: think of something more intelligent here.
+ if (task.symbol.toLowerCase().startsWith("mpi") && test == "mpi") {
+ return true;
+ }
+ return (task.group || task.symbol).toLowerCase().startsWith(test);
+ });
+
+ if (!found) {
+ return false;
+ }
+ }
+
+ // Filter extra builds.
+ if (task.group == "Builds" && !opts.extra) {
+ return false;
+ }
+
+ let coll = name => name == (task.collection || "opt");
+
+ // Filter by platform.
+ let found = opts.platforms.some(platform => {
+ let aliases = {
+ "linux": "linux32",
+ "linux64-asan": "linux64",
+ "linux64-fuzz": "linux64",
+ "linux64-gyp": "linux64",
+ "win64": "windows2012-64"
+ };
+
+ // Check the platform name.
+ let keep = (task.platform == (aliases[platform] || platform));
+
+ // Additional checks.
+ if (platform == "linux64-asan") {
+ keep &= coll("asan");
+ } else if (platform == "linux64-gyp") {
+ keep &= coll("gyp");
+ } else if (platform == "linux64-fuzz") {
+ keep &= coll("fuzz");
+ } else {
+ keep &= coll("opt") || coll("debug");
+ }
+
+ return keep;
+ });
+
+ if (!found) {
+ return false;
+ }
+
+ // Finally, filter by build type.
+ let isDebug = coll("debug") || coll("asan") || coll("gyp") ||
+ coll("fuzz");
+ return (isDebug && opts.builds.includes("d")) ||
+ (!isDebug && opts.builds.includes("o"));
+ }
+}
+
+export function initFilter() {
+ let comment = process.env.TC_COMMENT || "";
+
+ // Check for try syntax in changeset comment.
+ let match = comment.match(/^\s*try:\s*(.*)\s*$/);
+
+ // Add try syntax filter.
+ if (match) {
+ queue.filter(filter(parseOptions(match[1])));
+ }
+}
diff --git a/nss/automation/taskcluster/scripts/build.sh b/nss/automation/taskcluster/scripts/build.sh
new file mode 100755
index 0000000..649fdaa
--- /dev/null
+++ b/nss/automation/taskcluster/scripts/build.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+
+source $(dirname "$0")/tools.sh
+
+if [ -n "$NSS_BUILD_MODULAR" ]; then
+ $(dirname "$0")/build_nspr.sh || exit $?
+ $(dirname "$0")/build_util.sh || exit $?
+ $(dirname "$0")/build_softoken.sh || exit $?
+ $(dirname "$0")/build_nss.sh || exit $?
+ exit
+fi
+
+# Clone NSPR if needed.
+hg_clone https://hg.mozilla.org/projects/nspr ./nspr default
+
+# Build.
+make -C nss nss_build_all
+
+# Package.
+mkdir artifacts
+tar cvfjh artifacts/dist.tar.bz2 dist
diff --git a/nss/automation/taskcluster/scripts/build_gyp.sh b/nss/automation/taskcluster/scripts/build_gyp.sh
new file mode 100755
index 0000000..7190bd5
--- /dev/null
+++ b/nss/automation/taskcluster/scripts/build_gyp.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+
+source $(dirname "$0")/tools.sh
+
+# Clone NSPR if needed.
+hg_clone https://hg.mozilla.org/projects/nspr ./nspr default
+
+# Build.
+nss/build.sh -g -v "$@"
+
+# Package.
+mkdir artifacts
+tar cvfjh artifacts/dist.tar.bz2 dist
diff --git a/nss/automation/taskcluster/scripts/build_nspr.sh b/nss/automation/taskcluster/scripts/build_nspr.sh
new file mode 100755
index 0000000..4d19034
--- /dev/null
+++ b/nss/automation/taskcluster/scripts/build_nspr.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+
+set -v -e -x
+
+source $(dirname $0)/tools.sh
+
+# Clone NSPR if needed.
+hg_clone https://hg.mozilla.org/projects/nspr nspr default
+
+# Build.
+rm -rf dist
+make -C nss build_nspr
+
+# Package.
+test -d artifacts || mkdir artifacts
+rm -rf dist-nspr
+mv dist dist-nspr
+tar cvfjh artifacts/dist-nspr.tar.bz2 dist-nspr
diff --git a/nss/automation/taskcluster/scripts/build_nss.sh b/nss/automation/taskcluster/scripts/build_nss.sh
new file mode 100755
index 0000000..b909bc3
--- /dev/null
+++ b/nss/automation/taskcluster/scripts/build_nss.sh
@@ -0,0 +1,39 @@
+#!/usr/bin/env bash
+
+set -v -e -x
+
+source $(dirname $0)/tools.sh
+source $(dirname $0)/split.sh
+
+test -d dist-softoken || { echo "run build_softoken.sh first" 1>&2; exit 1; }
+
+rm -rf nss-nss
+split_nss nss nss-nss
+
+# Build.
+export NSS_BUILD_WITHOUT_SOFTOKEN=1
+export NSS_USE_SYSTEM_FREEBL=1
+
+platform=`make -s -C nss platform`
+
+export NSPR_LIB_DIR="$PWD/dist-nspr/$platform/lib"
+export NSSUTIL_LIB_DIR="$PWD/dist-util/$platform/lib"
+export FREEBL_LIB_DIR="$PWD/dist-softoken/$platform/lib"
+export SOFTOKEN_LIB_DIR="$PWD/dist-softoken/$platform/lib"
+export FREEBL_LIBS=-lfreebl
+
+export NSS_NO_PKCS11_BYPASS=1
+export FREEBL_NO_DEPEND=1
+
+export LIBRARY_PATH="$PWD/dist-nspr/$platform/lib:$PWD/dist-util/$platform/lib:$PWD/dist-softoken/$platform/lib"
+export LD_LIBRARY_PATH="$LIBRARY_PATH:$LD_LIBRARY_PATH"
+export INCLUDES="-I$PWD/dist-nspr/$platform/include -I$PWD/dist-util/public/nss -I$PWD/dist-softoken/public/nss"
+
+rm -rf dist
+make -C nss-nss nss_build_all
+
+# Package.
+test -d artifacts || mkdir artifacts
+rm -rf dist-nss
+mv dist dist-nss
+tar cvfjh artifacts/dist-nss.tar.bz2 dist-nss
diff --git a/nss/automation/taskcluster/scripts/build_softoken.sh b/nss/automation/taskcluster/scripts/build_softoken.sh
new file mode 100755
index 0000000..e5aaecc
--- /dev/null
+++ b/nss/automation/taskcluster/scripts/build_softoken.sh
@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+
+set -v -e -x
+
+source $(dirname $0)/tools.sh
+source $(dirname $0)/split.sh
+
+test -d dist-util || { echo "run build_util.sh first" 1>&2; exit 1; }
+
+rm -rf nss-softoken
+split_softoken nss nss-softoken
+
+# Build.
+platform=`make -s -C nss platform`
+export LIBRARY_PATH="$PWD/dist-nspr/$platform/lib:$PWD/dist-util/$platform/lib"
+export LD_LIBRARY_PATH="$LIBRARY_PATH:$LD_LIBRARY_PATH"
+export INCLUDES="-I$PWD/dist-nspr/$platform/include -I$PWD/dist-util/public/nss"
+export NSS_BUILD_SOFTOKEN_ONLY=1
+
+rm -rf dist
+make -C nss-softoken nss_build_all
+
+mv dist/private/nss/blapi.h dist/public/nss
+mv dist/private/nss/alghmac.h dist/public/nss
+
+# Package.
+test -d artifacts || mkdir artifacts
+rm -rf dist-softoken
+mv dist dist-softoken
+tar cvfjh artifacts/dist-softoken.tar.bz2 dist-softoken
diff --git a/nss/automation/taskcluster/scripts/build_util.sh b/nss/automation/taskcluster/scripts/build_util.sh
new file mode 100755
index 0000000..0d2ecc5
--- /dev/null
+++ b/nss/automation/taskcluster/scripts/build_util.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+
+set -v -e -x
+
+source $(dirname $0)/tools.sh
+source $(dirname $0)/split.sh
+
+rm -rf nss-util
+split_util nss nss-util
+
+# Build.
+platform=`make -s -C nss platform`
+export LIBRARY_PATH="$PWD/dist-nspr/$platform/lib"
+export LD_LIBRARY_PATH="$LIBRARY_PATH:$LD_LIBRARY_PATH"
+export INCLUDES="-I$PWD/dist-nspr/$platform/include"
+export NSS_BUILD_UTIL_ONLY=1
+
+rm -rf dist
+make -C nss-util nss_build_all
+
+# Package.
+test -d artifacts || mkdir artifacts
+rm -rf dist-util
+mv dist dist-util
+tar cvfjh artifacts/dist-util.tar.bz2 dist-util
diff --git a/nss/automation/taskcluster/scripts/extend_task_graph.sh b/nss/automation/taskcluster/scripts/extend_task_graph.sh
new file mode 100755
index 0000000..ade84cd
--- /dev/null
+++ b/nss/automation/taskcluster/scripts/extend_task_graph.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+source $(dirname "$0")/tools.sh
+
+mkdir -p /home/worker/artifacts
+
+# Install Node.JS dependencies.
+cd nss/automation/taskcluster/graph/ && npm install
+
+# Extend the task graph.
+node lib/index.js
diff --git a/nss/automation/taskcluster/scripts/fuzz.sh b/nss/automation/taskcluster/scripts/fuzz.sh
new file mode 100755
index 0000000..cd3ed93
--- /dev/null
+++ b/nss/automation/taskcluster/scripts/fuzz.sh
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+
+source $(dirname "$0")/tools.sh
+
+type="$1"
+shift
+
+# Fetch artifact if needed.
+fetch_dist
+
+# Clone corpus.
+./nss/fuzz/clone_corpus.sh
+
+# Ensure we have a corpus.
+if [ ! -d "nss/fuzz/corpus/$type" ]; then
+ mkdir -p nss/fuzz/corpus/$type
+
+ set +x
+
+ # Create a corpus out of what we have.
+ for f in $(find nss/fuzz/corpus -type f); do
+ cp $f "nss/fuzz/corpus/$type"
+ done
+
+ set -x
+fi
+
+# Fetch objdir name.
+objdir=$(cat dist/latest)
+
+# Run nssfuzz.
+dist/$objdir/bin/nssfuzz-"$type" "$@"
diff --git a/nss/automation/taskcluster/scripts/gen_certs.sh b/nss/automation/taskcluster/scripts/gen_certs.sh
new file mode 100755
index 0000000..b8d4f60
--- /dev/null
+++ b/nss/automation/taskcluster/scripts/gen_certs.sh
@@ -0,0 +1,16 @@
+#!/usr/bin/env bash
+
+source $(dirname "$0")/tools.sh
+
+# Fetch artifact if needed.
+fetch_dist
+
+# Generate certificates.
+NSS_TESTS=cert NSS_CYCLES="standard pkix sharedb" $(dirname $0)/run_tests.sh
+
+# Reset test counter so that test runs pick up our certificates.
+echo 1 > tests_results/security/localhost
+
+# Package.
+mkdir artifacts
+tar cvfjh artifacts/dist.tar.bz2 dist tests_results
diff --git a/nss/automation/taskcluster/scripts/run_clang_format.sh b/nss/automation/taskcluster/scripts/run_clang_format.sh
new file mode 100755
index 0000000..3a36042
--- /dev/null
+++ b/nss/automation/taskcluster/scripts/run_clang_format.sh
@@ -0,0 +1,60 @@
+#!/usr/bin/env bash
+
+source $(dirname "$0")/tools.sh
+
+# Apply clang-format on the provided folder and verify that this doesn't change any file.
+# If any file differs after formatting, the script eventually exits with 1.
+# Any differences between formatted and unformatted files is printed to stdout to give a hint what's wrong.
+
+# Includes a default set of directories.
+
+if [ $# -gt 0 ]; then
+ dirs=("$@")
+else
+ top=$(dirname $0)/../../..
+ dirs=( \
+ "$top/cmd" \
+ "$top/fuzz" \
+ "$top/lib/base" \
+ "$top/lib/certdb" \
+ "$top/lib/certhigh" \
+ "$top/lib/ckfw" \
+ "$top/lib/crmf" \
+ "$top/lib/cryptohi" \
+ "$top/lib/dbm" \
+ "$top/lib/dev" \
+ "$top/lib/freebl" \
+ "$top/lib/jar" \
+ "$top/lib/nss" \
+ "$top/lib/pk11wrap" \
+ "$top/lib/pkcs7" \
+ "$top/lib/pkcs12" \
+ "$top/lib/pki" \
+ "$top/lib/smime" \
+ "$top/lib/softoken" \
+ "$top/lib/ssl" \
+ "$top/lib/sysinit" \
+ "$top/lib/util" \
+ "$top/gtests/common" \
+ "$top/gtests/der_gtest" \
+ "$top/gtests/freebl_gtest" \
+ "$top/gtests/pk11_gtest" \
+ "$top/gtests/ssl_gtest" \
+ "$top/gtests/util_gtest" \
+ "$top/nss-tool" \
+ "$top/cpputil" \
+ )
+fi
+
+for dir in "${dirs[@]}"; do
+ find "$dir" -type f \( -name '*.[ch]' -o -name '*.cc' \) -exec clang-format -i {} \+
+done
+
+TMPFILE=$(mktemp /tmp/$(basename $0).XXXXXX)
+trap 'rm $TMPFILE' exit
+if (cd $(dirname $0); hg root >/dev/null 2>&1); then
+ hg diff --git "$top" | tee $TMPFILE
+else
+ git -C "$top" diff | tee $TMPFILE
+fi
+[[ ! -s $TMPFILE ]]
diff --git a/nss/automation/taskcluster/scripts/run_scan_build.sh b/nss/automation/taskcluster/scripts/run_scan_build.sh
new file mode 100755
index 0000000..4024c22
--- /dev/null
+++ b/nss/automation/taskcluster/scripts/run_scan_build.sh
@@ -0,0 +1,51 @@
+#!/usr/bin/env bash
+
+source $(dirname "$0")/tools.sh
+
+# Clone NSPR if needed.
+if [ ! -d "nspr" ]; then
+ hg_clone https://hg.mozilla.org/projects/nspr ./nspr default
+fi
+
+# Build.
+cd nss
+make nss_build_all
+
+# What we want to scan.
+# key: directory to scan
+# value: number of errors expected in that directory
+declare -A scan=( \
+ [lib/base]=0 \
+ [lib/certdb]=0 \
+ [lib/certhigh]=0 \
+ [lib/ckfw]=0 \
+ [lib/crmf]=0 \
+ [lib/cryptohi]=0 \
+ [lib/dev]=0 \
+ [lib/freebl]=0 \
+ [lib/nss]=0 \
+ [lib/ssl]=0 \
+ [lib/util]=0 \
+ )
+
+# remove .OBJ directories to force a rebuild of just the select few
+for i in "${!scan[@]}"; do
+ find "$i" -name "*.OBJ" -exec rm -rf {} \+
+done
+
+# run scan-build (only building affected directories)
+scan-build -o /home/worker/artifacts --use-cc=$CC --use-c++=$CCC make nss_build_all && cd ..
+
+# print errors we found
+set +v +x
+STATUS=0
+for i in "${!scan[@]}"; do
+ n=$(grep -Rn "$i" /home/worker/artifacts/*/report-*.html | wc -l)
+ if [ $n -ne ${scan[$i]} ]; then
+ STATUS=1
+ echo "$(date '+%T') WARNING - TEST-UNEXPECTED-FAIL: $i contains $n scan-build errors"
+ elif [ $n -ne 0 ]; then
+ echo "$(date '+%T') WARNING - TEST-EXPECTED-FAIL: $i contains $n scan-build errors"
+ fi
+done
+exit $STATUS
diff --git a/nss/automation/taskcluster/scripts/run_tests.sh b/nss/automation/taskcluster/scripts/run_tests.sh
new file mode 100755
index 0000000..b8e2676
--- /dev/null
+++ b/nss/automation/taskcluster/scripts/run_tests.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+source $(dirname "$0")/tools.sh
+
+# Fetch artifact if needed.
+fetch_dist
+
+# Run tests.
+cd nss/tests && ./all.sh
diff --git a/nss/automation/taskcluster/scripts/split.sh b/nss/automation/taskcluster/scripts/split.sh
new file mode 100644
index 0000000..c43c3e4
--- /dev/null
+++ b/nss/automation/taskcluster/scripts/split.sh
@@ -0,0 +1,152 @@
+copy_top()
+{
+ srcdir_="$1"
+ dstdir_="$2"
+ files=`find "$srcdir_" -maxdepth 1 -mindepth 1 -type f`
+ for f in $files; do
+ cp -p "$f" "$dstdir_"
+ done
+}
+
+split_util() {
+ nssdir="$1"
+ dstdir="$2"
+
+ # Prepare a source tree only containing files to build nss-util:
+ #
+ # nss/dbm full directory
+ # nss/coreconf full directory
+ # nss top files only
+ # nss/lib top files only
+ # nss/lib/util full directory
+
+ # Copy everything.
+ cp -R $nssdir $dstdir
+
+ # Skip gtests when building.
+ sed '/^DIRS = /s/ gtests$//' $nssdir/manifest.mn > $dstdir/manifest.mn-t && mv $dstdir/manifest.mn-t $dstdir/manifest.mn
+
+ # Remove subdirectories that we don't want.
+ rm -rf $dstdir/cmd
+ rm -rf $dstdir/tests
+ rm -rf $dstdir/lib
+ rm -rf $dstdir/automation
+ rm -rf $dstdir/gtests
+ rm -rf $dstdir/doc
+
+ # Start with an empty cmd lib directories to be filled selectively.
+ mkdir $dstdir/cmd
+ cp $nssdir/cmd/Makefile $dstdir/cmd
+ cp $nssdir/cmd/manifest.mn $dstdir/cmd
+ cp $nssdir/cmd/platlibs.mk $dstdir/cmd
+ cp $nssdir/cmd/platrules.mk $dstdir/cmd
+
+ # Copy some files at the top and the util subdirectory recursively.
+ mkdir $dstdir/lib
+ cp $nssdir/lib/Makefile $dstdir/lib
+ cp $nssdir/lib/manifest.mn $dstdir/lib
+ cp -R $nssdir/lib/util $dstdir/lib/util
+}
+
+split_softoken() {
+ nssdir="$1"
+ dstdir="$2"
+
+ # Prepare a source tree only containing files to build nss-softoken:
+ #
+ # nss/dbm full directory
+ # nss/coreconf full directory
+ # nss top files only
+ # nss/lib top files only
+ # nss/lib/freebl full directory
+ # nss/lib/softoken full directory
+ # nss/lib/softoken/dbm full directory
+
+ # Copy everything.
+ cp -R $nssdir $dstdir
+
+ # Skip gtests when building.
+ sed '/^DIRS = /s/ gtests$//' $nssdir/manifest.mn > $dstdir/manifest.mn-t && mv $dstdir/manifest.mn-t $dstdir/manifest.mn
+
+ # Remove subdirectories that we don't want.
+ rm -rf $dstdir/cmd
+ rm -rf $dstdir/tests
+ rm -rf $dstdir/lib
+ rm -rf $dstdir/pkg
+ rm -rf $dstdir/automation
+ rm -rf $dstdir/gtests
+ rm -rf $dstdir/doc
+
+ # Start with an empty lib directory and copy only what we need.
+ mkdir $dstdir/lib
+ copy_top $nssdir/lib $dstdir/lib
+ cp -R $nssdir/lib/dbm $dstdir/lib/dbm
+ cp -R $nssdir/lib/freebl $dstdir/lib/freebl
+ cp -R $nssdir/lib/softoken $dstdir/lib/softoken
+ cp -R $nssdir/lib/sqlite $dstdir/lib/sqlite
+
+ mkdir $dstdir/cmd
+ copy_top $nssdir/cmd $dstdir/cmd
+ cp -R $nssdir/cmd/bltest $dstdir/cmd/bltest
+ cp -R $nssdir/cmd/ecperf $dstdir/cmd/ecperf
+ cp -R $nssdir/cmd/fbectest $dstdir/cmd/fbectest
+ cp -R $nssdir/cmd/fipstest $dstdir/cmd/fipstest
+ cp -R $nssdir/cmd/lib $dstdir/cmd/lib
+ cp -R $nssdir/cmd/lowhashtest $dstdir/cmd/lowhashtest
+ cp -R $nssdir/cmd/shlibsign $dstdir/cmd/shlibsign
+
+ mkdir $dstdir/tests
+ copy_top $nssdir/tests $dstdir/tests
+
+ cp -R $nssdir/tests/cipher $dstdir/tests/cipher
+ cp -R $nssdir/tests/common $dstdir/tests/common
+ cp -R $nssdir/tests/ec $dstdir/tests/ec
+ cp -R $nssdir/tests/lowhash $dstdir/tests/lowhash
+
+ cp $nssdir/lib/util/verref.h $dstdir/lib/freebl
+ cp $nssdir/lib/util/verref.h $dstdir/lib/softoken
+ cp $nssdir/lib/util/verref.h $dstdir/lib/softoken/legacydb
+}
+
+split_nss() {
+ nssdir="$1"
+ dstdir="$2"
+
+ # Prepare a source tree only containing files to build nss:
+ #
+ # nss/dbm full directory
+ # nss/coreconf full directory
+ # nss top files only
+ # nss/lib top files only
+ # nss/lib/freebl full directory
+ # nss/lib/softoken full directory
+ # nss/lib/softoken/dbm full directory
+
+ # Copy everything.
+ cp -R $nssdir $dstdir
+
+ # Remove subdirectories that we don't want.
+ rm -rf $dstdir/lib/freebl
+ rm -rf $dstdir/lib/softoken
+ rm -rf $dstdir/lib/util
+ rm -rf $dstdir/cmd/bltest
+ rm -rf $dstdir/cmd/fipstest
+ rm -rf $dstdir/cmd/rsaperf_low
+
+ # Copy these headers until the upstream bug is accepted
+ # Upstream https://bugzilla.mozilla.org/show_bug.cgi?id=820207
+ cp $nssdir/lib/softoken/lowkeyi.h $dstdir/cmd/rsaperf
+ cp $nssdir/lib/softoken/lowkeyti.h $dstdir/cmd/rsaperf
+
+ # Copy verref.h which will be needed later during the build phase.
+ cp $nssdir/lib/util/verref.h $dstdir/lib/ckfw/builtins/verref.h
+ cp $nssdir/lib/util/verref.h $dstdir/lib/nss/verref.h
+ cp $nssdir/lib/util/verref.h $dstdir/lib/smime/verref.h
+ cp $nssdir/lib/util/verref.h $dstdir/lib/ssl/verref.h
+ cp $nssdir/lib/util/templates.c $dstdir/lib/nss/templates.c
+
+ # FIXME: Skip util_gtest because it links with libnssutil.a. Note
+ # that we can't use libnssutil3.so instead, because util_gtest
+ # depends on internal symbols not exported from the shared library.
+ sed '/ util_gtest \\/d' $dstdir/gtests/manifest.mn > $dstdir/gtests/manifest.mn-t && mv $dstdir/gtests/manifest.mn-t $dstdir/gtests/manifest.mn
+}
diff --git a/nss/automation/taskcluster/scripts/tools.sh b/nss/automation/taskcluster/scripts/tools.sh
new file mode 100644
index 0000000..46d567e
--- /dev/null
+++ b/nss/automation/taskcluster/scripts/tools.sh
@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+
+set -v -e -x
+
+if [[ $(id -u) -eq 0 ]]; then
+ # Drop privileges by re-running this script.
+ # Note: this mangles arguments, better to avoid running scripts as root.
+ exec su worker -c "$0 $*"
+fi
+
+# Usage: hg_clone repo dir [revision=@]
+hg_clone() {
+ repo=$1
+ dir=$2
+ rev=${3:-@}
+ if [ -d "$dir" ]; then
+ hg pull -R "$dir" -ur "$rev" "$repo" && return
+ rm -rf "$dir"
+ fi
+ for i in 0 2 5; do
+ sleep $i
+ hg clone -r "$rev" "$repo" "$dir" && return
+ rm -rf "$dir"
+ done
+ exit 1
+}
+
+fetch_dist() {
+ url=https://queue.taskcluster.net/v1/task/$TC_PARENT_TASK_ID/artifacts/public/dist.tar.bz2
+ if [ ! -d "dist" ]; then
+ for i in 0 2 5; do
+ sleep $i
+ curl --retry 3 -Lo dist.tar.bz2 $url && tar xvjf dist.tar.bz2 && return
+ rm -fr dist.tar.bz2 dist
+ done
+ exit 1
+ fi
+}
diff --git a/nss/automation/taskcluster/windows/build.sh b/nss/automation/taskcluster/windows/build.sh
new file mode 100644
index 0000000..6c8a474
--- /dev/null
+++ b/nss/automation/taskcluster/windows/build.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+
+set -v -e -x
+
+# Set up the toolchain.
+source $(dirname $0)/setup.sh
+
+# Clone NSPR.
+hg_clone https://hg.mozilla.org/projects/nspr nspr default
+
+# Build.
+make -C nss nss_build_all
+
+# Package.
+7z a public/build/dist.7z dist
diff --git a/nss/automation/taskcluster/windows/gen_certs.sh b/nss/automation/taskcluster/windows/gen_certs.sh
new file mode 100644
index 0000000..ead16bb
--- /dev/null
+++ b/nss/automation/taskcluster/windows/gen_certs.sh
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+
+set -v -e -x
+
+# Set up the toolchain.
+source $(dirname $0)/setup.sh
+
+# Fetch artifact.
+wget -t 3 --retry-connrefused -w 5 --random-wait https://queue.taskcluster.net/v1/task/$TC_PARENT_TASK_ID/artifacts/public/build/dist.7z -O dist.7z
+7z x dist.7z
+
+# Generate certificates.
+NSS_TESTS=cert NSS_CYCLES="standard pkix sharedb" nss/tests/all.sh
+
+# Reset test counter so that test runs pick up our certificates.
+echo 1 > tests_results/security/localhost
+
+# Package.
+7z a public/build/dist.7z dist tests_results
diff --git a/nss/automation/taskcluster/windows/releng.manifest b/nss/automation/taskcluster/windows/releng.manifest
new file mode 100644
index 0000000..403be2b
--- /dev/null
+++ b/nss/automation/taskcluster/windows/releng.manifest
@@ -0,0 +1,10 @@
+[
+ {
+ "version": "Visual Studio 2015 Update 3 14.0.25425.01 / SDK 10.0.14393.0",
+ "size": 326656969,
+ "digest": "babc414ffc0457d27f5a1ed24a8e4873afbe2f1c1a4075469a27c005e1babc3b2a788f643f825efedff95b79686664c67ec4340ed535487168a3482e68559bc7",
+ "algorithm": "sha512",
+ "filename": "vs2015u3.zip",
+ "unpack": true
+ }
+]
diff --git a/nss/automation/taskcluster/windows/run_tests.sh b/nss/automation/taskcluster/windows/run_tests.sh
new file mode 100644
index 0000000..f64a78e
--- /dev/null
+++ b/nss/automation/taskcluster/windows/run_tests.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+
+set -v -e -x
+
+# Set up the toolchain.
+source $(dirname $0)/setup.sh
+
+# Fetch artifact.
+wget -t 3 --retry-connrefused -w 5 --random-wait https://queue.taskcluster.net/v1/task/$TC_PARENT_TASK_ID/artifacts/public/build/dist.7z -O dist.7z
+7z x dist.7z
+
+# Run tests.
+cd nss/tests && ./all.sh
diff --git a/nss/automation/taskcluster/windows/setup.sh b/nss/automation/taskcluster/windows/setup.sh
new file mode 100644
index 0000000..3273277
--- /dev/null
+++ b/nss/automation/taskcluster/windows/setup.sh
@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+
+set -v -e -x
+
+# Usage: hg_clone repo dir [revision=@]
+hg_clone() {
+ repo=$1
+ dir=$2
+ rev=${3:-@}
+ for i in 0 2 5; do
+ sleep $i
+ hg clone -r "$rev" "$repo" "$dir" && return
+ rm -rf "$dir"
+ done
+ exit 1
+}
+
+hg_clone https://hg.mozilla.org/build/tools tools default
+
+tools/scripts/tooltool/tooltool_wrapper.sh $(dirname $0)/releng.manifest https://api.pub.build.mozilla.org/tooltool/ non-existant-file.sh /c/mozilla-build/python/python.exe /c/builds/tooltool.py --authentication-file /c/builds/relengapi.tok -c /c/builds/tooltool_cache
+VSPATH="$(pwd)/vs2015u3"
+
+export WINDOWSSDKDIR="${VSPATH}/SDK"
+export WIN32_REDIST_DIR="${VSPATH}/VC/redist/x64/Microsoft.VC140.CRT"
+export WIN_UCRT_REDIST_DIR="${VSPATH}/SDK/Redist/ucrt/DLLs/x64"
+
+export PATH="${VSPATH}/VC/bin/amd64:${VSPATH}/VC/bin:${VSPATH}/SDK/bin/x64:${VSPATH}/VC/redist/x64/Microsoft.VC140.CRT:${VSPATH}/SDK/Redist/ucrt/DLLs/x64:${PATH}"
+
+export INCLUDE="${VSPATH}/VC/include:${VSPATH}/SDK/Include/10.0.14393.0/ucrt:${VSPATH}/SDK/Include/10.0.14393.0/shared:${VSPATH}/SDK/Include/10.0.14393.0/um"
+export LIB="${VSPATH}/VC/lib/amd64:${VSPATH}/SDK/lib/10.0.14393.0/ucrt/x64:${VSPATH}/SDK/lib/10.0.14393.0/um/x64"
diff --git a/nss/automation/travis/validate-formatting.sh b/nss/automation/travis/validate-formatting.sh
new file mode 100755
index 0000000..246270f
--- /dev/null
+++ b/nss/automation/travis/validate-formatting.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# Apply clang-format 3.8 on the provided folder and verify that this doesn't change any file.
+# If any file differs after formatting, the script eventually exits with 1.
+# Any differences between formatted and unformatted files is printed to stdout to give a hint what's wrong.
+
+STATUS=0
+for i in $(find $1 -type f -name '*.[ch]' -print); do
+ if ! clang-format-3.8 $i | diff $i -; then
+ echo "Sorry, $i is not formatted properly. Please use clang-format 3.8 on your patch before landing."
+ STATUS=1
+ fi
+done
+exit $STATUS
diff --git a/nss/build.sh b/nss/build.sh
new file mode 100755
index 0000000..c9ff426
--- /dev/null
+++ b/nss/build.sh
@@ -0,0 +1,236 @@
+#!/usr/bin/env bash
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+################################################################################
+#
+# This script builds NSS with gyp and ninja.
+#
+# This build system is still under development. It does not yet support all
+# the features or platforms that NSS supports.
+
+set -e
+
+cwd=$(cd $(dirname $0); pwd -P)
+source "$cwd"/coreconf/nspr.sh
+source "$cwd"/coreconf/sanitizers.sh
+
+# Usage info
+show_help()
+{
+ cat << EOF
+Usage: ${0##*/} [-hcv] [-j ] [--nspr] [--gyp|-g] [--opt|-o] [-m32]
+ [--test] [--pprof] [--scan-build[=output]] [--ct-verif]
+ [--asan] [--ubsan] [--msan] [--sancov[=edge|bb|func|...]]
+ [--disable-tests] [--fuzz[=tls|oss]]
+
+This script builds NSS with gyp and ninja.
+
+This build system is still under development. It does not yet support all
+the features or platforms that NSS supports.
+
+NSS build tool options:
+
+ -h display this help and exit
+ -c clean before build
+ -v verbose build
+ -j run at most concurrent jobs
+ --nspr force a rebuild of NSPR
+ --gyp|-g force a rerun of gyp
+ --opt|-o do an opt build
+ -m32 do a 32-bit build on a 64-bit system
+ --test ignore map files and export everything we have
+ --fuzz build fuzzing targets (this always enables test builds)
+ --fuzz=tls to enable TLS fuzzing mode
+ --fuzz=oss to build for OSS-Fuzz
+ --pprof build with gperftool support
+ --ct-verif build with valgrind for ct-verif
+ --scan-build run the build with scan-build (scan-build has to be in the path)
+ --scan-build=/out/path sets the output path for scan-build
+ --asan do an asan build
+ --ubsan do an ubsan build
+ --ubsan=bool,shift,... sets specific UB sanitizers
+ --msan do an msan build
+ --sancov do sanitize coverage builds
+ --sancov=func sets coverage to function level for example
+ --disable-tests don't build tests and corresponding cmdline utils
+EOF
+}
+
+run_verbose()
+{
+ if [ "$verbose" = 1 ]; then
+ echo "$@"
+ exec 3>&1
+ else
+ exec 3>/dev/null
+ fi
+ "$@" 1>&3 2>&3
+ exec 3>&-
+}
+
+if [ -n "$CCC" ] && [ -z "$CXX" ]; then
+ export CXX="$CCC"
+fi
+
+opt_build=0
+build_64=0
+clean=0
+rebuild_gyp=0
+rebuild_nspr=0
+target=Debug
+verbose=0
+fuzz=0
+fuzz_tls=0
+fuzz_oss=0
+
+gyp_params=(--depth="$cwd" --generator-output=".")
+nspr_params=()
+ninja_params=()
+
+# try to guess sensible defaults
+arch=$(python "$cwd"/coreconf/detect_host_arch.py)
+if [ "$arch" = "x64" -o "$arch" = "aarch64" ]; then
+ build_64=1
+fi
+
+# parse command line arguments
+while [ $# -gt 0 ]; do
+ case $1 in
+ -c) clean=1 ;;
+ --gyp|-g) rebuild_gyp=1 ;;
+ --nspr) nspr_clean; rebuild_nspr=1 ;;
+ -j) ninja_params+=(-j "$2"); shift ;;
+ -v) ninja_params+=(-v); verbose=1 ;;
+ --test) gyp_params+=(-Dtest_build=1) ;;
+ --fuzz) fuzz=1 ;;
+ --fuzz=oss) fuzz=1; fuzz_oss=1 ;;
+ --fuzz=tls) fuzz=1; fuzz_tls=1 ;;
+ --scan-build) enable_scanbuild ;;
+ --scan-build=?*) enable_scanbuild "${1#*=}" ;;
+ --opt|-o) opt_build=1 ;;
+ -m32|--m32) build_64=0 ;;
+ --asan) enable_sanitizer asan ;;
+ --msan) enable_sanitizer msan ;;
+ --ubsan) enable_ubsan ;;
+ --ubsan=?*) enable_ubsan "${1#*=}" ;;
+ --sancov) enable_sancov ;;
+ --sancov=?*) enable_sancov "${1#*=}" ;;
+ --pprof) gyp_params+=(-Duse_pprof=1) ;;
+ --ct-verif) gyp_params+=(-Dct_verif=1) ;;
+ --disable-tests) gyp_params+=(-Ddisable_tests=1) ;;
+ --no-zdefs) gyp_params+=(-Dno_zdefs=1) ;;
+ *) show_help; exit 2 ;;
+ esac
+ shift
+done
+
+if [ "$opt_build" = 1 ]; then
+ target=Release
+else
+ target=Debug
+fi
+if [ "$build_64" = 1 ]; then
+ nspr_params+=(--enable-64bit)
+else
+ gyp_params+=(-Dtarget_arch=ia32)
+fi
+if [ "$fuzz" = 1 ]; then
+ source "$cwd"/coreconf/fuzz.sh
+fi
+
+# set paths
+target_dir="$cwd"/out/$target
+mkdir -p "$target_dir"
+dist_dir="$cwd"/../dist
+dist_dir=$(mkdir -p "$dist_dir"; cd "$dist_dir"; pwd -P)
+gyp_params+=(-Dnss_dist_dir="$dist_dir")
+
+# -c = clean first
+if [ "$clean" = 1 ]; then
+ nspr_clean
+ rm -rf "$cwd"/out
+ rm -rf "$dist_dir"
+fi
+
+# This saves a canonical representation of arguments that we are passing to gyp
+# or the NSPR build so that we can work out if a rebuild is needed.
+# Caveat: This can fail for arguments that are position-dependent.
+# e.g., "-e 2 -f 1" and "-e 1 -f 2" canonicalize the same.
+check_config()
+{
+ local newconf="$1".new oldconf="$1"
+ shift
+ mkdir -p $(dirname "$newconf")
+ echo CC="$CC" >"$newconf"
+ echo CCC="$CCC" >>"$newconf"
+ echo CXX="$CXX" >>"$newconf"
+ for i in "$@"; do echo $i; done | sort >>"$newconf"
+
+ # Note: The following diff fails if $oldconf isn't there as well, which
+ # happens if we don't have a previous successful build.
+ ! diff -q "$newconf" "$oldconf" >/dev/null 2>&1
+}
+
+gyp_config="$cwd"/out/gyp_config
+nspr_config="$cwd"/out/$target/nspr_config
+
+# If we don't have a build directory make sure that we rebuild.
+if [ ! -d "$target_dir" ]; then
+ rebuild_nspr=1
+ rebuild_gyp=1
+elif [ ! -d "$dist_dir"/$target ]; then
+ rebuild_nspr=1
+fi
+
+# Update NSPR ${C,CXX,LD}FLAGS.
+nspr_set_flags $sanitizer_flags
+
+if check_config "$nspr_config" "${nspr_params[@]}" \
+ nspr_cflags="$nspr_cflags" \
+ nspr_cxxflags="$nspr_cxxflags" \
+ nspr_ldflags="$nspr_ldflags"; then
+ rebuild_nspr=1
+fi
+
+# Forward sanitizer flags.
+if [ ! -z "$sanitizer_flags" ]; then
+ gyp_params+=(-Dsanitizer_flags="$sanitizer_flags")
+fi
+
+if check_config "$gyp_config" "${gyp_params[@]}"; then
+ rebuild_gyp=1
+fi
+
+# save the chosen target
+mkdir -p "$dist_dir"
+echo $target > "$dist_dir"/latest
+
+if [ "$rebuild_nspr" = 1 ]; then
+ nspr_build "${nspr_params[@]}"
+ mv -f "$nspr_config".new "$nspr_config"
+fi
+if [ "$rebuild_gyp" = 1 ]; then
+
+ # These extra arguments aren't used in determining whether to rebuild.
+ obj_dir="$dist_dir"/$target
+ gyp_params+=(-Dnss_dist_obj_dir=$obj_dir)
+ gyp_params+=(-Dnspr_lib_dir=$obj_dir/lib)
+ gyp_params+=(-Dnspr_include_dir=$obj_dir/include/nspr)
+
+ run_verbose run_scanbuild gyp -f ninja "${gyp_params[@]}" "$cwd"/nss.gyp
+
+ mv -f "$gyp_config".new "$gyp_config"
+fi
+
+# Run ninja.
+if hash ninja 2>/dev/null; then
+ ninja=ninja
+elif hash ninja-build 2>/dev/null; then
+ ninja=ninja-build
+else
+ echo "Please install ninja" 1>&2
+ exit 1
+fi
+run_scanbuild $ninja -C "$target_dir" "${ninja_params[@]}"
diff --git a/nss/cmd/Makefile b/nss/cmd/Makefile
new file mode 100644
index 0000000..86ef29a
--- /dev/null
+++ b/nss/cmd/Makefile
@@ -0,0 +1,44 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+CORE_DEPTH = ..
+DEPTH = ..
+
+include manifest.mn
+include $(CORE_DEPTH)/coreconf/config.mk
+
+ifdef BUILD_LIBPKIX_TESTS
+DIRS += libpkix
+endif
+
+ifeq ($(NSS_BUILD_WITHOUT_SOFTOKEN),1)
+BLTEST_SRCDIR =
+ECPERF_SRCDIR =
+FREEBL_ECTEST_SRCDIR =
+FIPSTEST_SRCDIR =
+SHLIBSIGN_SRCDIR =
+else
+BLTEST_SRCDIR = bltest
+ECPERF_SRCDIR = ecperf
+FREEBL_ECTEST_SRCDIR = fbectest
+FIPSTEST_SRCDIR = fipstest
+SHLIBSIGN_SRCDIR = shlibsign
+endif
+
+LOWHASHTEST_SRCDIR=
+ifeq ($(FREEBL_LOWHASH),1)
+LOWHASHTEST_SRCDIR = lowhashtest # Add the lowhashtest directory to DIRS.
+endif
+
+INCLUDES += \
+ -I$(DIST)/../public/security \
+ -I./include \
+ $(NULL)
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+symbols::
+ @echo "TARGETS = $(TARGETS)"
diff --git a/nss/cmd/addbuiltin/Makefile b/nss/cmd/addbuiltin/Makefile
new file mode 100644
index 0000000..74ae200
--- /dev/null
+++ b/nss/cmd/addbuiltin/Makefile
@@ -0,0 +1,48 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include ../platlibs.mk
+
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+
+include ../platrules.mk
+
diff --git a/nss/cmd/addbuiltin/addbuiltin.c b/nss/cmd/addbuiltin/addbuiltin.c
new file mode 100644
index 0000000..8316720
--- /dev/null
+++ b/nss/cmd/addbuiltin/addbuiltin.c
@@ -0,0 +1,574 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * Tool for converting builtin CA certs.
+ */
+
+#include "nssrenam.h"
+#include "nss.h"
+#include "cert.h"
+#include "certdb.h"
+#include "secutil.h"
+#include "pk11func.h"
+
+#if defined(WIN32)
+#include
+#include
+#endif
+
+void
+dumpbytes(unsigned char *buf, int len)
+{
+ int i;
+ for (i = 0; i < len; i++) {
+ if ((i != 0) && ((i & 0xf) == 0)) {
+ printf("\n");
+ }
+ printf("\\%03o", buf[i]);
+ }
+ printf("\n");
+}
+
+int
+hasPositiveTrust(unsigned int trust)
+{
+ if (trust & CERTDB_TRUSTED) {
+ if (trust & CERTDB_TRUSTED_CA) {
+ return PR_TRUE;
+ } else {
+ return PR_FALSE;
+ }
+ } else {
+ if (trust & CERTDB_TRUSTED_CA) {
+ return PR_TRUE;
+ } else if (trust & CERTDB_VALID_CA) {
+ return PR_TRUE;
+ } else if (trust & CERTDB_TERMINAL_RECORD) {
+ return PR_FALSE;
+ } else {
+ return PR_FALSE;
+ }
+ }
+ return PR_FALSE;
+}
+
+char *
+getTrustString(unsigned int trust)
+{
+ if (trust & CERTDB_TRUSTED) {
+ if (trust & CERTDB_TRUSTED_CA) {
+ return "CKT_NSS_TRUSTED_DELEGATOR";
+ } else {
+ return "CKT_NSS_TRUSTED";
+ }
+ } else {
+ if (trust & CERTDB_TRUSTED_CA) {
+ return "CKT_NSS_TRUSTED_DELEGATOR";
+ } else if (trust & CERTDB_VALID_CA) {
+ return "CKT_NSS_VALID_DELEGATOR";
+ } else if (trust & CERTDB_TERMINAL_RECORD) {
+ return "CKT_NSS_NOT_TRUSTED";
+ } else {
+ return "CKT_NSS_MUST_VERIFY_TRUST";
+ }
+ }
+ return "CKT_NSS_TRUST_UNKNOWN"; /* not reached */
+}
+
+static const SEC_ASN1Template serialTemplate[] = {
+ { SEC_ASN1_INTEGER, offsetof(CERTCertificate, serialNumber) },
+ { 0 }
+};
+
+void
+print_crl_info(CERTName *name, SECItem *serial)
+{
+ PRBool saveWrapeState = SECU_GetWrapEnabled();
+ SECU_EnableWrap(PR_FALSE);
+
+ SECU_PrintNameQuotesOptional(stdout, name, "# Issuer", 0, PR_FALSE);
+ printf("\n");
+
+ SECU_PrintInteger(stdout, serial, "# Serial Number", 0);
+
+ SECU_EnableWrap(saveWrapeState);
+}
+
+static SECStatus
+ConvertCRLEntry(SECItem *sdder, PRInt32 crlentry, char *nickname)
+{
+ int rv;
+ PLArenaPool *arena = NULL;
+ CERTSignedCrl *newCrl = NULL;
+ CERTCrlEntry *entry;
+
+ CERTName *name = NULL;
+ SECItem *derName = NULL;
+ SECItem *serial = NULL;
+
+ rv = SEC_ERROR_NO_MEMORY;
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena)
+ return rv;
+
+ newCrl = CERT_DecodeDERCrlWithFlags(arena, sdder, SEC_CRL_TYPE,
+ CRL_DECODE_DEFAULT_OPTIONS);
+ if (!newCrl)
+ return SECFailure;
+
+ name = &newCrl->crl.name;
+ derName = &newCrl->crl.derName;
+
+ if (newCrl->crl.entries != NULL) {
+ PRInt32 iv = 0;
+ while ((entry = newCrl->crl.entries[iv++]) != NULL) {
+ if (crlentry == iv) {
+ serial = &entry->serialNumber;
+ break;
+ }
+ }
+ }
+
+ if (!name || !derName || !serial)
+ return SECFailure;
+
+ printf("\n# Distrust \"%s\"\n", nickname);
+ print_crl_info(name, serial);
+
+ printf("CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST\n");
+ printf("CKA_TOKEN CK_BBOOL CK_TRUE\n");
+ printf("CKA_PRIVATE CK_BBOOL CK_FALSE\n");
+ printf("CKA_MODIFIABLE CK_BBOOL CK_FALSE\n");
+ printf("CKA_LABEL UTF8 \"%s\"\n", nickname);
+
+ printf("CKA_ISSUER MULTILINE_OCTAL\n");
+ dumpbytes(derName->data, derName->len);
+ printf("END\n");
+ printf("CKA_SERIAL_NUMBER MULTILINE_OCTAL\n");
+ printf("\\002\\%03o", serial->len); /* 002: type integer; len >=3 digits */
+ dumpbytes(serial->data, serial->len);
+ printf("END\n");
+
+ printf("CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED\n");
+ printf("CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED\n");
+ printf("CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED\n");
+ printf("CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE\n");
+
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+void
+print_info(SECItem *sdder, CERTCertificate *c)
+{
+ PRBool saveWrapeState = SECU_GetWrapEnabled();
+ SECU_EnableWrap(PR_FALSE);
+
+ SECU_PrintNameQuotesOptional(stdout, &c->issuer, "# Issuer", 0, PR_FALSE);
+ printf("\n");
+
+ SECU_PrintInteger(stdout, &c->serialNumber, "# Serial Number", 0);
+
+ SECU_PrintNameQuotesOptional(stdout, &c->subject, "# Subject", 0, PR_FALSE);
+ printf("\n");
+
+ SECU_PrintTimeChoice(stdout, &c->validity.notBefore, "# Not Valid Before", 0);
+ SECU_PrintTimeChoice(stdout, &c->validity.notAfter, "# Not Valid After ", 0);
+
+ SECU_PrintFingerprints(stdout, sdder, "# Fingerprint", 0);
+
+ SECU_EnableWrap(saveWrapeState);
+}
+
+static SECStatus
+ConvertCertificate(SECItem *sdder, char *nickname, CERTCertTrust *trust,
+ PRBool excludeCert, PRBool excludeHash)
+{
+ SECStatus rv = SECSuccess;
+ CERTCertificate *cert;
+ unsigned char sha1_hash[SHA1_LENGTH];
+ unsigned char md5_hash[MD5_LENGTH];
+ SECItem *serial = NULL;
+ PRBool step_up = PR_FALSE;
+ const char *trust_info;
+
+ cert = CERT_DecodeDERCertificate(sdder, PR_FALSE, nickname);
+ if (!cert) {
+ return SECFailure;
+ }
+ serial = SEC_ASN1EncodeItem(NULL, NULL, cert, serialTemplate);
+ if (!serial) {
+ return SECFailure;
+ }
+
+ if (!excludeCert) {
+ printf("\n#\n# Certificate \"%s\"\n#\n", nickname);
+ print_info(sdder, cert);
+ printf("CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE\n");
+ printf("CKA_TOKEN CK_BBOOL CK_TRUE\n");
+ printf("CKA_PRIVATE CK_BBOOL CK_FALSE\n");
+ printf("CKA_MODIFIABLE CK_BBOOL CK_FALSE\n");
+ printf("CKA_LABEL UTF8 \"%s\"\n", nickname);
+ printf("CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509\n");
+ printf("CKA_SUBJECT MULTILINE_OCTAL\n");
+ dumpbytes(cert->derSubject.data, cert->derSubject.len);
+ printf("END\n");
+ printf("CKA_ID UTF8 \"0\"\n");
+ printf("CKA_ISSUER MULTILINE_OCTAL\n");
+ dumpbytes(cert->derIssuer.data, cert->derIssuer.len);
+ printf("END\n");
+ printf("CKA_SERIAL_NUMBER MULTILINE_OCTAL\n");
+ dumpbytes(serial->data, serial->len);
+ printf("END\n");
+ printf("CKA_VALUE MULTILINE_OCTAL\n");
+ dumpbytes(sdder->data, sdder->len);
+ printf("END\n");
+ if (hasPositiveTrust(trust->sslFlags) ||
+ hasPositiveTrust(trust->emailFlags) ||
+ hasPositiveTrust(trust->objectSigningFlags)) {
+ printf("CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE\n");
+ }
+ }
+
+ if ((trust->sslFlags | trust->emailFlags | trust->objectSigningFlags) ==
+ CERTDB_TERMINAL_RECORD)
+ trust_info = "Distrust";
+ else
+ trust_info = "Trust for";
+
+ printf("\n# %s \"%s\"\n", trust_info, nickname);
+ print_info(sdder, cert);
+
+ printf("CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST\n");
+ printf("CKA_TOKEN CK_BBOOL CK_TRUE\n");
+ printf("CKA_PRIVATE CK_BBOOL CK_FALSE\n");
+ printf("CKA_MODIFIABLE CK_BBOOL CK_FALSE\n");
+ printf("CKA_LABEL UTF8 \"%s\"\n", nickname);
+
+ if (!excludeHash) {
+ PK11_HashBuf(SEC_OID_SHA1, sha1_hash, sdder->data, sdder->len);
+ printf("CKA_CERT_SHA1_HASH MULTILINE_OCTAL\n");
+ dumpbytes(sha1_hash, SHA1_LENGTH);
+ printf("END\n");
+ PK11_HashBuf(SEC_OID_MD5, md5_hash, sdder->data, sdder->len);
+ printf("CKA_CERT_MD5_HASH MULTILINE_OCTAL\n");
+ dumpbytes(md5_hash, MD5_LENGTH);
+ printf("END\n");
+ }
+
+ printf("CKA_ISSUER MULTILINE_OCTAL\n");
+ dumpbytes(cert->derIssuer.data, cert->derIssuer.len);
+ printf("END\n");
+ printf("CKA_SERIAL_NUMBER MULTILINE_OCTAL\n");
+ dumpbytes(serial->data, serial->len);
+ printf("END\n");
+
+ printf("CKA_TRUST_SERVER_AUTH CK_TRUST %s\n",
+ getTrustString(trust->sslFlags));
+ printf("CKA_TRUST_EMAIL_PROTECTION CK_TRUST %s\n",
+ getTrustString(trust->emailFlags));
+ printf("CKA_TRUST_CODE_SIGNING CK_TRUST %s\n",
+ getTrustString(trust->objectSigningFlags));
+#ifdef notdef
+ printf("CKA_TRUST_CLIENT_AUTH CK_TRUST CKT_NSS_TRUSTED\n");
+ printf("CKA_TRUST_DIGITAL_SIGNATURE CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n");
+ printf("CKA_TRUST_NON_REPUDIATION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n");
+ printf("CKA_TRUST_KEY_ENCIPHERMENT CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n");
+ printf("CKA_TRUST_DATA_ENCIPHERMENT CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n");
+ printf("CKA_TRUST_KEY_AGREEMENT CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n");
+ printf("CKA_TRUST_KEY_CERT_SIGN CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n");
+#endif
+
+ step_up = (trust->sslFlags & CERTDB_GOVT_APPROVED_CA);
+ printf("CKA_TRUST_STEP_UP_APPROVED CK_BBOOL %s\n",
+ step_up ? "CK_TRUE" : "CK_FALSE");
+
+ PORT_Free(sdder->data);
+ return (rv);
+}
+
+void
+printheader()
+{
+ printf("# \n"
+ "# This Source Code Form is subject to the terms of the Mozilla Public\n"
+ "# License, v. 2.0. If a copy of the MPL was not distributed with this\n"
+ "# file, You can obtain one at http://mozilla.org/MPL/2.0/.\n"
+ "#\n"
+ "# certdata.txt\n"
+ "#\n"
+ "# This file contains the object definitions for the certs and other\n"
+ "# information \"built into\" NSS.\n"
+ "#\n"
+ "# Object definitions:\n"
+ "#\n"
+ "# Certificates\n"
+ "#\n"
+ "# -- Attribute -- -- type -- -- value --\n"
+ "# CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE\n"
+ "# CKA_TOKEN CK_BBOOL CK_TRUE\n"
+ "# CKA_PRIVATE CK_BBOOL CK_FALSE\n"
+ "# CKA_MODIFIABLE CK_BBOOL CK_FALSE\n"
+ "# CKA_LABEL UTF8 (varies)\n"
+ "# CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509\n"
+ "# CKA_SUBJECT DER+base64 (varies)\n"
+ "# CKA_ID byte array (varies)\n"
+ "# CKA_ISSUER DER+base64 (varies)\n"
+ "# CKA_SERIAL_NUMBER DER+base64 (varies)\n"
+ "# CKA_VALUE DER+base64 (varies)\n"
+ "# CKA_NSS_EMAIL ASCII7 (unused here)\n"
+ "#\n"
+ "# Trust\n"
+ "#\n"
+ "# -- Attribute -- -- type -- -- value --\n"
+ "# CKA_CLASS CK_OBJECT_CLASS CKO_TRUST\n"
+ "# CKA_TOKEN CK_BBOOL CK_TRUE\n"
+ "# CKA_PRIVATE CK_BBOOL CK_FALSE\n"
+ "# CKA_MODIFIABLE CK_BBOOL CK_FALSE\n"
+ "# CKA_LABEL UTF8 (varies)\n"
+ "# CKA_ISSUER DER+base64 (varies)\n"
+ "# CKA_SERIAL_NUMBER DER+base64 (varies)\n"
+ "# CKA_CERT_HASH binary+base64 (varies)\n"
+ "# CKA_EXPIRES CK_DATE (not used here)\n"
+ "# CKA_TRUST_DIGITAL_SIGNATURE CK_TRUST (varies)\n"
+ "# CKA_TRUST_NON_REPUDIATION CK_TRUST (varies)\n"
+ "# CKA_TRUST_KEY_ENCIPHERMENT CK_TRUST (varies)\n"
+ "# CKA_TRUST_DATA_ENCIPHERMENT CK_TRUST (varies)\n"
+ "# CKA_TRUST_KEY_AGREEMENT CK_TRUST (varies)\n"
+ "# CKA_TRUST_KEY_CERT_SIGN CK_TRUST (varies)\n"
+ "# CKA_TRUST_CRL_SIGN CK_TRUST (varies)\n"
+ "# CKA_TRUST_SERVER_AUTH CK_TRUST (varies)\n"
+ "# CKA_TRUST_CLIENT_AUTH CK_TRUST (varies)\n"
+ "# CKA_TRUST_CODE_SIGNING CK_TRUST (varies)\n"
+ "# CKA_TRUST_EMAIL_PROTECTION CK_TRUST (varies)\n"
+ "# CKA_TRUST_IPSEC_END_SYSTEM CK_TRUST (varies)\n"
+ "# CKA_TRUST_IPSEC_TUNNEL CK_TRUST (varies)\n"
+ "# CKA_TRUST_IPSEC_USER CK_TRUST (varies)\n"
+ "# CKA_TRUST_TIME_STAMPING CK_TRUST (varies)\n"
+ "# (other trust attributes can be defined)\n"
+ "#\n"
+ "\n"
+ "#\n"
+ "# The object to tell NSS that this is a root list and we don't\n"
+ "# have to go looking for others.\n"
+ "#\n"
+ "BEGINDATA\n"
+ "CKA_CLASS CK_OBJECT_CLASS CKO_NSS_BUILTIN_ROOT_LIST\n"
+ "CKA_TOKEN CK_BBOOL CK_TRUE\n"
+ "CKA_PRIVATE CK_BBOOL CK_FALSE\n"
+ "CKA_MODIFIABLE CK_BBOOL CK_FALSE\n"
+ "CKA_LABEL UTF8 \"Mozilla Builtin Roots\"\n");
+}
+
+static void
+Usage(char *progName)
+{
+ fprintf(stderr, "%s -t trust -n nickname [-i certfile] [-c] [-h]\n", progName);
+ fprintf(stderr,
+ "\tRead a der-encoded cert from certfile or stdin, and output\n"
+ "\tit to stdout in a format suitable for the builtin root module.\n"
+ "\tExample: %s -n MyCA -t \"C,C,C\" -i myca.der >> certdata.txt\n",
+ progName);
+ fprintf(stderr, "%s -D -n label [-i certfile]\n", progName);
+ fprintf(stderr,
+ "\tRead a der-encoded cert from certfile or stdin, and output\n"
+ "\ta distrust record.\n"
+ "\t(-D is equivalent to -t p,p,p -c -h)\n");
+ fprintf(stderr, "%s -C -e crl-entry-number -n label [-i crlfile]\n", progName);
+ fprintf(stderr,
+ "\tRead a CRL from crlfile or stdin, and output\n"
+ "\ta distrust record (issuer+serial).\n"
+ "\t(-C implies -c -h)\n");
+ fprintf(stderr, "%-15s trust flags (cCTpPuw).\n", "-t trust");
+ fprintf(stderr, "%-15s nickname to assign to builtin cert, or\n",
+ "-n nickname");
+ fprintf(stderr, "%-15s a label for the distrust record.\n", "");
+ fprintf(stderr, "%-15s exclude the certificate (only add a trust record)\n", "-c");
+ fprintf(stderr, "%-15s exclude hash from trust record\n", "-h");
+ fprintf(stderr, "%-15s (useful to distrust any matching issuer/serial)\n", "");
+ fprintf(stderr, "%-15s (not allowed when adding positive trust)\n", "");
+ fprintf(stderr, "%-15s a CRL entry number, as shown by \"crlutil -S\"\n", "-e");
+ fprintf(stderr, "%-15s input file to read (default stdin)\n", "-i file");
+ fprintf(stderr, "%-15s (pipe through atob if the cert is b64-encoded)\n", "");
+ exit(-1);
+}
+
+enum {
+ opt_Input = 0,
+ opt_Nickname,
+ opt_Trust,
+ opt_Distrust,
+ opt_ExcludeCert,
+ opt_ExcludeHash,
+ opt_DistrustCRL,
+ opt_CRLEnry
+};
+
+static secuCommandFlag addbuiltin_options[] =
+ {
+ { /* opt_Input */ 'i', PR_TRUE, 0, PR_FALSE },
+ { /* opt_Nickname */ 'n', PR_TRUE, 0, PR_FALSE },
+ { /* opt_Trust */ 't', PR_TRUE, 0, PR_FALSE },
+ { /* opt_Distrust */ 'D', PR_FALSE, 0, PR_FALSE },
+ { /* opt_ExcludeCert */ 'c', PR_FALSE, 0, PR_FALSE },
+ { /* opt_ExcludeHash */ 'h', PR_FALSE, 0, PR_FALSE },
+ { /* opt_DistrustCRL */ 'C', PR_FALSE, 0, PR_FALSE },
+ { /* opt_CRLEnry */ 'e', PR_TRUE, 0, PR_FALSE },
+ };
+
+int
+main(int argc, char **argv)
+{
+ SECStatus rv;
+ char *nickname = NULL;
+ char *trusts = NULL;
+ char *progName;
+ PRFileDesc *infile;
+ CERTCertTrust trust = { 0 };
+ SECItem derItem = { 0 };
+ PRInt32 crlentry = 0;
+ PRInt32 mutuallyExclusiveOpts = 0;
+ PRBool decodeTrust = PR_FALSE;
+
+ secuCommand addbuiltin = { 0 };
+ addbuiltin.numOptions = sizeof(addbuiltin_options) / sizeof(secuCommandFlag);
+ addbuiltin.options = addbuiltin_options;
+
+ progName = strrchr(argv[0], '/');
+ progName = progName ? progName + 1 : argv[0];
+
+ rv = SECU_ParseCommandLine(argc, argv, progName, &addbuiltin);
+
+ if (rv != SECSuccess)
+ Usage(progName);
+
+ if (addbuiltin.options[opt_Trust].activated)
+ ++mutuallyExclusiveOpts;
+ if (addbuiltin.options[opt_Distrust].activated)
+ ++mutuallyExclusiveOpts;
+ if (addbuiltin.options[opt_DistrustCRL].activated)
+ ++mutuallyExclusiveOpts;
+
+ if (mutuallyExclusiveOpts != 1) {
+ fprintf(stderr, "%s: you must specify exactly one of -t or -D or -C\n",
+ progName);
+ Usage(progName);
+ }
+
+ if (addbuiltin.options[opt_DistrustCRL].activated) {
+ if (!addbuiltin.options[opt_CRLEnry].activated) {
+ fprintf(stderr, "%s: you must specify the CRL entry number.\n",
+ progName);
+ Usage(progName);
+ } else {
+ crlentry = atoi(addbuiltin.options[opt_CRLEnry].arg);
+ if (crlentry < 1) {
+ fprintf(stderr, "%s: The CRL entry number must be > 0.\n",
+ progName);
+ Usage(progName);
+ }
+ }
+ }
+
+ if (!addbuiltin.options[opt_Nickname].activated) {
+ fprintf(stderr, "%s: you must specify parameter -n (a nickname or a label).\n",
+ progName);
+ Usage(progName);
+ }
+
+ if (addbuiltin.options[opt_Input].activated) {
+ infile = PR_Open(addbuiltin.options[opt_Input].arg, PR_RDONLY, 00660);
+ if (!infile) {
+ fprintf(stderr, "%s: failed to open input file.\n", progName);
+ exit(1);
+ }
+ } else {
+#if defined(WIN32)
+ /* If we're going to read binary data from stdin, we must put stdin
+ ** into O_BINARY mode or else incoming \r\n's will become \n's,
+ ** and latin-1 characters will be altered.
+ */
+
+ int smrv = _setmode(_fileno(stdin), _O_BINARY);
+ if (smrv == -1) {
+ fprintf(stderr,
+ "%s: Cannot change stdin to binary mode. Use -i option instead.\n",
+ progName);
+ exit(1);
+ }
+#endif
+ infile = PR_STDIN;
+ }
+
+#if defined(WIN32)
+ /* We must put stdout into O_BINARY mode or else the output will include
+ ** carriage returns.
+ */
+ {
+ int smrv = _setmode(_fileno(stdout), _O_BINARY);
+ if (smrv == -1) {
+ fprintf(stderr, "%s: Cannot change stdout to binary mode.\n", progName);
+ exit(1);
+ }
+ }
+#endif
+
+ nickname = strdup(addbuiltin.options[opt_Nickname].arg);
+
+ NSS_NoDB_Init(NULL);
+
+ if (addbuiltin.options[opt_Distrust].activated ||
+ addbuiltin.options[opt_DistrustCRL].activated) {
+ addbuiltin.options[opt_ExcludeCert].activated = PR_TRUE;
+ addbuiltin.options[opt_ExcludeHash].activated = PR_TRUE;
+ }
+
+ if (addbuiltin.options[opt_Distrust].activated) {
+ trusts = strdup("p,p,p");
+ decodeTrust = PR_TRUE;
+ } else if (addbuiltin.options[opt_Trust].activated) {
+ trusts = strdup(addbuiltin.options[opt_Trust].arg);
+ decodeTrust = PR_TRUE;
+ }
+
+ if (decodeTrust) {
+ rv = CERT_DecodeTrustString(&trust, trusts);
+ if (rv) {
+ fprintf(stderr, "%s: incorrectly formatted trust string.\n", progName);
+ Usage(progName);
+ }
+ }
+
+ if (addbuiltin.options[opt_Trust].activated &&
+ addbuiltin.options[opt_ExcludeHash].activated) {
+ if ((trust.sslFlags | trust.emailFlags | trust.objectSigningFlags) !=
+ CERTDB_TERMINAL_RECORD) {
+ fprintf(stderr, "%s: Excluding the hash only allowed with distrust.\n", progName);
+ Usage(progName);
+ }
+ }
+
+ SECU_FileToItem(&derItem, infile);
+
+ /*printheader();*/
+
+ if (addbuiltin.options[opt_DistrustCRL].activated) {
+ rv = ConvertCRLEntry(&derItem, crlentry, nickname);
+ } else {
+ rv = ConvertCertificate(&derItem, nickname, &trust,
+ addbuiltin.options[opt_ExcludeCert].activated,
+ addbuiltin.options[opt_ExcludeHash].activated);
+ if (rv) {
+ fprintf(stderr, "%s: failed to convert certificate.\n", progName);
+ exit(1);
+ }
+ }
+
+ if (NSS_Shutdown() != SECSuccess) {
+ exit(1);
+ }
+
+ return (SECSuccess);
+}
diff --git a/nss/cmd/addbuiltin/addbuiltin.gyp b/nss/cmd/addbuiltin/addbuiltin.gyp
new file mode 100644
index 0000000..a8d1382
--- /dev/null
+++ b/nss/cmd/addbuiltin/addbuiltin.gyp
@@ -0,0 +1,24 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi',
+ '../../cmd/platlibs.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'addbuiltin',
+ 'type': 'executable',
+ 'sources': [
+ 'addbuiltin.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
\ No newline at end of file
diff --git a/nss/cmd/addbuiltin/manifest.mn b/nss/cmd/addbuiltin/manifest.mn
new file mode 100644
index 0000000..9c44c08
--- /dev/null
+++ b/nss/cmd/addbuiltin/manifest.mn
@@ -0,0 +1,20 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+CORE_DEPTH = ../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+CSRCS = \
+ addbuiltin.c \
+ $(NULL)
+
+# The MODULE is always implicitly required.
+# Listing it here in REQUIRES makes it appear twice in the cc command line.
+REQUIRES = seccmd
+
+PROGRAM = addbuiltin
+
diff --git a/nss/cmd/atob/Makefile b/nss/cmd/atob/Makefile
new file mode 100644
index 0000000..2aaef8f
--- /dev/null
+++ b/nss/cmd/atob/Makefile
@@ -0,0 +1,48 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include ../platlibs.mk
+
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+
+include ../platrules.mk
+
diff --git a/nss/cmd/atob/atob.c b/nss/cmd/atob/atob.c
new file mode 100644
index 0000000..115b0e9
--- /dev/null
+++ b/nss/cmd/atob/atob.c
@@ -0,0 +1,174 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "plgetopt.h"
+#include "secutil.h"
+#include "nssb64.h"
+#include
+
+#if defined(XP_WIN) || (defined(__sun) && !defined(SVR4))
+#if !defined(WIN32)
+extern int fread(char *, size_t, size_t, FILE *);
+extern int fwrite(char *, size_t, size_t, FILE *);
+extern int fprintf(FILE *, char *, ...);
+#endif
+#endif
+
+#if defined(WIN32)
+#include "fcntl.h"
+#include "io.h"
+#endif
+
+static PRInt32
+output_binary(void *arg, const unsigned char *obuf, PRInt32 size)
+{
+ FILE *outFile = arg;
+ int nb;
+
+ nb = fwrite(obuf, 1, size, outFile);
+ if (nb != size) {
+ PORT_SetError(SEC_ERROR_IO);
+ return -1;
+ }
+
+ return nb;
+}
+
+static PRBool
+isBase64Char(char c)
+{
+ return ((c >= 'A' && c <= 'Z') ||
+ (c >= 'a' && c <= 'z') ||
+ (c >= '0' && c <= '9') ||
+ c == '+' || c == '/' ||
+ c == '=');
+}
+
+static SECStatus
+decode_file(FILE *outFile, FILE *inFile)
+{
+ NSSBase64Decoder *cx;
+ SECStatus status = SECFailure;
+ char ibuf[4096];
+ const char *ptr;
+
+ cx = NSSBase64Decoder_Create(output_binary, outFile);
+ if (!cx) {
+ return -1;
+ }
+
+ for (;;) {
+ if (feof(inFile))
+ break;
+ if (!fgets(ibuf, sizeof(ibuf), inFile)) {
+ if (ferror(inFile)) {
+ PORT_SetError(SEC_ERROR_IO);
+ goto loser;
+ }
+ /* eof */
+ break;
+ }
+ for (ptr = ibuf; *ptr; ++ptr) {
+ char c = *ptr;
+ if (c == '\n' || c == '\r') {
+ break; /* found end of line */
+ }
+ if (!isBase64Char(c)) {
+ ptr = ibuf; /* ignore line */
+ break;
+ }
+ }
+ if (ibuf == ptr) {
+ continue; /* skip empty or non-base64 line */
+ }
+
+ status = NSSBase64Decoder_Update(cx, ibuf, ptr - ibuf);
+ if (status != SECSuccess)
+ goto loser;
+ }
+
+ return NSSBase64Decoder_Destroy(cx, PR_FALSE);
+
+loser:
+ (void)NSSBase64Decoder_Destroy(cx, PR_TRUE);
+ return status;
+}
+
+static void
+Usage(char *progName)
+{
+ fprintf(stderr,
+ "Usage: %s [-i input] [-o output]\n",
+ progName);
+ fprintf(stderr, "%-20s Define an input file to use (default is stdin)\n",
+ "-i input");
+ fprintf(stderr, "%-20s Define an output file to use (default is stdout)\n",
+ "-o output");
+ exit(-1);
+}
+
+int
+main(int argc, char **argv)
+{
+ char *progName;
+ SECStatus rv;
+ FILE *inFile, *outFile;
+ PLOptState *optstate;
+ PLOptStatus status;
+
+ inFile = 0;
+ outFile = 0;
+ progName = strrchr(argv[0], '/');
+ progName = progName ? progName + 1 : argv[0];
+
+ /* Parse command line arguments */
+ optstate = PL_CreateOptState(argc, argv, "?hi:o:");
+ while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
+ switch (optstate->option) {
+ case '?':
+ case 'h':
+ Usage(progName);
+ break;
+
+ case 'i':
+ inFile = fopen(optstate->value, "r");
+ if (!inFile) {
+ fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
+ progName, optstate->value);
+ return -1;
+ }
+ break;
+
+ case 'o':
+ outFile = fopen(optstate->value, "wb");
+ if (!outFile) {
+ fprintf(stderr, "%s: unable to open \"%s\" for writing\n",
+ progName, optstate->value);
+ return -1;
+ }
+ break;
+ }
+ }
+ if (!inFile)
+ inFile = stdin;
+ if (!outFile) {
+#if defined(WIN32)
+ int smrv = _setmode(_fileno(stdout), _O_BINARY);
+ if (smrv == -1) {
+ fprintf(stderr,
+ "%s: Cannot change stdout to binary mode. Use -o option instead.\n",
+ progName);
+ return smrv;
+ }
+#endif
+ outFile = stdout;
+ }
+ rv = decode_file(outFile, inFile);
+ if (rv != SECSuccess) {
+ fprintf(stderr, "%s: lossage: error=%d errno=%d\n",
+ progName, PORT_GetError(), errno);
+ return -1;
+ }
+ return 0;
+}
diff --git a/nss/cmd/atob/atob.gyp b/nss/cmd/atob/atob.gyp
new file mode 100644
index 0000000..af972c2
--- /dev/null
+++ b/nss/cmd/atob/atob.gyp
@@ -0,0 +1,30 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi',
+ '../../cmd/platlibs.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'atob',
+ 'type': 'executable',
+ 'sources': [
+ 'atob.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:dbm_exports',
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'target_defaults': {
+ 'defines': [
+ 'NSPR20'
+ ]
+ },
+ 'variables': {
+ 'module': 'nss'
+ }
+}
\ No newline at end of file
diff --git a/nss/cmd/atob/manifest.mn b/nss/cmd/atob/manifest.mn
new file mode 100644
index 0000000..5d822b9
--- /dev/null
+++ b/nss/cmd/atob/manifest.mn
@@ -0,0 +1,22 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+CORE_DEPTH = ../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+# This next line is used by .mk files
+# and gets translated into $LINCS in manifest.mnw
+# The MODULE is always implicitly required.
+# Listing it here in REQUIRES makes it appear twice in the cc command line.
+REQUIRES = seccmd dbm
+
+DEFINES = -DNSPR20
+
+CSRCS = atob.c
+
+PROGRAM = atob
+
diff --git a/nss/cmd/benchmark/.gitignore b/nss/cmd/benchmark/.gitignore
new file mode 100644
index 0000000..f1d55a6
--- /dev/null
+++ b/nss/cmd/benchmark/.gitignore
@@ -0,0 +1,2 @@
+.cproject
+
diff --git a/nss/cmd/benchmark/Makefile b/nss/cmd/benchmark/Makefile
new file mode 100644
index 0000000..a27a3ce
--- /dev/null
+++ b/nss/cmd/benchmark/Makefile
@@ -0,0 +1,46 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include ../platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+#include ../platlibs.mk
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+include ../platrules.mk
+
diff --git a/nss/cmd/benchmark/README.md b/nss/cmd/benchmark/README.md
new file mode 100644
index 0000000..7f511f2
--- /dev/null
+++ b/nss/cmd/benchmark/README.md
@@ -0,0 +1,5 @@
+tool to send http GET requests to a server requesting files 10.txt, ..., 10000000.txt
+run as e.g.
+`./benchmark localhost 4242 | grep -v 'HUBI' | grep -v "Message Hash" | grep -v "New Hash Chain Value"`
+
+to get a csv output, where the first column is the file size and the other columns are the time in seconds from sending the request to receiving the full response
diff --git a/nss/cmd/benchmark/client_db b/nss/cmd/benchmark/client_db
new file mode 120000
index 0000000..22ed056
--- /dev/null
+++ b/nss/cmd/benchmark/client_db
@@ -0,0 +1 @@
+../../../ca/client_db
\ No newline at end of file
diff --git a/nss/cmd/benchmark/main.c b/nss/cmd/benchmark/main.c
new file mode 100644
index 0000000..2823f23
--- /dev/null
+++ b/nss/cmd/benchmark/main.c
@@ -0,0 +1,247 @@
+#include
+#include
+#include
+#include
+
+#include "nspr.h"
+#include "plgetopt.h"
+#include "prerror.h"
+#include "prnetdb.h"
+
+#include "nss.h"
+#include "ssl.h"
+#include "sslproto.h"
+#include
+#include
+#include "tlsproofstr.h"
+
+#define SHA_256_LENGTH 32
+#define RUNS 100
+
+/*Error handler*/
+void error(const char *msg)
+{
+ PRErrorCode perr = PR_GetError();
+ const char *errString = PORT_ErrorToString(perr);
+
+ printf("!! ERROR function name: %s returned error %d:\n%s\n",msg, perr, errString);
+ exit(1);
+}
+
+/*Callback function that return the password of the certificate database.
+ * It is set when configuring NSS.*/
+char* getPwd(PK11SlotInfo *slot, PRBool retry, void *arg){
+ printf("Pass retrieved \n");
+
+ char *pwd= NULL;
+ pwd = PORT_Strdup("");
+
+ return pwd;
+}
+
+
+//*
+SECStatus fetchTLSProofCallBack(unsigned char *proof, unsigned int length){
+ printf("Got proof of size: %i\n", length);
+ if(SSL_TLSProofCheckProof(proof, length) == SECSuccess){
+ printf("Proof successfully verified!\n");
+ } else {
+ printf("Proof is incorrect\n");
+ }
+ return SECSuccess;
+}
+// */
+
+
+int main(int argc, char *argv[])
+{
+ PRFileDesc* socketfd = NULL;
+ PRHostEnt host;
+ PRNetAddr addr;
+ SECStatus rv;
+ PRStatus pr;
+ char buffer[65536];
+ char buffParam[256];
+ int n;
+ int extension_on;
+ PRSocketOptionData socketOption;
+ SSLVersionRange ver;
+
+ // 3 arguments are necessary for the client
+ if(argc < 4){
+ error("Specify host, port and whether the extension is on (1) or off (0)");
+ }
+ extension_on = atoi(argv[3]);
+ //Set the password callback
+ PK11_SetPasswordFunc(getPwd);
+
+ //Init
+ rv = NSS_Init("../client_db");
+ if(rv != SECSuccess) error("NSS_Init");
+
+ int response_size = 10;
+ for(int i=0 ; i < 7 ; i++)
+ {
+ //Open
+ socketfd = PR_OpenTCPSocket(PR_AF_INET);
+ if (socketfd == NULL) error("PR_OpenTCPSocket");
+
+
+ //Set socket option
+ socketOption.option = PR_SockOpt_Nonblocking;
+ socketOption.value.non_blocking = PR_FALSE;
+ pr = PR_SetSocketOption(socketfd, &socketOption);
+ if (pr != PR_SUCCESS) error("PR_SetSocketOption");
+
+ //Import
+ socketfd = SSL_ImportFD(NULL, socketfd);
+ if (socketfd == NULL) error("SSL_ImportFD");
+
+ //Set server mode
+ rv = SSL_OptionSet(socketfd, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
+ if(rv != SECSuccess) error("SSL_OptionSet, SSL_HANDSHAKE_AS_CLIENT ");
+
+ if (extension_on) {
+ //Enable TLS Proof extension for non-repudiation
+ rv = SSL_OptionSet(socketfd, SSL_ENABLE_TLS_PROOF, PR_TRUE);
+ if(rv != SECSuccess) error("SSL_OptionSet, SSL_ENABLE_TLS_PROOF");
+ fprintf(stderr, "TLS-N enabled\n");
+ //Set the proof return callback
+ rv = SSL_TLSProofSetReturnCallBack(socketfd, fetchTLSProofCallBack, hidden_plaintext_proof);
+ if(rv != SECSuccess) error("SLL_TLSProofSetReturnCallBack");
+ } else {
+ rv = SSL_OptionSet(socketfd, SSL_ENABLE_TLS_PROOF, PR_FALSE);
+ if(rv != SECSuccess) error("SSL_OptionSet, SSL_ENABLE_TLS_PROOF");
+ fprintf(stderr, "TLS-N disabled\n");
+ }
+
+ //Set url for authentication
+ rv = SSL_SetURL(socketfd, "tls-n.testserver");
+ if(rv != SECSuccess) error("SSL_SetURL");
+
+ //Force TLS 1.3
+ ver.max= SSL_LIBRARY_VERSION_TLS_1_3;
+ ver.min= SSL_LIBRARY_VERSION_TLS_1_3;
+ rv = SSL_VersionRangeSet(socketfd,&ver);
+ if(rv != SECSuccess) error("SSL_VersionRangeSet");
+
+ //Get host
+ pr = PR_GetHostByName(argv[1],buffParam,256,&host);
+ if (pr != PR_SUCCESS) error("PR_GetHostByName");
+ rv = PR_EnumerateHostEnt(0, &host, atoi(argv[2]), &addr);
+ if(rv < 0) error("PR_EnumerateHostEnt");
+
+ //Connect
+ pr = PR_Connect(socketfd, &addr, PR_INTERVAL_NO_TIMEOUT);
+ if(pr != PR_SUCCESS) error("PR_Connect");
+
+ PRBool val = PR_FALSE;
+
+ //Send one request to establish session
+ snprintf(buffer, sizeof(buffer), "GET /%d.txt HTTP/1.1\nHost: tls-n.testserver\n\n", response_size);
+ n = PR_Write(socketfd,buffer,strlen(buffer));
+ if (n < 0) {
+ error("ERROR writing to socket");
+ }
+
+ //See if the negotiation of TLS proof was successful
+ rv = SSL_TLSProofIsNegociated(socketfd,&val);
+ if(rv != SECSuccess) error("SSL_TLSProofIsNegociated");
+
+ //Get the TLS version used
+ rv = SSL_VersionRangeGet(socketfd,&ver);
+ if(rv != SECSuccess) error("SSL_VersionRangeGet");
+
+ //Read an incoming message
+ char current = '\0';
+ char last = '\0';
+ int header_size = 0;
+ while (!(current=='\n' && last=='\n')) {
+ if (current != '\r') {
+ last = current;
+ }
+ n = PR_Read(socketfd,¤t,1);
+ //printf("%x ",current);
+ header_size++;
+ if (n<=0) break;
+ }
+ n = 0;
+ int n_read = 1;
+ while (n < response_size && n_read > 0) {
+ bzero(buffer,sizeof(buffer));
+ n_read = PR_Read(socketfd,buffer,sizeof(buffer));
+ n += n_read;
+ }
+ if (n < 0){
+ error("ERROR reading from socket");
+ }
+ if (n == 0){
+ error("socket closed prematurely");
+ }
+ //printf("\nheader size: %d\n", header_size);
+ double times[RUNS];
+ for (int j=0; j=6);
+ sleep_time.tv_nsec = 100000000;
+ nanosleep(&sleep_time, &rem);
+
+ snprintf(buffer, sizeof(buffer), "GET /%d.txt HTTP/1.1\nHost: tls-n.testserver\n\n", response_size);
+
+ struct timespec start;
+ clock_gettime(CLOCK_REALTIME, &start);
+ //Send request
+ n = PR_Write(socketfd,buffer,strlen(buffer));
+ if (n < 0) {
+ error("ERROR writing to socket");
+ }
+
+ //Read an incoming message
+ current = '\0';
+ last = '\0';
+ while (!(current=='\n' && last=='\n')) {
+ if (current != '\r') {
+ last = current;
+ }
+ n = PR_Read(socketfd,¤t,1);
+ if (n<=0) break;
+ }
+ n = 0;
+ n_read = 1;
+ while (n < response_size && n_read > 0) {
+ bzero(buffer,sizeof(buffer));
+ n_read = PR_Read(socketfd,buffer,sizeof(buffer));
+ n += n_read;
+ //printf("%d\n",n);
+ }
+ if (n_read == 0){
+ error("socket closed prematurely");
+ }
+ if (n_read < 0){
+ printf("response_size: %d\trun: %d\n",response_size, j);
+ error("ERROR reading from socket");
+ }
+ //printf("\n");
+ struct timespec end;
+ clock_gettime(CLOCK_REALTIME, &end);
+ long long diff = (end.tv_sec - start.tv_sec)*1000000000 + end.tv_nsec - start.tv_nsec;
+ double diff_s = ((double) diff)/1000000000.0;
+ times[j] = diff_s;
+ //printf("Time: %f seconds", diff_s);
+
+ }
+ printf("%d", response_size);
+ for(int j=0;j
+#include
+
+#include "blapi.h"
+#include "secrng.h"
+#include "prmem.h"
+#include "prprf.h"
+#include "prtime.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "nssb64.h"
+#include "basicutil.h"
+#include "plgetopt.h"
+#include "softoken.h"
+#include "nspr.h"
+#include "secport.h"
+#include "secoid.h"
+#include "nssutil.h"
+
+#include "pkcs1_vectors.h"
+
+#ifndef NSS_DISABLE_ECC
+#include "ecl-curve.h"
+SECStatus EC_DecodeParams(const SECItem *encodedParams,
+ ECParams **ecparams);
+SECStatus EC_CopyParams(PLArenaPool *arena, ECParams *dstParams,
+ const ECParams *srcParams);
+#endif
+
+char *progName;
+char *testdir = NULL;
+
+#define BLTEST_DEFAULT_CHUNKSIZE 4096
+
+#define WORDSIZE sizeof(unsigned long)
+
+#define CHECKERROR(rv, ln) \
+ if (rv) { \
+ PRErrorCode prerror = PR_GetError(); \
+ PR_fprintf(PR_STDERR, "%s: ERR %d (%s) at line %d.\n", progName, \
+ prerror, PORT_ErrorToString(prerror), ln); \
+ exit(-1); \
+ }
+
+/* Macros for performance timing. */
+#define TIMESTART() \
+ time1 = PR_IntervalNow();
+
+#define TIMEFINISH(time, reps) \
+ time2 = (PRIntervalTime)(PR_IntervalNow() - time1); \
+ time1 = PR_IntervalToMilliseconds(time2); \
+ time = ((double)(time1)) / reps;
+
+#define TIMEMARK(seconds) \
+ time1 = PR_SecondsToInterval(seconds); \
+ { \
+ PRInt64 tmp; \
+ if (time2 == 0) { \
+ time2 = 1; \
+ } \
+ LL_DIV(tmp, time1, time2); \
+ if (tmp < 10) { \
+ if (tmp == 0) { \
+ opsBetweenChecks = 1; \
+ } else { \
+ LL_L2I(opsBetweenChecks, tmp); \
+ } \
+ } else { \
+ opsBetweenChecks = 10; \
+ } \
+ } \
+ time2 = time1; \
+ time1 = PR_IntervalNow();
+
+#define TIMETOFINISH() \
+ PR_IntervalNow() - time1 >= time2
+
+static void
+Usage()
+{
+#define PRINTUSAGE(subject, option, predicate) \
+ fprintf(stderr, "%10s %s\t%s\n", subject, option, predicate);
+ fprintf(stderr, "\n");
+ PRINTUSAGE(progName, "[-DEHSVR]", "List available cipher modes"); /* XXX */
+ fprintf(stderr, "\n");
+ PRINTUSAGE(progName, "-E -m mode ", "Encrypt a buffer");
+ PRINTUSAGE("", "", "[-i plaintext] [-o ciphertext] [-k key] [-v iv]");
+ PRINTUSAGE("", "", "[-b bufsize] [-g keysize] [-e exp] [-r rounds]");
+ PRINTUSAGE("", "", "[-w wordsize] [-p repetitions | -5 time_interval]");
+ PRINTUSAGE("", "", "[-4 th_num]");
+ PRINTUSAGE("", "-m", "cipher mode to use");
+ PRINTUSAGE("", "-i", "file which contains input buffer");
+ PRINTUSAGE("", "-o", "file for output buffer");
+ PRINTUSAGE("", "-k", "file which contains key");
+ PRINTUSAGE("", "-v", "file which contains initialization vector");
+ PRINTUSAGE("", "-b", "size of input buffer");
+ PRINTUSAGE("", "-g", "key size (in bytes)");
+ PRINTUSAGE("", "-p", "do performance test");
+ PRINTUSAGE("", "-4", "run test in multithread mode. th_num number of parallel threads");
+ PRINTUSAGE("", "-5", "run test for specified time interval(in seconds)");
+ PRINTUSAGE("", "--aad", "File with contains additional auth data");
+ PRINTUSAGE("(rsa)", "-e", "rsa public exponent");
+ PRINTUSAGE("(rc5)", "-r", "number of rounds");
+ PRINTUSAGE("(rc5)", "-w", "wordsize (32 or 64)");
+ fprintf(stderr, "\n");
+ PRINTUSAGE(progName, "-D -m mode", "Decrypt a buffer");
+ PRINTUSAGE("", "", "[-i plaintext] [-o ciphertext] [-k key] [-v iv]");
+ PRINTUSAGE("", "", "[-p repetitions | -5 time_interval] [-4 th_num]");
+ PRINTUSAGE("", "-m", "cipher mode to use");
+ PRINTUSAGE("", "-i", "file which contains input buffer");
+ PRINTUSAGE("", "-o", "file for output buffer");
+ PRINTUSAGE("", "-k", "file which contains key");
+ PRINTUSAGE("", "-v", "file which contains initialization vector");
+ PRINTUSAGE("", "-p", "do performance test");
+ PRINTUSAGE("", "-4", "run test in multithread mode. th_num number of parallel threads");
+ PRINTUSAGE("", "-5", "run test for specified time interval(in seconds)");
+ PRINTUSAGE("", "--aad", "File with contains additional auth data");
+ fprintf(stderr, "\n");
+ PRINTUSAGE(progName, "-H -m mode", "Hash a buffer");
+ PRINTUSAGE("", "", "[-i plaintext] [-o hash]");
+ PRINTUSAGE("", "", "[-b bufsize]");
+ PRINTUSAGE("", "", "[-p repetitions | -5 time_interval] [-4 th_num]");
+ PRINTUSAGE("", "-m", "cipher mode to use");
+ PRINTUSAGE("", "-i", "file which contains input buffer");
+ PRINTUSAGE("", "-o", "file for hash");
+ PRINTUSAGE("", "-b", "size of input buffer");
+ PRINTUSAGE("", "-p", "do performance test");
+ PRINTUSAGE("", "-4", "run test in multithread mode. th_num number of parallel threads");
+ PRINTUSAGE("", "-5", "run test for specified time interval(in seconds)");
+ fprintf(stderr, "\n");
+ PRINTUSAGE(progName, "-S -m mode", "Sign a buffer");
+ PRINTUSAGE("", "", "[-i plaintext] [-o signature] [-k key]");
+ PRINTUSAGE("", "", "[-b bufsize]");
+#ifndef NSS_DISABLE_ECC
+ PRINTUSAGE("", "", "[-n curvename]");
+#endif
+ PRINTUSAGE("", "", "[-p repetitions | -5 time_interval] [-4 th_num]");
+ PRINTUSAGE("", "-m", "cipher mode to use");
+ PRINTUSAGE("", "-i", "file which contains input buffer");
+ PRINTUSAGE("", "-o", "file for signature");
+ PRINTUSAGE("", "-k", "file which contains key");
+#ifndef NSS_DISABLE_ECC
+ PRINTUSAGE("", "-n", "name of curve for EC key generation; one of:");
+ PRINTUSAGE("", "", " nistp256, nistp384, nistp521");
+#endif
+ PRINTUSAGE("", "-p", "do performance test");
+ PRINTUSAGE("", "-4", "run test in multithread mode. th_num number of parallel threads");
+ PRINTUSAGE("", "-5", "run test for specified time interval(in seconds)");
+ fprintf(stderr, "\n");
+ PRINTUSAGE(progName, "-V -m mode", "Verify a signed buffer");
+ PRINTUSAGE("", "", "[-i plaintext] [-s signature] [-k key]");
+ PRINTUSAGE("", "", "[-p repetitions | -5 time_interval] [-4 th_num]");
+ PRINTUSAGE("", "-m", "cipher mode to use");
+ PRINTUSAGE("", "-i", "file which contains input buffer");
+ PRINTUSAGE("", "-s", "file which contains signature of input buffer");
+ PRINTUSAGE("", "-k", "file which contains key");
+ PRINTUSAGE("", "-p", "do performance test");
+ PRINTUSAGE("", "-4", "run test in multithread mode. th_num number of parallel threads");
+ PRINTUSAGE("", "-5", "run test for specified time interval(in seconds)");
+ fprintf(stderr, "\n");
+ PRINTUSAGE(progName, "-N -m mode -b bufsize",
+ "Create a nonce plaintext and key");
+ PRINTUSAGE("", "", "[-g keysize] [-u cxreps]");
+ PRINTUSAGE("", "-g", "key size (in bytes)");
+ PRINTUSAGE("", "-u", "number of repetitions of context creation");
+ fprintf(stderr, "\n");
+ PRINTUSAGE(progName, "-R [-g keysize] [-e exp]",
+ "Test the RSA populate key function");
+ PRINTUSAGE("", "", "[-r repetitions]");
+ PRINTUSAGE("", "-g", "key size (in bytes)");
+ PRINTUSAGE("", "-e", "rsa public exponent");
+ PRINTUSAGE("", "-r", "repetitions of the test");
+ fprintf(stderr, "\n");
+ PRINTUSAGE(progName, "-F", "Run the FIPS self-test");
+ fprintf(stderr, "\n");
+ PRINTUSAGE(progName, "-T [-m mode1,mode2...]", "Run the BLAPI self-test");
+ fprintf(stderr, "\n");
+ exit(1);
+}
+
+/* Helper functions for ascii<-->binary conversion/reading/writing */
+
+/* XXX argh */
+struct item_with_arena {
+ SECItem *item;
+ PLArenaPool *arena;
+};
+
+static PRInt32
+get_binary(void *arg, const unsigned char *ibuf, PRInt32 size)
+{
+ struct item_with_arena *it = arg;
+ SECItem *binary = it->item;
+ SECItem *tmp;
+ int index;
+ if (binary->data == NULL) {
+ tmp = SECITEM_AllocItem(it->arena, NULL, size);
+ binary->data = tmp->data;
+ binary->len = tmp->len;
+ index = 0;
+ } else {
+ SECITEM_ReallocItem(NULL, binary, binary->len, binary->len + size);
+ index = binary->len;
+ }
+ PORT_Memcpy(&binary->data[index], ibuf, size);
+ return binary->len;
+}
+
+static SECStatus
+atob(SECItem *ascii, SECItem *binary, PLArenaPool *arena)
+{
+ SECStatus status;
+ NSSBase64Decoder *cx;
+ struct item_with_arena it;
+ int len;
+ binary->data = NULL;
+ binary->len = 0;
+ it.item = binary;
+ it.arena = arena;
+ len = (strncmp((const char *)&ascii->data[ascii->len - 2], "\r\n", 2)) ? ascii->len
+ : ascii->len - 2;
+ cx = NSSBase64Decoder_Create(get_binary, &it);
+ status = NSSBase64Decoder_Update(cx, (const char *)ascii->data, len);
+ status = NSSBase64Decoder_Destroy(cx, PR_FALSE);
+ return status;
+}
+
+static PRInt32
+output_ascii(void *arg, const char *obuf, PRInt32 size)
+{
+ PRFileDesc *outfile = arg;
+ PRInt32 nb = PR_Write(outfile, obuf, size);
+ if (nb != size) {
+ PORT_SetError(SEC_ERROR_IO);
+ return -1;
+ }
+ return nb;
+}
+
+static SECStatus
+btoa_file(SECItem *binary, PRFileDesc *outfile)
+{
+ SECStatus status;
+ NSSBase64Encoder *cx;
+ if (binary->len == 0)
+ return SECSuccess;
+ cx = NSSBase64Encoder_Create(output_ascii, outfile);
+ status = NSSBase64Encoder_Update(cx, binary->data, binary->len);
+ status = NSSBase64Encoder_Destroy(cx, PR_FALSE);
+ status = PR_Write(outfile, "\r\n", 2);
+ return status;
+}
+
+SECStatus
+hex_from_2char(unsigned char *c2, unsigned char *byteval)
+{
+ int i;
+ unsigned char offset;
+ *byteval = 0;
+ for (i = 0; i < 2; i++) {
+ if (c2[i] >= '0' && c2[i] <= '9') {
+ offset = c2[i] - '0';
+ *byteval |= offset << 4 * (1 - i);
+ } else if (c2[i] >= 'a' && c2[i] <= 'f') {
+ offset = c2[i] - 'a';
+ *byteval |= (offset + 10) << 4 * (1 - i);
+ } else if (c2[i] >= 'A' && c2[i] <= 'F') {
+ offset = c2[i] - 'A';
+ *byteval |= (offset + 10) << 4 * (1 - i);
+ } else {
+ return SECFailure;
+ }
+ }
+ return SECSuccess;
+}
+
+SECStatus
+char2_from_hex(unsigned char byteval, char *c2)
+{
+ int i;
+ unsigned char offset;
+ for (i = 0; i < 2; i++) {
+ offset = (byteval >> 4 * (1 - i)) & 0x0f;
+ if (offset < 10) {
+ c2[i] = '0' + offset;
+ } else {
+ c2[i] = 'A' + offset - 10;
+ }
+ }
+ return SECSuccess;
+}
+
+void
+serialize_key(SECItem *it, int ni, PRFileDesc *file)
+{
+ unsigned char len[4];
+ int i;
+ NSSBase64Encoder *cx;
+ cx = NSSBase64Encoder_Create(output_ascii, file);
+ for (i = 0; i < ni; i++, it++) {
+ len[0] = (it->len >> 24) & 0xff;
+ len[1] = (it->len >> 16) & 0xff;
+ len[2] = (it->len >> 8) & 0xff;
+ len[3] = (it->len & 0xff);
+ NSSBase64Encoder_Update(cx, len, 4);
+ NSSBase64Encoder_Update(cx, it->data, it->len);
+ }
+ NSSBase64Encoder_Destroy(cx, PR_FALSE);
+ PR_Write(file, "\r\n", 2);
+}
+
+void
+key_from_filedata(PLArenaPool *arena, SECItem *it, int ns, int ni, SECItem *filedata)
+{
+ int fpos = 0;
+ int i, len;
+ unsigned char *buf = filedata->data;
+ for (i = 0; i < ni; i++) {
+ len = (buf[fpos++] & 0xff) << 24;
+ len |= (buf[fpos++] & 0xff) << 16;
+ len |= (buf[fpos++] & 0xff) << 8;
+ len |= (buf[fpos++] & 0xff);
+ if (ns <= i) {
+ if (len > 0) {
+ it->len = len;
+ it->data = PORT_ArenaAlloc(arena, it->len);
+ PORT_Memcpy(it->data, &buf[fpos], it->len);
+ } else {
+ it->len = 0;
+ it->data = NULL;
+ }
+ it++;
+ }
+ fpos += len;
+ }
+}
+
+static RSAPrivateKey *
+rsakey_from_filedata(PLArenaPool *arena, SECItem *filedata)
+{
+ RSAPrivateKey *key;
+ key = (RSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(RSAPrivateKey));
+ key->arena = arena;
+ key_from_filedata(arena, &key->version, 0, 9, filedata);
+ return key;
+}
+
+static PQGParams *
+pqg_from_filedata(PLArenaPool *arena, SECItem *filedata)
+{
+ PQGParams *pqg;
+ pqg = (PQGParams *)PORT_ArenaZAlloc(arena, sizeof(PQGParams));
+ pqg->arena = arena;
+ key_from_filedata(arena, &pqg->prime, 0, 3, filedata);
+ return pqg;
+}
+
+static DSAPrivateKey *
+dsakey_from_filedata(PLArenaPool *arena, SECItem *filedata)
+{
+ DSAPrivateKey *key;
+ key = (DSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(DSAPrivateKey));
+ key->params.arena = arena;
+ key_from_filedata(arena, &key->params.prime, 0, 5, filedata);
+ return key;
+}
+
+#ifndef NSS_DISABLE_ECC
+static ECPrivateKey *
+eckey_from_filedata(PLArenaPool *arena, SECItem *filedata)
+{
+ ECPrivateKey *key;
+ SECStatus rv;
+ ECParams *tmpECParams = NULL;
+ key = (ECPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(ECPrivateKey));
+ /* read and convert params */
+ key->ecParams.arena = arena;
+ key_from_filedata(arena, &key->ecParams.DEREncoding, 0, 1, filedata);
+ rv = SECOID_Init();
+ CHECKERROR(rv, __LINE__);
+ rv = EC_DecodeParams(&key->ecParams.DEREncoding, &tmpECParams);
+ CHECKERROR(rv, __LINE__);
+ rv = EC_CopyParams(key->ecParams.arena, &key->ecParams, tmpECParams);
+ CHECKERROR(rv, __LINE__);
+ rv = SECOID_Shutdown();
+ CHECKERROR(rv, __LINE__);
+ PORT_FreeArena(tmpECParams->arena, PR_TRUE);
+ /* read key */
+ key_from_filedata(arena, &key->publicValue, 1, 3, filedata);
+ return key;
+}
+
+typedef struct curveNameTagPairStr {
+ char *curveName;
+ SECOidTag curveOidTag;
+} CurveNameTagPair;
+
+static CurveNameTagPair nameTagPair[] =
+ {
+ { "sect163k1", SEC_OID_SECG_EC_SECT163K1 },
+ { "nistk163", SEC_OID_SECG_EC_SECT163K1 },
+ { "sect163r1", SEC_OID_SECG_EC_SECT163R1 },
+ { "sect163r2", SEC_OID_SECG_EC_SECT163R2 },
+ { "nistb163", SEC_OID_SECG_EC_SECT163R2 },
+ { "sect193r1", SEC_OID_SECG_EC_SECT193R1 },
+ { "sect193r2", SEC_OID_SECG_EC_SECT193R2 },
+ { "sect233k1", SEC_OID_SECG_EC_SECT233K1 },
+ { "nistk233", SEC_OID_SECG_EC_SECT233K1 },
+ { "sect233r1", SEC_OID_SECG_EC_SECT233R1 },
+ { "nistb233", SEC_OID_SECG_EC_SECT233R1 },
+ { "sect239k1", SEC_OID_SECG_EC_SECT239K1 },
+ { "sect283k1", SEC_OID_SECG_EC_SECT283K1 },
+ { "nistk283", SEC_OID_SECG_EC_SECT283K1 },
+ { "sect283r1", SEC_OID_SECG_EC_SECT283R1 },
+ { "nistb283", SEC_OID_SECG_EC_SECT283R1 },
+ { "sect409k1", SEC_OID_SECG_EC_SECT409K1 },
+ { "nistk409", SEC_OID_SECG_EC_SECT409K1 },
+ { "sect409r1", SEC_OID_SECG_EC_SECT409R1 },
+ { "nistb409", SEC_OID_SECG_EC_SECT409R1 },
+ { "sect571k1", SEC_OID_SECG_EC_SECT571K1 },
+ { "nistk571", SEC_OID_SECG_EC_SECT571K1 },
+ { "sect571r1", SEC_OID_SECG_EC_SECT571R1 },
+ { "nistb571", SEC_OID_SECG_EC_SECT571R1 },
+ { "secp160k1", SEC_OID_SECG_EC_SECP160K1 },
+ { "secp160r1", SEC_OID_SECG_EC_SECP160R1 },
+ { "secp160r2", SEC_OID_SECG_EC_SECP160R2 },
+ { "secp192k1", SEC_OID_SECG_EC_SECP192K1 },
+ { "secp192r1", SEC_OID_SECG_EC_SECP192R1 },
+ { "nistp192", SEC_OID_SECG_EC_SECP192R1 },
+ { "secp224k1", SEC_OID_SECG_EC_SECP224K1 },
+ { "secp224r1", SEC_OID_SECG_EC_SECP224R1 },
+ { "nistp224", SEC_OID_SECG_EC_SECP224R1 },
+ { "secp256k1", SEC_OID_SECG_EC_SECP256K1 },
+ { "secp256r1", SEC_OID_SECG_EC_SECP256R1 },
+ { "nistp256", SEC_OID_SECG_EC_SECP256R1 },
+ { "secp384r1", SEC_OID_SECG_EC_SECP384R1 },
+ { "nistp384", SEC_OID_SECG_EC_SECP384R1 },
+ { "secp521r1", SEC_OID_SECG_EC_SECP521R1 },
+ { "nistp521", SEC_OID_SECG_EC_SECP521R1 },
+
+ { "prime192v1", SEC_OID_ANSIX962_EC_PRIME192V1 },
+ { "prime192v2", SEC_OID_ANSIX962_EC_PRIME192V2 },
+ { "prime192v3", SEC_OID_ANSIX962_EC_PRIME192V3 },
+ { "prime239v1", SEC_OID_ANSIX962_EC_PRIME239V1 },
+ { "prime239v2", SEC_OID_ANSIX962_EC_PRIME239V2 },
+ { "prime239v3", SEC_OID_ANSIX962_EC_PRIME239V3 },
+
+ { "c2pnb163v1", SEC_OID_ANSIX962_EC_C2PNB163V1 },
+ { "c2pnb163v2", SEC_OID_ANSIX962_EC_C2PNB163V2 },
+ { "c2pnb163v3", SEC_OID_ANSIX962_EC_C2PNB163V3 },
+ { "c2pnb176v1", SEC_OID_ANSIX962_EC_C2PNB176V1 },
+ { "c2tnb191v1", SEC_OID_ANSIX962_EC_C2TNB191V1 },
+ { "c2tnb191v2", SEC_OID_ANSIX962_EC_C2TNB191V2 },
+ { "c2tnb191v3", SEC_OID_ANSIX962_EC_C2TNB191V3 },
+ { "c2onb191v4", SEC_OID_ANSIX962_EC_C2ONB191V4 },
+ { "c2onb191v5", SEC_OID_ANSIX962_EC_C2ONB191V5 },
+ { "c2pnb208w1", SEC_OID_ANSIX962_EC_C2PNB208W1 },
+ { "c2tnb239v1", SEC_OID_ANSIX962_EC_C2TNB239V1 },
+ { "c2tnb239v2", SEC_OID_ANSIX962_EC_C2TNB239V2 },
+ { "c2tnb239v3", SEC_OID_ANSIX962_EC_C2TNB239V3 },
+ { "c2onb239v4", SEC_OID_ANSIX962_EC_C2ONB239V4 },
+ { "c2onb239v5", SEC_OID_ANSIX962_EC_C2ONB239V5 },
+ { "c2pnb272w1", SEC_OID_ANSIX962_EC_C2PNB272W1 },
+ { "c2pnb304w1", SEC_OID_ANSIX962_EC_C2PNB304W1 },
+ { "c2tnb359v1", SEC_OID_ANSIX962_EC_C2TNB359V1 },
+ { "c2pnb368w1", SEC_OID_ANSIX962_EC_C2PNB368W1 },
+ { "c2tnb431r1", SEC_OID_ANSIX962_EC_C2TNB431R1 },
+
+ { "secp112r1", SEC_OID_SECG_EC_SECP112R1 },
+ { "secp112r2", SEC_OID_SECG_EC_SECP112R2 },
+ { "secp128r1", SEC_OID_SECG_EC_SECP128R1 },
+ { "secp128r2", SEC_OID_SECG_EC_SECP128R2 },
+
+ { "sect113r1", SEC_OID_SECG_EC_SECT113R1 },
+ { "sect113r2", SEC_OID_SECG_EC_SECT113R2 },
+ { "sect131r1", SEC_OID_SECG_EC_SECT131R1 },
+ { "sect131r2", SEC_OID_SECG_EC_SECT131R2 },
+ { "curve25519", SEC_OID_CURVE25519 },
+ };
+
+static SECItem *
+getECParams(const char *curve)
+{
+ SECItem *ecparams;
+ SECOidData *oidData = NULL;
+ SECOidTag curveOidTag = SEC_OID_UNKNOWN; /* default */
+ int i, numCurves;
+
+ if (curve != NULL) {
+ numCurves = sizeof(nameTagPair) / sizeof(CurveNameTagPair);
+ for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN));
+ i++) {
+ if (PL_strcmp(curve, nameTagPair[i].curveName) == 0)
+ curveOidTag = nameTagPair[i].curveOidTag;
+ }
+ }
+
+ /* Return NULL if curve name is not recognized */
+ if ((curveOidTag == SEC_OID_UNKNOWN) ||
+ (oidData = SECOID_FindOIDByTag(curveOidTag)) == NULL) {
+ fprintf(stderr, "Unrecognized elliptic curve %s\n", curve);
+ return NULL;
+ }
+
+ ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len));
+
+ /*
+ * ecparams->data needs to contain the ASN encoding of an object ID (OID)
+ * representing the named curve. The actual OID is in
+ * oidData->oid.data so we simply prepend 0x06 and OID length
+ */
+ ecparams->data[0] = SEC_ASN1_OBJECT_ID;
+ ecparams->data[1] = oidData->oid.len;
+ memcpy(ecparams->data + 2, oidData->oid.data, oidData->oid.len);
+
+ return ecparams;
+}
+#endif /* NSS_DISABLE_ECC */
+
+static void
+dump_pqg(PQGParams *pqg)
+{
+ SECU_PrintInteger(stdout, &pqg->prime, "PRIME:", 0);
+ SECU_PrintInteger(stdout, &pqg->subPrime, "SUBPRIME:", 0);
+ SECU_PrintInteger(stdout, &pqg->base, "BASE:", 0);
+}
+
+static void
+dump_dsakey(DSAPrivateKey *key)
+{
+ dump_pqg(&key->params);
+ SECU_PrintInteger(stdout, &key->publicValue, "PUBLIC VALUE:", 0);
+ SECU_PrintInteger(stdout, &key->privateValue, "PRIVATE VALUE:", 0);
+}
+
+#ifndef NSS_DISABLE_ECC
+static void
+dump_ecp(ECParams *ecp)
+{
+ /* TODO other fields */
+ SECU_PrintInteger(stdout, &ecp->base, "BASE POINT:", 0);
+}
+
+static void
+dump_eckey(ECPrivateKey *key)
+{
+ dump_ecp(&key->ecParams);
+ SECU_PrintInteger(stdout, &key->publicValue, "PUBLIC VALUE:", 0);
+ SECU_PrintInteger(stdout, &key->privateValue, "PRIVATE VALUE:", 0);
+}
+#endif
+
+static void
+dump_rsakey(RSAPrivateKey *key)
+{
+ SECU_PrintInteger(stdout, &key->version, "VERSION:", 0);
+ SECU_PrintInteger(stdout, &key->modulus, "MODULUS:", 0);
+ SECU_PrintInteger(stdout, &key->publicExponent, "PUBLIC EXP:", 0);
+ SECU_PrintInteger(stdout, &key->privateExponent, "PRIVATE EXP:", 0);
+ SECU_PrintInteger(stdout, &key->prime1, "CRT PRIME 1:", 0);
+ SECU_PrintInteger(stdout, &key->prime2, "CRT PRIME 2:", 0);
+ SECU_PrintInteger(stdout, &key->exponent1, "CRT EXP 1:", 0);
+ SECU_PrintInteger(stdout, &key->exponent2, "CRT EXP 2:", 0);
+ SECU_PrintInteger(stdout, &key->coefficient, "CRT COEFFICIENT:", 0);
+}
+
+typedef enum {
+ bltestBase64Encoded, /* Base64 encoded ASCII */
+ bltestBinary, /* straight binary */
+ bltestHexSpaceDelim, /* 0x12 0x34 0xab 0xCD ... */
+ bltestHexStream /* 1234abCD ... */
+} bltestIOMode;
+
+typedef struct
+{
+ SECItem buf;
+ SECItem pBuf;
+ bltestIOMode mode;
+ PRFileDesc *file;
+} bltestIO;
+
+typedef SECStatus (*bltestSymmCipherFn)(void *cx,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen);
+
+typedef SECStatus (*bltestAEADFn)(void *cx,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen,
+ const unsigned char *nonce,
+ unsigned int nonceLen,
+ const unsigned char *ad,
+ unsigned int adLen);
+
+typedef SECStatus (*bltestPubKeyCipherFn)(void *key,
+ SECItem *output,
+ const SECItem *input);
+
+typedef SECStatus (*bltestHashCipherFn)(unsigned char *dest,
+ const unsigned char *src,
+ PRUint32 src_length);
+
+/* Note: Algorithms are grouped in order to support is_symmkeyCipher /
+ * is_pubkeyCipher / is_hashCipher / is_sigCipher
+ */
+typedef enum {
+ bltestINVALID = -1,
+ bltestDES_ECB, /* Symmetric Key Ciphers */
+ bltestDES_CBC, /* . */
+ bltestDES_EDE_ECB, /* . */
+ bltestDES_EDE_CBC, /* . */
+ bltestRC2_ECB, /* . */
+ bltestRC2_CBC, /* . */
+ bltestRC4, /* . */
+#ifdef NSS_SOFTOKEN_DOES_RC5
+ bltestRC5_ECB, /* . */
+ bltestRC5_CBC, /* . */
+#endif
+ bltestAES_ECB, /* . */
+ bltestAES_CBC, /* . */
+ bltestAES_CTS, /* . */
+ bltestAES_CTR, /* . */
+ bltestAES_GCM, /* . */
+ bltestCAMELLIA_ECB, /* . */
+ bltestCAMELLIA_CBC, /* . */
+ bltestSEED_ECB, /* SEED algorithm */
+ bltestSEED_CBC, /* SEED algorithm */
+ bltestCHACHA20, /* ChaCha20 + Poly1305 */
+ bltestRSA, /* Public Key Ciphers */
+ bltestRSA_OAEP, /* . (Public Key Enc.) */
+ bltestRSA_PSS, /* . (Public Key Sig.) */
+#ifndef NSS_DISABLE_ECC
+ bltestECDSA, /* . (Public Key Sig.) */
+#endif
+ bltestDSA, /* . (Public Key Sig.) */
+ bltestMD2, /* Hash algorithms */
+ bltestMD5, /* . */
+ bltestSHA1, /* . */
+ bltestSHA224, /* . */
+ bltestSHA256, /* . */
+ bltestSHA384, /* . */
+ bltestSHA512, /* . */
+ NUMMODES
+} bltestCipherMode;
+
+static char *mode_strings[] =
+ {
+ "des_ecb",
+ "des_cbc",
+ "des3_ecb",
+ "des3_cbc",
+ "rc2_ecb",
+ "rc2_cbc",
+ "rc4",
+#ifdef NSS_SOFTOKEN_DOES_RC5
+ "rc5_ecb",
+ "rc5_cbc",
+#endif
+ "aes_ecb",
+ "aes_cbc",
+ "aes_cts",
+ "aes_ctr",
+ "aes_gcm",
+ "camellia_ecb",
+ "camellia_cbc",
+ "seed_ecb",
+ "seed_cbc",
+ "chacha20_poly1305",
+ "rsa",
+ "rsa_oaep",
+ "rsa_pss",
+#ifndef NSS_DISABLE_ECC
+ "ecdsa",
+#endif
+ /*"pqg",*/
+ "dsa",
+ "md2",
+ "md5",
+ "sha1",
+ "sha224",
+ "sha256",
+ "sha384",
+ "sha512",
+ };
+
+typedef struct
+{
+ bltestIO key;
+ bltestIO iv;
+} bltestSymmKeyParams;
+
+typedef struct
+{
+ bltestSymmKeyParams sk; /* must be first */
+ bltestIO aad;
+} bltestAuthSymmKeyParams;
+
+typedef struct
+{
+ bltestIO key;
+ bltestIO iv;
+ int rounds;
+ int wordsize;
+} bltestRC5Params;
+
+typedef struct
+{
+ bltestIO key;
+ int keysizeInBits;
+
+ /* OAEP & PSS */
+ HASH_HashType hashAlg;
+ HASH_HashType maskHashAlg;
+ bltestIO seed; /* salt if PSS */
+} bltestRSAParams;
+
+typedef struct
+{
+ bltestIO pqgdata;
+ unsigned int keysize;
+ bltestIO keyseed;
+ bltestIO sigseed;
+ PQGParams *pqg;
+} bltestDSAParams;
+
+#ifndef NSS_DISABLE_ECC
+typedef struct
+{
+ char *curveName;
+ bltestIO sigseed;
+} bltestECDSAParams;
+#endif
+
+typedef struct
+{
+ bltestIO key;
+ void *privKey;
+ void *pubKey;
+ bltestIO sig; /* if doing verify, the signature (which may come
+ * from sigfile. */
+
+ union {
+ bltestRSAParams rsa;
+ bltestDSAParams dsa;
+#ifndef NSS_DISABLE_ECC
+ bltestECDSAParams ecdsa;
+#endif
+ } cipherParams;
+} bltestAsymKeyParams;
+
+typedef struct
+{
+ bltestIO key; /* unused */
+ PRBool restart;
+} bltestHashParams;
+
+typedef union {
+ bltestIO key;
+ bltestSymmKeyParams sk;
+ bltestAuthSymmKeyParams ask;
+ bltestRC5Params rc5;
+ bltestAsymKeyParams asymk;
+ bltestHashParams hash;
+} bltestParams;
+
+typedef struct bltestCipherInfoStr bltestCipherInfo;
+
+struct bltestCipherInfoStr {
+ PLArenaPool *arena;
+ /* link to next in multithreaded test */
+ bltestCipherInfo *next;
+ PRThread *cipherThread;
+
+ /* MonteCarlo test flag*/
+ PRBool mCarlo;
+ /* cipher context */
+ void *cx;
+ /* I/O streams */
+ bltestIO input;
+ bltestIO output;
+ /* Cipher-specific parameters */
+ bltestParams params;
+ /* Cipher mode */
+ bltestCipherMode mode;
+ /* Cipher function (encrypt/decrypt/sign/verify/hash) */
+ union {
+ bltestSymmCipherFn symmkeyCipher;
+ bltestAEADFn aeadCipher;
+ bltestPubKeyCipherFn pubkeyCipher;
+ bltestHashCipherFn hashCipher;
+ } cipher;
+ /* performance testing */
+ int repetitionsToPerfom;
+ int seconds;
+ int repetitions;
+ int cxreps;
+ double cxtime;
+ double optime;
+};
+
+PRBool
+is_symmkeyCipher(bltestCipherMode mode)
+{
+ /* change as needed! */
+ if (mode >= bltestDES_ECB && mode <= bltestSEED_CBC)
+ return PR_TRUE;
+ return PR_FALSE;
+}
+
+PRBool
+is_aeadCipher(bltestCipherMode mode)
+{
+ /* change as needed! */
+ switch (mode) {
+ case bltestCHACHA20:
+ return PR_TRUE;
+ default:
+ return PR_FALSE;
+ }
+}
+
+PRBool
+is_authCipher(bltestCipherMode mode)
+{
+ /* change as needed! */
+ switch (mode) {
+ case bltestAES_GCM:
+ case bltestCHACHA20:
+ return PR_TRUE;
+ default:
+ return PR_FALSE;
+ }
+}
+
+PRBool
+is_singleShotCipher(bltestCipherMode mode)
+{
+ /* change as needed! */
+ switch (mode) {
+ case bltestAES_GCM:
+ case bltestAES_CTS:
+ case bltestCHACHA20:
+ return PR_TRUE;
+ default:
+ return PR_FALSE;
+ }
+}
+
+PRBool
+is_pubkeyCipher(bltestCipherMode mode)
+{
+ /* change as needed! */
+ if (mode >= bltestRSA && mode <= bltestDSA)
+ return PR_TRUE;
+ return PR_FALSE;
+}
+
+PRBool
+is_hashCipher(bltestCipherMode mode)
+{
+ /* change as needed! */
+ if (mode >= bltestMD2 && mode <= bltestSHA512)
+ return PR_TRUE;
+ return PR_FALSE;
+}
+
+PRBool
+is_sigCipher(bltestCipherMode mode)
+{
+ /* change as needed! */
+ if (mode >= bltestRSA_PSS && mode <= bltestDSA)
+ return PR_TRUE;
+ return PR_FALSE;
+}
+
+PRBool
+cipher_requires_IV(bltestCipherMode mode)
+{
+ /* change as needed! */
+ switch (mode) {
+ case bltestDES_CBC:
+ case bltestDES_EDE_CBC:
+ case bltestRC2_CBC:
+#ifdef NSS_SOFTOKEN_DOES_RC5
+ case bltestRC5_CBC:
+#endif
+ case bltestAES_CBC:
+ case bltestAES_CTS:
+ case bltestAES_CTR:
+ case bltestAES_GCM:
+ case bltestCAMELLIA_CBC:
+ case bltestSEED_CBC:
+ case bltestCHACHA20:
+ return PR_TRUE;
+ default:
+ return PR_FALSE;
+ }
+}
+
+SECStatus finishIO(bltestIO *output, PRFileDesc *file);
+
+SECStatus
+setupIO(PLArenaPool *arena, bltestIO *input, PRFileDesc *file,
+ char *str, int numBytes)
+{
+ SECStatus rv = SECSuccess;
+ SECItem fileData;
+ SECItem *in;
+ unsigned char *tok;
+ unsigned int i, j;
+ PRBool needToFreeFile = PR_FALSE;
+
+ if (file && (numBytes == 0 || file == PR_STDIN)) {
+ /* grabbing data from a file */
+ rv = SECU_FileToItem(&fileData, file);
+ if (rv != SECSuccess)
+ return SECFailure;
+ in = &fileData;
+ needToFreeFile = PR_TRUE;
+ } else if (str) {
+ /* grabbing data from command line */
+ fileData.data = (unsigned char *)str;
+ fileData.len = PL_strlen(str);
+ in = &fileData;
+ } else if (file) {
+ /* create nonce */
+ SECITEM_AllocItem(arena, &input->buf, numBytes);
+ RNG_GenerateGlobalRandomBytes(input->buf.data, numBytes);
+ return finishIO(input, file);
+ } else {
+ return SECFailure;
+ }
+
+ switch (input->mode) {
+ case bltestBase64Encoded:
+ if (in->len == 0) {
+ input->buf.data = NULL;
+ input->buf.len = 0;
+ break;
+ }
+ rv = atob(in, &input->buf, arena);
+ break;
+ case bltestBinary:
+ if (in->len == 0) {
+ input->buf.data = NULL;
+ input->buf.len = 0;
+ break;
+ }
+ if (in->data[in->len - 1] == '\n')
+ --in->len;
+ if (in->data[in->len - 1] == '\r')
+ --in->len;
+ rv = SECITEM_CopyItem(arena, &input->buf, in);
+ break;
+ case bltestHexSpaceDelim:
+ SECITEM_AllocItem(arena, &input->buf, in->len / 5);
+ for (i = 0, j = 0; i < in->len; i += 5, j++) {
+ tok = &in->data[i];
+ if (tok[0] != '0' || tok[1] != 'x' || tok[4] != ' ')
+ /* bad hex token */
+ break;
+
+ rv = hex_from_2char(&tok[2], input->buf.data + j);
+ if (rv)
+ break;
+ }
+ break;
+ case bltestHexStream:
+ SECITEM_AllocItem(arena, &input->buf, in->len / 2);
+ for (i = 0, j = 0; i < in->len; i += 2, j++) {
+ tok = &in->data[i];
+ rv = hex_from_2char(tok, input->buf.data + j);
+ if (rv)
+ break;
+ }
+ break;
+ }
+
+ if (needToFreeFile)
+ SECITEM_FreeItem(&fileData, PR_FALSE);
+ return rv;
+}
+
+SECStatus
+finishIO(bltestIO *output, PRFileDesc *file)
+{
+ SECStatus rv = SECSuccess;
+ PRInt32 nb;
+ unsigned char byteval;
+ SECItem *it;
+ char hexstr[5];
+ unsigned int i;
+ if (output->pBuf.len > 0) {
+ it = &output->pBuf;
+ } else {
+ it = &output->buf;
+ }
+ switch (output->mode) {
+ case bltestBase64Encoded:
+ rv = btoa_file(it, file);
+ break;
+ case bltestBinary:
+ nb = PR_Write(file, it->data, it->len);
+ rv = (nb == (PRInt32)it->len) ? SECSuccess : SECFailure;
+ break;
+ case bltestHexSpaceDelim:
+ hexstr[0] = '0';
+ hexstr[1] = 'x';
+ hexstr[4] = ' ';
+ for (i = 0; i < it->len; i++) {
+ byteval = it->data[i];
+ rv = char2_from_hex(byteval, hexstr + 2);
+ nb = PR_Write(file, hexstr, 5);
+ if (rv)
+ break;
+ }
+ PR_Write(file, "\n", 1);
+ break;
+ case bltestHexStream:
+ for (i = 0; i < it->len; i++) {
+ byteval = it->data[i];
+ rv = char2_from_hex(byteval, hexstr);
+ if (rv)
+ break;
+ nb = PR_Write(file, hexstr, 2);
+ }
+ PR_Write(file, "\n", 1);
+ break;
+ }
+ return rv;
+}
+
+SECStatus
+bltestCopyIO(PLArenaPool *arena, bltestIO *dest, bltestIO *src)
+{
+ if (SECITEM_CopyItem(arena, &dest->buf, &src->buf) != SECSuccess) {
+ return SECFailure;
+ }
+ if (src->pBuf.len > 0) {
+ dest->pBuf.len = src->pBuf.len;
+ dest->pBuf.data = dest->buf.data + (src->pBuf.data - src->buf.data);
+ }
+ dest->mode = src->mode;
+ dest->file = src->file;
+
+ return SECSuccess;
+}
+
+void
+misalignBuffer(PLArenaPool *arena, bltestIO *io, int off)
+{
+ ptrdiff_t offset = (ptrdiff_t)io->buf.data % WORDSIZE;
+ int length = io->buf.len;
+ if (offset != off) {
+ SECITEM_ReallocItemV2(arena, &io->buf, length + 2 * WORDSIZE);
+ /* offset may have changed? */
+ offset = (ptrdiff_t)io->buf.data % WORDSIZE;
+ if (offset != off) {
+ memmove(io->buf.data + off, io->buf.data, length);
+ io->pBuf.data = io->buf.data + off;
+ io->pBuf.len = length;
+ } else {
+ io->pBuf.data = io->buf.data;
+ io->pBuf.len = length;
+ }
+ } else {
+ io->pBuf.data = io->buf.data;
+ io->pBuf.len = length;
+ }
+}
+
+SECStatus
+des_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
+ unsigned int maxOutputLen, const unsigned char *input,
+ unsigned int inputLen)
+{
+ return DES_Encrypt((DESContext *)cx, output, outputLen, maxOutputLen,
+ input, inputLen);
+}
+
+SECStatus
+des_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
+ unsigned int maxOutputLen, const unsigned char *input,
+ unsigned int inputLen)
+{
+ return DES_Decrypt((DESContext *)cx, output, outputLen, maxOutputLen,
+ input, inputLen);
+}
+
+SECStatus
+rc2_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
+ unsigned int maxOutputLen, const unsigned char *input,
+ unsigned int inputLen)
+{
+ return RC2_Encrypt((RC2Context *)cx, output, outputLen, maxOutputLen,
+ input, inputLen);
+}
+
+SECStatus
+rc2_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
+ unsigned int maxOutputLen, const unsigned char *input,
+ unsigned int inputLen)
+{
+ return RC2_Decrypt((RC2Context *)cx, output, outputLen, maxOutputLen,
+ input, inputLen);
+}
+
+SECStatus
+rc4_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
+ unsigned int maxOutputLen, const unsigned char *input,
+ unsigned int inputLen)
+{
+ return RC4_Encrypt((RC4Context *)cx, output, outputLen, maxOutputLen,
+ input, inputLen);
+}
+
+SECStatus
+rc4_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
+ unsigned int maxOutputLen, const unsigned char *input,
+ unsigned int inputLen)
+{
+ return RC4_Decrypt((RC4Context *)cx, output, outputLen, maxOutputLen,
+ input, inputLen);
+}
+
+SECStatus
+aes_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
+ unsigned int maxOutputLen, const unsigned char *input,
+ unsigned int inputLen)
+{
+ return AES_Encrypt((AESContext *)cx, output, outputLen, maxOutputLen,
+ input, inputLen);
+}
+
+SECStatus
+aes_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
+ unsigned int maxOutputLen, const unsigned char *input,
+ unsigned int inputLen)
+{
+ return AES_Decrypt((AESContext *)cx, output, outputLen, maxOutputLen,
+ input, inputLen);
+}
+
+SECStatus
+chacha20_poly1305_Encrypt(void *cx, unsigned char *output,
+ unsigned int *outputLen, unsigned int maxOutputLen,
+ const unsigned char *input, unsigned int inputLen,
+ const unsigned char *nonce, unsigned int nonceLen,
+ const unsigned char *ad, unsigned int adLen)
+{
+ return ChaCha20Poly1305_Seal((ChaCha20Poly1305Context *)cx, output,
+ outputLen, maxOutputLen, input, inputLen,
+ nonce, nonceLen, ad, adLen);
+}
+
+SECStatus
+chacha20_poly1305_Decrypt(void *cx, unsigned char *output,
+ unsigned int *outputLen, unsigned int maxOutputLen,
+ const unsigned char *input, unsigned int inputLen,
+ const unsigned char *nonce, unsigned int nonceLen,
+ const unsigned char *ad, unsigned int adLen)
+{
+ return ChaCha20Poly1305_Open((ChaCha20Poly1305Context *)cx, output,
+ outputLen, maxOutputLen, input, inputLen,
+ nonce, nonceLen, ad, adLen);
+}
+
+SECStatus
+camellia_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
+ unsigned int maxOutputLen, const unsigned char *input,
+ unsigned int inputLen)
+{
+ return Camellia_Encrypt((CamelliaContext *)cx, output, outputLen,
+ maxOutputLen,
+ input, inputLen);
+}
+
+SECStatus
+camellia_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
+ unsigned int maxOutputLen, const unsigned char *input,
+ unsigned int inputLen)
+{
+ return Camellia_Decrypt((CamelliaContext *)cx, output, outputLen,
+ maxOutputLen,
+ input, inputLen);
+}
+
+SECStatus
+seed_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
+ unsigned int maxOutputLen, const unsigned char *input,
+ unsigned int inputLen)
+{
+ return SEED_Encrypt((SEEDContext *)cx, output, outputLen, maxOutputLen,
+ input, inputLen);
+}
+
+SECStatus
+seed_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
+ unsigned int maxOutputLen, const unsigned char *input,
+ unsigned int inputLen)
+{
+ return SEED_Decrypt((SEEDContext *)cx, output, outputLen, maxOutputLen,
+ input, inputLen);
+}
+
+SECStatus
+rsa_PublicKeyOp(void *cx, SECItem *output, const SECItem *input)
+{
+ bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
+ RSAPublicKey *pubKey = (RSAPublicKey *)params->pubKey;
+ SECStatus rv = RSA_PublicKeyOp(pubKey, output->data, input->data);
+ if (rv == SECSuccess) {
+ output->len = pubKey->modulus.data[0] ? pubKey->modulus.len : pubKey->modulus.len - 1;
+ }
+ return rv;
+}
+
+SECStatus
+rsa_PrivateKeyOp(void *cx, SECItem *output, const SECItem *input)
+{
+ bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
+ RSAPrivateKey *privKey = (RSAPrivateKey *)params->privKey;
+ SECStatus rv = RSA_PrivateKeyOp(privKey, output->data, input->data);
+ if (rv == SECSuccess) {
+ output->len = privKey->modulus.data[0] ? privKey->modulus.len : privKey->modulus.len - 1;
+ }
+ return rv;
+}
+
+SECStatus
+rsa_signDigestPSS(void *cx, SECItem *output, const SECItem *input)
+{
+ bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
+ bltestRSAParams *rsaParams = ¶ms->cipherParams.rsa;
+ return RSA_SignPSS((RSAPrivateKey *)params->privKey,
+ rsaParams->hashAlg,
+ rsaParams->maskHashAlg,
+ rsaParams->seed.buf.data,
+ rsaParams->seed.buf.len,
+ output->data, &output->len, output->len,
+ input->data, input->len);
+}
+
+SECStatus
+rsa_verifyDigestPSS(void *cx, SECItem *output, const SECItem *input)
+{
+ bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
+ bltestRSAParams *rsaParams = ¶ms->cipherParams.rsa;
+ return RSA_CheckSignPSS((RSAPublicKey *)params->pubKey,
+ rsaParams->hashAlg,
+ rsaParams->maskHashAlg,
+ rsaParams->seed.buf.len,
+ output->data, output->len,
+ input->data, input->len);
+}
+
+SECStatus
+rsa_encryptOAEP(void *cx, SECItem *output, const SECItem *input)
+{
+ bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
+ bltestRSAParams *rsaParams = ¶ms->cipherParams.rsa;
+ return RSA_EncryptOAEP((RSAPublicKey *)params->pubKey,
+ rsaParams->hashAlg,
+ rsaParams->maskHashAlg,
+ NULL, 0,
+ rsaParams->seed.buf.data,
+ rsaParams->seed.buf.len,
+ output->data, &output->len, output->len,
+ input->data, input->len);
+}
+
+SECStatus
+rsa_decryptOAEP(void *cx, SECItem *output, const SECItem *input)
+{
+ bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
+ bltestRSAParams *rsaParams = ¶ms->cipherParams.rsa;
+ return RSA_DecryptOAEP((RSAPrivateKey *)params->privKey,
+ rsaParams->hashAlg,
+ rsaParams->maskHashAlg,
+ NULL, 0,
+ output->data, &output->len, output->len,
+ input->data, input->len);
+}
+
+SECStatus
+dsa_signDigest(void *cx, SECItem *output, const SECItem *input)
+{
+ bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
+ if (params->cipherParams.dsa.sigseed.buf.len > 0) {
+ return DSA_SignDigestWithSeed((DSAPrivateKey *)params->privKey,
+ output, input,
+ params->cipherParams.dsa.sigseed.buf.data);
+ }
+ return DSA_SignDigest((DSAPrivateKey *)params->privKey, output, input);
+}
+
+SECStatus
+dsa_verifyDigest(void *cx, SECItem *output, const SECItem *input)
+{
+ bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
+ return DSA_VerifyDigest((DSAPublicKey *)params->pubKey, output, input);
+}
+
+#ifndef NSS_DISABLE_ECC
+SECStatus
+ecdsa_signDigest(void *cx, SECItem *output, const SECItem *input)
+{
+ bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
+ if (params->cipherParams.ecdsa.sigseed.buf.len > 0) {
+ return ECDSA_SignDigestWithSeed(
+ (ECPrivateKey *)params->privKey,
+ output, input,
+ params->cipherParams.ecdsa.sigseed.buf.data,
+ params->cipherParams.ecdsa.sigseed.buf.len);
+ }
+ return ECDSA_SignDigest((ECPrivateKey *)params->privKey, output, input);
+}
+
+SECStatus
+ecdsa_verifyDigest(void *cx, SECItem *output, const SECItem *input)
+{
+ bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
+ return ECDSA_VerifyDigest((ECPublicKey *)params->pubKey, output, input);
+}
+#endif
+
+SECStatus
+bltest_des_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
+{
+ PRIntervalTime time1, time2;
+ bltestSymmKeyParams *desp = &cipherInfo->params.sk;
+ int minorMode;
+ int i;
+ switch (cipherInfo->mode) {
+ case bltestDES_ECB:
+ minorMode = NSS_DES;
+ break;
+ case bltestDES_CBC:
+ minorMode = NSS_DES_CBC;
+ break;
+ case bltestDES_EDE_ECB:
+ minorMode = NSS_DES_EDE3;
+ break;
+ case bltestDES_EDE_CBC:
+ minorMode = NSS_DES_EDE3_CBC;
+ break;
+ default:
+ return SECFailure;
+ }
+ cipherInfo->cx = (void *)DES_CreateContext(desp->key.buf.data,
+ desp->iv.buf.data,
+ minorMode, encrypt);
+ if (cipherInfo->cxreps > 0) {
+ DESContext **dummycx;
+ dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(DESContext *));
+ TIMESTART();
+ for (i = 0; i < cipherInfo->cxreps; i++) {
+ dummycx[i] = (void *)DES_CreateContext(desp->key.buf.data,
+ desp->iv.buf.data,
+ minorMode, encrypt);
+ }
+ TIMEFINISH(cipherInfo->cxtime, 1.0);
+ for (i = 0; i < cipherInfo->cxreps; i++) {
+ DES_DestroyContext(dummycx[i], PR_TRUE);
+ }
+ PORT_Free(dummycx);
+ }
+ if (encrypt)
+ cipherInfo->cipher.symmkeyCipher = des_Encrypt;
+ else
+ cipherInfo->cipher.symmkeyCipher = des_Decrypt;
+ return SECSuccess;
+}
+
+SECStatus
+bltest_rc2_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
+{
+ PRIntervalTime time1, time2;
+ bltestSymmKeyParams *rc2p = &cipherInfo->params.sk;
+ int minorMode;
+ int i;
+ switch (cipherInfo->mode) {
+ case bltestRC2_ECB:
+ minorMode = NSS_RC2;
+ break;
+ case bltestRC2_CBC:
+ minorMode = NSS_RC2_CBC;
+ break;
+ default:
+ return SECFailure;
+ }
+ cipherInfo->cx = (void *)RC2_CreateContext(rc2p->key.buf.data,
+ rc2p->key.buf.len,
+ rc2p->iv.buf.data,
+ minorMode,
+ rc2p->key.buf.len);
+ if (cipherInfo->cxreps > 0) {
+ RC2Context **dummycx;
+ dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(RC2Context *));
+ TIMESTART();
+ for (i = 0; i < cipherInfo->cxreps; i++) {
+ dummycx[i] = (void *)RC2_CreateContext(rc2p->key.buf.data,
+ rc2p->key.buf.len,
+ rc2p->iv.buf.data,
+ minorMode,
+ rc2p->key.buf.len);
+ }
+ TIMEFINISH(cipherInfo->cxtime, 1.0);
+ for (i = 0; i < cipherInfo->cxreps; i++) {
+ RC2_DestroyContext(dummycx[i], PR_TRUE);
+ }
+ PORT_Free(dummycx);
+ }
+ if (encrypt)
+ cipherInfo->cipher.symmkeyCipher = rc2_Encrypt;
+ else
+ cipherInfo->cipher.symmkeyCipher = rc2_Decrypt;
+ return SECSuccess;
+}
+
+SECStatus
+bltest_rc4_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
+{
+ PRIntervalTime time1, time2;
+ int i;
+ bltestSymmKeyParams *rc4p = &cipherInfo->params.sk;
+ cipherInfo->cx = (void *)RC4_CreateContext(rc4p->key.buf.data,
+ rc4p->key.buf.len);
+ if (cipherInfo->cxreps > 0) {
+ RC4Context **dummycx;
+ dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(RC4Context *));
+ TIMESTART();
+ for (i = 0; i < cipherInfo->cxreps; i++) {
+ dummycx[i] = (void *)RC4_CreateContext(rc4p->key.buf.data,
+ rc4p->key.buf.len);
+ }
+ TIMEFINISH(cipherInfo->cxtime, 1.0);
+ for (i = 0; i < cipherInfo->cxreps; i++) {
+ RC4_DestroyContext(dummycx[i], PR_TRUE);
+ }
+ PORT_Free(dummycx);
+ }
+ if (encrypt)
+ cipherInfo->cipher.symmkeyCipher = rc4_Encrypt;
+ else
+ cipherInfo->cipher.symmkeyCipher = rc4_Decrypt;
+ return SECSuccess;
+}
+
+SECStatus
+bltest_rc5_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
+{
+#ifdef NSS_SOFTOKEN_DOES_RC5
+ PRIntervalTime time1, time2;
+ bltestRC5Params *rc5p = &cipherInfo->params.rc5;
+ int minorMode;
+ switch (cipherInfo->mode) {
+ case bltestRC5_ECB:
+ minorMode = NSS_RC5;
+ break;
+ case bltestRC5_CBC:
+ minorMode = NSS_RC5_CBC;
+ break;
+ default:
+ return SECFailure;
+ }
+ TIMESTART();
+ cipherInfo->cx = (void *)RC5_CreateContext(&rc5p->key.buf,
+ rc5p->rounds, rc5p->wordsize,
+ rc5p->iv.buf.data, minorMode);
+ TIMEFINISH(cipherInfo->cxtime, 1.0);
+ if (encrypt)
+ cipherInfo->cipher.symmkeyCipher = RC5_Encrypt;
+ else
+ cipherInfo->cipher.symmkeyCipher = RC5_Decrypt;
+ return SECSuccess;
+#else
+ return SECFailure;
+#endif
+}
+
+SECStatus
+bltest_aes_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
+{
+ bltestSymmKeyParams *aesp = &cipherInfo->params.sk;
+ bltestAuthSymmKeyParams *gcmp = &cipherInfo->params.ask;
+ int minorMode;
+ int i;
+ int keylen = aesp->key.buf.len;
+ unsigned int blocklen = AES_BLOCK_SIZE;
+ PRIntervalTime time1, time2;
+ unsigned char *params;
+ int len;
+ CK_AES_CTR_PARAMS ctrParams;
+ CK_GCM_PARAMS gcmParams;
+
+ params = aesp->iv.buf.data;
+ switch (cipherInfo->mode) {
+ case bltestAES_ECB:
+ minorMode = NSS_AES;
+ break;
+ case bltestAES_CBC:
+ minorMode = NSS_AES_CBC;
+ break;
+ case bltestAES_CTS:
+ minorMode = NSS_AES_CTS;
+ break;
+ case bltestAES_CTR:
+ minorMode = NSS_AES_CTR;
+ ctrParams.ulCounterBits = 32;
+ len = PR_MIN(aesp->iv.buf.len, blocklen);
+ PORT_Memset(ctrParams.cb, 0, blocklen);
+ PORT_Memcpy(ctrParams.cb, aesp->iv.buf.data, len);
+ params = (unsigned char *)&ctrParams;
+ break;
+ case bltestAES_GCM:
+ minorMode = NSS_AES_GCM;
+ gcmParams.pIv = gcmp->sk.iv.buf.data;
+ gcmParams.ulIvLen = gcmp->sk.iv.buf.len;
+ gcmParams.pAAD = gcmp->aad.buf.data;
+ gcmParams.ulAADLen = gcmp->aad.buf.len;
+ gcmParams.ulTagBits = blocklen * 8;
+ params = (unsigned char *)&gcmParams;
+ break;
+ default:
+ return SECFailure;
+ }
+ cipherInfo->cx = (void *)AES_CreateContext(aesp->key.buf.data,
+ params,
+ minorMode, encrypt,
+ keylen, blocklen);
+ if (cipherInfo->cxreps > 0) {
+ AESContext **dummycx;
+ dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(AESContext *));
+ TIMESTART();
+ for (i = 0; i < cipherInfo->cxreps; i++) {
+ dummycx[i] = (void *)AES_CreateContext(aesp->key.buf.data,
+ params,
+ minorMode, encrypt,
+ keylen, blocklen);
+ }
+ TIMEFINISH(cipherInfo->cxtime, 1.0);
+ for (i = 0; i < cipherInfo->cxreps; i++) {
+ AES_DestroyContext(dummycx[i], PR_TRUE);
+ }
+ PORT_Free(dummycx);
+ }
+ if (encrypt)
+ cipherInfo->cipher.symmkeyCipher = aes_Encrypt;
+ else
+ cipherInfo->cipher.symmkeyCipher = aes_Decrypt;
+ return SECSuccess;
+}
+
+SECStatus
+bltest_camellia_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
+{
+ bltestSymmKeyParams *camelliap = &cipherInfo->params.sk;
+ int minorMode;
+ int i;
+ int keylen = camelliap->key.buf.len;
+ PRIntervalTime time1, time2;
+
+ switch (cipherInfo->mode) {
+ case bltestCAMELLIA_ECB:
+ minorMode = NSS_CAMELLIA;
+ break;
+ case bltestCAMELLIA_CBC:
+ minorMode = NSS_CAMELLIA_CBC;
+ break;
+ default:
+ return SECFailure;
+ }
+ cipherInfo->cx = (void *)Camellia_CreateContext(camelliap->key.buf.data,
+ camelliap->iv.buf.data,
+ minorMode, encrypt,
+ keylen);
+ if (cipherInfo->cxreps > 0) {
+ CamelliaContext **dummycx;
+ dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(CamelliaContext *));
+ TIMESTART();
+ for (i = 0; i < cipherInfo->cxreps; i++) {
+ dummycx[i] = (void *)Camellia_CreateContext(camelliap->key.buf.data,
+ camelliap->iv.buf.data,
+ minorMode, encrypt,
+ keylen);
+ }
+ TIMEFINISH(cipherInfo->cxtime, 1.0);
+ for (i = 0; i < cipherInfo->cxreps; i++) {
+ Camellia_DestroyContext(dummycx[i], PR_TRUE);
+ }
+ PORT_Free(dummycx);
+ }
+ if (encrypt)
+ cipherInfo->cipher.symmkeyCipher = camellia_Encrypt;
+ else
+ cipherInfo->cipher.symmkeyCipher = camellia_Decrypt;
+ return SECSuccess;
+}
+
+SECStatus
+bltest_seed_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
+{
+ PRIntervalTime time1, time2;
+ bltestSymmKeyParams *seedp = &cipherInfo->params.sk;
+ int minorMode;
+ int i;
+
+ switch (cipherInfo->mode) {
+ case bltestSEED_ECB:
+ minorMode = NSS_SEED;
+ break;
+ case bltestSEED_CBC:
+ minorMode = NSS_SEED_CBC;
+ break;
+ default:
+ return SECFailure;
+ }
+ cipherInfo->cx = (void *)SEED_CreateContext(seedp->key.buf.data,
+ seedp->iv.buf.data,
+ minorMode, encrypt);
+ if (cipherInfo->cxreps > 0) {
+ SEEDContext **dummycx;
+ dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(SEEDContext *));
+ TIMESTART();
+ for (i = 0; i < cipherInfo->cxreps; i++) {
+ dummycx[i] = (void *)SEED_CreateContext(seedp->key.buf.data,
+ seedp->iv.buf.data,
+ minorMode, encrypt);
+ }
+ TIMEFINISH(cipherInfo->cxtime, 1.0);
+ for (i = 0; i < cipherInfo->cxreps; i++) {
+ SEED_DestroyContext(dummycx[i], PR_TRUE);
+ }
+ PORT_Free(dummycx);
+ }
+ if (encrypt)
+ cipherInfo->cipher.symmkeyCipher = seed_Encrypt;
+ else
+ cipherInfo->cipher.symmkeyCipher = seed_Decrypt;
+
+ return SECSuccess;
+}
+
+SECStatus
+bltest_chacha20_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
+{
+ const unsigned int tagLen = 16;
+ const bltestSymmKeyParams *sk = &cipherInfo->params.sk;
+ cipherInfo->cx = ChaCha20Poly1305_CreateContext(sk->key.buf.data,
+ sk->key.buf.len, tagLen);
+
+ if (encrypt)
+ cipherInfo->cipher.aeadCipher = chacha20_poly1305_Encrypt;
+ else
+ cipherInfo->cipher.aeadCipher = chacha20_poly1305_Decrypt;
+ return SECSuccess;
+}
+
+SECStatus
+bltest_rsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
+{
+ int i;
+ RSAPrivateKey **dummyKey;
+ RSAPrivateKey *privKey;
+ RSAPublicKey *pubKey;
+ PRIntervalTime time1, time2;
+
+ bltestAsymKeyParams *asymk = &cipherInfo->params.asymk;
+ bltestRSAParams *rsap = &asymk->cipherParams.rsa;
+
+ /* RSA key gen was done during parameter setup */
+ cipherInfo->cx = asymk;
+ privKey = (RSAPrivateKey *)asymk->privKey;
+
+ /* For performance testing */
+ if (cipherInfo->cxreps > 0) {
+ /* Create space for n private key objects */
+ dummyKey = (RSAPrivateKey **)PORT_Alloc(cipherInfo->cxreps *
+ sizeof(RSAPrivateKey *));
+ /* Time n keygens, storing in the array */
+ TIMESTART();
+ for (i = 0; i < cipherInfo->cxreps; i++)
+ dummyKey[i] = RSA_NewKey(rsap->keysizeInBits,
+ &privKey->publicExponent);
+ TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps);
+ /* Free the n key objects */
+ for (i = 0; i < cipherInfo->cxreps; i++)
+ PORT_FreeArena(dummyKey[i]->arena, PR_TRUE);
+ PORT_Free(dummyKey);
+ }
+
+ if ((encrypt && !is_sigCipher(cipherInfo->mode)) ||
+ (!encrypt && is_sigCipher(cipherInfo->mode))) {
+ /* Have to convert private key to public key. Memory
+ * is freed with private key's arena */
+ pubKey = (RSAPublicKey *)PORT_ArenaAlloc(privKey->arena,
+ sizeof(RSAPublicKey));
+ pubKey->modulus.len = privKey->modulus.len;
+ pubKey->modulus.data = privKey->modulus.data;
+ pubKey->publicExponent.len = privKey->publicExponent.len;
+ pubKey->publicExponent.data = privKey->publicExponent.data;
+ asymk->pubKey = (void *)pubKey;
+ }
+ switch (cipherInfo->mode) {
+ case bltestRSA:
+ cipherInfo->cipher.pubkeyCipher = encrypt ? rsa_PublicKeyOp
+ : rsa_PrivateKeyOp;
+ break;
+ case bltestRSA_PSS:
+ cipherInfo->cipher.pubkeyCipher = encrypt ? rsa_signDigestPSS
+ : rsa_verifyDigestPSS;
+ break;
+ case bltestRSA_OAEP:
+ cipherInfo->cipher.pubkeyCipher = encrypt ? rsa_encryptOAEP
+ : rsa_decryptOAEP;
+ break;
+ default:
+ break;
+ }
+ return SECSuccess;
+}
+
+SECStatus
+blapi_pqg_param_gen(unsigned int keysize, PQGParams **pqg, PQGVerify **vfy)
+{
+ if (keysize < 1024) {
+ int j = PQG_PBITS_TO_INDEX(keysize);
+ return PQG_ParamGen(j, pqg, vfy);
+ }
+ return PQG_ParamGenV2(keysize, 0, 0, pqg, vfy);
+}
+
+SECStatus
+bltest_pqg_init(bltestDSAParams *dsap)
+{
+ SECStatus rv, res;
+ PQGVerify *vfy = NULL;
+ rv = blapi_pqg_param_gen(dsap->keysize, &dsap->pqg, &vfy);
+ CHECKERROR(rv, __LINE__);
+ rv = PQG_VerifyParams(dsap->pqg, vfy, &res);
+ CHECKERROR(res, __LINE__);
+ CHECKERROR(rv, __LINE__);
+ return rv;
+}
+
+SECStatus
+bltest_dsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
+{
+ int i;
+ DSAPrivateKey **dummyKey;
+ PQGParams *dummypqg;
+ PRIntervalTime time1, time2;
+ bltestAsymKeyParams *asymk = &cipherInfo->params.asymk;
+ bltestDSAParams *dsap = &asymk->cipherParams.dsa;
+ PQGVerify *ignore = NULL;
+ cipherInfo->cx = asymk;
+ /* For performance testing */
+ if (cipherInfo->cxreps > 0) {
+ /* Create space for n private key objects */
+ dummyKey = (DSAPrivateKey **)PORT_ZAlloc(cipherInfo->cxreps *
+ sizeof(DSAPrivateKey *));
+ /* Time n keygens, storing in the array */
+ TIMESTART();
+ for (i = 0; i < cipherInfo->cxreps; i++) {
+ dummypqg = NULL;
+ blapi_pqg_param_gen(dsap->keysize, &dummypqg, &ignore);
+ DSA_NewKey(dummypqg, &dummyKey[i]);
+ }
+ TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps);
+ /* Free the n key objects */
+ for (i = 0; i < cipherInfo->cxreps; i++)
+ PORT_FreeArena(dummyKey[i]->params.arena, PR_TRUE);
+ PORT_Free(dummyKey);
+ }
+ if (!dsap->pqg && dsap->pqgdata.buf.len > 0) {
+ dsap->pqg = pqg_from_filedata(cipherInfo->arena, &dsap->pqgdata.buf);
+ }
+ if (!asymk->privKey && asymk->key.buf.len > 0) {
+ asymk->privKey = dsakey_from_filedata(cipherInfo->arena, &asymk->key.buf);
+ }
+ if (encrypt) {
+ cipherInfo->cipher.pubkeyCipher = dsa_signDigest;
+ } else {
+ /* Have to convert private key to public key. Memory
+ * is freed with private key's arena */
+ DSAPublicKey *pubkey;
+ DSAPrivateKey *key = (DSAPrivateKey *)asymk->privKey;
+ pubkey = (DSAPublicKey *)PORT_ArenaZAlloc(key->params.arena,
+ sizeof(DSAPublicKey));
+ pubkey->params.prime.len = key->params.prime.len;
+ pubkey->params.prime.data = key->params.prime.data;
+ pubkey->params.subPrime.len = key->params.subPrime.len;
+ pubkey->params.subPrime.data = key->params.subPrime.data;
+ pubkey->params.base.len = key->params.base.len;
+ pubkey->params.base.data = key->params.base.data;
+ pubkey->publicValue.len = key->publicValue.len;
+ pubkey->publicValue.data = key->publicValue.data;
+ asymk->pubKey = pubkey;
+ cipherInfo->cipher.pubkeyCipher = dsa_verifyDigest;
+ }
+ return SECSuccess;
+}
+
+#ifndef NSS_DISABLE_ECC
+SECStatus
+bltest_ecdsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
+{
+ int i;
+ ECPrivateKey **dummyKey;
+ PRIntervalTime time1, time2;
+ bltestAsymKeyParams *asymk = &cipherInfo->params.asymk;
+ cipherInfo->cx = asymk;
+ /* For performance testing */
+ if (cipherInfo->cxreps > 0) {
+ /* Create space for n private key objects */
+ dummyKey = (ECPrivateKey **)PORT_ZAlloc(cipherInfo->cxreps *
+ sizeof(ECPrivateKey *));
+ /* Time n keygens, storing in the array */
+ TIMESTART();
+ for (i = 0; i < cipherInfo->cxreps; i++) {
+ EC_NewKey(&((ECPrivateKey *)asymk->privKey)->ecParams, &dummyKey[i]);
+ }
+ TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps);
+ /* Free the n key objects */
+ for (i = 0; i < cipherInfo->cxreps; i++)
+ PORT_FreeArena(dummyKey[i]->ecParams.arena, PR_TRUE);
+ PORT_Free(dummyKey);
+ }
+ if (!asymk->privKey && asymk->key.buf.len > 0) {
+ asymk->privKey = eckey_from_filedata(cipherInfo->arena, &asymk->key.buf);
+ }
+ if (encrypt) {
+ cipherInfo->cipher.pubkeyCipher = ecdsa_signDigest;
+ } else {
+ /* Have to convert private key to public key. Memory
+ * is freed with private key's arena */
+ ECPublicKey *pubkey;
+ ECPrivateKey *key = (ECPrivateKey *)asymk->privKey;
+ pubkey = (ECPublicKey *)PORT_ArenaZAlloc(key->ecParams.arena,
+ sizeof(ECPublicKey));
+ pubkey->ecParams.type = key->ecParams.type;
+ pubkey->ecParams.fieldID.size = key->ecParams.fieldID.size;
+ pubkey->ecParams.fieldID.type = key->ecParams.fieldID.type;
+ pubkey->ecParams.fieldID.u.prime.len = key->ecParams.fieldID.u.prime.len;
+ pubkey->ecParams.fieldID.u.prime.data = key->ecParams.fieldID.u.prime.data;
+ pubkey->ecParams.fieldID.k1 = key->ecParams.fieldID.k1;
+ pubkey->ecParams.fieldID.k2 = key->ecParams.fieldID.k2;
+ pubkey->ecParams.fieldID.k3 = key->ecParams.fieldID.k3;
+ pubkey->ecParams.curve.a.len = key->ecParams.curve.a.len;
+ pubkey->ecParams.curve.a.data = key->ecParams.curve.a.data;
+ pubkey->ecParams.curve.b.len = key->ecParams.curve.b.len;
+ pubkey->ecParams.curve.b.data = key->ecParams.curve.b.data;
+ pubkey->ecParams.curve.seed.len = key->ecParams.curve.seed.len;
+ pubkey->ecParams.curve.seed.data = key->ecParams.curve.seed.data;
+ pubkey->ecParams.base.len = key->ecParams.base.len;
+ pubkey->ecParams.base.data = key->ecParams.base.data;
+ pubkey->ecParams.order.len = key->ecParams.order.len;
+ pubkey->ecParams.order.data = key->ecParams.order.data;
+ pubkey->ecParams.cofactor = key->ecParams.cofactor;
+ pubkey->ecParams.DEREncoding.len = key->ecParams.DEREncoding.len;
+ pubkey->ecParams.DEREncoding.data = key->ecParams.DEREncoding.data;
+ pubkey->ecParams.name = key->ecParams.name;
+ pubkey->publicValue.len = key->publicValue.len;
+ pubkey->publicValue.data = key->publicValue.data;
+ asymk->pubKey = pubkey;
+ cipherInfo->cipher.pubkeyCipher = ecdsa_verifyDigest;
+ }
+ return SECSuccess;
+}
+#endif
+
+/* XXX unfortunately, this is not defined in blapi.h */
+SECStatus
+md2_HashBuf(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
+{
+ unsigned int len;
+ MD2Context *cx = MD2_NewContext();
+ if (cx == NULL)
+ return SECFailure;
+ MD2_Begin(cx);
+ MD2_Update(cx, src, src_length);
+ MD2_End(cx, dest, &len, MD2_LENGTH);
+ MD2_DestroyContext(cx, PR_TRUE);
+ return SECSuccess;
+}
+
+SECStatus
+md2_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
+{
+ MD2Context *cx, *cx_cpy;
+ unsigned char *cxbytes;
+ unsigned int len;
+ unsigned int i, quarter;
+ SECStatus rv = SECSuccess;
+ cx = MD2_NewContext();
+ MD2_Begin(cx);
+ /* divide message by 4, restarting 3 times */
+ quarter = (src_length + 3) / 4;
+ for (i = 0; i < 4 && src_length > 0; i++) {
+ MD2_Update(cx, src + i * quarter, PR_MIN(quarter, src_length));
+ len = MD2_FlattenSize(cx);
+ cxbytes = PORT_Alloc(len);
+ MD2_Flatten(cx, cxbytes);
+ cx_cpy = MD2_Resurrect(cxbytes, NULL);
+ if (!cx_cpy) {
+ PR_fprintf(PR_STDERR, "%s: MD2_Resurrect failed!\n", progName);
+ goto finish;
+ }
+ rv = PORT_Memcmp(cx, cx_cpy, len);
+ if (rv) {
+ MD2_DestroyContext(cx_cpy, PR_TRUE);
+ PR_fprintf(PR_STDERR, "%s: MD2_restart failed!\n", progName);
+ goto finish;
+ }
+ MD2_DestroyContext(cx_cpy, PR_TRUE);
+ PORT_Free(cxbytes);
+ src_length -= quarter;
+ }
+ MD2_End(cx, dest, &len, MD2_LENGTH);
+finish:
+ MD2_DestroyContext(cx, PR_TRUE);
+ return rv;
+}
+
+SECStatus
+md5_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
+{
+ SECStatus rv = SECSuccess;
+ MD5Context *cx, *cx_cpy;
+ unsigned char *cxbytes;
+ unsigned int len;
+ unsigned int i, quarter;
+ cx = MD5_NewContext();
+ MD5_Begin(cx);
+ /* divide message by 4, restarting 3 times */
+ quarter = (src_length + 3) / 4;
+ for (i = 0; i < 4 && src_length > 0; i++) {
+ MD5_Update(cx, src + i * quarter, PR_MIN(quarter, src_length));
+ len = MD5_FlattenSize(cx);
+ cxbytes = PORT_Alloc(len);
+ MD5_Flatten(cx, cxbytes);
+ cx_cpy = MD5_Resurrect(cxbytes, NULL);
+ if (!cx_cpy) {
+ PR_fprintf(PR_STDERR, "%s: MD5_Resurrect failed!\n", progName);
+ rv = SECFailure;
+ goto finish;
+ }
+ rv = PORT_Memcmp(cx, cx_cpy, len);
+ if (rv) {
+ MD5_DestroyContext(cx_cpy, PR_TRUE);
+ PR_fprintf(PR_STDERR, "%s: MD5_restart failed!\n", progName);
+ goto finish;
+ }
+ MD5_DestroyContext(cx_cpy, PR_TRUE);
+ PORT_Free(cxbytes);
+ src_length -= quarter;
+ }
+ MD5_End(cx, dest, &len, MD5_LENGTH);
+finish:
+ MD5_DestroyContext(cx, PR_TRUE);
+ return rv;
+}
+
+SECStatus
+sha1_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
+{
+ SECStatus rv = SECSuccess;
+ SHA1Context *cx, *cx_cpy;
+ unsigned char *cxbytes;
+ unsigned int len;
+ unsigned int i, quarter;
+ cx = SHA1_NewContext();
+ SHA1_Begin(cx);
+ /* divide message by 4, restarting 3 times */
+ quarter = (src_length + 3) / 4;
+ for (i = 0; i < 4 && src_length > 0; i++) {
+ SHA1_Update(cx, src + i * quarter, PR_MIN(quarter, src_length));
+ len = SHA1_FlattenSize(cx);
+ cxbytes = PORT_Alloc(len);
+ SHA1_Flatten(cx, cxbytes);
+ cx_cpy = SHA1_Resurrect(cxbytes, NULL);
+ if (!cx_cpy) {
+ PR_fprintf(PR_STDERR, "%s: SHA1_Resurrect failed!\n", progName);
+ rv = SECFailure;
+ goto finish;
+ }
+ rv = PORT_Memcmp(cx, cx_cpy, len);
+ if (rv) {
+ SHA1_DestroyContext(cx_cpy, PR_TRUE);
+ PR_fprintf(PR_STDERR, "%s: SHA1_restart failed!\n", progName);
+ goto finish;
+ }
+ SHA1_DestroyContext(cx_cpy, PR_TRUE);
+ PORT_Free(cxbytes);
+ src_length -= quarter;
+ }
+ SHA1_End(cx, dest, &len, MD5_LENGTH);
+finish:
+ SHA1_DestroyContext(cx, PR_TRUE);
+ return rv;
+}
+
+SECStatus
+SHA224_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
+{
+ SECStatus rv = SECSuccess;
+ SHA224Context *cx, *cx_cpy;
+ unsigned char *cxbytes;
+ unsigned int len;
+ unsigned int i, quarter;
+ cx = SHA224_NewContext();
+ SHA224_Begin(cx);
+ /* divide message by 4, restarting 3 times */
+ quarter = (src_length + 3) / 4;
+ for (i = 0; i < 4 && src_length > 0; i++) {
+ SHA224_Update(cx, src + i * quarter, PR_MIN(quarter, src_length));
+ len = SHA224_FlattenSize(cx);
+ cxbytes = PORT_Alloc(len);
+ SHA224_Flatten(cx, cxbytes);
+ cx_cpy = SHA224_Resurrect(cxbytes, NULL);
+ if (!cx_cpy) {
+ PR_fprintf(PR_STDERR, "%s: SHA224_Resurrect failed!\n", progName);
+ rv = SECFailure;
+ goto finish;
+ }
+ rv = PORT_Memcmp(cx, cx_cpy, len);
+ if (rv) {
+ SHA224_DestroyContext(cx_cpy, PR_TRUE);
+ PR_fprintf(PR_STDERR, "%s: SHA224_restart failed!\n", progName);
+ goto finish;
+ }
+
+ SHA224_DestroyContext(cx_cpy, PR_TRUE);
+ PORT_Free(cxbytes);
+ src_length -= quarter;
+ }
+ SHA224_End(cx, dest, &len, MD5_LENGTH);
+finish:
+ SHA224_DestroyContext(cx, PR_TRUE);
+ return rv;
+}
+
+SECStatus
+SHA256_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
+{
+ SECStatus rv = SECSuccess;
+ SHA256Context *cx, *cx_cpy;
+ unsigned char *cxbytes;
+ unsigned int len;
+ unsigned int i, quarter;
+ cx = SHA256_NewContext();
+ SHA256_Begin(cx);
+ /* divide message by 4, restarting 3 times */
+ quarter = (src_length + 3) / 4;
+ for (i = 0; i < 4 && src_length > 0; i++) {
+ SHA256_Update(cx, src + i * quarter, PR_MIN(quarter, src_length));
+ len = SHA256_FlattenSize(cx);
+ cxbytes = PORT_Alloc(len);
+ SHA256_Flatten(cx, cxbytes);
+ cx_cpy = SHA256_Resurrect(cxbytes, NULL);
+ if (!cx_cpy) {
+ PR_fprintf(PR_STDERR, "%s: SHA256_Resurrect failed!\n", progName);
+ rv = SECFailure;
+ goto finish;
+ }
+ rv = PORT_Memcmp(cx, cx_cpy, len);
+ if (rv) {
+ SHA256_DestroyContext(cx_cpy, PR_TRUE);
+ PR_fprintf(PR_STDERR, "%s: SHA256_restart failed!\n", progName);
+ goto finish;
+ }
+ SHA256_DestroyContext(cx_cpy, PR_TRUE);
+ PORT_Free(cxbytes);
+ src_length -= quarter;
+ }
+ SHA256_End(cx, dest, &len, MD5_LENGTH);
+finish:
+ SHA256_DestroyContext(cx, PR_TRUE);
+ return rv;
+}
+
+SECStatus
+SHA384_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
+{
+ SECStatus rv = SECSuccess;
+ SHA384Context *cx, *cx_cpy;
+ unsigned char *cxbytes;
+ unsigned int len;
+ unsigned int i, quarter;
+ cx = SHA384_NewContext();
+ SHA384_Begin(cx);
+ /* divide message by 4, restarting 3 times */
+ quarter = (src_length + 3) / 4;
+ for (i = 0; i < 4 && src_length > 0; i++) {
+ SHA384_Update(cx, src + i * quarter, PR_MIN(quarter, src_length));
+ len = SHA384_FlattenSize(cx);
+ cxbytes = PORT_Alloc(len);
+ SHA384_Flatten(cx, cxbytes);
+ cx_cpy = SHA384_Resurrect(cxbytes, NULL);
+ if (!cx_cpy) {
+ PR_fprintf(PR_STDERR, "%s: SHA384_Resurrect failed!\n", progName);
+ rv = SECFailure;
+ goto finish;
+ }
+ rv = PORT_Memcmp(cx, cx_cpy, len);
+ if (rv) {
+ SHA384_DestroyContext(cx_cpy, PR_TRUE);
+ PR_fprintf(PR_STDERR, "%s: SHA384_restart failed!\n", progName);
+ goto finish;
+ }
+ SHA384_DestroyContext(cx_cpy, PR_TRUE);
+ PORT_Free(cxbytes);
+ src_length -= quarter;
+ }
+ SHA384_End(cx, dest, &len, MD5_LENGTH);
+finish:
+ SHA384_DestroyContext(cx, PR_TRUE);
+ return rv;
+}
+
+SECStatus
+SHA512_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
+{
+ SECStatus rv = SECSuccess;
+ SHA512Context *cx, *cx_cpy;
+ unsigned char *cxbytes;
+ unsigned int len;
+ unsigned int i, quarter;
+ cx = SHA512_NewContext();
+ SHA512_Begin(cx);
+ /* divide message by 4, restarting 3 times */
+ quarter = (src_length + 3) / 4;
+ for (i = 0; i < 4 && src_length > 0; i++) {
+ SHA512_Update(cx, src + i * quarter, PR_MIN(quarter, src_length));
+ len = SHA512_FlattenSize(cx);
+ cxbytes = PORT_Alloc(len);
+ SHA512_Flatten(cx, cxbytes);
+ cx_cpy = SHA512_Resurrect(cxbytes, NULL);
+ if (!cx_cpy) {
+ PR_fprintf(PR_STDERR, "%s: SHA512_Resurrect failed!\n", progName);
+ rv = SECFailure;
+ goto finish;
+ }
+ rv = PORT_Memcmp(cx, cx_cpy, len);
+ if (rv) {
+ SHA512_DestroyContext(cx_cpy, PR_TRUE);
+ PR_fprintf(PR_STDERR, "%s: SHA512_restart failed!\n", progName);
+ goto finish;
+ }
+ SHA512_DestroyContext(cx_cpy, PR_TRUE);
+ PORT_Free(cxbytes);
+ src_length -= quarter;
+ }
+ SHA512_End(cx, dest, &len, MD5_LENGTH);
+finish:
+ SHA512_DestroyContext(cx, PR_TRUE);
+ return rv;
+}
+
+SECStatus
+pubkeyInitKey(bltestCipherInfo *cipherInfo, PRFileDesc *file,
+#ifndef NSS_DISABLE_ECC
+ int keysize, int exponent, char *curveName)
+#else
+ int keysize, int exponent)
+#endif
+{
+ int i;
+ SECStatus rv = SECSuccess;
+ bltestAsymKeyParams *asymk = &cipherInfo->params.asymk;
+ bltestRSAParams *rsap;
+ RSAPrivateKey **rsaKey = NULL;
+ bltestDSAParams *dsap;
+ DSAPrivateKey **dsaKey = NULL;
+#ifndef NSS_DISABLE_ECC
+ SECItem *tmpECParamsDER;
+ ECParams *tmpECParams = NULL;
+ SECItem ecSerialize[3];
+ ECPrivateKey **ecKey = NULL;
+#endif
+ switch (cipherInfo->mode) {
+ case bltestRSA:
+ case bltestRSA_PSS:
+ case bltestRSA_OAEP:
+ rsap = &asymk->cipherParams.rsa;
+ rsaKey = (RSAPrivateKey **)&asymk->privKey;
+ if (keysize > 0) {
+ SECItem expitem = { 0, 0, 0 };
+ SECITEM_AllocItem(cipherInfo->arena, &expitem, sizeof(int));
+ for (i = 1; i <= sizeof(int); i++)
+ expitem.data[i - 1] = exponent >> (8 * (sizeof(int) - i));
+ *rsaKey = RSA_NewKey(keysize * 8, &expitem);
+ serialize_key(&(*rsaKey)->version, 9, file);
+ rsap->keysizeInBits = keysize * 8;
+ } else {
+ setupIO(cipherInfo->arena, &asymk->key, file, NULL, 0);
+ *rsaKey = rsakey_from_filedata(cipherInfo->arena, &asymk->key.buf);
+ rsap->keysizeInBits = (*rsaKey)->modulus.len * 8;
+ }
+ break;
+ case bltestDSA:
+ dsap = &asymk->cipherParams.dsa;
+ dsaKey = (DSAPrivateKey **)&asymk->privKey;
+ if (keysize > 0) {
+ dsap->keysize = keysize * 8;
+ if (!dsap->pqg)
+ bltest_pqg_init(dsap);
+ rv = DSA_NewKey(dsap->pqg, dsaKey);
+ CHECKERROR(rv, __LINE__);
+ serialize_key(&(*dsaKey)->params.prime, 5, file);
+ } else {
+ setupIO(cipherInfo->arena, &asymk->key, file, NULL, 0);
+ *dsaKey = dsakey_from_filedata(cipherInfo->arena, &asymk->key.buf);
+ dsap->keysize = (*dsaKey)->params.prime.len * 8;
+ }
+ break;
+#ifndef NSS_DISABLE_ECC
+ case bltestECDSA:
+ ecKey = (ECPrivateKey **)&asymk->privKey;
+ if (curveName != NULL) {
+ tmpECParamsDER = getECParams(curveName);
+ rv = SECOID_Init();
+ CHECKERROR(rv, __LINE__);
+ rv = EC_DecodeParams(tmpECParamsDER, &tmpECParams) == SECFailure;
+ CHECKERROR(rv, __LINE__);
+ rv = EC_NewKey(tmpECParams, ecKey);
+ CHECKERROR(rv, __LINE__);
+ ecSerialize[0].type = tmpECParamsDER->type;
+ ecSerialize[0].data = tmpECParamsDER->data;
+ ecSerialize[0].len = tmpECParamsDER->len;
+ ecSerialize[1].type = (*ecKey)->publicValue.type;
+ ecSerialize[1].data = (*ecKey)->publicValue.data;
+ ecSerialize[1].len = (*ecKey)->publicValue.len;
+ ecSerialize[2].type = (*ecKey)->privateValue.type;
+ ecSerialize[2].data = (*ecKey)->privateValue.data;
+ ecSerialize[2].len = (*ecKey)->privateValue.len;
+ serialize_key(&(ecSerialize[0]), 3, file);
+ SECITEM_FreeItem(tmpECParamsDER, PR_TRUE);
+ PORT_FreeArena(tmpECParams->arena, PR_TRUE);
+ rv = SECOID_Shutdown();
+ CHECKERROR(rv, __LINE__);
+ } else {
+ setupIO(cipherInfo->arena, &asymk->key, file, NULL, 0);
+ *ecKey = eckey_from_filedata(cipherInfo->arena, &asymk->key.buf);
+ }
+ break;
+#endif
+ default:
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+SECStatus
+cipherInit(bltestCipherInfo *cipherInfo, PRBool encrypt)
+{
+ PRBool restart;
+ int outlen;
+ switch (cipherInfo->mode) {
+ case bltestDES_ECB:
+ case bltestDES_CBC:
+ case bltestDES_EDE_ECB:
+ case bltestDES_EDE_CBC:
+ SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
+ cipherInfo->input.pBuf.len);
+ return bltest_des_init(cipherInfo, encrypt);
+ break;
+ case bltestRC2_ECB:
+ case bltestRC2_CBC:
+ SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
+ cipherInfo->input.pBuf.len);
+ return bltest_rc2_init(cipherInfo, encrypt);
+ break;
+ case bltestRC4:
+ SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
+ cipherInfo->input.pBuf.len);
+ return bltest_rc4_init(cipherInfo, encrypt);
+ break;
+#ifdef NSS_SOFTOKEN_DOES_RC5
+ case bltestRC5_ECB:
+ case bltestRC5_CBC:
+ SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
+ cipherInfo->input.pBuf.len);
+#endif
+ return bltest_rc5_init(cipherInfo, encrypt);
+ break;
+ case bltestAES_ECB:
+ case bltestAES_CBC:
+ case bltestAES_CTS:
+ case bltestAES_CTR:
+ case bltestAES_GCM:
+ outlen = cipherInfo->input.pBuf.len;
+ if (cipherInfo->mode == bltestAES_GCM && encrypt) {
+ outlen += 16;
+ }
+ SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, outlen);
+ return bltest_aes_init(cipherInfo, encrypt);
+ break;
+ case bltestCAMELLIA_ECB:
+ case bltestCAMELLIA_CBC:
+ SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
+ cipherInfo->input.pBuf.len);
+ return bltest_camellia_init(cipherInfo, encrypt);
+ break;
+ case bltestSEED_ECB:
+ case bltestSEED_CBC:
+ SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
+ cipherInfo->input.pBuf.len);
+ return bltest_seed_init(cipherInfo, encrypt);
+ break;
+ case bltestCHACHA20:
+ outlen = cipherInfo->input.pBuf.len + (encrypt ? 16 : 0);
+ SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, outlen);
+ return bltest_chacha20_init(cipherInfo, encrypt);
+ break;
+ case bltestRSA:
+ case bltestRSA_OAEP:
+ case bltestRSA_PSS:
+ if (encrypt || cipherInfo->mode != bltestRSA_PSS) {
+ /* Don't allocate a buffer for PSS in verify mode, as no actual
+ * output is produced. */
+ SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
+ RSA_MAX_MODULUS_BITS / 8);
+ }
+ return bltest_rsa_init(cipherInfo, encrypt);
+ break;
+ case bltestDSA:
+ if (encrypt) {
+ SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
+ DSA_MAX_SIGNATURE_LEN);
+ }
+ return bltest_dsa_init(cipherInfo, encrypt);
+ break;
+#ifndef NSS_DISABLE_ECC
+ case bltestECDSA:
+ if (encrypt) {
+ SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
+ 2 * MAX_ECKEY_LEN);
+ }
+ return bltest_ecdsa_init(cipherInfo, encrypt);
+ break;
+#endif
+ case bltestMD2:
+ restart = cipherInfo->params.hash.restart;
+ SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
+ MD2_LENGTH);
+ cipherInfo->cipher.hashCipher = (restart) ? md2_restart : md2_HashBuf;
+ return SECSuccess;
+ break;
+ case bltestMD5:
+ restart = cipherInfo->params.hash.restart;
+ SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
+ MD5_LENGTH);
+ cipherInfo->cipher.hashCipher = (restart) ? md5_restart : MD5_HashBuf;
+ return SECSuccess;
+ break;
+ case bltestSHA1:
+ restart = cipherInfo->params.hash.restart;
+ SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
+ SHA1_LENGTH);
+ cipherInfo->cipher.hashCipher = (restart) ? sha1_restart : SHA1_HashBuf;
+ return SECSuccess;
+ break;
+ case bltestSHA224:
+ restart = cipherInfo->params.hash.restart;
+ SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
+ SHA224_LENGTH);
+ cipherInfo->cipher.hashCipher = (restart) ? SHA224_restart
+ : SHA224_HashBuf;
+ return SECSuccess;
+ break;
+ case bltestSHA256:
+ restart = cipherInfo->params.hash.restart;
+ SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
+ SHA256_LENGTH);
+ cipherInfo->cipher.hashCipher = (restart) ? SHA256_restart
+ : SHA256_HashBuf;
+ return SECSuccess;
+ break;
+ case bltestSHA384:
+ restart = cipherInfo->params.hash.restart;
+ SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
+ SHA384_LENGTH);
+ cipherInfo->cipher.hashCipher = (restart) ? SHA384_restart
+ : SHA384_HashBuf;
+ return SECSuccess;
+ break;
+ case bltestSHA512:
+ restart = cipherInfo->params.hash.restart;
+ SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
+ SHA512_LENGTH);
+ cipherInfo->cipher.hashCipher = (restart) ? SHA512_restart
+ : SHA512_HashBuf;
+ return SECSuccess;
+ break;
+ default:
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+SECStatus
+cipherDoOp(bltestCipherInfo *cipherInfo)
+{
+ PRIntervalTime time1, time2;
+ SECStatus rv = SECSuccess;
+ int i;
+ unsigned int len;
+ unsigned int maxLen = cipherInfo->output.pBuf.len;
+ unsigned char *dummyOut;
+ dummyOut = PORT_Alloc(maxLen);
+ if (is_symmkeyCipher(cipherInfo->mode)) {
+ const unsigned char *input = cipherInfo->input.pBuf.data;
+ unsigned int inputLen = is_singleShotCipher(cipherInfo->mode) ? cipherInfo->input.pBuf.len
+ : PR_MIN(cipherInfo->input.pBuf.len, 16);
+ unsigned char *output = cipherInfo->output.pBuf.data;
+ unsigned int outputLen = maxLen;
+ unsigned int totalOutputLen = 0;
+ TIMESTART();
+ rv = (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx,
+ output, &len, outputLen,
+ input, inputLen);
+ CHECKERROR(rv, __LINE__);
+ totalOutputLen += len;
+ if (cipherInfo->input.pBuf.len > inputLen) {
+ input += inputLen;
+ inputLen = cipherInfo->input.pBuf.len - inputLen;
+ output += len;
+ outputLen -= len;
+ rv = (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx,
+ output, &len, outputLen,
+ input, inputLen);
+ CHECKERROR(rv, __LINE__);
+ totalOutputLen += len;
+ }
+ cipherInfo->output.pBuf.len = totalOutputLen;
+ TIMEFINISH(cipherInfo->optime, 1.0);
+ cipherInfo->repetitions = 0;
+ if (cipherInfo->repetitionsToPerfom != 0) {
+ TIMESTART();
+ for (i = 0; i < cipherInfo->repetitionsToPerfom; i++,
+ cipherInfo->repetitions++) {
+ (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx, dummyOut,
+ &len, maxLen,
+ cipherInfo->input.pBuf.data,
+ cipherInfo->input.pBuf.len);
+
+ CHECKERROR(rv, __LINE__);
+ }
+ } else {
+ int opsBetweenChecks = 0;
+ TIMEMARK(cipherInfo->seconds);
+ while (!(TIMETOFINISH())) {
+ int j = 0;
+ for (; j < opsBetweenChecks; j++) {
+ (*cipherInfo->cipher.symmkeyCipher)(
+ cipherInfo->cx, dummyOut, &len, maxLen,
+ cipherInfo->input.pBuf.data,
+ cipherInfo->input.pBuf.len);
+ }
+ cipherInfo->repetitions += j;
+ }
+ }
+ TIMEFINISH(cipherInfo->optime, 1.0);
+ } else if (is_aeadCipher(cipherInfo->mode)) {
+ const unsigned char *input = cipherInfo->input.pBuf.data;
+ unsigned int inputLen = cipherInfo->input.pBuf.len;
+ unsigned char *output = cipherInfo->output.pBuf.data;
+ unsigned int outputLen;
+ bltestSymmKeyParams *sk = &cipherInfo->params.sk;
+ bltestAuthSymmKeyParams *ask = &cipherInfo->params.ask;
+
+ TIMESTART();
+ rv = (*cipherInfo->cipher.aeadCipher)(
+ cipherInfo->cx,
+ output, &outputLen, maxLen,
+ input, inputLen,
+ sk->iv.buf.data, sk->iv.buf.len,
+ ask->aad.buf.data, ask->aad.buf.len);
+ CHECKERROR(rv, __LINE__);
+ cipherInfo->output.pBuf.len = outputLen;
+ TIMEFINISH(cipherInfo->optime, 1.0);
+
+ cipherInfo->repetitions = 0;
+ if (cipherInfo->repetitionsToPerfom != 0) {
+ TIMESTART();
+ for (i = 0; i < cipherInfo->repetitionsToPerfom; i++,
+ cipherInfo->repetitions++) {
+ rv = (*cipherInfo->cipher.aeadCipher)(
+ cipherInfo->cx,
+ output, &outputLen, maxLen,
+ input, inputLen,
+ sk->iv.buf.data, sk->iv.buf.len,
+ ask->aad.buf.data, ask->aad.buf.len);
+ CHECKERROR(rv, __LINE__);
+ }
+ } else {
+ int opsBetweenChecks = 0;
+ TIMEMARK(cipherInfo->seconds);
+ while (!(TIMETOFINISH())) {
+ int j = 0;
+ for (; j < opsBetweenChecks; j++) {
+ (*cipherInfo->cipher.aeadCipher)(
+ cipherInfo->cx,
+ output, &outputLen, maxLen,
+ input, inputLen,
+ sk->iv.buf.data, sk->iv.buf.len,
+ ask->aad.buf.data, ask->aad.buf.len);
+ }
+ cipherInfo->repetitions += j;
+ }
+ }
+ TIMEFINISH(cipherInfo->optime, 1.0);
+ } else if (is_pubkeyCipher(cipherInfo->mode)) {
+ TIMESTART();
+ rv = (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx,
+ &cipherInfo->output.pBuf,
+ &cipherInfo->input.pBuf);
+ TIMEFINISH(cipherInfo->optime, 1.0);
+ CHECKERROR(rv, __LINE__);
+ cipherInfo->repetitions = 0;
+ if (cipherInfo->repetitionsToPerfom != 0) {
+ TIMESTART();
+ for (i = 0; i < cipherInfo->repetitionsToPerfom;
+ i++, cipherInfo->repetitions++) {
+ SECItem dummy;
+ dummy.data = dummyOut;
+ dummy.len = maxLen;
+ (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx, &dummy,
+ &cipherInfo->input.pBuf);
+ CHECKERROR(rv, __LINE__);
+ }
+ } else {
+ int opsBetweenChecks = 0;
+ TIMEMARK(cipherInfo->seconds);
+ while (!(TIMETOFINISH())) {
+ int j = 0;
+ for (; j < opsBetweenChecks; j++) {
+ SECItem dummy;
+ dummy.data = dummyOut;
+ dummy.len = maxLen;
+ (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx, &dummy,
+ &cipherInfo->input.pBuf);
+ CHECKERROR(rv, __LINE__);
+ }
+ cipherInfo->repetitions += j;
+ }
+ }
+ TIMEFINISH(cipherInfo->optime, 1.0);
+ } else if (is_hashCipher(cipherInfo->mode)) {
+ TIMESTART();
+ rv = (*cipherInfo->cipher.hashCipher)(cipherInfo->output.pBuf.data,
+ cipherInfo->input.pBuf.data,
+ cipherInfo->input.pBuf.len);
+ TIMEFINISH(cipherInfo->optime, 1.0);
+ CHECKERROR(rv, __LINE__);
+ cipherInfo->repetitions = 0;
+ if (cipherInfo->repetitionsToPerfom != 0) {
+ TIMESTART();
+ for (i = 0; i < cipherInfo->repetitionsToPerfom;
+ i++, cipherInfo->repetitions++) {
+ (*cipherInfo->cipher.hashCipher)(dummyOut,
+ cipherInfo->input.pBuf.data,
+ cipherInfo->input.pBuf.len);
+ CHECKERROR(rv, __LINE__);
+ }
+ } else {
+ int opsBetweenChecks = 0;
+ TIMEMARK(cipherInfo->seconds);
+ while (!(TIMETOFINISH())) {
+ int j = 0;
+ for (; j < opsBetweenChecks; j++) {
+ bltestIO *input = &cipherInfo->input;
+ (*cipherInfo->cipher.hashCipher)(dummyOut,
+ input->pBuf.data,
+ input->pBuf.len);
+ CHECKERROR(rv, __LINE__);
+ }
+ cipherInfo->repetitions += j;
+ }
+ }
+ TIMEFINISH(cipherInfo->optime, 1.0);
+ }
+ PORT_Free(dummyOut);
+ return rv;
+}
+
+SECStatus
+cipherFinish(bltestCipherInfo *cipherInfo)
+{
+ SECStatus rv = SECSuccess;
+
+ switch (cipherInfo->mode) {
+ case bltestDES_ECB:
+ case bltestDES_CBC:
+ case bltestDES_EDE_ECB:
+ case bltestDES_EDE_CBC:
+ DES_DestroyContext((DESContext *)cipherInfo->cx, PR_TRUE);
+ break;
+ case bltestAES_GCM:
+ case bltestAES_ECB:
+ case bltestAES_CBC:
+ case bltestAES_CTS:
+ case bltestAES_CTR:
+ AES_DestroyContext((AESContext *)cipherInfo->cx, PR_TRUE);
+ break;
+ case bltestCAMELLIA_ECB:
+ case bltestCAMELLIA_CBC:
+ Camellia_DestroyContext((CamelliaContext *)cipherInfo->cx, PR_TRUE);
+ break;
+ case bltestSEED_ECB:
+ case bltestSEED_CBC:
+ SEED_DestroyContext((SEEDContext *)cipherInfo->cx, PR_TRUE);
+ break;
+ case bltestCHACHA20:
+ ChaCha20Poly1305_DestroyContext((ChaCha20Poly1305Context *)
+ cipherInfo->cx,
+ PR_TRUE);
+ break;
+ case bltestRC2_ECB:
+ case bltestRC2_CBC:
+ RC2_DestroyContext((RC2Context *)cipherInfo->cx, PR_TRUE);
+ break;
+ case bltestRC4:
+ RC4_DestroyContext((RC4Context *)cipherInfo->cx, PR_TRUE);
+ break;
+#ifdef NSS_SOFTOKEN_DOES_RC5
+ case bltestRC5_ECB:
+ case bltestRC5_CBC:
+ RC5_DestroyContext((RC5Context *)cipherInfo->cx, PR_TRUE);
+ break;
+#endif
+ case bltestRSA: /* keys are alloc'ed within cipherInfo's arena, */
+ case bltestRSA_PSS: /* will be freed with it. */
+ case bltestRSA_OAEP:
+ case bltestDSA:
+#ifndef NSS_DISABLE_ECC
+ case bltestECDSA:
+#endif
+ case bltestMD2: /* hash contexts are ephemeral */
+ case bltestMD5:
+ case bltestSHA1:
+ case bltestSHA224:
+ case bltestSHA256:
+ case bltestSHA384:
+ case bltestSHA512:
+ return SECSuccess;
+ break;
+ default:
+ return SECFailure;
+ }
+ return rv;
+}
+
+void
+print_exponent(SECItem *exp)
+{
+ int i;
+ int e = 0;
+ if (exp->len <= 4) {
+ for (i = exp->len; i >= 0; --i)
+ e |= exp->data[exp->len - i] << 8 * (i - 1);
+ fprintf(stdout, "%12d", e);
+ } else {
+ e = 8 * exp->len;
+ fprintf(stdout, "~2**%-8d", e);
+ }
+}
+
+static void
+splitToReportUnit(PRInt64 res, int *resArr, int *del, int size)
+{
+ PRInt64 remaining = res, tmp = 0;
+ PRInt64 Ldel;
+ int i = -1;
+
+ while (remaining > 0 && ++i < size) {
+ LL_I2L(Ldel, del[i]);
+ LL_MOD(tmp, remaining, Ldel);
+ LL_L2I(resArr[i], tmp);
+ LL_DIV(remaining, remaining, Ldel);
+ }
+}
+
+static char *
+getHighUnitBytes(PRInt64 res)
+{
+ int spl[] = { 0, 0, 0, 0 };
+ int del[] = { 1024, 1024, 1024, 1024 };
+ char *marks[] = { "b", "Kb", "Mb", "Gb" };
+ int i = 3;
+
+ splitToReportUnit(res, spl, del, 4);
+
+ for (; i > 0; i--) {
+ if (spl[i] != 0) {
+ break;
+ }
+ }
+
+ return PR_smprintf("%d%s", spl[i], marks[i]);
+}
+
+static void
+printPR_smpString(const char *sformat, char *reportStr,
+ const char *nformat, PRInt64 rNum)
+{
+ if (reportStr) {
+ fprintf(stdout, sformat, reportStr);
+ PR_smprintf_free(reportStr);
+ } else {
+ fprintf(stdout, nformat, rNum);
+ }
+}
+
+static char *
+getHighUnitOps(PRInt64 res)
+{
+ int spl[] = { 0, 0, 0, 0 };
+ int del[] = { 1000, 1000, 1000, 1000 };
+ char *marks[] = { "", "T", "M", "B" };
+ int i = 3;
+
+ splitToReportUnit(res, spl, del, 4);
+
+ for (; i > 0; i--) {
+ if (spl[i] != 0) {
+ break;
+ }
+ }
+
+ return PR_smprintf("%d%s", spl[i], marks[i]);
+}
+
+void
+dump_performance_info(bltestCipherInfo *infoList, double totalTimeInt,
+ PRBool encrypt, PRBool cxonly)
+{
+ bltestCipherInfo *info = infoList;
+
+ PRInt64 totalIn = 0;
+ PRBool td = PR_TRUE;
+
+ int repetitions = 0;
+ int cxreps = 0;
+ double cxtime = 0;
+ double optime = 0;
+ while (info != NULL) {
+ repetitions += info->repetitions;
+ cxreps += info->cxreps;
+ cxtime += info->cxtime;
+ optime += info->optime;
+ totalIn += (PRInt64)info->input.buf.len * (PRInt64)info->repetitions;
+
+ info = info->next;
+ }
+ info = infoList;
+
+ fprintf(stdout, "#%9s", "mode");
+ fprintf(stdout, "%12s", "in");
+print_td:
+ switch (info->mode) {
+ case bltestDES_ECB:
+ case bltestDES_CBC:
+ case bltestDES_EDE_ECB:
+ case bltestDES_EDE_CBC:
+ case bltestAES_ECB:
+ case bltestAES_CBC:
+ case bltestAES_CTS:
+ case bltestAES_CTR:
+ case bltestAES_GCM:
+ case bltestCAMELLIA_ECB:
+ case bltestCAMELLIA_CBC:
+ case bltestSEED_ECB:
+ case bltestSEED_CBC:
+ case bltestRC2_ECB:
+ case bltestRC2_CBC:
+ case bltestRC4:
+ if (td)
+ fprintf(stdout, "%8s", "symmkey");
+ else
+ fprintf(stdout, "%8d", 8 * info->params.sk.key.buf.len);
+ break;
+#ifdef NSS_SOFTOKEN_DOES_RC5
+ case bltestRC5_ECB:
+ case bltestRC5_CBC:
+ if (info->params.sk.key.buf.len > 0)
+ printf("symmetric key(bytes)=%d,", info->params.sk.key.buf.len);
+ if (info->rounds > 0)
+ printf("rounds=%d,", info->params.rc5.rounds);
+ if (info->wordsize > 0)
+ printf("wordsize(bytes)=%d,", info->params.rc5.wordsize);
+ break;
+#endif
+ case bltestRSA:
+ case bltestRSA_PSS:
+ case bltestRSA_OAEP:
+ if (td) {
+ fprintf(stdout, "%8s", "rsa_mod");
+ fprintf(stdout, "%12s", "rsa_pe");
+ } else {
+ bltestAsymKeyParams *asymk = &info->params.asymk;
+ fprintf(stdout, "%8d", asymk->cipherParams.rsa.keysizeInBits);
+ print_exponent(
+ &((RSAPrivateKey *)asymk->privKey)->publicExponent);
+ }
+ break;
+ case bltestDSA:
+ if (td) {
+ fprintf(stdout, "%8s", "pqg_mod");
+ } else {
+ fprintf(stdout, "%8d", info->params.asymk.cipherParams.dsa.keysize);
+ }
+ break;
+#ifndef NSS_DISABLE_ECC
+ case bltestECDSA:
+ if (td) {
+ fprintf(stdout, "%12s", "ec_curve");
+ } else {
+ ECPrivateKey *key = (ECPrivateKey *)info->params.asymk.privKey;
+ ECCurveName curveName = key->ecParams.name;
+ fprintf(stdout, "%12s",
+ ecCurve_map[curveName] ? ecCurve_map[curveName]->text : "Unsupported curve");
+ }
+ break;
+#endif
+ case bltestMD2:
+ case bltestMD5:
+ case bltestSHA1:
+ case bltestSHA256:
+ case bltestSHA384:
+ case bltestSHA512:
+ default:
+ break;
+ }
+ if (!td) {
+ PRInt64 totalThroughPut;
+
+ printPR_smpString("%8s", getHighUnitOps(repetitions),
+ "%8d", repetitions);
+
+ printPR_smpString("%8s", getHighUnitOps(cxreps), "%8d", cxreps);
+
+ fprintf(stdout, "%12.3f", cxtime);
+ fprintf(stdout, "%12.3f", optime);
+ fprintf(stdout, "%12.03f", totalTimeInt / 1000);
+
+ totalThroughPut = (PRInt64)(totalIn / totalTimeInt * 1000);
+ printPR_smpString("%12s", getHighUnitBytes(totalThroughPut),
+ "%12d", totalThroughPut);
+
+ fprintf(stdout, "\n");
+ return;
+ }
+
+ fprintf(stdout, "%8s", "opreps");
+ fprintf(stdout, "%8s", "cxreps");
+ fprintf(stdout, "%12s", "context");
+ fprintf(stdout, "%12s", "op");
+ fprintf(stdout, "%12s", "time(sec)");
+ fprintf(stdout, "%12s", "thrgput");
+ fprintf(stdout, "\n");
+ fprintf(stdout, "%8s", mode_strings[info->mode]);
+ fprintf(stdout, "_%c", (cxonly) ? 'c' : (encrypt) ? 'e' : 'd');
+ printPR_smpString("%12s", getHighUnitBytes(totalIn), "%12d", totalIn);
+
+ td = !td;
+ goto print_td;
+}
+
+void
+printmodes()
+{
+ bltestCipherMode mode;
+ int nummodes = sizeof(mode_strings) / sizeof(char *);
+ fprintf(stderr, "%s: Available modes (specify with -m):\n", progName);
+ for (mode = 0; mode < nummodes; mode++)
+ fprintf(stderr, "%s\n", mode_strings[mode]);
+}
+
+bltestCipherMode
+get_mode(const char *modestring)
+{
+ bltestCipherMode mode;
+ int nummodes = sizeof(mode_strings) / sizeof(char *);
+ for (mode = 0; mode < nummodes; mode++)
+ if (PL_strcmp(modestring, mode_strings[mode]) == 0)
+ return mode;
+ fprintf(stderr, "%s: invalid mode: %s\n", progName, modestring);
+ return bltestINVALID;
+}
+
+void
+load_file_data(PLArenaPool *arena, bltestIO *data,
+ char *fn, bltestIOMode ioMode)
+{
+ PRFileDesc *file;
+ data->mode = ioMode;
+ data->file = NULL; /* don't use -- not saving anything */
+ data->pBuf.data = NULL;
+ data->pBuf.len = 0;
+ file = PR_Open(fn, PR_RDONLY, 00660);
+ if (file) {
+ setupIO(arena, data, file, NULL, 0);
+ PR_Close(file);
+ }
+}
+
+HASH_HashType
+mode_str_to_hash_alg(const SECItem *modeStr)
+{
+ bltestCipherMode mode;
+ char *tempModeStr = NULL;
+ if (!modeStr || modeStr->len == 0)
+ return HASH_AlgNULL;
+ tempModeStr = PORT_Alloc(modeStr->len + 1);
+ if (!tempModeStr)
+ return HASH_AlgNULL;
+ memcpy(tempModeStr, modeStr->data, modeStr->len);
+ tempModeStr[modeStr->len] = '\0';
+ mode = get_mode(tempModeStr);
+ PORT_Free(tempModeStr);
+ switch (mode) {
+ case bltestMD2:
+ return HASH_AlgMD2;
+ case bltestMD5:
+ return HASH_AlgMD5;
+ case bltestSHA1:
+ return HASH_AlgSHA1;
+ case bltestSHA224:
+ return HASH_AlgSHA224;
+ case bltestSHA256:
+ return HASH_AlgSHA256;
+ case bltestSHA384:
+ return HASH_AlgSHA384;
+ case bltestSHA512:
+ return HASH_AlgSHA512;
+ default:
+ return HASH_AlgNULL;
+ }
+}
+
+void
+get_params(PLArenaPool *arena, bltestParams *params,
+ bltestCipherMode mode, int j)
+{
+ char filename[256];
+ char *modestr = mode_strings[mode];
+ bltestIO tempIO;
+
+#ifdef NSS_SOFTOKEN_DOES_RC5
+ FILE *file;
+ char *mark, *param, *val;
+ int index = 0;
+#endif
+ switch (mode) {
+ case bltestAES_GCM:
+ case bltestCHACHA20:
+ sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "aad", j);
+ load_file_data(arena, ¶ms->ask.aad, filename, bltestBinary);
+ case bltestDES_CBC:
+ case bltestDES_EDE_CBC:
+ case bltestRC2_CBC:
+ case bltestAES_CBC:
+ case bltestAES_CTS:
+ case bltestAES_CTR:
+ case bltestCAMELLIA_CBC:
+ case bltestSEED_CBC:
+ sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "iv", j);
+ load_file_data(arena, ¶ms->sk.iv, filename, bltestBinary);
+ case bltestDES_ECB:
+ case bltestDES_EDE_ECB:
+ case bltestRC2_ECB:
+ case bltestRC4:
+ case bltestAES_ECB:
+ case bltestCAMELLIA_ECB:
+ case bltestSEED_ECB:
+ sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
+ load_file_data(arena, ¶ms->sk.key, filename, bltestBinary);
+ break;
+#ifdef NSS_SOFTOKEN_DOES_RC5
+ case bltestRC5_ECB:
+ case bltestRC5_CBC:
+ sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "iv", j);
+ load_file_data(arena, ¶ms->sk.iv, filename, bltestBinary);
+ sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
+ load_file_data(arena, ¶ms->sk.key, filename, bltestBinary);
+ sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr,
+ "params", j);
+ file = fopen(filename, "r");
+ if (!file)
+ return;
+ param = malloc(100);
+ len = fread(param, 1, 100, file);
+ while (index < len) {
+ mark = PL_strchr(param, '=');
+ *mark = '\0';
+ val = mark + 1;
+ mark = PL_strchr(val, '\n');
+ *mark = '\0';
+ if (PL_strcmp(param, "rounds") == 0) {
+ params->rc5.rounds = atoi(val);
+ } else if (PL_strcmp(param, "wordsize") == 0) {
+ params->rc5.wordsize = atoi(val);
+ }
+ index += PL_strlen(param) + PL_strlen(val) + 2;
+ param = mark + 1;
+ }
+ break;
+#endif
+ case bltestRSA_PSS:
+ sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "ciphertext", j);
+ load_file_data(arena, ¶ms->asymk.sig, filename, bltestBase64Encoded);
+ /* fall through */
+ case bltestRSA_OAEP:
+ sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "seed", j);
+ load_file_data(arena, ¶ms->asymk.cipherParams.rsa.seed,
+ filename, bltestBase64Encoded);
+
+ sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "hash", j);
+ load_file_data(arena, &tempIO, filename, bltestBinary);
+ params->asymk.cipherParams.rsa.hashAlg =
+ mode_str_to_hash_alg(&tempIO.buf);
+
+ sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "maskhash", j);
+ load_file_data(arena, &tempIO, filename, bltestBinary);
+ params->asymk.cipherParams.rsa.maskHashAlg =
+ mode_str_to_hash_alg(&tempIO.buf);
+ /* fall through */
+ case bltestRSA:
+ sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
+ load_file_data(arena, ¶ms->asymk.key, filename,
+ bltestBase64Encoded);
+ params->asymk.privKey =
+ (void *)rsakey_from_filedata(arena, ¶ms->asymk.key.buf);
+ break;
+ case bltestDSA:
+ sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
+ load_file_data(arena, ¶ms->asymk.key, filename, bltestBase64Encoded);
+ params->asymk.privKey =
+ (void *)dsakey_from_filedata(arena, ¶ms->asymk.key.buf);
+ sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "pqg", j);
+ load_file_data(arena, ¶ms->asymk.cipherParams.dsa.pqgdata, filename,
+ bltestBase64Encoded);
+ params->asymk.cipherParams.dsa.pqg =
+ pqg_from_filedata(arena, ¶ms->asymk.cipherParams.dsa.pqgdata.buf);
+ sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "keyseed", j);
+ load_file_data(arena, ¶ms->asymk.cipherParams.dsa.keyseed, filename,
+ bltestBase64Encoded);
+ sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "sigseed", j);
+ load_file_data(arena, ¶ms->asymk.cipherParams.dsa.sigseed, filename,
+ bltestBase64Encoded);
+ sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "ciphertext", j);
+ load_file_data(arena, ¶ms->asymk.sig, filename, bltestBase64Encoded);
+ break;
+#ifndef NSS_DISABLE_ECC
+ case bltestECDSA:
+ sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
+ load_file_data(arena, ¶ms->asymk.key, filename, bltestBase64Encoded);
+ params->asymk.privKey =
+ (void *)eckey_from_filedata(arena, ¶ms->asymk.key.buf);
+ sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "sigseed", j);
+ load_file_data(arena, ¶ms->asymk.cipherParams.ecdsa.sigseed,
+ filename, bltestBase64Encoded);
+ sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "ciphertext", j);
+ load_file_data(arena, ¶ms->asymk.sig, filename, bltestBase64Encoded);
+ break;
+#endif
+ case bltestMD2:
+ case bltestMD5:
+ case bltestSHA1:
+ case bltestSHA224:
+ case bltestSHA256:
+ case bltestSHA384:
+ case bltestSHA512:
+ /*params->hash.restart = PR_TRUE;*/
+ params->hash.restart = PR_FALSE;
+ break;
+ default:
+ break;
+ }
+}
+
+SECStatus
+verify_self_test(bltestIO *result, bltestIO *cmp, bltestCipherMode mode,
+ PRBool forward, SECStatus sigstatus)
+{
+ PRBool equal;
+ char *modestr = mode_strings[mode];
+ equal = SECITEM_ItemsAreEqual(&result->pBuf, &cmp->buf);
+ if (is_sigCipher(mode)) {
+ if (forward) {
+ if (equal) {
+ printf("Signature self-test for %s passed.\n", modestr);
+ } else {
+ printf("Signature self-test for %s failed!\n", modestr);
+ }
+ return equal ? SECSuccess : SECFailure;
+ } else {
+ if (sigstatus == SECSuccess) {
+ printf("Verification self-test for %s passed.\n", modestr);
+ } else {
+ printf("Verification self-test for %s failed!\n", modestr);
+ }
+ return sigstatus;
+ }
+ } else if (is_hashCipher(mode)) {
+ if (equal) {
+ printf("Hash self-test for %s passed.\n", modestr);
+ } else {
+ printf("Hash self-test for %s failed!\n", modestr);
+ }
+ } else {
+ if (forward) {
+ if (equal) {
+ printf("Encryption self-test for %s passed.\n", modestr);
+ } else {
+ printf("Encryption self-test for %s failed!\n", modestr);
+ }
+ } else {
+ if (equal) {
+ printf("Decryption self-test for %s passed.\n", modestr);
+ } else {
+ printf("Decryption self-test for %s failed!\n", modestr);
+ }
+ }
+ }
+ return equal ? SECSuccess : SECFailure;
+}
+
+static SECStatus
+ReadFileToItem(PLArenaPool *arena, SECItem *dst, const char *filename)
+{
+ SECItem tmp = { siBuffer, NULL, 0 };
+ PRFileDesc *file;
+ SECStatus rv;
+
+ file = PR_Open(filename, PR_RDONLY, 00660);
+ if (!file) {
+ return SECFailure;
+ }
+ rv = SECU_FileToItem(&tmp, file);
+ rv |= SECITEM_CopyItem(arena, dst, &tmp);
+ SECITEM_FreeItem(&tmp, PR_FALSE);
+ PR_Close(file);
+ return rv;
+}
+
+static SECStatus
+blapi_selftest(bltestCipherMode *modes, int numModes, int inoff, int outoff,
+ PRBool encrypt, PRBool decrypt)
+{
+ bltestCipherInfo cipherInfo;
+ bltestIO pt, ct;
+ bltestCipherMode mode;
+ bltestParams *params;
+ unsigned int i, j, nummodes, numtests;
+ char *modestr;
+ char filename[256];
+ PLArenaPool *arena;
+ SECItem item;
+ SECStatus rv = SECSuccess, srv;
+
+ PORT_Memset(&cipherInfo, 0, sizeof(cipherInfo));
+ arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
+ cipherInfo.arena = arena;
+
+ nummodes = (numModes == 0) ? NUMMODES : numModes;
+ for (i = 0; i < nummodes; i++) {
+ if (numModes > 0)
+ mode = modes[i];
+ else
+ mode = i;
+ if (mode == bltestINVALID) {
+ fprintf(stderr, "%s: Skipping invalid mode.\n", progName);
+ continue;
+ }
+ modestr = mode_strings[mode];
+ cipherInfo.mode = mode;
+ params = &cipherInfo.params;
+ /* get the number of tests in the directory */
+ sprintf(filename, "%s/tests/%s/%s", testdir, modestr, "numtests");
+ if (ReadFileToItem(arena, &item, filename) != SECSuccess) {
+ fprintf(stderr, "%s: Cannot read file %s.\n", progName, filename);
+ rv = SECFailure;
+ continue;
+ }
+ /* loop over the tests in the directory */
+ numtests = 0;
+ for (j = 0; j < item.len; j++) {
+ if (!isdigit(item.data[j])) {
+ break;
+ }
+ numtests *= 10;
+ numtests += (int)(item.data[j] - '0');
+ }
+ for (j = 0; j < numtests; j++) {
+ sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr,
+ "plaintext", j);
+ load_file_data(arena, &pt, filename,
+ is_sigCipher(mode) ? bltestBase64Encoded
+ : bltestBinary);
+ sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr,
+ "ciphertext", j);
+ load_file_data(arena, &ct, filename, bltestBase64Encoded);
+
+ get_params(arena, params, mode, j);
+ /* Forward Operation (Encrypt/Sign/Hash)
+ ** Align the input buffer (plaintext) according to request
+ ** then perform operation and compare to ciphertext
+ */
+ if (encrypt) {
+ rv |= bltestCopyIO(arena, &cipherInfo.input, &pt);
+ misalignBuffer(arena, &cipherInfo.input, inoff);
+ memset(&cipherInfo.output.buf, 0, sizeof cipherInfo.output.buf);
+ rv |= cipherInit(&cipherInfo, PR_TRUE);
+ misalignBuffer(arena, &cipherInfo.output, outoff);
+ rv |= cipherDoOp(&cipherInfo);
+ rv |= cipherFinish(&cipherInfo);
+ rv |= verify_self_test(&cipherInfo.output,
+ &ct, mode, PR_TRUE, SECSuccess);
+ /* If testing hash, only one op to test */
+ if (is_hashCipher(mode))
+ continue;
+ if (is_sigCipher(mode)) {
+ /* Verify operations support detached signature files. For
+ ** consistency between tests that run Sign/Verify back to
+ ** back (eg: self-tests) and tests that are only running
+ ** verify operations, copy the output into the sig buf,
+ ** and then copy the sig buf back out when verifying. For
+ ** self-tests, this is unnecessary copying, but for
+ ** verify-only operations, this ensures that the output
+ ** buffer is properly configured
+ */
+ rv |= bltestCopyIO(arena, ¶ms->asymk.sig, &cipherInfo.output);
+ }
+ }
+ if (!decrypt)
+ continue;
+ /* Reverse Operation (Decrypt/Verify)
+ ** Align the input buffer (ciphertext) according to request
+ ** then perform operation and compare to plaintext
+ */
+ if (is_sigCipher(mode)) {
+ rv |= bltestCopyIO(arena, &cipherInfo.input, &pt);
+ rv |= bltestCopyIO(arena, &cipherInfo.output, ¶ms->asymk.sig);
+ } else {
+ rv |= bltestCopyIO(arena, &cipherInfo.input, &ct);
+ memset(&cipherInfo.output.buf, 0, sizeof cipherInfo.output.buf);
+ }
+ misalignBuffer(arena, &cipherInfo.input, inoff);
+ rv |= cipherInit(&cipherInfo, PR_FALSE);
+ misalignBuffer(arena, &cipherInfo.output, outoff);
+ srv = SECSuccess;
+ srv |= cipherDoOp(&cipherInfo);
+ rv |= cipherFinish(&cipherInfo);
+ rv |= verify_self_test(&cipherInfo.output,
+ &pt, mode, PR_FALSE, srv);
+ }
+ }
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+SECStatus
+dump_file(bltestCipherMode mode, char *filename)
+{
+ bltestIO keydata;
+ PLArenaPool *arena = NULL;
+ arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ return SECFailure;
+ }
+ if (mode == bltestRSA || mode == bltestRSA_PSS || mode == bltestRSA_OAEP) {
+ RSAPrivateKey *key;
+ load_file_data(arena, &keydata, filename, bltestBase64Encoded);
+ key = rsakey_from_filedata(arena, &keydata.buf);
+ dump_rsakey(key);
+ } else if (mode == bltestDSA) {
+#if 0
+ PQGParams *pqg;
+ get_file_data(filename, &item, PR_TRUE);
+ pqg = pqg_from_filedata(&item);
+ dump_pqg(pqg);
+#endif
+ DSAPrivateKey *key;
+ load_file_data(arena, &keydata, filename, bltestBase64Encoded);
+ key = dsakey_from_filedata(arena, &keydata.buf);
+ dump_dsakey(key);
+#ifndef NSS_DISABLE_ECC
+ } else if (mode == bltestECDSA) {
+ ECPrivateKey *key;
+ load_file_data(arena, &keydata, filename, bltestBase64Encoded);
+ key = eckey_from_filedata(arena, &keydata.buf);
+ dump_eckey(key);
+#endif
+ }
+ PORT_FreeArena(arena, PR_FALSE);
+ return SECFailure;
+}
+
+void
+ThreadExecTest(void *data)
+{
+ bltestCipherInfo *cipherInfo = (bltestCipherInfo *)data;
+
+ if (cipherInfo->mCarlo == PR_TRUE) {
+ int mciter;
+ for (mciter = 0; mciter < 10000; mciter++) {
+ cipherDoOp(cipherInfo);
+ memcpy(cipherInfo->input.buf.data,
+ cipherInfo->output.buf.data,
+ cipherInfo->input.buf.len);
+ }
+ } else {
+ cipherDoOp(cipherInfo);
+ }
+ cipherFinish(cipherInfo);
+}
+
+static void
+rsaPrivKeyReset(RSAPrivateKey *tstKey)
+{
+ PLArenaPool *arena;
+
+ tstKey->version.data = NULL;
+ tstKey->version.len = 0;
+ tstKey->modulus.data = NULL;
+ tstKey->modulus.len = 0;
+ tstKey->publicExponent.data = NULL;
+ tstKey->publicExponent.len = 0;
+ tstKey->privateExponent.data = NULL;
+ tstKey->privateExponent.len = 0;
+ tstKey->prime1.data = NULL;
+ tstKey->prime1.len = 0;
+ tstKey->prime2.data = NULL;
+ tstKey->prime2.len = 0;
+ tstKey->exponent1.data = NULL;
+ tstKey->exponent1.len = 0;
+ tstKey->exponent2.data = NULL;
+ tstKey->exponent2.len = 0;
+ tstKey->coefficient.data = NULL;
+ tstKey->coefficient.len = 0;
+
+ arena = tstKey->arena;
+ tstKey->arena = NULL;
+ if (arena) {
+ PORT_FreeArena(arena, PR_TRUE);
+ }
+}
+
+#define RSA_TEST_EQUAL(comp) \
+ if (!SECITEM_ItemsAreEqual(&(src->comp), &(dest->comp))) { \
+ fprintf(stderr, "key->" #comp " not equal"); \
+ if (src->comp.len != dest->comp.len) { \
+ fprintf(stderr, "src_len = %d, dest_len = %d", \
+ src->comp.len, dest->comp.len); \
+ } \
+ fprintf(stderr, "\n"); \
+ areEqual = PR_FALSE; \
+ }
+
+static PRBool
+rsaPrivKeysAreEqual(RSAPrivateKey *src, RSAPrivateKey *dest)
+{
+ PRBool areEqual = PR_TRUE;
+ RSA_TEST_EQUAL(modulus)
+ RSA_TEST_EQUAL(publicExponent)
+ RSA_TEST_EQUAL(privateExponent)
+ RSA_TEST_EQUAL(prime1)
+ RSA_TEST_EQUAL(prime2)
+ RSA_TEST_EQUAL(exponent1)
+ RSA_TEST_EQUAL(exponent2)
+ RSA_TEST_EQUAL(coefficient)
+ if (!areEqual) {
+ fprintf(stderr, "original key:\n");
+ dump_rsakey(src);
+ fprintf(stderr, "recreated key:\n");
+ dump_rsakey(dest);
+ }
+ return areEqual;
+}
+
+static int
+doRSAPopulateTestKV()
+{
+ RSAPrivateKey tstKey = { 0 };
+ SECStatus rv;
+ int failed = 0;
+ int i;
+
+ tstKey.arena = NULL;
+
+ /* Test public exponent, private exponent, modulus cases from
+ * pkcs1v15sign-vectors.txt. Some are valid PKCS#1 keys but not valid RSA
+ * ones (de = 1 mod lcm(p − 1, q − 1))
+ */
+ for (i = 0; i < PR_ARRAY_SIZE(PKCS1_VECTORS); ++i) {
+ struct pkcs1_test_vector *v = &PKCS1_VECTORS[i];
+
+ rsaPrivKeyReset(&tstKey);
+ tstKey.privateExponent.data = v->d;
+ tstKey.privateExponent.len = v->d_len;
+ tstKey.publicExponent.data = v->e;
+ tstKey.publicExponent.len = v->e_len;
+ tstKey.modulus.data = v->n;
+ tstKey.modulus.len = v->n_len;
+
+ rv = RSA_PopulatePrivateKey(&tstKey);
+ if (rv != SECSuccess) {
+ fprintf(stderr, "RSA Populate failed: pkcs1v15sign-vector %d\n", i);
+ failed = 1;
+ } else if (memcmp(v->q, tstKey.prime1.data, v->q_len) ||
+ tstKey.prime1.len != v->q_len) {
+ fprintf(stderr, "RSA Populate key mismatch: pkcs1v15sign-vector %d q\n", i);
+ failed = 1;
+ } else if (memcmp(v->p, tstKey.prime2.data, v->p_len) ||
+ tstKey.prime1.len != v->p_len) {
+ fprintf(stderr, "RSA Populate key mismatch: pkcs1v15sign-vector %d p\n", i);
+ failed = 1;
+ } else {
+ fprintf(stderr, "RSA Populate success: pkcs1v15sign-vector %d p\n", i);
+ }
+ }
+
+ PORT_FreeArena(tstKey.arena, PR_TRUE);
+ return failed;
+}
+
+/*
+ * Test the RSA populate command to see that it can really build
+ * keys from its components.
+ */
+static int
+doRSAPopulateTest(unsigned int keySize, unsigned long exponent)
+{
+ RSAPrivateKey *srcKey;
+ RSAPrivateKey tstKey = { 0 };
+ SECItem expitem = { 0, 0, 0 };
+ SECStatus rv;
+ unsigned char pubExp[32];
+ int expLen = 0;
+ int failed = 0;
+ int i;
+
+ for (i = 0; i < sizeof(unsigned long); i++) {
+ int shift = (sizeof(unsigned long) - i - 1) * 8;
+ if (expLen || (exponent && ((unsigned long)0xffL << shift))) {
+ pubExp[expLen] = (unsigned char)((exponent >> shift) & 0xff);
+ expLen++;
+ }
+ }
+
+ expitem.data = pubExp;
+ expitem.len = expLen;
+
+ srcKey = RSA_NewKey(keySize, &expitem);
+ if (srcKey == NULL) {
+ fprintf(stderr, "RSA Key Gen failed");
+ return -1;
+ }
+
+ /* test the basic case - most common, public exponent, modulus, prime */
+ tstKey.arena = NULL;
+ rsaPrivKeyReset(&tstKey);
+
+ tstKey.publicExponent = srcKey->publicExponent;
+ tstKey.modulus = srcKey->modulus;
+ tstKey.prime1 = srcKey->prime1;
+
+ rv = RSA_PopulatePrivateKey(&tstKey);
+ if (rv != SECSuccess) {
+ fprintf(stderr, "RSA Populate failed: pubExp mod p\n");
+ failed = 1;
+ } else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) {
+ fprintf(stderr, "RSA Populate key mismatch: pubExp mod p\n");
+ failed = 1;
+ }
+
+ /* test the basic2 case, public exponent, modulus, prime2 */
+ rsaPrivKeyReset(&tstKey);
+
+ tstKey.publicExponent = srcKey->publicExponent;
+ tstKey.modulus = srcKey->modulus;
+ tstKey.prime1 = srcKey->prime2; /* test with q in the prime1 position */
+
+ rv = RSA_PopulatePrivateKey(&tstKey);
+ if (rv != SECSuccess) {
+ fprintf(stderr, "RSA Populate failed: pubExp mod q\n");
+ failed = 1;
+ } else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) {
+ fprintf(stderr, "RSA Populate key mismatch: pubExp mod q\n");
+ failed = 1;
+ }
+
+ /* test the medium case, private exponent, prime1, prime2 */
+ rsaPrivKeyReset(&tstKey);
+
+ tstKey.privateExponent = srcKey->privateExponent;
+ tstKey.prime1 = srcKey->prime2; /* purposefully swap them to make */
+ tstKey.prime2 = srcKey->prime1; /* sure populated swaps them back */
+
+ rv = RSA_PopulatePrivateKey(&tstKey);
+ if (rv != SECSuccess) {
+ fprintf(stderr, "RSA Populate failed: privExp p q\n");
+ failed = 1;
+ } else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) {
+ fprintf(stderr, "RSA Populate key mismatch: privExp p q\n");
+ failed = 1;
+ }
+
+ /* test the advanced case, public exponent, private exponent, prime2 */
+ rsaPrivKeyReset(&tstKey);
+
+ tstKey.privateExponent = srcKey->privateExponent;
+ tstKey.publicExponent = srcKey->publicExponent;
+ tstKey.prime2 = srcKey->prime2; /* use q in the prime2 position */
+
+ rv = RSA_PopulatePrivateKey(&tstKey);
+ if (rv != SECSuccess) {
+ fprintf(stderr, "RSA Populate failed: pubExp privExp q\n");
+ fprintf(stderr, " - not fatal\n");
+ /* it's possible that we can't uniquely determine the original key
+ * from just the exponents and prime. Populate returns an error rather
+ * than return the wrong key. */
+ } else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) {
+ /* if we returned a key, it *must* be correct */
+ fprintf(stderr, "RSA Populate key mismatch: pubExp privExp q\n");
+ rv = RSA_PrivateKeyCheck(&tstKey);
+ failed = 1;
+ }
+
+ /* test the advanced case2, public exponent, private exponent, modulus */
+ rsaPrivKeyReset(&tstKey);
+
+ tstKey.privateExponent = srcKey->privateExponent;
+ tstKey.publicExponent = srcKey->publicExponent;
+ tstKey.modulus = srcKey->modulus;
+
+ rv = RSA_PopulatePrivateKey(&tstKey);
+ if (rv != SECSuccess) {
+ fprintf(stderr, "RSA Populate failed: pubExp privExp mod\n");
+ failed = 1;
+ } else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) {
+ fprintf(stderr, "RSA Populate key mismatch: pubExp privExp mod\n");
+ failed = 1;
+ }
+
+ PORT_FreeArena(srcKey->arena, PR_TRUE);
+ return failed ? -1 : 0;
+}
+
+/* bltest commands */
+enum {
+ cmd_Decrypt = 0,
+ cmd_Encrypt,
+ cmd_FIPS,
+ cmd_Hash,
+ cmd_Nonce,
+ cmd_Dump,
+ cmd_RSAPopulate,
+ cmd_RSAPopulateKV,
+ cmd_Sign,
+ cmd_SelfTest,
+ cmd_Verify
+};
+
+/* bltest options */
+enum {
+ opt_B64 = 0,
+ opt_BufSize,
+ opt_Restart,
+ opt_SelfTestDir,
+ opt_Exponent,
+ opt_SigFile,
+ opt_KeySize,
+ opt_Hex,
+ opt_Input,
+ opt_PQGFile,
+ opt_Key,
+ opt_HexWSpc,
+ opt_Mode,
+#ifndef NSS_DISABLE_ECC
+ opt_CurveName,
+#endif
+ opt_Output,
+ opt_Repetitions,
+ opt_ZeroBuf,
+ opt_Rounds,
+ opt_Seed,
+ opt_SigSeedFile,
+ opt_CXReps,
+ opt_IV,
+ opt_WordSize,
+ opt_UseSeed,
+ opt_UseSigSeed,
+ opt_SeedFile,
+ opt_AAD,
+ opt_InputOffset,
+ opt_OutputOffset,
+ opt_MonteCarlo,
+ opt_ThreadNum,
+ opt_SecondsToRun,
+ opt_CmdLine
+};
+
+static secuCommandFlag bltest_commands[] =
+ {
+ { /* cmd_Decrypt */ 'D', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_Encrypt */ 'E', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_FIPS */ 'F', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_Hash */ 'H', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_Nonce */ 'N', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_Dump */ 'P', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_RSAPopulate */ 'R', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_RSAPopulateKV */ 'K', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_Sign */ 'S', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_SelfTest */ 'T', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_Verify */ 'V', PR_FALSE, 0, PR_FALSE }
+ };
+
+static secuCommandFlag bltest_options[] =
+ {
+ { /* opt_B64 */ 'a', PR_FALSE, 0, PR_FALSE },
+ { /* opt_BufSize */ 'b', PR_TRUE, 0, PR_FALSE },
+ { /* opt_Restart */ 'c', PR_FALSE, 0, PR_FALSE },
+ { /* opt_SelfTestDir */ 'd', PR_TRUE, 0, PR_FALSE },
+ { /* opt_Exponent */ 'e', PR_TRUE, 0, PR_FALSE },
+ { /* opt_SigFile */ 'f', PR_TRUE, 0, PR_FALSE },
+ { /* opt_KeySize */ 'g', PR_TRUE, 0, PR_FALSE },
+ { /* opt_Hex */ 'h', PR_FALSE, 0, PR_FALSE },
+ { /* opt_Input */ 'i', PR_TRUE, 0, PR_FALSE },
+ { /* opt_PQGFile */ 'j', PR_TRUE, 0, PR_FALSE },
+ { /* opt_Key */ 'k', PR_TRUE, 0, PR_FALSE },
+ { /* opt_HexWSpc */ 'l', PR_FALSE, 0, PR_FALSE },
+ { /* opt_Mode */ 'm', PR_TRUE, 0, PR_FALSE },
+#ifndef NSS_DISABLE_ECC
+ { /* opt_CurveName */ 'n', PR_TRUE, 0, PR_FALSE },
+#endif
+ { /* opt_Output */ 'o', PR_TRUE, 0, PR_FALSE },
+ { /* opt_Repetitions */ 'p', PR_TRUE, 0, PR_FALSE },
+ { /* opt_ZeroBuf */ 'q', PR_FALSE, 0, PR_FALSE },
+ { /* opt_Rounds */ 'r', PR_TRUE, 0, PR_FALSE },
+ { /* opt_Seed */ 's', PR_TRUE, 0, PR_FALSE },
+ { /* opt_SigSeedFile */ 't', PR_TRUE, 0, PR_FALSE },
+ { /* opt_CXReps */ 'u', PR_TRUE, 0, PR_FALSE },
+ { /* opt_IV */ 'v', PR_TRUE, 0, PR_FALSE },
+ { /* opt_WordSize */ 'w', PR_TRUE, 0, PR_FALSE },
+ { /* opt_UseSeed */ 'x', PR_FALSE, 0, PR_FALSE },
+ { /* opt_UseSigSeed */ 'y', PR_FALSE, 0, PR_FALSE },
+ { /* opt_SeedFile */ 'z', PR_FALSE, 0, PR_FALSE },
+ { /* opt_AAD */ 0, PR_TRUE, 0, PR_FALSE, "aad" },
+ { /* opt_InputOffset */ '1', PR_TRUE, 0, PR_FALSE },
+ { /* opt_OutputOffset */ '2', PR_TRUE, 0, PR_FALSE },
+ { /* opt_MonteCarlo */ '3', PR_FALSE, 0, PR_FALSE },
+ { /* opt_ThreadNum */ '4', PR_TRUE, 0, PR_FALSE },
+ { /* opt_SecondsToRun */ '5', PR_TRUE, 0, PR_FALSE },
+ { /* opt_CmdLine */ '-', PR_FALSE, 0, PR_FALSE }
+ };
+
+int
+main(int argc, char **argv)
+{
+ SECStatus rv = SECFailure;
+
+ double totalTime = 0.0;
+ PRIntervalTime time1, time2;
+ PRFileDesc *outfile = NULL;
+ bltestCipherInfo *cipherInfoListHead, *cipherInfo = NULL;
+ bltestIOMode ioMode;
+ int bufsize, exponent, curThrdNum;
+#ifndef NSS_DISABLE_ECC
+ char *curveName = NULL;
+#endif
+ int i, commandsEntered;
+ int inoff, outoff;
+ int threads = 1;
+
+ secuCommand bltest;
+ bltest.numCommands = sizeof(bltest_commands) / sizeof(secuCommandFlag);
+ bltest.numOptions = sizeof(bltest_options) / sizeof(secuCommandFlag);
+ bltest.commands = bltest_commands;
+ bltest.options = bltest_options;
+
+ progName = strrchr(argv[0], '/');
+ if (!progName)
+ progName = strrchr(argv[0], '\\');
+ progName = progName ? progName + 1 : argv[0];
+
+ rv = NSS_InitializePRErrorTable();
+ if (rv != SECSuccess) {
+ SECU_PrintPRandOSError(progName);
+ return -1;
+ }
+ rv = RNG_RNGInit();
+ if (rv != SECSuccess) {
+ SECU_PrintPRandOSError(progName);
+ return -1;
+ }
+ rv = BL_Init();
+ if (rv != SECSuccess) {
+ SECU_PrintPRandOSError(progName);
+ return -1;
+ }
+ RNG_SystemInfoForRNG();
+
+ rv = SECU_ParseCommandLine(argc, argv, progName, &bltest);
+ if (rv == SECFailure) {
+ fprintf(stderr, "%s: command line parsing error!\n", progName);
+ goto print_usage;
+ }
+ rv = SECFailure;
+
+ cipherInfo = PORT_ZNew(bltestCipherInfo);
+ cipherInfoListHead = cipherInfo;
+
+ /* Check the number of commands entered on the command line. */
+ commandsEntered = 0;
+ for (i = 0; i < bltest.numCommands; i++)
+ if (bltest.commands[i].activated)
+ commandsEntered++;
+
+ if (commandsEntered > 1 &&
+ !(commandsEntered == 2 && bltest.commands[cmd_SelfTest].activated)) {
+ fprintf(stderr, "%s: one command at a time!\n", progName);
+ goto print_usage;
+ }
+
+ if (commandsEntered == 0) {
+ fprintf(stderr, "%s: you must enter a command!\n", progName);
+ goto print_usage;
+ }
+
+ if (bltest.commands[cmd_Sign].activated)
+ bltest.commands[cmd_Encrypt].activated = PR_TRUE;
+ if (bltest.commands[cmd_Verify].activated)
+ bltest.commands[cmd_Decrypt].activated = PR_TRUE;
+ if (bltest.commands[cmd_Hash].activated)
+ bltest.commands[cmd_Encrypt].activated = PR_TRUE;
+
+ inoff = outoff = 0;
+ if (bltest.options[opt_InputOffset].activated)
+ inoff = PORT_Atoi(bltest.options[opt_InputOffset].arg);
+ if (bltest.options[opt_OutputOffset].activated)
+ outoff = PORT_Atoi(bltest.options[opt_OutputOffset].arg);
+
+ testdir = (bltest.options[opt_SelfTestDir].activated) ? strdup(bltest.options[opt_SelfTestDir].arg)
+ : ".";
+
+ /*
+ * Handle three simple cases first
+ */
+
+ /* test the RSA_PopulatePrivateKey function with known vectors */
+ if (bltest.commands[cmd_RSAPopulateKV].activated) {
+ PORT_Free(cipherInfo);
+ return doRSAPopulateTestKV();
+ }
+
+ /* test the RSA_PopulatePrivateKey function */
+ if (bltest.commands[cmd_RSAPopulate].activated) {
+ unsigned int keySize = 1024;
+ unsigned long exponent = 65537;
+ int rounds = 1;
+ int ret = -1;
+
+ if (bltest.options[opt_KeySize].activated) {
+ keySize = PORT_Atoi(bltest.options[opt_KeySize].arg);
+ }
+ if (bltest.options[opt_Rounds].activated) {
+ rounds = PORT_Atoi(bltest.options[opt_Rounds].arg);
+ }
+ if (bltest.options[opt_Exponent].activated) {
+ exponent = PORT_Atoi(bltest.options[opt_Exponent].arg);
+ }
+
+ for (i = 0; i < rounds; i++) {
+ printf("Running RSA Populate test round %d\n", i);
+ ret = doRSAPopulateTest(keySize, exponent);
+ if (ret != 0) {
+ break;
+ }
+ }
+ if (ret != 0) {
+ fprintf(stderr, "RSA Populate test round %d: FAILED\n", i);
+ }
+ PORT_Free(cipherInfo);
+ return ret;
+ }
+
+ /* Do BLAPI self-test */
+ if (bltest.commands[cmd_SelfTest].activated) {
+ PRBool encrypt = PR_TRUE, decrypt = PR_TRUE;
+ /* user may specified a set of ciphers to test. parse them. */
+ bltestCipherMode modesToTest[NUMMODES];
+ int numModesToTest = 0;
+ char *tok, *str;
+ str = bltest.options[opt_Mode].arg;
+ while (str) {
+ tok = strchr(str, ',');
+ if (tok)
+ *tok = '\0';
+ modesToTest[numModesToTest++] = get_mode(str);
+ if (tok) {
+ *tok = ',';
+ str = tok + 1;
+ } else {
+ break;
+ }
+ }
+ if (bltest.commands[cmd_Decrypt].activated &&
+ !bltest.commands[cmd_Encrypt].activated)
+ encrypt = PR_FALSE;
+ if (bltest.commands[cmd_Encrypt].activated &&
+ !bltest.commands[cmd_Decrypt].activated)
+ decrypt = PR_FALSE;
+ rv = blapi_selftest(modesToTest, numModesToTest, inoff, outoff,
+ encrypt, decrypt);
+ PORT_Free(cipherInfo);
+ return rv == SECSuccess ? 0 : 1;
+ }
+
+ /* Do FIPS self-test */
+ if (bltest.commands[cmd_FIPS].activated) {
+ CK_RV ckrv = sftk_FIPSEntryOK();
+ fprintf(stdout, "CK_RV: %ld.\n", ckrv);
+ PORT_Free(cipherInfo);
+ if (ckrv == CKR_OK)
+ return SECSuccess;
+ return SECFailure;
+ }
+
+ /*
+ * Check command line arguments for Encrypt/Decrypt/Hash/Sign/Verify
+ */
+
+ if ((bltest.commands[cmd_Decrypt].activated ||
+ bltest.commands[cmd_Verify].activated) &&
+ bltest.options[opt_BufSize].activated) {
+ fprintf(stderr, "%s: Cannot use a nonce as input to decrypt/verify.\n",
+ progName);
+ goto print_usage;
+ }
+
+ if (bltest.options[opt_Mode].activated) {
+ cipherInfo->mode = get_mode(bltest.options[opt_Mode].arg);
+ if (cipherInfo->mode == bltestINVALID) {
+ goto print_usage;
+ }
+ } else {
+ fprintf(stderr, "%s: You must specify a cipher mode with -m.\n",
+ progName);
+ goto print_usage;
+ }
+
+ if (bltest.options[opt_Repetitions].activated &&
+ bltest.options[opt_SecondsToRun].activated) {
+ fprintf(stderr, "%s: Operation time should be defined in either "
+ "repetitions(-p) or seconds(-5) not both",
+ progName);
+ goto print_usage;
+ }
+
+ if (bltest.options[opt_Repetitions].activated) {
+ cipherInfo->repetitionsToPerfom =
+ PORT_Atoi(bltest.options[opt_Repetitions].arg);
+ } else {
+ cipherInfo->repetitionsToPerfom = 0;
+ }
+
+ if (bltest.options[opt_SecondsToRun].activated) {
+ cipherInfo->seconds = PORT_Atoi(bltest.options[opt_SecondsToRun].arg);
+ } else {
+ cipherInfo->seconds = 0;
+ }
+
+ if (bltest.options[opt_CXReps].activated) {
+ cipherInfo->cxreps = PORT_Atoi(bltest.options[opt_CXReps].arg);
+ } else {
+ cipherInfo->cxreps = 0;
+ }
+
+ if (bltest.options[opt_ThreadNum].activated) {
+ threads = PORT_Atoi(bltest.options[opt_ThreadNum].arg);
+ if (threads <= 0) {
+ threads = 1;
+ }
+ }
+
+ /* Dump a file (rsakey, dsakey, etc.) */
+ if (bltest.commands[cmd_Dump].activated) {
+ rv = dump_file(cipherInfo->mode, bltest.options[opt_Input].arg);
+ PORT_Free(cipherInfo);
+ return rv;
+ }
+
+ /* default input mode is binary */
+ ioMode = (bltest.options[opt_B64].activated)
+ ? bltestBase64Encoded
+ : (bltest.options[opt_Hex].activated)
+ ? bltestHexStream
+ : (bltest.options[opt_HexWSpc].activated) ? bltestHexSpaceDelim
+ : bltestBinary;
+
+ if (bltest.options[opt_Exponent].activated)
+ exponent = PORT_Atoi(bltest.options[opt_Exponent].arg);
+ else
+ exponent = 65537;
+
+#ifndef NSS_DISABLE_ECC
+ if (bltest.options[opt_CurveName].activated)
+ curveName = PORT_Strdup(bltest.options[opt_CurveName].arg);
+ else
+ curveName = NULL;
+#endif
+
+ if (bltest.commands[cmd_Verify].activated &&
+ !bltest.options[opt_SigFile].activated) {
+ fprintf(stderr, "%s: You must specify a signature file with -f.\n",
+ progName);
+
+ print_usage:
+ if (cipherInfo) {
+ PORT_Free(cipherInfo);
+ }
+ Usage();
+ }
+
+ if (bltest.options[opt_MonteCarlo].activated) {
+ cipherInfo->mCarlo = PR_TRUE;
+ } else {
+ cipherInfo->mCarlo = PR_FALSE;
+ }
+
+ for (curThrdNum = 0; curThrdNum < threads; curThrdNum++) {
+ int keysize = 0;
+ PRFileDesc *file = NULL, *infile;
+ bltestParams *params;
+ char *instr = NULL;
+ PLArenaPool *arena;
+
+ if (curThrdNum > 0) {
+ bltestCipherInfo *newCInfo = PORT_ZNew(bltestCipherInfo);
+ if (!newCInfo) {
+ fprintf(stderr, "%s: Can not allocate memory.\n", progName);
+ goto exit_point;
+ }
+ newCInfo->mode = cipherInfo->mode;
+ newCInfo->mCarlo = cipherInfo->mCarlo;
+ newCInfo->repetitionsToPerfom =
+ cipherInfo->repetitionsToPerfom;
+ newCInfo->seconds = cipherInfo->seconds;
+ newCInfo->cxreps = cipherInfo->cxreps;
+ cipherInfo->next = newCInfo;
+ cipherInfo = newCInfo;
+ }
+ arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ fprintf(stderr, "%s: Can not allocate memory.\n", progName);
+ goto exit_point;
+ }
+ cipherInfo->arena = arena;
+ params = &cipherInfo->params;
+
+ /* Set up an encryption key. */
+ keysize = 0;
+ file = NULL;
+ if (is_symmkeyCipher(cipherInfo->mode) ||
+ is_aeadCipher(cipherInfo->mode)) {
+ char *keystr = NULL; /* if key is on command line */
+ if (bltest.options[opt_Key].activated) {
+ if (bltest.options[opt_CmdLine].activated) {
+ keystr = bltest.options[opt_Key].arg;
+ } else {
+ file = PR_Open(bltest.options[opt_Key].arg,
+ PR_RDONLY, 00660);
+ }
+ } else {
+ if (bltest.options[opt_KeySize].activated)
+ keysize = PORT_Atoi(bltest.options[opt_KeySize].arg);
+ else
+ keysize = 8; /* use 64-bit default (DES) */
+ /* save the random key for reference */
+ file = PR_Open("tmp.key", PR_WRONLY | PR_CREATE_FILE, 00660);
+ }
+ params->key.mode = ioMode;
+ setupIO(cipherInfo->arena, ¶ms->key, file, keystr, keysize);
+ if (file)
+ PR_Close(file);
+ } else if (is_pubkeyCipher(cipherInfo->mode)) {
+ if (bltest.options[opt_Key].activated) {
+ file = PR_Open(bltest.options[opt_Key].arg, PR_RDONLY, 00660);
+ } else {
+ if (bltest.options[opt_KeySize].activated)
+ keysize = PORT_Atoi(bltest.options[opt_KeySize].arg);
+ else
+ keysize = 64; /* use 512-bit default */
+ file = PR_Open("tmp.key", PR_WRONLY | PR_CREATE_FILE, 00660);
+ }
+ params->key.mode = bltestBase64Encoded;
+#ifndef NSS_DISABLE_ECC
+ pubkeyInitKey(cipherInfo, file, keysize, exponent, curveName);
+#else
+ pubkeyInitKey(cipherInfo, file, keysize, exponent);
+#endif
+ PR_Close(file);
+ }
+
+ /* set up an initialization vector. */
+ if (cipher_requires_IV(cipherInfo->mode)) {
+ char *ivstr = NULL;
+ bltestSymmKeyParams *skp;
+ file = NULL;
+#ifdef NSS_SOFTOKEN_DOES_RC5
+ if (cipherInfo->mode == bltestRC5_CBC)
+ skp = (bltestSymmKeyParams *)¶ms->rc5;
+ else
+#endif
+ skp = ¶ms->sk;
+ if (bltest.options[opt_IV].activated) {
+ if (bltest.options[opt_CmdLine].activated) {
+ ivstr = bltest.options[opt_IV].arg;
+ } else {
+ file = PR_Open(bltest.options[opt_IV].arg,
+ PR_RDONLY, 00660);
+ }
+ } else {
+ /* save the random iv for reference */
+ file = PR_Open("tmp.iv", PR_WRONLY | PR_CREATE_FILE, 00660);
+ }
+ memset(&skp->iv, 0, sizeof skp->iv);
+ skp->iv.mode = ioMode;
+ setupIO(cipherInfo->arena, &skp->iv, file, ivstr, keysize);
+ if (file) {
+ PR_Close(file);
+ }
+ }
+
+ /* set up an initialization vector. */
+ if (is_authCipher(cipherInfo->mode)) {
+ char *aadstr = NULL;
+ bltestAuthSymmKeyParams *askp;
+ file = NULL;
+ askp = ¶ms->ask;
+ if (bltest.options[opt_AAD].activated) {
+ if (bltest.options[opt_CmdLine].activated) {
+ aadstr = bltest.options[opt_AAD].arg;
+ } else {
+ file = PR_Open(bltest.options[opt_AAD].arg,
+ PR_RDONLY, 00660);
+ }
+ } else {
+ file = NULL;
+ }
+ memset(&askp->aad, 0, sizeof askp->aad);
+ askp->aad.mode = ioMode;
+ setupIO(cipherInfo->arena, &askp->aad, file, aadstr, 0);
+ if (file) {
+ PR_Close(file);
+ }
+ }
+
+ if (bltest.commands[cmd_Verify].activated) {
+ file = PR_Open(bltest.options[opt_SigFile].arg, PR_RDONLY, 00660);
+ if (is_sigCipher(cipherInfo->mode)) {
+ memset(¶ms->asymk.sig, 0, sizeof(bltestIO));
+ params->asymk.sig.mode = ioMode;
+ setupIO(cipherInfo->arena, ¶ms->asymk.sig, file, NULL, 0);
+ }
+ if (file) {
+ PR_Close(file);
+ }
+ }
+
+ if (bltest.options[opt_PQGFile].activated) {
+ file = PR_Open(bltest.options[opt_PQGFile].arg, PR_RDONLY, 00660);
+ params->asymk.cipherParams.dsa.pqgdata.mode = bltestBase64Encoded;
+ setupIO(cipherInfo->arena, ¶ms->asymk.cipherParams.dsa.pqgdata,
+ file, NULL, 0);
+ if (file) {
+ PR_Close(file);
+ }
+ }
+
+ /* Set up the input buffer */
+ if (bltest.options[opt_Input].activated) {
+ if (bltest.options[opt_CmdLine].activated) {
+ instr = bltest.options[opt_Input].arg;
+ infile = NULL;
+ } else {
+ /* form file name from testdir and input arg. */
+ char *filename = bltest.options[opt_Input].arg;
+ if (bltest.options[opt_SelfTestDir].activated &&
+ testdir && filename && filename[0] != '/') {
+ filename = PR_smprintf("%s/tests/%s/%s", testdir,
+ mode_strings[cipherInfo->mode],
+ filename);
+ if (!filename) {
+ fprintf(stderr, "%s: Can not allocate memory.\n",
+ progName);
+ goto exit_point;
+ }
+ infile = PR_Open(filename, PR_RDONLY, 00660);
+ PR_smprintf_free(filename);
+ } else {
+ infile = PR_Open(filename, PR_RDONLY, 00660);
+ }
+ }
+ } else if (bltest.options[opt_BufSize].activated) {
+ /* save the random plaintext for reference */
+ char *tmpFName = PR_smprintf("tmp.in.%d", curThrdNum);
+ if (!tmpFName) {
+ fprintf(stderr, "%s: Can not allocate memory.\n", progName);
+ goto exit_point;
+ }
+ infile = PR_Open(tmpFName, PR_WRONLY | PR_CREATE_FILE, 00660);
+ PR_smprintf_free(tmpFName);
+ } else {
+ infile = PR_STDIN;
+ }
+ if (!infile) {
+ fprintf(stderr, "%s: Failed to open input file.\n", progName);
+ goto exit_point;
+ }
+ cipherInfo->input.mode = ioMode;
+
+ /* Set up the output stream */
+ if (bltest.options[opt_Output].activated) {
+ /* form file name from testdir and input arg. */
+ char *filename = bltest.options[opt_Output].arg;
+ if (bltest.options[opt_SelfTestDir].activated &&
+ testdir && filename && filename[0] != '/') {
+ filename = PR_smprintf("%s/tests/%s/%s", testdir,
+ mode_strings[cipherInfo->mode],
+ filename);
+ if (!filename) {
+ fprintf(stderr, "%s: Can not allocate memory.\n", progName);
+ goto exit_point;
+ }
+ outfile = PR_Open(filename, PR_WRONLY | PR_CREATE_FILE, 00660);
+ PR_smprintf_free(filename);
+ } else {
+ outfile = PR_Open(filename, PR_WRONLY | PR_CREATE_FILE, 00660);
+ }
+ } else {
+ outfile = PR_STDOUT;
+ }
+ if (!outfile) {
+ fprintf(stderr, "%s: Failed to open output file.\n", progName);
+ rv = SECFailure;
+ goto exit_point;
+ }
+ cipherInfo->output.mode = ioMode;
+ if (bltest.options[opt_SelfTestDir].activated && ioMode == bltestBinary)
+ cipherInfo->output.mode = bltestBase64Encoded;
+
+ if (is_hashCipher(cipherInfo->mode))
+ cipherInfo->params.hash.restart =
+ bltest.options[opt_Restart].activated;
+
+ bufsize = 0;
+ if (bltest.options[opt_BufSize].activated)
+ bufsize = PORT_Atoi(bltest.options[opt_BufSize].arg);
+
+ /*infile = NULL;*/
+ setupIO(cipherInfo->arena, &cipherInfo->input, infile, instr, bufsize);
+ if (infile && infile != PR_STDIN)
+ PR_Close(infile);
+ misalignBuffer(cipherInfo->arena, &cipherInfo->input, inoff);
+
+ cipherInit(cipherInfo, bltest.commands[cmd_Encrypt].activated);
+ misalignBuffer(cipherInfo->arena, &cipherInfo->output, outoff);
+ }
+
+ if (!bltest.commands[cmd_Nonce].activated) {
+ TIMESTART();
+ cipherInfo = cipherInfoListHead;
+ while (cipherInfo != NULL) {
+ cipherInfo->cipherThread =
+ PR_CreateThread(PR_USER_THREAD,
+ ThreadExecTest,
+ cipherInfo,
+ PR_PRIORITY_NORMAL,
+ PR_GLOBAL_THREAD,
+ PR_JOINABLE_THREAD,
+ 0);
+ cipherInfo = cipherInfo->next;
+ }
+
+ cipherInfo = cipherInfoListHead;
+ while (cipherInfo != NULL) {
+ PR_JoinThread(cipherInfo->cipherThread);
+ finishIO(&cipherInfo->output, outfile);
+ cipherInfo = cipherInfo->next;
+ }
+ TIMEFINISH(totalTime, 1);
+ }
+
+ cipherInfo = cipherInfoListHead;
+ if (cipherInfo->repetitions > 0 || cipherInfo->cxreps > 0 ||
+ threads > 1)
+ dump_performance_info(cipherInfoListHead, totalTime,
+ bltest.commands[cmd_Encrypt].activated,
+ (cipherInfo->repetitions == 0));
+
+ rv = SECSuccess;
+
+exit_point:
+ if (outfile && outfile != PR_STDOUT)
+ PR_Close(outfile);
+ cipherInfo = cipherInfoListHead;
+ while (cipherInfo != NULL) {
+ bltestCipherInfo *tmpInfo = cipherInfo;
+
+ if (cipherInfo->arena)
+ PORT_FreeArena(cipherInfo->arena, PR_TRUE);
+ cipherInfo = cipherInfo->next;
+ PORT_Free(tmpInfo);
+ }
+
+ /*NSS_Shutdown();*/
+
+ return SECSuccess;
+}
diff --git a/nss/cmd/bltest/bltest.gyp b/nss/cmd/bltest/bltest.gyp
new file mode 100644
index 0000000..7139c31
--- /dev/null
+++ b/nss/cmd/bltest/bltest.gyp
@@ -0,0 +1,35 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi',
+ '../../cmd/platlibs.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'bltest',
+ 'type': 'executable',
+ 'sources': [
+ 'blapitest.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:dbm_exports',
+ '<(DEPTH)/exports.gyp:nss_exports',
+ '<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3'
+ ]
+ }
+ ],
+ 'target_defaults': {
+ 'include_dirs': [
+ '../../nss/lib/softoken'
+ ],
+ 'defines': [
+ 'NSS_USE_STATIC_LIBS'
+ ]
+ },
+ 'variables': {
+ 'module': 'nss',
+ 'use_static_libs': 1
+ }
+}
\ No newline at end of file
diff --git a/nss/cmd/bltest/manifest.mn b/nss/cmd/bltest/manifest.mn
new file mode 100644
index 0000000..6e9946c
--- /dev/null
+++ b/nss/cmd/bltest/manifest.mn
@@ -0,0 +1,26 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+CORE_DEPTH = ../..
+
+MODULE = nss
+
+REQUIRES = seccmd dbm softoken
+
+INCLUDES += -I$(CORE_DEPTH)/nss/lib/softoken
+
+PROGRAM = bltest
+
+ USE_STATIC_LIBS = 1
+
+EXPORTS = \
+ $(NULL)
+
+PRIVATE_EXPORTS = \
+ $(NULL)
+
+CSRCS = \
+ blapitest.c \
+ $(NULL)
+
diff --git a/nss/cmd/bltest/pkcs1_vectors.h b/nss/cmd/bltest/pkcs1_vectors.h
new file mode 100644
index 0000000..0672967
--- /dev/null
+++ b/nss/cmd/bltest/pkcs1_vectors.h
@@ -0,0 +1,789 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* Vectors from pkcs1v15sign-vectors.txt */
+
+struct pkcs1_test_vector {
+ unsigned char *n;
+ unsigned long n_len;
+ unsigned char *e;
+ unsigned long e_len;
+ unsigned char *d;
+ unsigned long d_len;
+ unsigned char *p;
+ unsigned long p_len;
+ unsigned char *q;
+ unsigned long q_len;
+};
+
+struct pkcs1_test_vector PKCS1_VECTORS[15] = {
+ {
+ (unsigned char[]){
+ 0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+ 0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+ 0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+ 0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+ 0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+ 0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+ 0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+ 0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+ 0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+ 0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+ 0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+ 0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+ 0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+ 128,
+ (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+ (unsigned char[]){
+ 0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+ 0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+ 0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+ 0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+ 0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+ 0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+ 0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+ 0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+ 0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+ 0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+ 0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+ 0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+ 0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+ 128,
+ (unsigned char[]){
+ 0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+ 0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+ 0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+ 0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+ 0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+ 0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+ 0x9a, 0x67, 0x99, 0xfd },
+ 64,
+ (unsigned char[]){
+ 0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+ 0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+ 0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+ 0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+ 0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+ 0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+ 0xda, 0x8e, 0x64, 0x43 },
+ 64,
+ },
+ {
+ (unsigned char[]){
+ 0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+ 0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+ 0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+ 0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+ 0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+ 0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+ 0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+ 0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+ 0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+ 0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+ 0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+ 0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+ 0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+ 128,
+ (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+ (unsigned char[]){
+ 0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+ 0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+ 0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+ 0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+ 0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+ 0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+ 0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+ 0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+ 0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+ 0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+ 0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+ 0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+ 0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+ 128,
+ (unsigned char[]){
+ 0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+ 0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+ 0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+ 0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+ 0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+ 0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+ 0x9a, 0x67, 0x99, 0xfd },
+ 64,
+ (unsigned char[]){
+ 0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+ 0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+ 0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+ 0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+ 0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+ 0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+ 0xda, 0x8e, 0x64, 0x43 },
+ 64,
+ },
+ {
+ (unsigned char[]){
+ 0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+ 0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+ 0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+ 0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+ 0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+ 0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+ 0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+ 0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+ 0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+ 0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+ 0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+ 0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+ 0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+ 128,
+ (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+ (unsigned char[]){
+ 0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+ 0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+ 0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+ 0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+ 0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+ 0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+ 0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+ 0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+ 0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+ 0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+ 0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+ 0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+ 0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+ 128,
+ (unsigned char[]){
+ 0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+ 0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+ 0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+ 0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+ 0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+ 0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+ 0x9a, 0x67, 0x99, 0xfd },
+ 64,
+ (unsigned char[]){
+ 0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+ 0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+ 0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+ 0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+ 0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+ 0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+ 0xda, 0x8e, 0x64, 0x43 },
+ 64,
+ },
+ {
+ (unsigned char[]){
+ 0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+ 0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+ 0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+ 0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+ 0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+ 0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+ 0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+ 0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+ 0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+ 0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+ 0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+ 0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+ 0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+ 128,
+ (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+ (unsigned char[]){
+ 0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+ 0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+ 0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+ 0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+ 0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+ 0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+ 0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+ 0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+ 0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+ 0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+ 0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+ 0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+ 0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+ 128,
+ (unsigned char[]){
+ 0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+ 0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+ 0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+ 0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+ 0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+ 0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+ 0x9a, 0x67, 0x99, 0xfd },
+ 64,
+ (unsigned char[]){
+ 0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+ 0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+ 0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+ 0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+ 0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+ 0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+ 0xda, 0x8e, 0x64, 0x43 },
+ 64,
+ },
+ {
+ (unsigned char[]){
+ 0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+ 0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+ 0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+ 0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+ 0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+ 0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+ 0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+ 0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+ 0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+ 0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+ 0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+ 0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+ 0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+ 128,
+ (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+ (unsigned char[]){
+ 0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+ 0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+ 0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+ 0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+ 0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+ 0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+ 0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+ 0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+ 0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+ 0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+ 0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+ 0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+ 0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+ 128,
+ (unsigned char[]){
+ 0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+ 0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+ 0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+ 0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+ 0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+ 0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+ 0x9a, 0x67, 0x99, 0xfd },
+ 64,
+ (unsigned char[]){
+ 0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+ 0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+ 0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+ 0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+ 0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+ 0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+ 0xda, 0x8e, 0x64, 0x43 },
+ 64,
+ },
+ {
+ (unsigned char[]){
+ 0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+ 0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+ 0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+ 0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+ 0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+ 0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+ 0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+ 0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+ 0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+ 0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+ 0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+ 0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+ 0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+ 128,
+ (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+ (unsigned char[]){
+ 0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+ 0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+ 0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+ 0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+ 0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+ 0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+ 0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+ 0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+ 0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+ 0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+ 0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+ 0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+ 0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+ 128,
+ (unsigned char[]){
+ 0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+ 0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+ 0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+ 0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+ 0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+ 0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+ 0x9a, 0x67, 0x99, 0xfd },
+ 64,
+ (unsigned char[]){
+ 0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+ 0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+ 0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+ 0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+ 0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+ 0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+ 0xda, 0x8e, 0x64, 0x43 },
+ 64,
+ },
+ {
+ (unsigned char[]){
+ 0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+ 0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+ 0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+ 0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+ 0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+ 0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+ 0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+ 0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+ 0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+ 0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+ 0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+ 0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+ 0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+ 128,
+ (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+ (unsigned char[]){
+ 0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+ 0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+ 0x88, 0x43, 0x40, 0xae, 0xf9, 0x88,
+ 0x5f, 0x2a, 0x4b, 0xbe, 0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac,
+
+ 0x3c, 0x56, 0x8c, 0x8f, 0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02,
+
+ 0x66, 0xc8, 0xc6, 0xa3, 0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1,
+ 0x12, 0x31, 0x88, 0x44, 0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f,
+ 0xee, 0x89, 0x6a, 0x10, 0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7,
+ 0x34, 0xe4, 0x47, 0x27, 0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53,
+ 0x26, 0x83, 0x10, 0x9c, 0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c,
+ 0x31, 0xb4, 0xbd, 0x2f, 0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52,
+ 0xce, 0xe3, 0x4f, 0x9e, 0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22,
+ 0xad, 0x79, 0xc6, 0xdc, 0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3,
+ 0xb3, 0x25 },
+ 128,
+ (unsigned char[]){
+ 0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+ 0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+ 0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+ 0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+ 0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+ 0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+ 0x9a, 0x67, 0x99, 0xfd },
+ 64,
+ (unsigned char[]){
+ 0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+ 0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+ 0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+ 0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+ 0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+ 0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+ 0xda, 0x8e, 0x64, 0x43 },
+ 64,
+ },
+ {
+ (unsigned char[]){
+ 0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+ 0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+ 0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+ 0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+ 0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+ 0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+ 0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+ 0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+ 0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+ 0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+ 0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+ 0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+ 0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+ 128,
+ (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+ (unsigned char[]){
+ 0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+ 0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+ 0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+ 0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+ 0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+ 0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+ 0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+ 0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+ 0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+ 0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+ 0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+ 0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+ 0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+ 128,
+ (unsigned char[]){
+ 0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+ 0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+ 0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+ 0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+ 0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+ 0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+ 0x9a, 0x67, 0x99, 0xfd },
+ 64,
+ (unsigned char[]){
+ 0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+ 0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+ 0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+ 0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+ 0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+ 0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+ 0xda, 0x8e, 0x64, 0x43 },
+ 64,
+ },
+ {
+ (unsigned char[]){
+ 0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+ 0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+ 0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+ 0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+ 0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+ 0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+ 0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+ 0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+ 0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+ 0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+ 0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+ 0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+ 0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+ 128,
+ (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+ (unsigned char[]){
+ 0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+ 0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+ 0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+ 0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+ 0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+ 0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+ 0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+ 0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+ 0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+ 0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+ 0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+ 0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+ 0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+ 128,
+ (unsigned char[]){
+ 0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+ 0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+ 0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+ 0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+ 0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+ 0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+ 0x9a, 0x67, 0x99, 0xfd },
+ 64,
+ (unsigned char[]){
+ 0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+ 0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+ 0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+ 0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+ 0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+ 0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+ 0xda, 0x8e, 0x64, 0x43 },
+ 64,
+ },
+ {
+ (unsigned char[]){
+ 0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+ 0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+ 0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+ 0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+ 0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+ 0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+ 0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+ 0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+ 0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+ 0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+ 0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+ 0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+ 0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+ 128,
+ (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+ (unsigned char[]){
+ 0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+ 0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+ 0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+ 0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+ 0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+ 0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+ 0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+ 0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+ 0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+ 0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+ 0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+ 0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+ 0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+ 128,
+ (unsigned char[]){
+ 0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+ 0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+ 0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+ 0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+ 0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+ 0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+ 0x9a, 0x67, 0x99, 0xfd },
+ 64,
+ (unsigned char[]){
+ 0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+ 0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+ 0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+ 0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+ 0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+ 0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+ 0xda, 0x8e, 0x64, 0x43 },
+ 64,
+ },
+ {
+ (unsigned char[]){
+ 0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+ 0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+ 0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+ 0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+ 0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+ 0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+ 0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+ 0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+ 0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+ 0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+ 0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+ 0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+ 0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+ 128,
+ (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+ (unsigned char[]){
+ 0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+ 0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+ 0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+ 0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+ 0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+ 0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+ 0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+ 0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+ 0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+ 0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+ 0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+ 0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+ 0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+ 128,
+ (unsigned char[]){
+ 0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+ 0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+ 0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+ 0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+ 0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+ 0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+ 0x9a, 0x67, 0x99, 0xfd },
+ 64,
+ (unsigned char[]){
+ 0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+ 0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+ 0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+ 0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+ 0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+ 0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+ 0xda, 0x8e, 0x64, 0x43 },
+ 64,
+ },
+ {
+ (unsigned char[]){
+ 0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+ 0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+ 0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+ 0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+ 0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+ 0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+ 0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+ 0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+ 0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+ 0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+ 0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+ 0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+ 0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+ 128,
+ (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+ (unsigned char[]){
+ 0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+ 0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+ 0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+ 0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+ 0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+ 0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+ 0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+ 0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+ 0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+ 0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+ 0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+ 0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+ 0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+ 128,
+ (unsigned char[]){
+ 0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+ 0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+ 0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+ 0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+ 0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+ 0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+ 0x9a, 0x67, 0x99, 0xfd },
+ 64,
+ (unsigned char[]){
+ 0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+ 0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+ 0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+ 0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+ 0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+ 0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+ 0xda, 0x8e, 0x64, 0x43 },
+ 64,
+ },
+ {
+ (unsigned char[]){
+ 0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+ 0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+ 0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+ 0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+ 0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+ 0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+ 0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+ 0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+ 0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+ 0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+ 0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+ 0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+ 0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+ 128,
+ (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+ (unsigned char[]){
+ 0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+ 0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+ 0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+ 0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+ 0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+ 0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+ 0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+ 0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+ 0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+ 0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+ 0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+ 0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+ 0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+ 128,
+ (unsigned char[]){
+ 0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+ 0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+ 0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+ 0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+ 0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+ 0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+ 0x9a, 0x67, 0x99, 0xfd },
+ 64,
+ (unsigned char[]){
+ 0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+ 0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+ 0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+ 0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+ 0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+ 0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+ 0xda, 0x8e, 0x64, 0x43 },
+ 64,
+ },
+ {
+ (unsigned char[]){
+ 0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+ 0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+ 0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+ 0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+ 0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+ 0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+ 0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+ 0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+ 0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+ 0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+ 0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+ 0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+ 0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+ 128,
+ (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+ (unsigned char[]){
+ 0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+ 0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+ 0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+ 0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+ 0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+ 0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+ 0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+ 0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+ 0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+ 0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+ 0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+ 0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+ 0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+ 128,
+ (unsigned char[]){
+ 0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+ 0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+ 0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+ 0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+ 0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+ 0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+ 0x9a, 0x67, 0x99, 0xfd },
+ 64,
+ (unsigned char[]){
+ 0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+ 0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+ 0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+ 0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+ 0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+ 0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+ 0xda, 0x8e, 0x64, 0x43 },
+ 64,
+ },
+ {
+ (unsigned char[]){
+ 0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
+ 0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e,
+ 0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a,
+ 0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
+ 0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf,
+ 0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
+ 0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d,
+ 0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
+ 0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59,
+ 0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3,
+ 0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f,
+ 0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
+ 0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37 },
+ 128,
+ (unsigned char[]){ 0x01, 0x00, 0x01 }, 3,
+ (unsigned char[]){
+ 0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51,
+ 0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf,
+ 0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe,
+ 0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
+ 0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8, 0xc6, 0xa3,
+ 0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
+ 0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10,
+ 0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
+ 0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c,
+ 0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c, 0x31, 0xb4, 0xbd, 0x2f,
+ 0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e,
+ 0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
+ 0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25 },
+ 128,
+ (unsigned char[]){
+ 0xb6, 0x9d, 0xca, 0x1c, 0xf7, 0xd4, 0xd7, 0xec, 0x81, 0xe7,
+ 0x5b, 0x90, 0xfc, 0xca, 0x87, 0x4a, 0xbc, 0xde, 0x12, 0x3f,
+ 0xd2, 0x70, 0x01, 0x80, 0xaa, 0x90, 0x47, 0x9b, 0x6e, 0x48,
+ 0xde, 0x8d, 0x67, 0xed, 0x24, 0xf9, 0xf1, 0x9d, 0x85, 0xba,
+ 0x27, 0x58, 0x74, 0xf5, 0x42, 0xcd, 0x20, 0xdc, 0x72, 0x3e,
+ 0x69, 0x63, 0x36, 0x4a, 0x1f, 0x94, 0x25, 0x45, 0x2b, 0x26,
+ 0x9a, 0x67, 0x99, 0xfd },
+ 64,
+ (unsigned char[]){
+ 0xe7, 0xe8, 0x94, 0x27, 0x20, 0xa8, 0x77, 0x51, 0x72, 0x73,
+ 0xa3, 0x56, 0x05, 0x3e, 0xa2, 0xa1, 0xbc, 0x0c, 0x94, 0xaa,
+ 0x72, 0xd5, 0x5c, 0x6e, 0x86, 0x29, 0x6b, 0x2d, 0xfc, 0x96,
+ 0x79, 0x48, 0xc0, 0xa7, 0x2c, 0xbc, 0xcc, 0xa7, 0xea, 0xcb,
+ 0x35, 0x70, 0x6e, 0x09, 0xa1, 0xdf, 0x55, 0xa1, 0x53, 0x5b,
+ 0xd9, 0xb3, 0xcc, 0x34, 0x16, 0x0b, 0x3b, 0x6d, 0xcd, 0x3e,
+ 0xda, 0x8e, 0x64, 0x43 },
+ 64,
+ }
+};
diff --git a/nss/cmd/bltest/tests/README b/nss/cmd/bltest/tests/README
new file mode 100644
index 0000000..6d1302b
--- /dev/null
+++ b/nss/cmd/bltest/tests/README
@@ -0,0 +1,56 @@
+This directory contains a set of tests for each cipher supported by
+BLAPI. Each subdirectory contains known plaintext and ciphertext pairs
+(and keys and/or iv's if needed). The tests can be run as a full set
+with:
+ bltest -T
+or as subsets, for example:
+ bltest -T -m des_ecb,md2,rsa
+
+In each subdirectory, the plaintext, key, and iv are ascii, and treated
+as such. The ciphertext is base64-encoded to avoid the hassle of binary
+files.
+
+To add a test, incremement the value in the numtests file. Create a
+plaintext, key, and iv file, such that the name of the file is
+incrememted one from the last set of tests. For example, if you are
+adding the second test, put your data in files named plaintext1, key1,
+and iv1 (ignoring key and iv if they are not needed, of course). Make
+sure your key and iv are the correct number of bytes for your cipher (a
+trailing \n is okay, but any other trailing bytes will be used!). Once
+you have your input data, create output data by running bltest on a
+trusted implementation. For example, for a new DES ECB test, run
+ bltest -E -m des_ecb -i plaintext1 -k key1 -o ciphertext1 -a in the
+tests/des_ecb directory. Then run
+ bltest -T des_ecb from the cmd/bltest directory in the tree of the
+implementation you want to test.
+
+Note that the -a option above is important, it tells bltest to expect
+the input to be straight ASCII, and not base64 encoded binary!
+
+Special cases:
+
+RC5:
+RC5 can take additional parameters, the number of rounds to perform and
+the wordsize to use. The number of rounds is between is between 0 and
+255, and the wordsize is either is either 16, 32, or 64 bits (at this
+time only 32-bit is supported). These parameters are specified in a
+paramsN file, where N is an index as above. The format of the file is
+"rounds=R\nwordsize=W\n".
+
+public key modes (RSA and DSA):
+Asymmetric key ciphers use keys with special properties, so creating a
+key file with "Mozilla!" in it will not get you very far! To create a
+public key, run bltest with the plaintext you want to encrypt, using a
+trusted implementation. bltest will generate a key and store it in
+"tmp.key", rename that file to keyN. For example:
+ bltest -E -m rsa -i plaintext0 -o ciphertext0 -e 65537 -g 32 -a
+ mv tmp.key key0
+
+RSA-OAEP/RSA-PSS:
+RSA-OAEP and RSA-PSS have a number of additional parameters to feed in.
+- "seedN": The seed or salt to use when encrypting/signing
+- "hashN" / "maskhashN" - The base digest algorithm and the digest algorithm
+ to use with MGF1, respectively. This should be an ASCII string specifying
+ one of the hash algorithms recognized by bltest (eg: "sha1", "sha256")
+
+[note: specifying a keysize (-g) when using RSA is important!]
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext0 b/nss/cmd/bltest/tests/aes_cbc/ciphertext0
new file mode 100644
index 0000000..4da9e52
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext0
@@ -0,0 +1 @@
+oJLgOzZ1GiWt3DGo2sPKaOnyGuRz5sZwmDyn4dvAqd8=
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext1 b/nss/cmd/bltest/tests/aes_cbc/ciphertext1
new file mode 100644
index 0000000..1126bbf
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext1
@@ -0,0 +1 @@
+AzZ2PpZtkllaVnzJzlN/Xg==
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext10 b/nss/cmd/bltest/tests/aes_cbc/ciphertext10
new file mode 100644
index 0000000..c3d443f
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext10
@@ -0,0 +1,3 @@
+eykx9YVfcXFF4A8VKp9HlDWbH/yz5V9ZTjMJi1HCOmx0oGwdlP3tf9KuQsfbesrv
+WETLM67dxoUlhe0AIKZpnSy1OAnO/RaRSM5CKSr6sGNEOXgwbFgsGLnODaPQhM5N
+PEgs/Y/PGoUITon7iLQKCE1elyRm0HZmEm+3YfhAePI=
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext11 b/nss/cmd/bltest/tests/aes_cbc/ciphertext11
new file mode 100644
index 0000000..ae00d8b
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext11
@@ -0,0 +1,3 @@
+sJUS8+/57Q2FiQmDpz2tu3w2eNUlgb5kqKj8WG9JDyUhKXpHigWYBA69D1UJ+vsJ
+afnZ5gDq7zOxuT7tmWh7Fn+JpQZarEOc5G87jSLTCGXmTkXvjNMLaYQ1OoRKEcjN
+YNug6IZrPuMNJLP6imQ7MoNT4GAQ+oJzyP1U7woraTDlUgquXNWQL5uGozWSykNl
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext12 b/nss/cmd/bltest/tests/aes_cbc/ciphertext12
new file mode 100644
index 0000000..605a1ba
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext12
@@ -0,0 +1,4 @@
+a+ihKABFWjIFOIU+DLoxvS2A6gyFFkpMXCYa5IVBfZPv/i68DQoLUdbqGGM9IQz2
+PAxN28J2B/LoHtkRMZHvhtVvO5m+bEFaQVApn7hGznFgtAtjuvEXnRknWi6DaYN2
+0ouSVIxo4G5tmU4sFQHtKXAU5wLN7+4vZWRHcGAJYU2AHeHKr3P4t/pWzxupS2MZ
+M7vld2JDgIUPEXQ1oDVbKw==
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext13 b/nss/cmd/bltest/tests/aes_cbc/ciphertext13
new file mode 100644
index 0000000..2abf369
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext13
@@ -0,0 +1 @@
+UdRHefkNQKgASCdsA1y0nKKke8ubnPcnC5FEeTeH1T8=
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext14 b/nss/cmd/bltest/tests/aes_cbc/ciphertext14
new file mode 100644
index 0000000..f16428a
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext14
@@ -0,0 +1,2 @@
+1fVYl2C/nHYiKP3iNt4fot0trUSNs/qb4MQZbv1Go1yE3RrHfZ21jJWRjLMXpkMK
+CNL7ao6LDxybcsejRNw0nw==
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext15 b/nss/cmd/bltest/tests/aes_cbc/ciphertext15
new file mode 100644
index 0000000..ed1cecd
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext15
@@ -0,0 +1,2 @@
+dTlZdL0ys2ZWVKbI45a4iuNLEjV1hyp6tofY52tG35EailkM0B0vXDML46Zibp3T
+ql4Q7RTo/4KYEbb+1Q8/UzykOFocvKePXEdE5Q8vg1kWXCSF0TJOdsPq52oMysYp
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext16 b/nss/cmd/bltest/tests/aes_cbc/ciphertext16
new file mode 100644
index 0000000..8fa8952
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext16
@@ -0,0 +1,3 @@
+gVjiFCDyW1nWrpQ/ocvyHwLpefQZ2rASanIbfu9Vvumtl/XM/30jkFe7wZqMN4FC
+92cvHV5+F9e+vLAHDoNVys5mYBcaU7YYFq6CSm72nORwtv/TtbtLQ4h02R0nhU07
+byWGDTholY3jMH1isTOb3duKMYwM4PM8F8rw6fYECCA=
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext17 b/nss/cmd/bltest/tests/aes_cbc/ciphertext17
new file mode 100644
index 0000000..8ca864c
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext17
@@ -0,0 +1,3 @@
+km2ySMwbog8MV2MafIrvCU95GTe5BZSeNGAkDov6b6SDEVobMQtuQ2nK68UmKIg3
+ex3apYAOpJaivf8PmhAx5xKcmiDjViHn8Li6yg2HAw8q58qFk8hZlnegb9SyYAnq
+0I/srCTKqc8srTtHDIInQVp7Hg8uqz+tltcKIJyLsmxidnfiUxuUNcpuPERNGVtf
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext18 b/nss/cmd/bltest/tests/aes_cbc/ciphertext18
new file mode 100644
index 0000000..9b42740
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext18
@@ -0,0 +1,4 @@
+yCzyxHbeqMtqbmB6QNLwORvoLqnshKU3poIPmvuZe3Y5fQBUJPqmp03E6MeqSokA
+aQ+JS20dyoBnU5PSJDrax2LxWTAeNX6YtyR2IxDNWnuv4cKgMNukb9k6n9uJzBMs
+qcF9xyAx7Ggi7lqdmdvKZseEwBsIhcu2LinZeAGSfsQVpdIVFY0yX57miUN60bdo
+StM8DZJzlFGsh/Of+MMbhA==
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext19 b/nss/cmd/bltest/tests/aes_cbc/ciphertext19
new file mode 100644
index 0000000..39bf937
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext19
@@ -0,0 +1 @@
+L6Dfciqf07ZMsY+ys9tV/yJnQidXKJQT+PZXUHQSpkw=
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext2 b/nss/cmd/bltest/tests/aes_cbc/ciphertext2
new file mode 100644
index 0000000..ec069ab
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext2
@@ -0,0 +1 @@
+qaFjG/SZaVTrwJOVeyNFiQ==
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext20 b/nss/cmd/bltest/tests/aes_cbc/ciphertext20
new file mode 100644
index 0000000..d74f0e0
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext20
@@ -0,0 +1,2 @@
+BdXHdylCGwi3N+QRGfpEONH1cMx3Kk1sPff/7aA4TvhCiM43/ExMfRElpJmwUTZM
+OJ/WOb3aZH2qO9rasutVlA==
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext21 b/nss/cmd/bltest/tests/aes_cbc/ciphertext21
new file mode 100644
index 0000000..9f3b9ea
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext21
@@ -0,0 +1,2 @@
+rD1tuv4uD3QGMv2eggv2BEzVsVUcu5zAPAslw5zLfzO4Oqz8pAoyZfK7/4eRU0SK
+ysuI/Ps7t7EP5GOmjAEJ8Cg4Lj5VexrfAu1kira7iV3wIF0m67+ppf2M69jkvuPc
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext22 b/nss/cmd/bltest/tests/aes_cbc/ciphertext22
new file mode 100644
index 0000000..b9b5b5c
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext22
@@ -0,0 +1,3 @@
+kLe5YwojePU/UBq3vv8DkVUAgHG8hDjniZMs/T6xKZGVRl5mM4SUY/20Q3Unji/b
+ExCCHmSSz4D/Fct3JQn7Qm867uJ71JOIgv0q5rW9nZH6SkOxe7Q5675ZwEIxAWOo
+Kl/lOIeW7uNaGBoScfAL4puFLY+nWbrQH/RnjwEFlM0=
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext23 b/nss/cmd/bltest/tests/aes_cbc/ciphertext23
new file mode 100644
index 0000000..e7710c1
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext23
@@ -0,0 +1,3 @@
+AlSyNGO8q+xaOV63TI+w6xN6B7xvXp9h7AsFfeMFcU+PopQiHJGhWcMVk5uB4wDu
+kCGS7F8VJUQo2HcveTJOxDKYyiHACzcCc+5eXtkOQ++h4FpdFxIJ/jT58pI326Km
+cmZQ/TsTIXR9EgiGPGw8az4th5q18leC8Iuo8qu+Y+C+20oifoGvs2u2ZFUINW00
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext24 b/nss/cmd/bltest/tests/aes_cbc/ciphertext24
new file mode 100644
index 0000000..d5234aa
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext24
@@ -0,0 +1,4 @@
+/Fhz5Q3o+vTGuEunB7CFTp25qy6ffXB/u6M4xoQ6GPxvrOuvZj0mKW+zKbTSbxhJ
+THngnneWR/m6+odIljDXn0MBYQwjAMGdvzFIt8rIxPSUQQJ1TzMukrb3xedbxhee
+uHegeNRxkAkCF0TBTxP9KlWiucRNGAAGhahFpPYyx8VqdzBu+maiTQXQiNzXwT/i
+T8RHJ1ll255NN/vJMERIzQ==
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext3 b/nss/cmd/bltest/tests/aes_cbc/ciphertext3
new file mode 100644
index 0000000..82c4cd2
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext3
@@ -0,0 +1 @@
+J1z8BBPYzLcFE8OFmx0Pcg==
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext4 b/nss/cmd/bltest/tests/aes_cbc/ciphertext4
new file mode 100644
index 0000000..81714bd
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext4
@@ -0,0 +1 @@
+ybgTX/G1rcQT39BTshvZbQ==
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext5 b/nss/cmd/bltest/tests/aes_cbc/ciphertext5
new file mode 100644
index 0000000..ce9672a
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext5
@@ -0,0 +1 @@
+XJ2ETtRvmIUIXl1qT5TH1w==
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext6 b/nss/cmd/bltest/tests/aes_cbc/ciphertext6
new file mode 100644
index 0000000..fc53a4f
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext6
@@ -0,0 +1 @@
+qf91vXz2YT03Mcd8O20MBA==
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext7 b/nss/cmd/bltest/tests/aes_cbc/ciphertext7
new file mode 100644
index 0000000..1d6d84b
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext7
@@ -0,0 +1 @@
+xNxh2XJZZ6MCAQSpc48jhoUnzoOaqxdS/YvblagsTQA=
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext8 b/nss/cmd/bltest/tests/aes_cbc/ciphertext8
new file mode 100644
index 0000000..7191a64
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext8
@@ -0,0 +1,2 @@
+Gblgl3LGPzOGCL9utSyhC+ZQl/icHgkFxCQB/Ud5GuLFRAstRzEWyni9n/L7YBXP
+0xZSTq59y5Wuc46+roSkZw==
diff --git a/nss/cmd/bltest/tests/aes_cbc/ciphertext9 b/nss/cmd/bltest/tests/aes_cbc/ciphertext9
new file mode 100644
index 0000000..232a691
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/ciphertext9
@@ -0,0 +1,2 @@
+O4YRv8SXPFzY6YKwc7MxhM0mEQFZFy5EmI61/1ZhoeFvrWclj8v+5VRpJnoS3DdI
+k7TjUz029WNMMJVYNZbxNaqM0RONyJi8VlHuNakuv4mrautTZmU7xgpw4AdPwR7+
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv0 b/nss/cmd/bltest/tests/aes_cbc/iv0
new file mode 100644
index 0000000..4e65bc0
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/iv0
@@ -0,0 +1 @@
+qwertyuiopasdfgh
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv1 b/nss/cmd/bltest/tests/aes_cbc/iv1
new file mode 100644
index 0000000000000000000000000000000000000000..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
KcmZQzKm`B*5C8!H
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv10 b/nss/cmd/bltest/tests/aes_cbc/iv10
new file mode 100644
index 0000000..58d7a2d
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/iv10
@@ -0,0 +1 @@
+žù4”n\Ю—½XS,´“
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv11 b/nss/cmd/bltest/tests/aes_cbc/iv11
new file mode 100644
index 0000000..6847886
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/iv11
@@ -0,0 +1 @@
+$_&[vëëÂíÊÄ¢ø
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv12 b/nss/cmd/bltest/tests/aes_cbc/iv12
new file mode 100644
index 0000000..15040cd
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/iv12
@@ -0,0 +1 @@
+»ë/«´H¯„—–$J×
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv13 b/nss/cmd/bltest/tests/aes_cbc/iv13
new file mode 100644
index 0000000..1bef08a
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/iv13
@@ -0,0 +1 @@
+óÖf~My`÷P[£ƒë
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv14 b/nss/cmd/bltest/tests/aes_cbc/iv14
new file mode 100644
index 0000000..099828f
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/iv14
@@ -0,0 +1 @@
+‹YÉ œRœ¨9ŸÀÎ<8
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv15 b/nss/cmd/bltest/tests/aes_cbc/iv15
new file mode 100644
index 0000000..d7a44d9
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/iv15
@@ -0,0 +1 @@
+6긃¯ï“lÃc(FÍ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv16 b/nss/cmd/bltest/tests/aes_cbc/iv16
new file mode 100644
index 0000000..678bb8d
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/iv16
@@ -0,0 +1 @@
+ãțЗëÝöOHÛm¿â
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv17 b/nss/cmd/bltest/tests/aes_cbc/iv17
new file mode 100644
index 0000000..7ff21ab
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/iv17
@@ -0,0 +1 @@
+’¤(3ñE
¤½Æè<
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv18 b/nss/cmd/bltest/tests/aes_cbc/iv18
new file mode 100644
index 0000000..244b502
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/iv18
@@ -0,0 +1 @@
+$@€8,Êà{›¶cUÁ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv19 b/nss/cmd/bltest/tests/aes_cbc/iv19
new file mode 100644
index 0000000..919e165
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/iv19
@@ -0,0 +1 @@
+ýê¡4È×7EquýWÓü
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv2 b/nss/cmd/bltest/tests/aes_cbc/iv2
new file mode 100644
index 0000000000000000000000000000000000000000..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
KcmZQzKm`B*5C8!H
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv20 b/nss/cmd/bltest/tests/aes_cbc/iv20
new file mode 100644
index 0000000..c49bf8f
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/iv20
@@ -0,0 +1 @@
+ÀÍ+ëÌ»lI’ÕH*ÇVè
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv21 b/nss/cmd/bltest/tests/aes_cbc/iv21
new file mode 100644
index 0000000..6452e3d
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/iv21
@@ -0,0 +1,2 @@
+³Ë—¨
+S™¸ÂE
;“•
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv22 b/nss/cmd/bltest/tests/aes_cbc/iv22
new file mode 100644
index 0000000..42b7bd3
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/iv22
@@ -0,0 +1 @@
+LïüYcÔY`&u>–I
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv23 b/nss/cmd/bltest/tests/aes_cbc/iv23
new file mode 100644
index 0000000000000000000000000000000000000000..99b22495ccacd11ae5c41ccdd2a241b9470d3a3b
GIT binary patch
literal 16
YcmWGMCi&;XCVQSr)h`UoPMyvL07fVXQ~&?~
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv24 b/nss/cmd/bltest/tests/aes_cbc/iv24
new file mode 100644
index 0000000..0104daf
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/iv24
@@ -0,0 +1 @@
+ÖÕ¸ÏëӶ꡵?~á
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv3 b/nss/cmd/bltest/tests/aes_cbc/iv3
new file mode 100644
index 0000000000000000000000000000000000000000..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
KcmZQzKm`B*5C8!H
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv4 b/nss/cmd/bltest/tests/aes_cbc/iv4
new file mode 100644
index 0000000000000000000000000000000000000000..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
KcmZQzKm`B*5C8!H
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv5 b/nss/cmd/bltest/tests/aes_cbc/iv5
new file mode 100644
index 0000000000000000000000000000000000000000..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
KcmZQzKm`B*5C8!H
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv6 b/nss/cmd/bltest/tests/aes_cbc/iv6
new file mode 100644
index 0000000000000000000000000000000000000000..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
KcmZQzKm`B*5C8!H
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv7 b/nss/cmd/bltest/tests/aes_cbc/iv7
new file mode 100644
index 0000000..524d1b9
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/iv7
@@ -0,0 +1 @@
+ªÑX<Ùeã»/40Ðe»
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv8 b/nss/cmd/bltest/tests/aes_cbc/iv8
new file mode 100644
index 0000000..f58e954
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/iv8
@@ -0,0 +1 @@
+È ]‹± `iŸ|—J
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/iv9 b/nss/cmd/bltest/tests/aes_cbc/iv9
new file mode 100644
index 0000000..d6c4782
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/iv9
@@ -0,0 +1 @@
+eµî60¾Ö¸BÙ¹z
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/key0 b/nss/cmd/bltest/tests/aes_cbc/key0
new file mode 100644
index 0000000..13911cc
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/key0
@@ -0,0 +1 @@
+fedcba9876543210
diff --git a/nss/cmd/bltest/tests/aes_cbc/key1 b/nss/cmd/bltest/tests/aes_cbc/key1
new file mode 100644
index 0000000000000000000000000000000000000000..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
KcmZQzKm`B*5C8!H
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_cbc/key10 b/nss/cmd/bltest/tests/aes_cbc/key10
new file mode 100644
index 0000000..3cdff7a
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/key10
@@ -0,0 +1 @@
+Ä‘Ê1ùEŽ)©%ìUx
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/key11 b/nss/cmd/bltest/tests/aes_cbc/key11
new file mode 100644
index 0000000..4a13040
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/key11
@@ -0,0 +1 @@
+öè}q°Mn°jhÜjqô˜
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/key12 b/nss/cmd/bltest/tests/aes_cbc/key12
new file mode 100644
index 0000000..0a0103d
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/key12
@@ -0,0 +1 @@
+,A7QÃ'0W£6xk
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/key13 b/nss/cmd/bltest/tests/aes_cbc/key13
new file mode 100644
index 0000000..87ae208
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/key13
@@ -0,0 +1 @@
+ê³±œX¨sᘃ«ƒ»øQû.k!
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/key14 b/nss/cmd/bltest/tests/aes_cbc/key14
new file mode 100644
index 0000000..de4da4d
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/key14
@@ -0,0 +1 @@
+{±{M÷…i~¬Ï–˜âËuæy|é5Ë
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/key15 b/nss/cmd/bltest/tests/aes_cbc/key15
new file mode 100644
index 0000000..b13351f
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/key15
@@ -0,0 +1 @@
+ãþÌuðZ ³ƒßÓ‰£Ó<ɸT³²TÀô
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/key16 b/nss/cmd/bltest/tests/aes_cbc/key16
new file mode 100644
index 0000000000000000000000000000000000000000..71afcb384f652847a5a15141d4bec356a5376dc6
GIT binary patch
literal 24
gcmey(d43+l?H|n1W1poj5
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_cbc/key17 b/nss/cmd/bltest/tests/aes_cbc/key17
new file mode 100644
index 0000000..291b89b
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/key17
@@ -0,0 +1 @@
+¼¦úHjsK}G-#EH9{xvY2qGus8}
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_cbc/key8 b/nss/cmd/bltest/tests/aes_cbc/key8
new file mode 100644
index 0000000..804b8d4
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/key8
@@ -0,0 +1 @@
+·óÉWnÝ
¶>¬+š9
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/key9 b/nss/cmd/bltest/tests/aes_cbc/key9
new file mode 100644
index 0000000..193a2a1
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/key9
@@ -0,0 +1 @@
+»ç·ºOñ®|4þ‹F^
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/mktst.sh b/nss/cmd/bltest/tests/aes_cbc/mktst.sh
new file mode 100644
index 0000000..443167e
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/mktst.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
+do
+ file="test$i.txt"
+ grep "KEY = " $file | sed -e 's;KEY = ;;' | hex > key$i
+ grep "IV = " $file | sed -e 's;IV = ;;' | hex > iv$i
+ grep "PLAINTEXT = " $file | sed -e 's;PLAINTEXT = ;;' | hex > plaintext$i
+ grep "CIPHERTEXT = " $file | sed -e 's;CIPHERTEXT = ;;' | hex > ciphertext$i.bin
+ btoa < ciphertext$i.bin > ciphertext$i
+ rm ciphertext$i.bin
+done
diff --git a/nss/cmd/bltest/tests/aes_cbc/numtests b/nss/cmd/bltest/tests/aes_cbc/numtests
new file mode 100644
index 0000000..7273c0f
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/numtests
@@ -0,0 +1 @@
+25
diff --git a/nss/cmd/bltest/tests/aes_cbc/plaintext0 b/nss/cmd/bltest/tests/aes_cbc/plaintext0
new file mode 100644
index 0000000..cc67189
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/plaintext0
@@ -0,0 +1 @@
+0123456789abcdef0123456789abcdef
diff --git a/nss/cmd/bltest/tests/aes_cbc/plaintext1 b/nss/cmd/bltest/tests/aes_cbc/plaintext1
new file mode 100644
index 0000000..8bac1b7
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/plaintext1
@@ -0,0 +1 @@
+óDì<Æ'ºÍ]Ãûòsæ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/plaintext10 b/nss/cmd/bltest/tests/aes_cbc/plaintext10
new file mode 100644
index 0000000..779400b
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/plaintext10
@@ -0,0 +1,2 @@
+Ëjx~
ìVù¡e•¯3l¦´…Ùé@“ÆQRdŸˆ.‡My¬^{Ò§Lå®.èTöSž
+”ykÔÉüÛÇšËïMvÑŠ÷â¤üGÝfßlM¾PäfTšG¶6¼Ç³¦$•µk¶{mE_ëÙ¿ï켦Çó5ÏΛEË
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/plaintext11 b/nss/cmd/bltest/tests/aes_cbc/plaintext11
new file mode 100644
index 0000000..c226c29
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/plaintext11
@@ -0,0 +1 @@
+ø+ïÅÌͼìLå`ÏÒ"W 2mM甎TÖÐ×þ×Rû#ñªD”û°0éÞÔç~7Ày-‚€@Ã%±¥ïÑ_ÈBä@ÊCt¿8óÃü>ã's;Šî¼ÐUw/Ü`?{,¦Ÿöb6+à¡q»Üê]?
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/plaintext13 b/nss/cmd/bltest/tests/aes_cbc/plaintext13
new file mode 100644
index 0000000..88c5250
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/plaintext13
@@ -0,0 +1 @@
+NLÌÑh#!…mðiãñÆú9:Ÿ°-YÛtÁ@³¬Ä
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/plaintext14 b/nss/cmd/bltest/tests/aes_cbc/plaintext14
new file mode 100644
index 0000000..c42aec2
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/plaintext14
@@ -0,0 +1 @@
+Û7…¨‰´½8wTÚ"/L-+þ
yà[Éû©A¾ê0ñ#ž¬ðFìÃhé†ü¦·ÅŽIyÒ–½y†ïõO
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/plaintext15 b/nss/cmd/bltest/tests/aes_cbc/plaintext15
new file mode 100644
index 0000000..1266255
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/plaintext15
@@ -0,0 +1 @@
+“/_:X Õ:kêªd1:4ˆôë°õµ~ø8áW–#;Öæ€wS‹.QïpV4iRw+KME&Ay;4I?#{dym
OzYdV7vJO4i!bGmGT}_$*
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_cbc/plaintext19 b/nss/cmd/bltest/tests/aes_cbc/plaintext19
new file mode 100644
index 0000000000000000000000000000000000000000..0d6ad5e8c8ce9227c5d865f9611d744f34fa2470
GIT binary patch
literal 32
ocmWG|`R?JGpa#wtr_Y*ZmUhTbEehFaKk@ppG+hBhg`n3A03N;%bN~PV
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_cbc/plaintext2 b/nss/cmd/bltest/tests/aes_cbc/plaintext2
new file mode 100644
index 0000000..b2153e2
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/plaintext2
@@ -0,0 +1 @@
+—˜ÄduÇÃ"}¹Nr
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/plaintext20 b/nss/cmd/bltest/tests/aes_cbc/plaintext20
new file mode 100644
index 0000000..6873047
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/plaintext20
@@ -0,0 +1 @@
+‹7ùô»%•kæ1sÈÜXê—ÿI¶C{4É¿ð–©OíÖ‚5&«ÂzŽanî%J´V}ÖŽŒÍL8¬V;cœ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cbc/plaintext21 b/nss/cmd/bltest/tests/aes_cbc/plaintext21
new file mode 100644
index 0000000..22bfbac
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cbc/plaintext21
@@ -0,0 +1 @@
+:Þ¦ànBÄðA‘òw^ö7Œ°ˆ$^ÜOdHâ2[`Ð4[Ÿœxße–ì"·¹çn1>QHhoX
zSU=>-u|1Q7abA#tJRfi+zLGYo2ZLi;*=pqoQB#Xflv%$QJP9-d$8`uK{W<=Ql
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_cbc/plaintext24 b/nss/cmd/bltest/tests/aes_cbc/plaintext24
new file mode 100644
index 0000000000000000000000000000000000000000..42c59ead887f692e13b6e5bbfe82c26331c34b2e
GIT binary patch
literal 160
zcmV;R0AK$MW7HGVhDC7a3$|g4_@ud5RfcGcGP|Iq?7=oKt*1)bGQ}#-(W-Prx>kEm
zeX8vD%p9_jg0B`z key$i
+ grep "Init. Counter" $file | sed -e 's;Init. Counter=;;' | hex > iv$i
+ grep "Ciphertext" $file | sed -e 's;Ciphertext=;;' | hex | btoa > ciphertext$i
+ grep "Plaintext" $file | sed -e 's;Plaintext=;;' | hex > plaintext$i
+done
diff --git a/nss/cmd/bltest/tests/aes_ctr/numtests b/nss/cmd/bltest/tests/aes_ctr/numtests
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ctr/numtests
@@ -0,0 +1 @@
+3
diff --git a/nss/cmd/bltest/tests/aes_ctr/plaintext0 b/nss/cmd/bltest/tests/aes_ctr/plaintext0
new file mode 100644
index 0000000..8ad7704
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ctr/plaintext0
@@ -0,0 +1,2 @@
+kÁ¾â.@Ÿ–é=~s“*®-ŠW¬œž·o¬E¯ŽQ0ÈF£\äåûÁ
+RïöŸ$EßO›+A{æl7
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_ctr/plaintext1 b/nss/cmd/bltest/tests/aes_ctr/plaintext1
new file mode 100644
index 0000000..8ad7704
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ctr/plaintext1
@@ -0,0 +1,2 @@
+kÁ¾â.@Ÿ–é=~s“*®-ŠW¬œž·o¬E¯ŽQ0ÈF£\äåûÁ
+RïöŸ$EßO›+A{æl7
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_ctr/plaintext2 b/nss/cmd/bltest/tests/aes_ctr/plaintext2
new file mode 100644
index 0000000..8ad7704
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ctr/plaintext2
@@ -0,0 +1,2 @@
+kÁ¾â.@Ÿ–é=~s“*®-ŠW¬œž·o¬E¯ŽQ0ÈF£\äåûÁ
+RïöŸ$EßO›+A{æl7
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cts/aes-cts-type-1-vectors.txt b/nss/cmd/bltest/tests/aes_cts/aes-cts-type-1-vectors.txt
new file mode 100644
index 0000000..b107586
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cts/aes-cts-type-1-vectors.txt
@@ -0,0 +1,47 @@
+# Raeburn Standards Track [Page 12]
+#
+# RFC 3962 AES Encryption for Kerberos 5 February 2005
+#
+# Some test vectors for CBC with ciphertext stealing, using an initial
+# vector of all-zero.
+#
+# Original Test vectors were for AES CTS-3 (Kerberos). These test vectors have been modified for AES CTS-1 (NIST)
+#
+
+Key: 63 68 69 63 6b 65 6e 20 74 65 72 69 79 61 6b 69
+IV: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+Input: 49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20
+Output: 97 c6 35 35 68 f2 bf 8c b4 d8 a5 80 36 2d a7 ff 7f
+Next IV: c6 35 35 68 f2 bf 8c b4 d8 a5 80 36 2d a7 ff 7f
+
+Key: 63 68 69 63 6b 65 6e 20 74 65 72 69 79 61 6b 69
+IV: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+Input: 49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20 47 65 6e 65 72 61 6c 20 47 61 75 27 73 20
+Output: 97 68 72 68 d6 ec cc c0 c0 7b 25 e2 5e cf e5 fc 00 78 3e 0e fd b2 c1 d4 45 d4 c8 ef f7 ed 22
+Next IV: fc 00 78 3e 0e fd b2 c1 d4 45 d4 c8 ef f7 ed 22
+
+Key: 63 68 69 63 6b 65 6e 20 74 65 72 69 79 61 6b 69
+IV: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+Input: 49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20 47 65 6e 65 72 61 6c 20 47 61 75 27 73 20 43
+Output: 97 68 72 68 d6 ec cc c0 c0 7b 25 e2 5e cf e5 84 39 31 25 23 a7 86 62 d5 be 7f cb cc 98 eb f5 a8
+Next IV: 39 31 25 23 a7 86 62 d5 be 7f cb cc 98 eb f5 a8
+
+Key: 63 68 69 63 6b 65 6e 20 74 65 72 69 79 61 6b 69
+IV: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+Input: 49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20 47 65 6e 65 72 61 6c 20 47 61 75 27 73 20 43 68 69 63 6b 65 6e 2c 20 70 6c 65 61 73 65 2c
+Output: 97 68 72 68 d6 ec cc c0 c0 7b 25 e2 5e cf e5 84 39 31 25 23 a7 86 62 d5 be 7f cb cc 98 eb f5 b3 ff fd 94 0c 16 a1 8c 1b 55 49 d2 f8 38 02 9e
+Next IV: b3 ff fd 94 0c 16 a1 8c 1b 55 49 d2 f8 38 02 9e
+
+Key: 63 68 69 63 6b 65 6e 20 74 65 72 69 79 61 6b 69
+IV: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+Input: 49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20 47 65 6e 65 72 61 6c 20 47 61 75 27 73 20 43 68 69 63 6b 65 6e 2c 20 70 6c 65 61 73 65 2c 20
+Output: 97 68 72 68 d6 ec cc c0 c0 7b 25 e2 5e cf e5 84 39 31 25 23 a7 86 62 d5 be 7f cb cc 98 eb f5 a8 9d ad 8b bb 96 c4 cd c0 3b c1 03 e1 a1 94 bb d8
+Next IV: 9d ad 8b bb 96 c4 cd c0 3b c1 03 e1 a1 94 bb d8
+
+Key: 63 68 69 63 6b 65 6e 20 74 65 72 69 79 61 6b 69
+IV: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+Input: 49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20 47 65 6e 65 72 61 6c 20 47 61 75 27 73 20 43 68 69 63 6b 65 6e 2c 20 70 6c 65 61 73 65 2c 20 61 6e 64 20 77 6f 6e 74 6f 6e 20 73 6f 75 70 2e
+Output: 97 68 72 68 d6 ec cc c0 c0 7b 25 e2 5e cf e5 84 39 31 25 23 a7 86 62 d5 be 7f cb cc 98 eb f5 a8 9d ad 8b bb 96 c4 cd c0 3b c1 03 e1 a1 94 bb d8 48 07 ef e8 36 ee 89 a5 26 73 0d bc 2f 7b c8 40
+Next IV: 48 07 ef e8 36 ee 89 a5 26 73 0d bc 2f 7b c8 40
+
+
diff --git a/nss/cmd/bltest/tests/aes_cts/aes_cts_0.txt b/nss/cmd/bltest/tests/aes_cts/aes_cts_0.txt
new file mode 100644
index 0000000..fa28439
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cts/aes_cts_0.txt
@@ -0,0 +1,6 @@
+Key: 63 68 69 63 6b 65 6e 20 74 65 72 69 79 61 6b 69
+IV: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+Input: 49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20
+Output: 97 c6 35 35 68 f2 bf 8c b4 d8 a5 80 36 2d a7 ff 7f
+Next IV: c6 35 35 68 f2 bf 8c b4 d8 a5 80 36 2d a7 ff 7f
+
diff --git a/nss/cmd/bltest/tests/aes_cts/aes_cts_1.txt b/nss/cmd/bltest/tests/aes_cts/aes_cts_1.txt
new file mode 100644
index 0000000..dae9735
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cts/aes_cts_1.txt
@@ -0,0 +1,6 @@
+Key: 63 68 69 63 6b 65 6e 20 74 65 72 69 79 61 6b 69
+IV: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+Input: 49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20 47 65 6e 65 72 61 6c 20 47 61 75 27 73 20
+Output: 97 68 72 68 d6 ec cc c0 c0 7b 25 e2 5e cf e5 fc 00 78 3e 0e fd b2 c1 d4 45 d4 c8 ef f7 ed 22
+Next IV: fc 00 78 3e 0e fd b2 c1 d4 45 d4 c8 ef f7 ed 22
+
diff --git a/nss/cmd/bltest/tests/aes_cts/aes_cts_2.txt b/nss/cmd/bltest/tests/aes_cts/aes_cts_2.txt
new file mode 100644
index 0000000..df89289
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cts/aes_cts_2.txt
@@ -0,0 +1,6 @@
+Key: 63 68 69 63 6b 65 6e 20 74 65 72 69 79 61 6b 69
+IV: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+Input: 49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20 47 65 6e 65 72 61 6c 20 47 61 75 27 73 20 43
+Output: 97 68 72 68 d6 ec cc c0 c0 7b 25 e2 5e cf e5 84 39 31 25 23 a7 86 62 d5 be 7f cb cc 98 eb f5 a8
+Next IV: 39 31 25 23 a7 86 62 d5 be 7f cb cc 98 eb f5 a8
+
diff --git a/nss/cmd/bltest/tests/aes_cts/aes_cts_3.txt b/nss/cmd/bltest/tests/aes_cts/aes_cts_3.txt
new file mode 100644
index 0000000..11e68e0
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cts/aes_cts_3.txt
@@ -0,0 +1,6 @@
+Key: 63 68 69 63 6b 65 6e 20 74 65 72 69 79 61 6b 69
+IV: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+Input: 49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20 47 65 6e 65 72 61 6c 20 47 61 75 27 73 20 43 68 69 63 6b 65 6e 2c 20 70 6c 65 61 73 65 2c
+Output: 97 68 72 68 d6 ec cc c0 c0 7b 25 e2 5e cf e5 84 39 31 25 23 a7 86 62 d5 be 7f cb cc 98 eb f5 b3 ff fd 94 0c 16 a1 8c 1b 55 49 d2 f8 38 02 9e
+Next IV: b3 ff fd 94 0c 16 a1 8c 1b 55 49 d2 f8 38 02 9e
+
diff --git a/nss/cmd/bltest/tests/aes_cts/aes_cts_4.txt b/nss/cmd/bltest/tests/aes_cts/aes_cts_4.txt
new file mode 100644
index 0000000..b5dc5ae
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cts/aes_cts_4.txt
@@ -0,0 +1,6 @@
+Key: 63 68 69 63 6b 65 6e 20 74 65 72 69 79 61 6b 69
+IV: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+Input: 49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20 47 65 6e 65 72 61 6c 20 47 61 75 27 73 20 43 68 69 63 6b 65 6e 2c 20 70 6c 65 61 73 65 2c 20
+Output: 97 68 72 68 d6 ec cc c0 c0 7b 25 e2 5e cf e5 84 39 31 25 23 a7 86 62 d5 be 7f cb cc 98 eb f5 a8 9d ad 8b bb 96 c4 cd c0 3b c1 03 e1 a1 94 bb d8
+Next IV: 9d ad 8b bb 96 c4 cd c0 3b c1 03 e1 a1 94 bb d8
+
diff --git a/nss/cmd/bltest/tests/aes_cts/aes_cts_5.txt b/nss/cmd/bltest/tests/aes_cts/aes_cts_5.txt
new file mode 100644
index 0000000..db837f9
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cts/aes_cts_5.txt
@@ -0,0 +1,6 @@
+Key: 63 68 69 63 6b 65 6e 20 74 65 72 69 79 61 6b 69
+IV: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+Input: 49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20 47 65 6e 65 72 61 6c 20 47 61 75 27 73 20 43 68 69 63 6b 65 6e 2c 20 70 6c 65 61 73 65 2c 20 61 6e 64 20 77 6f 6e 74 6f 6e 20 73 6f 75 70 2e
+Output: 97 68 72 68 d6 ec cc c0 c0 7b 25 e2 5e cf e5 84 39 31 25 23 a7 86 62 d5 be 7f cb cc 98 eb f5 a8 9d ad 8b bb 96 c4 cd c0 3b c1 03 e1 a1 94 bb d8 48 07 ef e8 36 ee 89 a5 26 73 0d bc 2f 7b c8 40
+Next IV: 48 07 ef e8 36 ee 89 a5 26 73 0d bc 2f 7b c8 40
+
diff --git a/nss/cmd/bltest/tests/aes_cts/ciphertext0 b/nss/cmd/bltest/tests/aes_cts/ciphertext0
new file mode 100644
index 0000000..bcfdc10
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cts/ciphertext0
@@ -0,0 +1 @@
+l8Y1NWjyv4y02KWANi2n/38=
diff --git a/nss/cmd/bltest/tests/aes_cts/ciphertext1 b/nss/cmd/bltest/tests/aes_cts/ciphertext1
new file mode 100644
index 0000000..6656080
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cts/ciphertext1
@@ -0,0 +1 @@
+l2hyaNbszMDAeyXiXs/l/AB4Pg79ssHURdTI7/ftIg==
diff --git a/nss/cmd/bltest/tests/aes_cts/ciphertext2 b/nss/cmd/bltest/tests/aes_cts/ciphertext2
new file mode 100644
index 0000000..336d705
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cts/ciphertext2
@@ -0,0 +1 @@
+l2hyaNbszMDAeyXiXs/lhDkxJSOnhmLVvn/LzJjr9ag=
diff --git a/nss/cmd/bltest/tests/aes_cts/ciphertext3 b/nss/cmd/bltest/tests/aes_cts/ciphertext3
new file mode 100644
index 0000000..7c53d40
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cts/ciphertext3
@@ -0,0 +1 @@
+l2hyaNbszMDAeyXiXs/lhDkxJSOnhmLVvn/LzJjr9bP//ZQMFqGMG1VJ0vg4Ap4=
diff --git a/nss/cmd/bltest/tests/aes_cts/ciphertext4 b/nss/cmd/bltest/tests/aes_cts/ciphertext4
new file mode 100644
index 0000000..ef31331
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cts/ciphertext4
@@ -0,0 +1 @@
+l2hyaNbszMDAeyXiXs/lhDkxJSOnhmLVvn/LzJjr9aidrYu7lsTNwDvBA+GhlLvY
diff --git a/nss/cmd/bltest/tests/aes_cts/ciphertext5 b/nss/cmd/bltest/tests/aes_cts/ciphertext5
new file mode 100644
index 0000000..0ead143
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cts/ciphertext5
@@ -0,0 +1,2 @@
+l2hyaNbszMDAeyXiXs/lhDkxJSOnhmLVvn/LzJjr9aidrYu7lsTNwDvBA+GhlLvY
+SAfv6DbuiaUmcw28L3vIQA==
diff --git a/nss/cmd/bltest/tests/aes_cts/iv0 b/nss/cmd/bltest/tests/aes_cts/iv0
new file mode 100644
index 0000000000000000000000000000000000000000..4bdfab8333086af48b9ece6d1f9db9aa9a07cdff
GIT binary patch
literal 34
dcmZQzKm~jZ$4pH#KJD+>a${+OneOuc^#Dwl2^|0c
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_cts/iv1 b/nss/cmd/bltest/tests/aes_cts/iv1
new file mode 100644
index 0000000000000000000000000000000000000000..3e8c8e9e6b97306f58059d6807b665465bc3bc64
GIT binary patch
literal 34
ecmZQzKm~jZe;6w4`2KD>c*XU~iTB^%DggjZ*a_(X
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_cts/iv2 b/nss/cmd/bltest/tests/aes_cts/iv2
new file mode 100644
index 0000000000000000000000000000000000000000..b4bbc2e76fb0ee149bce3609e147cae594ccf0d4
GIT binary patch
literal 34
dcmZQzKm~jZmWHaz%iEH!?yEn2X2$EUD*!$l2^jzY
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_cts/iv3 b/nss/cmd/bltest/tests/aes_cts/iv3
new file mode 100644
index 0000000000000000000000000000000000000000..c065e8362dc47e875113249f9a575f490363087a
GIT binary patch
literal 34
dcmZQzKm~jZoB#iv!Xvh@M>^E=(hm!!c>qgx2mAm4
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_cts/iv4 b/nss/cmd/bltest/tests/aes_cts/iv4
new file mode 100644
index 0000000000000000000000000000000000000000..ba11a0ec02ff240e50a83121b4c2b60eed06e3a3
GIT binary patch
literal 34
ecmZQzKm~jZbJuq7o_6Hy0qcXz4;N0^eFFeigbFSI
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_cts/iv5 b/nss/cmd/bltest/tests/aes_cts/iv5
new file mode 100644
index 0000000000000000000000000000000000000000..213a4bd3c7541d93cdc6bd0427ca28cc3cb2c062
GIT binary patch
literal 34
dcmZQzKm~jZ9_;U5n7!* key$i
+ grep "IV" $file | sed -e 's;IV:;;' | hex > iv$i
+ grep "Input" $file | sed -e 's;Input:;;' | hex > plaintext$i
+ grep "Output" $file | sed -e 's;Output:;;' | hex | btoa > ciphertext$i
+done
diff --git a/nss/cmd/bltest/tests/aes_cts/numtests b/nss/cmd/bltest/tests/aes_cts/numtests
new file mode 100644
index 0000000..1e8b314
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cts/numtests
@@ -0,0 +1 @@
+6
diff --git a/nss/cmd/bltest/tests/aes_cts/plaintext0 b/nss/cmd/bltest/tests/aes_cts/plaintext0
new file mode 100644
index 0000000..3f35c97
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cts/plaintext0
@@ -0,0 +1 @@
+I would like the
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cts/plaintext1 b/nss/cmd/bltest/tests/aes_cts/plaintext1
new file mode 100644
index 0000000..3975448
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cts/plaintext1
@@ -0,0 +1 @@
+I would like the General Gau's
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cts/plaintext2 b/nss/cmd/bltest/tests/aes_cts/plaintext2
new file mode 100644
index 0000000..d0664ea
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cts/plaintext2
@@ -0,0 +1 @@
+I would like the General Gau's C
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cts/plaintext3 b/nss/cmd/bltest/tests/aes_cts/plaintext3
new file mode 100644
index 0000000..563970b
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cts/plaintext3
@@ -0,0 +1 @@
+I would like the General Gau's Chicken, please,
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cts/plaintext4 b/nss/cmd/bltest/tests/aes_cts/plaintext4
new file mode 100644
index 0000000..b908471
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cts/plaintext4
@@ -0,0 +1 @@
+I would like the General Gau's Chicken, please,
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_cts/plaintext5 b/nss/cmd/bltest/tests/aes_cts/plaintext5
new file mode 100644
index 0000000..5e4c069
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_cts/plaintext5
@@ -0,0 +1 @@
+I would like the General Gau's Chicken, please, and wonton soup.
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_ecb/ciphertext0 b/nss/cmd/bltest/tests/aes_ecb/ciphertext0
new file mode 100644
index 0000000..d6818c1
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/ciphertext0
@@ -0,0 +1 @@
+PVuaCIiaKQhblgFCbVMTTg==
diff --git a/nss/cmd/bltest/tests/aes_ecb/ciphertext1 b/nss/cmd/bltest/tests/aes_ecb/ciphertext1
new file mode 100644
index 0000000..1126bbf
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/ciphertext1
@@ -0,0 +1 @@
+AzZ2PpZtkllaVnzJzlN/Xg==
diff --git a/nss/cmd/bltest/tests/aes_ecb/ciphertext2 b/nss/cmd/bltest/tests/aes_ecb/ciphertext2
new file mode 100644
index 0000000..ec069ab
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/ciphertext2
@@ -0,0 +1 @@
+qaFjG/SZaVTrwJOVeyNFiQ==
diff --git a/nss/cmd/bltest/tests/aes_ecb/ciphertext3 b/nss/cmd/bltest/tests/aes_ecb/ciphertext3
new file mode 100644
index 0000000..82c4cd2
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/ciphertext3
@@ -0,0 +1 @@
+J1z8BBPYzLcFE8OFmx0Pcg==
diff --git a/nss/cmd/bltest/tests/aes_ecb/ciphertext4 b/nss/cmd/bltest/tests/aes_ecb/ciphertext4
new file mode 100644
index 0000000..81714bd
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/ciphertext4
@@ -0,0 +1 @@
+ybgTX/G1rcQT39BTshvZbQ==
diff --git a/nss/cmd/bltest/tests/aes_ecb/ciphertext5 b/nss/cmd/bltest/tests/aes_ecb/ciphertext5
new file mode 100644
index 0000000..ce9672a
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/ciphertext5
@@ -0,0 +1 @@
+XJ2ETtRvmIUIXl1qT5TH1w==
diff --git a/nss/cmd/bltest/tests/aes_ecb/ciphertext6 b/nss/cmd/bltest/tests/aes_ecb/ciphertext6
new file mode 100644
index 0000000..fc53a4f
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/ciphertext6
@@ -0,0 +1 @@
+qf91vXz2YT03Mcd8O20MBA==
diff --git a/nss/cmd/bltest/tests/aes_ecb/key0 b/nss/cmd/bltest/tests/aes_ecb/key0
new file mode 100644
index 0000000..13911cc
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/key0
@@ -0,0 +1 @@
+fedcba9876543210
diff --git a/nss/cmd/bltest/tests/aes_ecb/key1 b/nss/cmd/bltest/tests/aes_ecb/key1
new file mode 100644
index 0000000000000000000000000000000000000000..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
KcmZQzKm`B*5C8!H
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_ecb/key2 b/nss/cmd/bltest/tests/aes_ecb/key2
new file mode 100644
index 0000000000000000000000000000000000000000..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
KcmZQzKm`B*5C8!H
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_ecb/key3 b/nss/cmd/bltest/tests/aes_ecb/key3
new file mode 100644
index 0000000000000000000000000000000000000000..4ac5fc6cf890b46738523c4d4d9d964e312f368f
GIT binary patch
literal 24
KcmZQzzzzTa7ytnP
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_ecb/key4 b/nss/cmd/bltest/tests/aes_ecb/key4
new file mode 100644
index 0000000000000000000000000000000000000000..4ac5fc6cf890b46738523c4d4d9d964e312f368f
GIT binary patch
literal 24
KcmZQzzzzTa7ytnP
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_ecb/key5 b/nss/cmd/bltest/tests/aes_ecb/key5
new file mode 100644
index 0000000000000000000000000000000000000000..4e4e4935707a596987ec1cc32e3d0d587dbe4f04
GIT binary patch
literal 32
KcmZQzzz+ZbAOHaX
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_ecb/key6 b/nss/cmd/bltest/tests/aes_ecb/key6
new file mode 100644
index 0000000000000000000000000000000000000000..4e4e4935707a596987ec1cc32e3d0d587dbe4f04
GIT binary patch
literal 32
KcmZQzzz+ZbAOHaX
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_ecb/mktst.sh b/nss/cmd/bltest/tests/aes_ecb/mktst.sh
new file mode 100644
index 0000000..6d46509
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/mktst.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+for i in 1 2 3 4 5 6
+do
+ file="test$i.txt"
+ grep "KEY = " $file | sed -e 's;KEY = ;;' | hex > key$i
+ grep "PLAINTEXT = " $file | sed -e 's;PLAINTEXT = ;;' | hex > plaintext$i
+ grep "CIPHERTEXT = " $file | sed -e 's;CIPHERTEXT = ;;' | hex > ciphertext$i.bin
+ btoa < ciphertext$i.bin > ciphertext$i
+ rm ciphertext$i.bin
+done
diff --git a/nss/cmd/bltest/tests/aes_ecb/numtests b/nss/cmd/bltest/tests/aes_ecb/numtests
new file mode 100644
index 0000000..7f8f011
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/numtests
@@ -0,0 +1 @@
+7
diff --git a/nss/cmd/bltest/tests/aes_ecb/plaintext0 b/nss/cmd/bltest/tests/aes_ecb/plaintext0
new file mode 100644
index 0000000..8d6a8d5
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/plaintext0
@@ -0,0 +1 @@
+0123456789abcdef
diff --git a/nss/cmd/bltest/tests/aes_ecb/plaintext1 b/nss/cmd/bltest/tests/aes_ecb/plaintext1
new file mode 100644
index 0000000..8bac1b7
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/plaintext1
@@ -0,0 +1 @@
+óDì<Æ'ºÍ]Ãûòsæ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_ecb/plaintext2 b/nss/cmd/bltest/tests/aes_ecb/plaintext2
new file mode 100644
index 0000000..b2153e2
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/plaintext2
@@ -0,0 +1 @@
+—˜ÄduÇÃ"}¹Nr
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_ecb/plaintext3 b/nss/cmd/bltest/tests/aes_ecb/plaintext3
new file mode 100644
index 0000000..b565f3a
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/plaintext3
@@ -0,0 +1 @@
+zjô·ù‚)Þxmu¶9
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_ecb/plaintext4 b/nss/cmd/bltest/tests/aes_ecb/plaintext4
new file mode 100644
index 0000000..9ef1cbb
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/plaintext4
@@ -0,0 +1 @@
+œ-ˆBåôWd‚Óš#šñ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_ecb/plaintext5 b/nss/cmd/bltest/tests/aes_ecb/plaintext5
new file mode 100644
index 0000000..767e9f4
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/plaintext5
@@ -0,0 +1,2 @@
+G0ø
+Æ%þ„ð&ÆýT}
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_ecb/plaintext6 b/nss/cmd/bltest/tests/aes_ecb/plaintext6
new file mode 100644
index 0000000..e8537b6
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/plaintext6
@@ -0,0 +1 @@
+$¯6<äf_(%×´tœ˜
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_ecb/test1.txt b/nss/cmd/bltest/tests/aes_ecb/test1.txt
new file mode 100644
index 0000000..96a2adb
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/test1.txt
@@ -0,0 +1,4 @@
+COUNT = 0
+KEY = 00000000000000000000000000000000
+PLAINTEXT = f34481ec3cc627bacd5dc3fb08f273e6
+CIPHERTEXT = 0336763e966d92595a567cc9ce537f5e
diff --git a/nss/cmd/bltest/tests/aes_ecb/test2.txt b/nss/cmd/bltest/tests/aes_ecb/test2.txt
new file mode 100644
index 0000000..a01daae
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/test2.txt
@@ -0,0 +1,4 @@
+COUNT = 1
+KEY = 00000000000000000000000000000000
+PLAINTEXT = 9798c4640bad75c7c3227db910174e72
+CIPHERTEXT = a9a1631bf4996954ebc093957b234589
diff --git a/nss/cmd/bltest/tests/aes_ecb/test3.txt b/nss/cmd/bltest/tests/aes_ecb/test3.txt
new file mode 100644
index 0000000..803c23c
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/test3.txt
@@ -0,0 +1,4 @@
+COUNT = 0
+KEY = 000000000000000000000000000000000000000000000000
+PLAINTEXT = 1b077a6af4b7f98229de786d7516b639
+CIPHERTEXT = 275cfc0413d8ccb70513c3859b1d0f72
diff --git a/nss/cmd/bltest/tests/aes_ecb/test4.txt b/nss/cmd/bltest/tests/aes_ecb/test4.txt
new file mode 100644
index 0000000..e567fab
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/test4.txt
@@ -0,0 +1,4 @@
+COUNT = 1
+KEY = 000000000000000000000000000000000000000000000000
+PLAINTEXT = 9c2d8842e5f48f57648205d39a239af1
+CIPHERTEXT = c9b8135ff1b5adc413dfd053b21bd96d
diff --git a/nss/cmd/bltest/tests/aes_ecb/test5.txt b/nss/cmd/bltest/tests/aes_ecb/test5.txt
new file mode 100644
index 0000000..c96940e
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/test5.txt
@@ -0,0 +1,4 @@
+COUNT = 0
+KEY = 0000000000000000000000000000000000000000000000000000000000000000
+PLAINTEXT = 014730f80ac625fe84f026c60bfd547d
+CIPHERTEXT = 5c9d844ed46f9885085e5d6a4f94c7d7
diff --git a/nss/cmd/bltest/tests/aes_ecb/test6.txt b/nss/cmd/bltest/tests/aes_ecb/test6.txt
new file mode 100644
index 0000000..d8d0058
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_ecb/test6.txt
@@ -0,0 +1,4 @@
+COUNT = 1
+KEY = 0000000000000000000000000000000000000000000000000000000000000000
+PLAINTEXT = 0b24af36193ce4665f2825d7b4749c98
+CIPHERTEXT = a9ff75bd7cf6613d3731c77c3b6d0c04
diff --git a/nss/cmd/bltest/tests/aes_gcm/aad0 b/nss/cmd/bltest/tests/aes_gcm/aad0
new file mode 100644
index 0000000..e69de29
diff --git a/nss/cmd/bltest/tests/aes_gcm/aad1 b/nss/cmd/bltest/tests/aes_gcm/aad1
new file mode 100644
index 0000000..e69de29
diff --git a/nss/cmd/bltest/tests/aes_gcm/aad10 b/nss/cmd/bltest/tests/aes_gcm/aad10
new file mode 100644
index 0000000..87b29d3
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/aad10
@@ -0,0 +1 @@
+þíúÎÞ¾ïþíúÎÞ¾ï«ÚÒ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/aad11 b/nss/cmd/bltest/tests/aes_gcm/aad11
new file mode 100644
index 0000000..87b29d3
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/aad11
@@ -0,0 +1 @@
+þíúÎÞ¾ïþíúÎÞ¾ï«ÚÒ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/aad12 b/nss/cmd/bltest/tests/aes_gcm/aad12
new file mode 100644
index 0000000..e69de29
diff --git a/nss/cmd/bltest/tests/aes_gcm/aad13 b/nss/cmd/bltest/tests/aes_gcm/aad13
new file mode 100644
index 0000000..e69de29
diff --git a/nss/cmd/bltest/tests/aes_gcm/aad14 b/nss/cmd/bltest/tests/aes_gcm/aad14
new file mode 100644
index 0000000..e69de29
diff --git a/nss/cmd/bltest/tests/aes_gcm/aad15 b/nss/cmd/bltest/tests/aes_gcm/aad15
new file mode 100644
index 0000000..87b29d3
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/aad15
@@ -0,0 +1 @@
+þíúÎÞ¾ïþíúÎÞ¾ï«ÚÒ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/aad16 b/nss/cmd/bltest/tests/aes_gcm/aad16
new file mode 100644
index 0000000..87b29d3
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/aad16
@@ -0,0 +1 @@
+þíúÎÞ¾ïþíúÎÞ¾ï«ÚÒ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/aad17 b/nss/cmd/bltest/tests/aes_gcm/aad17
new file mode 100644
index 0000000..87b29d3
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/aad17
@@ -0,0 +1 @@
+þíúÎÞ¾ïþíúÎÞ¾ï«ÚÒ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/aad2 b/nss/cmd/bltest/tests/aes_gcm/aad2
new file mode 100644
index 0000000..e69de29
diff --git a/nss/cmd/bltest/tests/aes_gcm/aad3 b/nss/cmd/bltest/tests/aes_gcm/aad3
new file mode 100644
index 0000000..87b29d3
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/aad3
@@ -0,0 +1 @@
+þíúÎÞ¾ïþíúÎÞ¾ï«ÚÒ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/aad4 b/nss/cmd/bltest/tests/aes_gcm/aad4
new file mode 100644
index 0000000..87b29d3
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/aad4
@@ -0,0 +1 @@
+þíúÎÞ¾ïþíúÎÞ¾ï«ÚÒ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/aad5 b/nss/cmd/bltest/tests/aes_gcm/aad5
new file mode 100644
index 0000000..87b29d3
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/aad5
@@ -0,0 +1 @@
+þíúÎÞ¾ïþíúÎÞ¾ï«ÚÒ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/aad6 b/nss/cmd/bltest/tests/aes_gcm/aad6
new file mode 100644
index 0000000..e69de29
diff --git a/nss/cmd/bltest/tests/aes_gcm/aad7 b/nss/cmd/bltest/tests/aes_gcm/aad7
new file mode 100644
index 0000000..e69de29
diff --git a/nss/cmd/bltest/tests/aes_gcm/aad8 b/nss/cmd/bltest/tests/aes_gcm/aad8
new file mode 100644
index 0000000..e69de29
diff --git a/nss/cmd/bltest/tests/aes_gcm/aad9 b/nss/cmd/bltest/tests/aes_gcm/aad9
new file mode 100644
index 0000000..87b29d3
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/aad9
@@ -0,0 +1 @@
+þíúÎÞ¾ïþíúÎÞ¾ï«ÚÒ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/ciphertext0 b/nss/cmd/bltest/tests/aes_gcm/ciphertext0
new file mode 100644
index 0000000..3b35214
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/ciphertext0
@@ -0,0 +1 @@
+WOL8zvp+MGE2fx1XpOdFWg==
diff --git a/nss/cmd/bltest/tests/aes_gcm/ciphertext1 b/nss/cmd/bltest/tests/aes_gcm/ciphertext1
new file mode 100644
index 0000000..9913ff1
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/ciphertext1
@@ -0,0 +1 @@
+A4jazmC2o5LzKMK5cbL+eKtuR9Qs7BO99TpnshJXvd8=
diff --git a/nss/cmd/bltest/tests/aes_gcm/ciphertext10 b/nss/cmd/bltest/tests/aes_gcm/ciphertext10
new file mode 100644
index 0000000..70cb471
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/ciphertext10
@@ -0,0 +1,2 @@
+DxD1ma4UoVTtJLNuJTJNuMVmYy7yu7NPg0coD8RQcFf93CnfmkcfdcZlQdTU2tHJ
+6ToZpY6LRz+g8GL3ZdzFf89iOiQJT8ykDTUz+A==
diff --git a/nss/cmd/bltest/tests/aes_gcm/ciphertext11 b/nss/cmd/bltest/tests/aes_gcm/ciphertext11
new file mode 100644
index 0000000..b9c4236
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/ciphertext11
@@ -0,0 +1,2 @@
+0n6IaBzjJDxIMBZaj9z5/x3podjmtEfvbve3mChmbkWB55ASrzTd2eLwN1ibKS2z
+5nwDZ0X6Iufptzc73PVm/ykcJbu4Vo/D03am2Q==
diff --git a/nss/cmd/bltest/tests/aes_gcm/ciphertext12 b/nss/cmd/bltest/tests/aes_gcm/ciphertext12
new file mode 100644
index 0000000..b756f5c
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/ciphertext12
@@ -0,0 +1 @@
+Uw+K+8dFNrmpY7TxxMtziw==
diff --git a/nss/cmd/bltest/tests/aes_gcm/ciphertext13 b/nss/cmd/bltest/tests/aes_gcm/ciphertext13
new file mode 100644
index 0000000..15bc5e1
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/ciphertext13
@@ -0,0 +1 @@
+zqdAPU1ga24HTsXTuvOdGNDRyKeZmWvwJluYtdSKuRk=
diff --git a/nss/cmd/bltest/tests/aes_gcm/ciphertext14 b/nss/cmd/bltest/tests/aes_gcm/ciphertext14
new file mode 100644
index 0000000..a982ef2
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/ciphertext14
@@ -0,0 +1,2 @@
+Ui3B8JlWfQf0fzejKoRCfWQ6jNy/5cDJdZiivSVV0aqMsI5IWQ27PaewixBWgog4
+xfYeY5O6egq8yfZiiYAVrbCU2sXZNHG97BpQInDjzGw=
diff --git a/nss/cmd/bltest/tests/aes_gcm/ciphertext15 b/nss/cmd/bltest/tests/aes_gcm/ciphertext15
new file mode 100644
index 0000000..5f5b952
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/ciphertext15
@@ -0,0 +1,2 @@
+Ui3B8JlWfQf0fzejKoRCfWQ6jNy/5cDJdZiivSVV0aqMsI5IWQ27PaewixBWgog4
+xfYeY5O6egq8yfZidvxuzg9OF2jN34hTuy1VGw==
diff --git a/nss/cmd/bltest/tests/aes_gcm/ciphertext16 b/nss/cmd/bltest/tests/aes_gcm/ciphertext16
new file mode 100644
index 0000000..86d9096
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/ciphertext16
@@ -0,0 +1,2 @@
+w3Yt8cp4fTKuR8E78ZhEy68a4U0Ll2r6xS/315u6neD+tYLTOTSk8JVMwjY7xz94
+YqxDDmSr5Jn0fJsfOjN9v0anksReRUkT/i6o8g==
diff --git a/nss/cmd/bltest/tests/aes_gcm/ciphertext17 b/nss/cmd/bltest/tests/aes_gcm/ciphertext17
new file mode 100644
index 0000000..6be2346
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/ciphertext17
@@ -0,0 +1,2 @@
+Wo3vLwyeU/H3XXhTZZ4qIO6ysiqv3mQZoFirT290a/QPwMO3gPJERS2j6/HF2Cze
+okGJlyAO+C5Ern4/pEqCZu4cjrDItdTPWunxmg==
diff --git a/nss/cmd/bltest/tests/aes_gcm/ciphertext2 b/nss/cmd/bltest/tests/aes_gcm/ciphertext2
new file mode 100644
index 0000000..f5efb3d
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/ciphertext2
@@ -0,0 +1,2 @@
+QoMewiF3dCRLciG3hNDUnOOqIS8sAqTgNcF+IymsoS4h1RSyVGaTHH2PalqshKoF
+G6MLOWoKrJc9WOCRRz9ZhU1cKvMnzWSmLPNavSum+rQ=
diff --git a/nss/cmd/bltest/tests/aes_gcm/ciphertext3 b/nss/cmd/bltest/tests/aes_gcm/ciphertext3
new file mode 100644
index 0000000..80fe95e
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/ciphertext3
@@ -0,0 +1,2 @@
+QoMewiF3dCRLciG3hNDUnOOqIS8sAqTgNcF+IymsoS4h1RSyVGaTHH2PalqshKoF
+G6MLOWoKrJc9WOCRW8lPvDIhpduU+ula5xIaRw==
diff --git a/nss/cmd/bltest/tests/aes_gcm/ciphertext4 b/nss/cmd/bltest/tests/aes_gcm/ciphertext4
new file mode 100644
index 0000000..cbc0194
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/ciphertext4
@@ -0,0 +1,2 @@
+YTU7TCgGk0p3f/UfoipHVWmbKnFPzcb4N2bl+XtsdCNzgGkA5J8ksisJdUTUiWtC
+SYm14eusDwfCP0WYNhLS5547B4VWG+FKrKL8yw==
diff --git a/nss/cmd/bltest/tests/aes_gcm/ciphertext5 b/nss/cmd/bltest/tests/aes_gcm/ciphertext5
new file mode 100644
index 0000000..77127ff
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/ciphertext5
@@ -0,0 +1,2 @@
+jOJJmGJWFbYDoDOsoT+4lL6REqXDohGouiYqPMp+LKcB5Kmk+6Q8kMzcsoHUjHxv
+1ih10qykFwNMNK7lYZzFrv/+C/pGKvQ8FpnQUA==
diff --git a/nss/cmd/bltest/tests/aes_gcm/ciphertext6 b/nss/cmd/bltest/tests/aes_gcm/ciphertext6
new file mode 100644
index 0000000..dc07bfd
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/ciphertext6
@@ -0,0 +1 @@
+zTOyisdz90ugDtHzElckNQ==
diff --git a/nss/cmd/bltest/tests/aes_gcm/ciphertext7 b/nss/cmd/bltest/tests/aes_gcm/ciphertext7
new file mode 100644
index 0000000..d405c82
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/ciphertext7
@@ -0,0 +1 @@
+mOckfAfw/kEcJn5DhLD2AC/1jYADOSerjvTUWHUU8Ps=
diff --git a/nss/cmd/bltest/tests/aes_gcm/ciphertext8 b/nss/cmd/bltest/tests/aes_gcm/ciphertext8
new file mode 100644
index 0000000..53738bb
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/ciphertext8
@@ -0,0 +1,2 @@
+OYDKCzwA6EHrBvrEhyonV4WeHOqm79mEYoWTtAyh4Zx9dz0AwUTFJaxhnRjISj9H
+GOJEiy/jJNnM2icQrK3iVpkkp8hYcza/sRgCTbhnShQ=
diff --git a/nss/cmd/bltest/tests/aes_gcm/ciphertext9 b/nss/cmd/bltest/tests/aes_gcm/ciphertext9
new file mode 100644
index 0000000..bde2785
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/ciphertext9
@@ -0,0 +1,2 @@
+OYDKCzwA6EHrBvrEhyonV4WeHOqm79mEYoWTtAyh4Zx9dz0AwUTFJaxhnRjISj9H
+GOJEiy/jJNnM2icQJRlJjoDxR483ulW9bSdhjA==
diff --git a/nss/cmd/bltest/tests/aes_gcm/hex.c b/nss/cmd/bltest/tests/aes_gcm/hex.c
new file mode 100644
index 0000000..cdf583d
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/hex.c
@@ -0,0 +1,78 @@
+#include
+#include
+#include
+
+int
+tohex(int c)
+{
+ if ((c >= '0') && (c <= '9')) {
+ return c - '0';
+ }
+ if ((c >= 'a') && (c <= 'f')) {
+ return c - 'a' + 10;
+ }
+ if ((c >= 'A') && (c <= 'F')) {
+ return c - 'A' + 10;
+ }
+ return 0;
+}
+
+int
+isspace(int c)
+{
+ if (c <= ' ')
+ return 1;
+ if (c == '\n')
+ return 1;
+ if (c == '\t')
+ return 1;
+ if (c == ':')
+ return 1;
+ if (c == ';')
+ return 1;
+ if (c == ',')
+ return 1;
+ return 0;
+}
+
+void
+verify_nibble(int nibble, int current)
+{
+ if (nibble != 0) {
+ fprintf(stderr, "count mismatch %d (nibbles=0x%x)\n", nibble, current);
+ fflush(stderr);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int current = 0;
+ int nibble = 0;
+ int skip = 0;
+
+ if (argv[1]) {
+ skip = atoi(argv[1]);
+ }
+
+#define NIBBLE_COUNT 2
+ while ((c = getchar()) != EOF) {
+ if (isspace(c)) {
+ verify_nibble(nibble, current);
+ continue;
+ }
+ if (skip) {
+ skip--;
+ continue;
+ }
+ current = current << 4 | tohex(c);
+ nibble++;
+ if (nibble == NIBBLE_COUNT) {
+ putchar(current);
+ nibble = 0;
+ current = 0;
+ }
+ }
+ return 0;
+}
diff --git a/nss/cmd/bltest/tests/aes_gcm/iv0 b/nss/cmd/bltest/tests/aes_gcm/iv0
new file mode 100644
index 0000000000000000000000000000000000000000..ce58bc9f84b9623e708de4eb8427a57d9f9a160f
GIT binary patch
literal 12
KcmZQzKmY&$3;+QD
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_gcm/iv1 b/nss/cmd/bltest/tests/aes_gcm/iv1
new file mode 100644
index 0000000000000000000000000000000000000000..ce58bc9f84b9623e708de4eb8427a57d9f9a160f
GIT binary patch
literal 12
KcmZQzKmY&$3;+QD
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_gcm/iv10 b/nss/cmd/bltest/tests/aes_gcm/iv10
new file mode 100644
index 0000000..bad60b0
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/iv10
@@ -0,0 +1 @@
+Êþº¾úÎÛ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/iv11 b/nss/cmd/bltest/tests/aes_gcm/iv11
new file mode 100644
index 0000000..f446641
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/iv11
@@ -0,0 +1 @@
+“"]ø„åUœZÿRiªjz•8SO}¡äÃÒ£§(ÃÀÉQV€•9üðâBškRT®Ûõ ÞjW¦7³›
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/iv12 b/nss/cmd/bltest/tests/aes_gcm/iv12
new file mode 100644
index 0000000000000000000000000000000000000000..ce58bc9f84b9623e708de4eb8427a57d9f9a160f
GIT binary patch
literal 12
KcmZQzKmY&$3;+QD
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_gcm/iv13 b/nss/cmd/bltest/tests/aes_gcm/iv13
new file mode 100644
index 0000000000000000000000000000000000000000..ce58bc9f84b9623e708de4eb8427a57d9f9a160f
GIT binary patch
literal 12
KcmZQzKmY&$3;+QD
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_gcm/iv14 b/nss/cmd/bltest/tests/aes_gcm/iv14
new file mode 100644
index 0000000..e3728f7
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/iv14
@@ -0,0 +1 @@
+Êþº¾úÎÛÞÊøˆ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/iv15 b/nss/cmd/bltest/tests/aes_gcm/iv15
new file mode 100644
index 0000000..e3728f7
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/iv15
@@ -0,0 +1 @@
+Êþº¾úÎÛÞÊøˆ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/iv16 b/nss/cmd/bltest/tests/aes_gcm/iv16
new file mode 100644
index 0000000..bad60b0
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/iv16
@@ -0,0 +1 @@
+Êþº¾úÎÛ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/iv17 b/nss/cmd/bltest/tests/aes_gcm/iv17
new file mode 100644
index 0000000..f446641
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/iv17
@@ -0,0 +1 @@
+“"]ø„åUœZÿRiªjz•8SO}¡äÃÒ£§(ÃÀÉQV€•9üðâBškRT®Ûõ ÞjW¦7³›
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/iv2 b/nss/cmd/bltest/tests/aes_gcm/iv2
new file mode 100644
index 0000000..e3728f7
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/iv2
@@ -0,0 +1 @@
+Êþº¾úÎÛÞÊøˆ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/iv3 b/nss/cmd/bltest/tests/aes_gcm/iv3
new file mode 100644
index 0000000..e3728f7
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/iv3
@@ -0,0 +1 @@
+Êþº¾úÎÛÞÊøˆ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/iv4 b/nss/cmd/bltest/tests/aes_gcm/iv4
new file mode 100644
index 0000000..bad60b0
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/iv4
@@ -0,0 +1 @@
+Êþº¾úÎÛ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/iv5 b/nss/cmd/bltest/tests/aes_gcm/iv5
new file mode 100644
index 0000000..f446641
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/iv5
@@ -0,0 +1 @@
+“"]ø„åUœZÿRiªjz•8SO}¡äÃÒ£§(ÃÀÉQV€•9üðâBškRT®Ûõ ÞjW¦7³›
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/iv6 b/nss/cmd/bltest/tests/aes_gcm/iv6
new file mode 100644
index 0000000000000000000000000000000000000000..ce58bc9f84b9623e708de4eb8427a57d9f9a160f
GIT binary patch
literal 12
KcmZQzKmY&$3;+QD
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_gcm/iv7 b/nss/cmd/bltest/tests/aes_gcm/iv7
new file mode 100644
index 0000000000000000000000000000000000000000..ce58bc9f84b9623e708de4eb8427a57d9f9a160f
GIT binary patch
literal 12
KcmZQzKmY&$3;+QD
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_gcm/iv8 b/nss/cmd/bltest/tests/aes_gcm/iv8
new file mode 100644
index 0000000..e3728f7
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/iv8
@@ -0,0 +1 @@
+Êþº¾úÎÛÞÊøˆ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/iv9 b/nss/cmd/bltest/tests/aes_gcm/iv9
new file mode 100644
index 0000000..e3728f7
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/iv9
@@ -0,0 +1 @@
+Êþº¾úÎÛÞÊøˆ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/key0 b/nss/cmd/bltest/tests/aes_gcm/key0
new file mode 100644
index 0000000000000000000000000000000000000000..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
KcmZQzKm`B*5C8!H
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_gcm/key1 b/nss/cmd/bltest/tests/aes_gcm/key1
new file mode 100644
index 0000000000000000000000000000000000000000..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
KcmZQzKm`B*5C8!H
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_gcm/key10 b/nss/cmd/bltest/tests/aes_gcm/key10
new file mode 100644
index 0000000..222b4b5
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/key10
@@ -0,0 +1 @@
+þÿé’†esmj”g0ƒþÿé’†es
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/key11 b/nss/cmd/bltest/tests/aes_gcm/key11
new file mode 100644
index 0000000..222b4b5
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/key11
@@ -0,0 +1 @@
+þÿé’†esmj”g0ƒþÿé’†es
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/key12 b/nss/cmd/bltest/tests/aes_gcm/key12
new file mode 100644
index 0000000000000000000000000000000000000000..4e4e4935707a596987ec1cc32e3d0d587dbe4f04
GIT binary patch
literal 32
KcmZQzzz+ZbAOHaX
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_gcm/key13 b/nss/cmd/bltest/tests/aes_gcm/key13
new file mode 100644
index 0000000000000000000000000000000000000000..4e4e4935707a596987ec1cc32e3d0d587dbe4f04
GIT binary patch
literal 32
KcmZQzzz+ZbAOHaX
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_gcm/key14 b/nss/cmd/bltest/tests/aes_gcm/key14
new file mode 100644
index 0000000..2163baf
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/key14
@@ -0,0 +1 @@
+þÿé’†esmj”g0ƒþÿé’†esmj”g0ƒ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/key15 b/nss/cmd/bltest/tests/aes_gcm/key15
new file mode 100644
index 0000000..2163baf
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/key15
@@ -0,0 +1 @@
+þÿé’†esmj”g0ƒþÿé’†esmj”g0ƒ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/key16 b/nss/cmd/bltest/tests/aes_gcm/key16
new file mode 100644
index 0000000..2163baf
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/key16
@@ -0,0 +1 @@
+þÿé’†esmj”g0ƒþÿé’†esmj”g0ƒ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/key17 b/nss/cmd/bltest/tests/aes_gcm/key17
new file mode 100644
index 0000000..2163baf
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/key17
@@ -0,0 +1 @@
+þÿé’†esmj”g0ƒþÿé’†esmj”g0ƒ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/key2 b/nss/cmd/bltest/tests/aes_gcm/key2
new file mode 100644
index 0000000..767ebda
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/key2
@@ -0,0 +1 @@
+þÿé’†esmj”g0ƒ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/key3 b/nss/cmd/bltest/tests/aes_gcm/key3
new file mode 100644
index 0000000..767ebda
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/key3
@@ -0,0 +1 @@
+þÿé’†esmj”g0ƒ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/key4 b/nss/cmd/bltest/tests/aes_gcm/key4
new file mode 100644
index 0000000..767ebda
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/key4
@@ -0,0 +1 @@
+þÿé’†esmj”g0ƒ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/key5 b/nss/cmd/bltest/tests/aes_gcm/key5
new file mode 100644
index 0000000..767ebda
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/key5
@@ -0,0 +1 @@
+þÿé’†esmj”g0ƒ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/key6 b/nss/cmd/bltest/tests/aes_gcm/key6
new file mode 100644
index 0000000000000000000000000000000000000000..4ac5fc6cf890b46738523c4d4d9d964e312f368f
GIT binary patch
literal 24
KcmZQzzzzTa7ytnP
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_gcm/key7 b/nss/cmd/bltest/tests/aes_gcm/key7
new file mode 100644
index 0000000000000000000000000000000000000000..4ac5fc6cf890b46738523c4d4d9d964e312f368f
GIT binary patch
literal 24
KcmZQzzzzTa7ytnP
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_gcm/key8 b/nss/cmd/bltest/tests/aes_gcm/key8
new file mode 100644
index 0000000..222b4b5
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/key8
@@ -0,0 +1 @@
+þÿé’†esmj”g0ƒþÿé’†es
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/key9 b/nss/cmd/bltest/tests/aes_gcm/key9
new file mode 100644
index 0000000..222b4b5
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/key9
@@ -0,0 +1 @@
+þÿé’†esmj”g0ƒþÿé’†es
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/mktst.sh b/nss/cmd/bltest/tests/aes_gcm/mktst.sh
new file mode 100644
index 0000000..a990f51
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/mktst.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
+do
+ file="test$i.txt"
+ grep K= $file | sed -e 's;K=;;' | hex > key$i
+ grep IV= $file | sed -e 's;IV=;;' | hex > iv$i
+ grep "C=" $file | sed -e 's;C=;;' | hex > ciphertext$i.bin
+ grep "P=" $file | sed -e 's;P=;;' | hex > plaintext$i
+ grep "A=" $file | sed -e 's;A=;;' | hex > aad$i
+ grep "T=" $file | sed -e 's;T=;;' | hex >> ciphertext$i.bin
+ btoa < ciphertext$i.bin > ciphertext$i
+ rm ciphertext$i.bin
+done
diff --git a/nss/cmd/bltest/tests/aes_gcm/numtests b/nss/cmd/bltest/tests/aes_gcm/numtests
new file mode 100644
index 0000000..3c03207
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/numtests
@@ -0,0 +1 @@
+18
diff --git a/nss/cmd/bltest/tests/aes_gcm/plaintext0 b/nss/cmd/bltest/tests/aes_gcm/plaintext0
new file mode 100644
index 0000000..e69de29
diff --git a/nss/cmd/bltest/tests/aes_gcm/plaintext1 b/nss/cmd/bltest/tests/aes_gcm/plaintext1
new file mode 100644
index 0000000000000000000000000000000000000000..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
KcmZQzKm`B*5C8!H
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_gcm/plaintext10 b/nss/cmd/bltest/tests/aes_gcm/plaintext10
new file mode 100644
index 0000000..0050587
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/plaintext10
@@ -0,0 +1 @@
+Ù12%ø„å¥Y ůõ&š†§©S4÷Ú.L0=Š1Šr<••h S/Ï$I¦µ%±jíõª
æWºc{9
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/plaintext11 b/nss/cmd/bltest/tests/aes_gcm/plaintext11
new file mode 100644
index 0000000..0050587
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/plaintext11
@@ -0,0 +1 @@
+Ù12%ø„å¥Y ůõ&š†§©S4÷Ú.L0=Š1Šr<••h S/Ï$I¦µ%±jíõª
æWºc{9
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/plaintext12 b/nss/cmd/bltest/tests/aes_gcm/plaintext12
new file mode 100644
index 0000000..e69de29
diff --git a/nss/cmd/bltest/tests/aes_gcm/plaintext13 b/nss/cmd/bltest/tests/aes_gcm/plaintext13
new file mode 100644
index 0000000000000000000000000000000000000000..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
KcmZQzKm`B*5C8!H
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_gcm/plaintext14 b/nss/cmd/bltest/tests/aes_gcm/plaintext14
new file mode 100644
index 0000000..664f6c9
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/plaintext14
@@ -0,0 +1 @@
+Ù12%ø„å¥Y ůõ&š†§©S4÷Ú.L0=Š1Šr<••h S/Ï$I¦µ%±jíõª
æWºc{9¯ÒU
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/plaintext15 b/nss/cmd/bltest/tests/aes_gcm/plaintext15
new file mode 100644
index 0000000..0050587
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/plaintext15
@@ -0,0 +1 @@
+Ù12%ø„å¥Y ůõ&š†§©S4÷Ú.L0=Š1Šr<••h S/Ï$I¦µ%±jíõª
æWºc{9
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/plaintext16 b/nss/cmd/bltest/tests/aes_gcm/plaintext16
new file mode 100644
index 0000000..0050587
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/plaintext16
@@ -0,0 +1 @@
+Ù12%ø„å¥Y ůõ&š†§©S4÷Ú.L0=Š1Šr<••h S/Ï$I¦µ%±jíõª
æWºc{9
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/plaintext17 b/nss/cmd/bltest/tests/aes_gcm/plaintext17
new file mode 100644
index 0000000..0050587
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/plaintext17
@@ -0,0 +1 @@
+Ù12%ø„å¥Y ůõ&š†§©S4÷Ú.L0=Š1Šr<••h S/Ï$I¦µ%±jíõª
æWºc{9
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/plaintext2 b/nss/cmd/bltest/tests/aes_gcm/plaintext2
new file mode 100644
index 0000000..664f6c9
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/plaintext2
@@ -0,0 +1 @@
+Ù12%ø„å¥Y ůõ&š†§©S4÷Ú.L0=Š1Šr<••h S/Ï$I¦µ%±jíõª
æWºc{9¯ÒU
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/plaintext3 b/nss/cmd/bltest/tests/aes_gcm/plaintext3
new file mode 100644
index 0000000..0050587
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/plaintext3
@@ -0,0 +1 @@
+Ù12%ø„å¥Y ůõ&š†§©S4÷Ú.L0=Š1Šr<••h S/Ï$I¦µ%±jíõª
æWºc{9
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/plaintext4 b/nss/cmd/bltest/tests/aes_gcm/plaintext4
new file mode 100644
index 0000000..0050587
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/plaintext4
@@ -0,0 +1 @@
+Ù12%ø„å¥Y ůõ&š†§©S4÷Ú.L0=Š1Šr<••h S/Ï$I¦µ%±jíõª
æWºc{9
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/plaintext5 b/nss/cmd/bltest/tests/aes_gcm/plaintext5
new file mode 100644
index 0000000..0050587
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/plaintext5
@@ -0,0 +1 @@
+Ù12%ø„å¥Y ůõ&š†§©S4÷Ú.L0=Š1Šr<••h S/Ï$I¦µ%±jíõª
æWºc{9
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/plaintext6 b/nss/cmd/bltest/tests/aes_gcm/plaintext6
new file mode 100644
index 0000000..e69de29
diff --git a/nss/cmd/bltest/tests/aes_gcm/plaintext7 b/nss/cmd/bltest/tests/aes_gcm/plaintext7
new file mode 100644
index 0000000000000000000000000000000000000000..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
KcmZQzKm`B*5C8!H
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/aes_gcm/plaintext8 b/nss/cmd/bltest/tests/aes_gcm/plaintext8
new file mode 100644
index 0000000..664f6c9
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/plaintext8
@@ -0,0 +1 @@
+Ù12%ø„å¥Y ůõ&š†§©S4÷Ú.L0=Š1Šr<••h S/Ï$I¦µ%±jíõª
æWºc{9¯ÒU
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/plaintext9 b/nss/cmd/bltest/tests/aes_gcm/plaintext9
new file mode 100644
index 0000000..0050587
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/plaintext9
@@ -0,0 +1 @@
+Ù12%ø„å¥Y ůõ&š†§©S4÷Ú.L0=Š1Šr<••h S/Ï$I¦µ%±jíõª
æWºc{9
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/aes_gcm/test0.txt b/nss/cmd/bltest/tests/aes_gcm/test0.txt
new file mode 100644
index 0000000..a8bd4e1
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/test0.txt
@@ -0,0 +1,11 @@
+test="Test Case 1"
+K=00000000000000000000000000000000
+P=
+IV=000000000000000000000000
+H=66e94bd4ef8a2c3b884cfa59ca342b2e
+Y0=00000000000000000000000000000001
+E(K,Y0)=58e2fccefa7e3061367f1d57a4e7455a
+len(A)||len(C)=00000000000000000000000000000000
+GHASH(H,A,C)=00000000000000000000000000000000
+C=
+T=58e2fccefa7e3061367f1d57a4e7455a
diff --git a/nss/cmd/bltest/tests/aes_gcm/test1.txt b/nss/cmd/bltest/tests/aes_gcm/test1.txt
new file mode 100644
index 0000000..7bb83ce
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/test1.txt
@@ -0,0 +1,14 @@
+test="Test Case 2"
+K=00000000000000000000000000000000
+P=00000000000000000000000000000000
+IV=000000000000000000000000
+H=66e94bd4ef8a2c3b884cfa59ca342b2e
+Y0=00000000000000000000000000000001
+E(K,Y0)=58e2fccefa7e3061367f1d57a4e7455a
+Y1=00000000000000000000000000000002
+E(K,Y1)=0388dace60b6a392f328c2b971b2fe78
+X1 5e2ec746917062882c85b0685353deb7
+len(A)||len(C)=00000000000000000000000000000080
+GHASH(H,A,C)=f38cbb1ad69223dcc3457ae5b6b0f885
+C=0388dace60b6a392f328c2b971b2fe78
+T=ab6e47d42cec13bdf53a67b21257bddf
diff --git a/nss/cmd/bltest/tests/aes_gcm/test10.txt b/nss/cmd/bltest/tests/aes_gcm/test10.txt
new file mode 100644
index 0000000..2a4a5a9
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/test10.txt
@@ -0,0 +1,28 @@
+test="Test Case 11"
+K=feffe9928665731c6d6a8f9467308308feffe9928665731c
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+A=feedfacedeadbeeffeedfacedeadbeefabaddad2
+IV=cafebabefacedbad
+H=466923ec9ae682214f2c082badb39249
+N1=9473c07b02544299cf007c42c5778218
+len({})||len(IV)=00000000000000000000000000000040
+Y0=a14378078d27258a6292737e1802ada5
+E(K,Y0)=7bb6d647c902427ce7cf26563a337371
+X1=f3bf7ba3e305aeb05ed0d2e4fe076666
+X2=20a51fa2302e9c01b87c48f2c3d91a56
+Y1=a14378078d27258a6292737e1802ada6
+E(K,Y1)=d621c7bc5690a7b1487dbaab8ac76b22
+Y2=a14378078d27258a6292737e1802ada7
+E(K,Y2)=43c1ca7de78f4495ad0b18324e61fa25
+Y3=a14378078d27258a6292737e1802ada8
+E(K,Y3)=e1e0254a0f2f1626e9aa4ff09d7c64ec
+Y4=a14378078d27258a6292737e1802ada9
+E(K,Y4)=5850f4502486a1681a9319ce7d0afa59
+X3=8bdedafd6ee8e529689de3a269b8240d
+X4=6607feb377b49c9ecdbc696344fe22d8
+X5=8a19570a06500ba9405fcece4a73fb48
+X6=8532826e63ce4a5b89b70fa28f8070fe
+len(A)||len(C)=00000000000000a000000000000001e0
+GHASH(H,A,C)=1e6a133806607858ee80eaf237064089
+C=0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f7
+T=65dcc57fcf623a24094fcca40d3533f8
diff --git a/nss/cmd/bltest/tests/aes_gcm/test11.txt b/nss/cmd/bltest/tests/aes_gcm/test11.txt
new file mode 100644
index 0000000..d46e6f9
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/test11.txt
@@ -0,0 +1,31 @@
+test="Test Case 12"
+K=feffe9928665731c6d6a8f9467308308feffe9928665731c
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+A=feedfacedeadbeeffeedfacedeadbeefabaddad2
+IV=9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b
+H=466923ec9ae682214f2c082badb39249
+N1=19aef0f04763b0c87903c5a217d5314f
+N2=62120253f79efc978625d1feb03b5b5b
+N3=b6ce2a84e366de900fa78a1653df77fb
+N4=374ecad90487f0bb261ba817447e022c
+len({})||len(IV)=000000000000000000000000000001e0
+Y0=4505cdc367a054c5002820e96aebef27
+E(K,Y0)=5ea3194f9dd012a3b9bc5103d6e0284d
+X1=f3bf7ba3e305aeb05ed0d2e4fe076666
+X2=20a51fa2302e9c01b87c48f2c3d91a56
+Y1=4505cdc367a054c5002820e96aebef28
+E(K,Y1)=0b4fba4de46722d9ed691f9f2029df65
+Y2=4505cdc367a054c5002820e96aebef29
+E(K,Y2)=9b4e088bf380b03540bb87a5a257e437
+Y3=4505cdc367a054c5002820e96aebef2a
+E(K,Y3)=9ddb9c873a5cd48acd3f397cd28f9896
+Y4=4505cdc367a054c5002820e96aebef2b
+E(K,Y4)=5716ee92eff7c4b053d44c0294ea88cd
+X3=f70d61693ea7f53f08c866d6eedb1e4b
+X4=dc40bc9a181b35aed66488071ef282ae
+X5=85ffa424b87b35cac7be9c450f0d7aee
+X6=65233cbe5251f7d246bfc967a8678647
+len(A)||len(C)=00000000000000a000000000000001e0
+GHASH(H,A,C)=82567fb0b4cc371801eadec005968e94
+C=d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e4581e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373b
+T=dcf566ff291c25bbb8568fc3d376a6d9
diff --git a/nss/cmd/bltest/tests/aes_gcm/test12.txt b/nss/cmd/bltest/tests/aes_gcm/test12.txt
new file mode 100644
index 0000000..b9ccfa8
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/test12.txt
@@ -0,0 +1,11 @@
+test="Test Case 13"
+K=0000000000000000000000000000000000000000000000000000000000000000
+P=
+IV=000000000000000000000000
+H=dc95c078a2408989ad48a21492842087
+Y0=00000000000000000000000000000001
+E(K,Y0)=530f8afbc74536b9a963b4f1c4cb738b
+len(A)||len(C)=00000000000000000000000000000000
+GHASH(H,A,C)=00000000000000000000000000000000
+C=
+T=530f8afbc74536b9a963b4f1c4cb738b
diff --git a/nss/cmd/bltest/tests/aes_gcm/test13.txt b/nss/cmd/bltest/tests/aes_gcm/test13.txt
new file mode 100644
index 0000000..b589ba4
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/test13.txt
@@ -0,0 +1,14 @@
+test="Test Case 14"
+K=0000000000000000000000000000000000000000000000000000000000000000
+P=00000000000000000000000000000000
+IV=000000000000000000000000
+H=dc95c078a2408989ad48a21492842087
+Y0=00000000000000000000000000000001
+E(K,Y0)=530f8afbc74536b9a963b4f1c4cb738b
+Y1=00000000000000000000000000000002
+E(K,Y1)=cea7403d4d606b6e074ec5d3baf39d18
+X1=fd6ab7586e556dba06d69cfe6223b262
+len(A)||len(C)=00000000000000000000000000000080
+GHASH(H,A,C)=83de425c5edc5d498f382c441041ca92
+C=cea7403d4d606b6e074ec5d3baf39d18
+T=d0d1c8a799996bf0265b98b5d48ab919
diff --git a/nss/cmd/bltest/tests/aes_gcm/test14.txt b/nss/cmd/bltest/tests/aes_gcm/test14.txt
new file mode 100644
index 0000000..f650ea7
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/test14.txt
@@ -0,0 +1,23 @@
+test="Test Case 15"
+K=feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255
+IV=cafebabefacedbaddecaf888
+H=acbef20579b4b8ebce889bac8732dad7
+Y0=cafebabefacedbaddecaf88800000001
+E(K,Y0)=fd2caa16a5832e76aa132c1453eeda7e
+Y1=cafebabefacedbaddecaf88800000002
+E(K,Y1)=8b1cf3d561d27be251263e66857164e7
+Y2=cafebabefacedbaddecaf88800000003
+E(K,Y2)=e29d258faad137135bd49280af645bd8
+Y3=cafebabefacedbaddecaf88800000004
+E(K,Y3)=908c82ddcc65b26e887f85341f243d1d
+Y4=cafebabefacedbaddecaf88800000005
+E(K,Y4)=749cf39639b79c5d06aa8d5b932fc7f8
+X1=fcbefb78635d598eddaf982310670f35
+X2=29de812309d3116a6eff7ec844484f3e
+X3=45fad9deeda9ea561b8f199c3613845b
+X4=ed95f8e164bf3213febc740f0bd9c6af
+len(A)||len(C)=00000000000000000000000000000200
+GHASH(H,A,C)=4db870d37cb75fcb46097c36230d1612
+C=522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad
+T=b094dac5d93471bdec1a502270e3cc6c
diff --git a/nss/cmd/bltest/tests/aes_gcm/test15.txt b/nss/cmd/bltest/tests/aes_gcm/test15.txt
new file mode 100644
index 0000000..f1a49e3
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/test15.txt
@@ -0,0 +1,26 @@
+test="Test Case 16"
+K=feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+A=feedfacedeadbeeffeedfacedeadbeefabaddad2
+IV=cafebabefacedbaddecaf888
+H=acbef20579b4b8ebce889bac8732dad7
+Y0=cafebabefacedbaddecaf88800000001
+E(K,Y0)=fd2caa16a5832e76aa132c1453eeda7e
+X1=5165d242c2592c0a6375e2622cf925d2
+X2=8efa30ce83298b85fe71abefc0cdd01d
+Y1=cafebabefacedbaddecaf88800000002
+E(K,Y1)=8b1cf3d561d27be251263e66857164e7
+Y2=cafebabefacedbaddecaf88800000003
+E(K,Y2)=e29d258faad137135bd49280af645bd8
+Y3=cafebabefacedbaddecaf88800000004
+E(K,Y3)=908c82ddcc65b26e887f85341f243d1d
+Y4=cafebabefacedbaddecaf88800000005
+E(K,Y4)=749cf39639b79c5d06aa8d5b932fc7f8
+X3=abe07e0bb62354177480b550f9f6cdcc
+X4=3978e4f141b95f3b4699756b1c3c2082
+X5=8abf3c48901debe76837d8a05c7d6e87
+X6=9249beaf520c48b912fa120bbf391dc8
+len(A)||len(C)=00000000000000a000000000000001e0
+GHASH(H,A,C)=8bd0c4d8aacd391e67cca447e8c38f65
+C=522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662
+T=76fc6ece0f4e1768cddf8853bb2d551b
diff --git a/nss/cmd/bltest/tests/aes_gcm/test16.txt b/nss/cmd/bltest/tests/aes_gcm/test16.txt
new file mode 100644
index 0000000..6918aca
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/test16.txt
@@ -0,0 +1,28 @@
+test="Test Case 17"
+K=feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+A=feedfacedeadbeeffeedfacedeadbeefabaddad2
+IV=cafebabefacedbad
+H=acbef20579b4b8ebce889bac8732dad7
+N1=90c22e3d2aca34b971e8bd09708fae5c
+len({})||len(IV)=00000000000000000000000000000040
+Y0=0095df49dd90abe3e4d252475748f5d4
+E(K,Y0)=4f903f37fe611d454217fbfa5cd7d791
+X1=5165d242c2592c0a6375e2622cf925d2
+X2=8efa30ce83298b85fe71abefc0cdd01d
+Y1=0095df49dd90abe3e4d252475748f5d5
+E(K,Y1)=1a471fd432fc7bd70b1ec8fe5e6d6251
+Y2=0095df49dd90abe3e4d252475748f5d6
+E(K,Y2)=29bd481e1ea39d20eb63c7ea118b1792
+Y3=0095df49dd90abe3e4d252475748f5d7
+E(K,Y3)=e2898e46ac5cada3ba83cc1272618a5d
+Y4=0095df49dd90abe3e4d252475748f5d8
+E(K,Y4)=d3c6aefbcea602ce4e1fe026065447bf
+X3=55e1ff68f9249e64b95223858e5cb936
+X4=cef1c034383dc96f733aaa4c99bd3e61
+X5=68588d004fd468f5854515039b08165d
+X6=2378943c034697f72a80fce5059bf3f3
+len(A)||len(C)=00000000000000a000000000000001e0
+GHASH(H,A,C)=75a34288b8c68f811c52b2e9a2f97f63
+C=c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f
+T=3a337dbf46a792c45e454913fe2ea8f2
diff --git a/nss/cmd/bltest/tests/aes_gcm/test17.txt b/nss/cmd/bltest/tests/aes_gcm/test17.txt
new file mode 100644
index 0000000..a5c538e
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/test17.txt
@@ -0,0 +1,31 @@
+test="Test Case 18"
+K=feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+A=feedfacedeadbeeffeedfacedeadbeefabaddad2
+IV=9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b
+H=acbef20579b4b8ebce889bac8732dad7
+N1=0bfe66e2032f195516379f5fb710f987
+N2=f0631554d11409915feec8f9f5102aba
+N3=749b90dda19a1557fd9e9fd31fed1d14
+N4=7a6a833f260d848793b327cb07d1b190
+len({})||len(IV)=000000000000000000000000000001e0
+Y0=0cd953e2140a5976079f8e2406bc8eb4
+E(K,Y0)=71b54d092bb0c3d9ba94538d4096e691
+X1=5165d242c2592c0a6375e2622cf925d2
+X2=8efa30ce83298b85fe71abefc0cdd01d
+Y1=0cd953e2140a5976079f8e2406bc8eb5
+E(K,Y1)=83bcdd0af41a551452047196ca6b0cba
+Y2=0cd953e2140a5976079f8e2406bc8eb6
+E(K,Y2)=68151b79baea93c38e149b72e545e186
+Y3=0cd953e2140a5976079f8e2406bc8eb7
+E(K,Y3)=13fccf22159a4d16026ce5d58c7e99fb
+Y4=0cd953e2140a5976079f8e2406bc8eb8
+E(K,Y4)=132b64628a031e79fecd050675a64f07
+X3=e963941cfa8c417bdaa3b3d94ab4e905
+X4=2178d7f836e5fa105ce0fdf0fc8f0654
+X5=bac14eeba3216f966b3e7e011475b832
+X6=cc9ae9175729a649936e890bd971a8bf
+len(A)||len(C)=00000000000000a000000000000001e0
+GHASH(H,A,C)=d5ffcf6fc5ac4d69722187421a7f170b
+C=5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f
+T=a44a8266ee1c8eb0c8b5d4cf5ae9f19a
diff --git a/nss/cmd/bltest/tests/aes_gcm/test2.txt b/nss/cmd/bltest/tests/aes_gcm/test2.txt
new file mode 100644
index 0000000..8e69bf6
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/test2.txt
@@ -0,0 +1,23 @@
+test="Test Case 3"
+K=feffe9928665731c6d6a8f9467308308
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255
+IV=cafebabefacedbaddecaf888
+H=b83b533708bf535d0aa6e52980d53b78
+Y0=cafebabefacedbaddecaf88800000001
+E(K,Y0)=3247184b3c4f69a44dbcd22887bbb418
+Y1=cafebabefacedbaddecaf88800000002
+E(K,Y1)=9bb22ce7d9f372c1ee2b28722b25f206
+Y2=cafebabefacedbaddecaf88800000003
+E(K,Y2)=650d887c3936533a1b8d4e1ea39d2b5c
+Y3=cafebabefacedbaddecaf88800000004
+E(K,Y3)=3de91827c10e9a4f5240647ee5221f20
+Y4=cafebabefacedbaddecaf88800000005
+E(K,Y4)=aac9e6ccc0074ac0873b9ba85d908bd0
+X1=59ed3f2bb1a0aaa07c9f56c6a504647b
+X2=b714c9048389afd9f9bc5c1d4378e052
+X3=47400c6577b1ee8d8f40b2721e86ff10
+X4=4796cf49464704b5dd91f159bb1b7f95
+len(A)||len(C)=00000000000000000000000000000200
+GHASH(H,A,C)=7f1b32b81b820d02614f8895ac1d4eac
+C=42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985
+T=4d5c2af327cd64a62cf35abd2ba6fab4
diff --git a/nss/cmd/bltest/tests/aes_gcm/test3.txt b/nss/cmd/bltest/tests/aes_gcm/test3.txt
new file mode 100644
index 0000000..4083eac
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/test3.txt
@@ -0,0 +1,26 @@
+test="Test Case 4"
+K=feffe9928665731c6d6a8f9467308308
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+A=feedfacedeadbeeffeedfacedeadbeefabaddad2
+IV=cafebabefacedbaddecaf888
+H=b83b533708bf535d0aa6e52980d53b78
+Y0=cafebabefacedbaddecaf88800000001
+E(K,Y0)=3247184b3c4f69a44dbcd22887bbb418
+X1=ed56aaf8a72d67049fdb9228edba1322
+X2=cd47221ccef0554ee4bb044c88150352
+Y1=cafebabefacedbaddecaf88800000002
+E(K,Y1)=9bb22ce7d9f372c1ee2b28722b25f206
+Y2=cafebabefacedbaddecaf88800000003
+E(K,Y2)=650d887c3936533a1b8d4e1ea39d2b5c
+Y3=cafebabefacedbaddecaf88800000004
+E(K,Y3)=3de91827c10e9a4f5240647ee5221f20
+Y4=cafebabefacedbaddecaf88800000005
+E(K,Y4)=aac9e6ccc0074ac0873b9ba85d908bd0
+X3=54f5e1b2b5a8f9525c23924751a3ca51
+X4=324f585c6ffc1359ab371565d6c45f93
+X5=ca7dd446af4aa70cc3c0cd5abba6aa1c
+X6=1590df9b2eb6768289e57d56274c8570
+len(A)||len(C)=00000000000000a000000000000001e0
+GHASH(H,A,C)=698e57f70e6ecc7fd9463b7260a9ae5f
+C=42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091
+T=5bc94fbc3221a5db94fae95ae7121a47
diff --git a/nss/cmd/bltest/tests/aes_gcm/test4.txt b/nss/cmd/bltest/tests/aes_gcm/test4.txt
new file mode 100644
index 0000000..ec62258
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/test4.txt
@@ -0,0 +1,28 @@
+test="Test Case 5"
+K=feffe9928665731c6d6a8f9467308308
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+A=feedfacedeadbeeffeedfacedeadbeefabaddad2
+IV=cafebabefacedbad
+H=b83b533708bf535d0aa6e52980d53b78
+N1=6f288b846e5fed9a18376829c86a6a16
+len({})||len(C)=00000000000000000000000000000040
+Y0=c43a83c4c4badec4354ca984db252f7d
+E(K,Y0)=e94ab9535c72bea9e089c93d48e62fb0
+X1=ed56aaf8a72d67049fdb9228edba1322
+X2=cd47221ccef0554ee4bb044c88150352
+Y1=c43a83c4c4badec4354ca984db252f7e
+E(K,Y1)=b8040969d08295afd226fcda0ddf61cf
+Y2=c43a83c4c4badec4354ca984db252f7f
+E(K,Y2)=ef3c83225af93122192ad5c4f15dfe51
+Y3=c43a83c4c4badec4354ca984db252f80
+E(K,Y3)=6fbc659571f72de104c67b609d2fde67
+Y4=c43a83c4c4badec4354ca984db252f81
+E(K,Y4)=f8e3581441a1e950785c3ea1430c6fa6
+X3=9379e2feae14649c86cf2250e3a81916
+X4=65dde904c92a6b3db877c4817b50a5f4
+X5=48c53cf863b49a1b0bbfc48c3baaa89d
+X6=08c873f1c8cec3effc209a07468caab1
+len(A)||len(C)=00000000000000a000000000000001e0
+GHASH(H,A,C)=df586bb4c249b92cb6922877e444d37b
+C=61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c742373806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598
+T=3612d2e79e3b0785561be14aaca2fccb
diff --git a/nss/cmd/bltest/tests/aes_gcm/test5.txt b/nss/cmd/bltest/tests/aes_gcm/test5.txt
new file mode 100644
index 0000000..709251b
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/test5.txt
@@ -0,0 +1,31 @@
+test="Test Case 6"
+K=feffe9928665731c6d6a8f9467308308
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+A=feedfacedeadbeeffeedfacedeadbeefabaddad2
+IV=9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b
+H=b83b533708bf535d0aa6e52980d53b78
+N1=004d6599d7fb1634756e1e299d81630f
+N2=88ffe8a3c8033df4b54d732f7f88408e
+N3=24e694cfab657beabba8055aad495e23
+N4=d8349a5eda24943c8fbb2ef5168b20cb
+len({})||len(IV)=000000000000000000000000000001e0
+Y0=3bab75780a31c059f83d2a44752f9864
+7dc63b399f2d98d57ab073b6baa4138e
+X1=ed56aaf8a72d67049fdb9228edba1322
+X2=cd47221ccef0554ee4bb044c88150352
+Y1=3bab75780a31c059f83d2a44752f9865
+E(K,Y1)=55d37bbd9ad21353a6f93a690eca9e0e
+Y2=3bab75780a31c059f83d2a44752f9866
+E(K,Y2)=3836bbf6d696e672946a1a01404fa6d5
+Y3=3bab75780a31c059f83d2a44752f9867
+E(K,Y3)=1dd8a5316ecc35c3e313bca59d2ac94a
+Y4=3bab75780a31c059f83d2a44752f9868
+E(K,Y4)=6742982706a9f154f657d5dc94b746db
+X3=31727669c63c6f078b5d22adbbbca384
+X4=480c00db2679065a7ed2f771a53acacd
+X5=1c1ae3c355e2214466a9923d2ba6ab35
+X6=0694c6f16bb0275a48891d06590344b0
+len(A)||len(C)=00000000000000a000000000000001e0
+GHASH(H,A,C)=1c5afe9760d3932f3c9a878aac3dc3de
+C=8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5
+T=619cc5aefffe0bfa462af43c1699d050
diff --git a/nss/cmd/bltest/tests/aes_gcm/test6.txt b/nss/cmd/bltest/tests/aes_gcm/test6.txt
new file mode 100644
index 0000000..b738e1f
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/test6.txt
@@ -0,0 +1,11 @@
+test="Test Case 7"
+K=000000000000000000000000000000000000000000000000
+P=
+IV=000000000000000000000000
+H=aae06992acbf52a3e8f4a96ec9300bd7
+Y0=00000000000000000000000000000001
+E(K,Y0)=cd33b28ac773f74ba00ed1f312572435
+len(A)||len(C)=00000000000000000000000000000000
+GHASH(H,A,C)=00000000000000000000000000000000
+C=
+T=cd33b28ac773f74ba00ed1f312572435
diff --git a/nss/cmd/bltest/tests/aes_gcm/test7.txt b/nss/cmd/bltest/tests/aes_gcm/test7.txt
new file mode 100644
index 0000000..68bc521
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/test7.txt
@@ -0,0 +1,14 @@
+test="Test Case 8"
+K=000000000000000000000000000000000000000000000000
+P=00000000000000000000000000000000
+IV=000000000000000000000000
+H=aae06992acbf52a3e8f4a96ec9300bd7
+Y0=00000000000000000000000000000001
+E(K,Y0)=cd33b28ac773f74ba00ed1f312572435
+Y1=00000000000000000000000000000002
+E(K,Y1)=98e7247c07f0fe411c267e4384b0f600
+X1=90e87315fb7d4e1b4092ec0cbfda5d7d
+len(A)||len(C)=00000000000000000000000000000080
+GHASH(H,A,C)=e2c63f0ac44ad0e02efa05ab6743d4ce
+C=98e7247c07f0fe411c267e4384b0f600
+T=2ff58d80033927ab8ef4d4587514f0fb
diff --git a/nss/cmd/bltest/tests/aes_gcm/test8.txt b/nss/cmd/bltest/tests/aes_gcm/test8.txt
new file mode 100644
index 0000000..5443240
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/test8.txt
@@ -0,0 +1,23 @@
+test="Test Case 9"
+K=feffe9928665731c6d6a8f9467308308feffe9928665731c
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255
+IV=cafebabefacedbaddecaf888
+H=466923ec9ae682214f2c082badb39249
+Y0=cafebabefacedbaddecaf88800000001
+E(K,Y0)=c835aa88aebbc94f5a02e179fdcfc3e4
+Y1=cafebabefacedbaddecaf88800000002
+E(K,Y1)=e0b1f82ec484eea44e5ff30128df01cd
+Y2=cafebabefacedbaddecaf88800000003
+E(K,Y2)=0339b5b9b3db2e5e4cc9a38986906bee
+Y3=cafebabefacedbaddecaf88800000004
+E(K,Y3)=614b3195542ccc7683ae933c81ec8a62
+Y4=cafebabefacedbaddecaf88800000005
+E(K,Y4)=a988a97e85eec28e76b95c29b6023003
+X1=dddca3f91c17821ffac4a6d0fed176f7
+X2=a4e84ac60e2730f4a7e0e1eef708b198
+X3=e67592048dd7153973a0dbbb8804bee2
+X4=503e86628536625fb746ce3cecea433f
+len(A)||len(C)=00000000000000000000000000000200
+GHASH(H,A,C)=51110d40f6c8fff0eb1ae33445a889f0
+C=3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710acade256
+T=9924a7c8587336bfb118024db8674a14
diff --git a/nss/cmd/bltest/tests/aes_gcm/test9.txt b/nss/cmd/bltest/tests/aes_gcm/test9.txt
new file mode 100644
index 0000000..bcd5939
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/test9.txt
@@ -0,0 +1,26 @@
+test="Test Case 10"
+K=feffe9928665731c6d6a8f9467308308feffe9928665731c
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+A=feedfacedeadbeeffeedfacedeadbeefabaddad2
+IV=cafebabefacedbaddecaf888
+H=466923ec9ae682214f2c082badb39249
+Y0=cafebabefacedbaddecaf88800000001
+E(K,Y0)=c835aa88aebbc94f5a02e179fdcfc3e4
+X1=f3bf7ba3e305aeb05ed0d2e4fe076666
+X2=20a51fa2302e9c01b87c48f2c3d91a56
+Y1=cafebabefacedbaddecaf88800000002
+E(K,Y1)=e0b1f82ec484eea44e5ff30128df01cd
+Y2=cafebabefacedbaddecaf88800000003
+E(K,Y2)=0339b5b9b3db2e5e4cc9a38986906bee
+Y3=cafebabefacedbaddecaf88800000004
+E(K,Y3)=614b3195542ccc7683ae933c81ec8a62
+Y4=cafebabefacedbaddecaf88800000005
+E(K,Y4)=a988a97e85eec28e76b95c29b6023003
+X3=714f9700ddf520f20695f6180c6e669d
+X4=e858680b7b240d2ecf7e06bbad4524e2
+X5=3f4865abd6bb3fb9f5c4a816f0a9b778
+X6=4256f67fe87b4f49422ba11af857c973
+len(A)||len(C)=00000000000000a000000000000001e0
+GHASH(H,A,C)=ed2ce3062e4a8ec06db8b4c490e8a268
+C=3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710
+T=2519498e80f1478f37ba55bd6d27618c
diff --git a/nss/cmd/bltest/tests/aes_gcm/test_source.txt b/nss/cmd/bltest/tests/aes_gcm/test_source.txt
new file mode 100644
index 0000000..61c78fc
--- /dev/null
+++ b/nss/cmd/bltest/tests/aes_gcm/test_source.txt
@@ -0,0 +1,439 @@
+# AppendixB AES Test Vectors
+# From "The Galois/Counter Mode of Operation (GCM)", David A McGree & John Viega,
+# http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf
+#
+# This appendix contains test cases for AES GCM, with AES key sizes of 128, 192, and 256 bits. These
+# cases use the same notation as in Equations 1 and 2, with the exception that Ni is used in place of
+# Xi when GHASH is used to compute Y0 , in order to distinguish that case from the later invocation
+# of GHASH. All values are in hexadecimal, and a zero-length variable is indicated by the absence
+# of any hex digits. Each line consists of 128 bits of data, and variables whose lengths exceed that
+# value are continued on successive lines. The leftmost hex digit corresponds to the leftmost four
+# bits of the variable. For example, the lowest 128 bits of the field polynomial are represented as
+# e100000000000000000000000000000000.
+#
+
+test="Test Case 1"
+K=00000000000000000000000000000000
+P=
+IV=000000000000000000000000
+H=66e94bd4ef8a2c3b884cfa59ca342b2e
+Y0=00000000000000000000000000000001
+E(K,Y0)=58e2fccefa7e3061367f1d57a4e7455a
+len(A)||len(C)=00000000000000000000000000000000
+GHASH(H,A,C)=00000000000000000000000000000000
+C=
+T=58e2fccefa7e3061367f1d57a4e7455a
+
+
+test="Test Case 2"
+K=00000000000000000000000000000000
+P=00000000000000000000000000000000
+IV=000000000000000000000000
+H=66e94bd4ef8a2c3b884cfa59ca342b2e
+Y0=00000000000000000000000000000001
+E(K,Y0)=58e2fccefa7e3061367f1d57a4e7455a
+Y1=00000000000000000000000000000002
+E(K,Y1)=0388dace60b6a392f328c2b971b2fe78
+X1 5e2ec746917062882c85b0685353deb7
+len(A)||len(C)=00000000000000000000000000000080
+GHASH(H,A,C)=f38cbb1ad69223dcc3457ae5b6b0f885
+C=0388dace60b6a392f328c2b971b2fe78
+T=ab6e47d42cec13bdf53a67b21257bddf
+
+test="Test Case 3"
+K=feffe9928665731c6d6a8f9467308308
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255
+IV=cafebabefacedbaddecaf888
+H=b83b533708bf535d0aa6e52980d53b78
+Y0=cafebabefacedbaddecaf88800000001
+E(K,Y0)=3247184b3c4f69a44dbcd22887bbb418
+Y1=cafebabefacedbaddecaf88800000002
+E(K,Y1)=9bb22ce7d9f372c1ee2b28722b25f206
+Y2=cafebabefacedbaddecaf88800000003
+E(K,Y2)=650d887c3936533a1b8d4e1ea39d2b5c
+Y3=cafebabefacedbaddecaf88800000004
+E(K,Y3)=3de91827c10e9a4f5240647ee5221f20
+Y4=cafebabefacedbaddecaf88800000005
+E(K,Y4)=aac9e6ccc0074ac0873b9ba85d908bd0
+X1=59ed3f2bb1a0aaa07c9f56c6a504647b
+X2=b714c9048389afd9f9bc5c1d4378e052
+X3=47400c6577b1ee8d8f40b2721e86ff10
+X4=4796cf49464704b5dd91f159bb1b7f95
+len(A)||len(C)=00000000000000000000000000000200
+GHASH(H,A,C)=7f1b32b81b820d02614f8895ac1d4eac
+C=42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985
+T=4d5c2af327cd64a62cf35abd2ba6fab4
+
+test="Test Case 4"
+K=feffe9928665731c6d6a8f9467308308
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+A=feedfacedeadbeeffeedfacedeadbeefabaddad2
+IV=cafebabefacedbaddecaf888
+H=b83b533708bf535d0aa6e52980d53b78
+Y0=cafebabefacedbaddecaf88800000001
+E(K,Y0)=3247184b3c4f69a44dbcd22887bbb418
+X1=ed56aaf8a72d67049fdb9228edba1322
+X2=cd47221ccef0554ee4bb044c88150352
+Y1=cafebabefacedbaddecaf88800000002
+E(K,Y1)=9bb22ce7d9f372c1ee2b28722b25f206
+Y2=cafebabefacedbaddecaf88800000003
+E(K,Y2)=650d887c3936533a1b8d4e1ea39d2b5c
+Y3=cafebabefacedbaddecaf88800000004
+E(K,Y3)=3de91827c10e9a4f5240647ee5221f20
+Y4=cafebabefacedbaddecaf88800000005
+E(K,Y4)=aac9e6ccc0074ac0873b9ba85d908bd0
+X3=54f5e1b2b5a8f9525c23924751a3ca51
+X4=324f585c6ffc1359ab371565d6c45f93
+X5=ca7dd446af4aa70cc3c0cd5abba6aa1c
+X6=1590df9b2eb6768289e57d56274c8570
+len(A)||len(C)=00000000000000a000000000000001e0
+GHASH(H,A,C)=698e57f70e6ecc7fd9463b7260a9ae5f
+C=42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091
+T=5bc94fbc3221a5db94fae95ae7121a47
+
+test="Test Case 5"
+K=feffe9928665731c6d6a8f9467308308
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+A=feedfacedeadbeeffeedfacedeadbeefabaddad2
+IV=cafebabefacedbad
+H=b83b533708bf535d0aa6e52980d53b78
+N1=6f288b846e5fed9a18376829c86a6a16
+len({})||len(C)=00000000000000000000000000000040
+Y0=c43a83c4c4badec4354ca984db252f7d
+E(K,Y0)=e94ab9535c72bea9e089c93d48e62fb0
+X1=ed56aaf8a72d67049fdb9228edba1322
+X2=cd47221ccef0554ee4bb044c88150352
+Y1=c43a83c4c4badec4354ca984db252f7e
+E(K,Y1)=b8040969d08295afd226fcda0ddf61cf
+Y2=c43a83c4c4badec4354ca984db252f7f
+E(K,Y2)=ef3c83225af93122192ad5c4f15dfe51
+Y3=c43a83c4c4badec4354ca984db252f80
+E(K,Y3)=6fbc659571f72de104c67b609d2fde67
+Y4=c43a83c4c4badec4354ca984db252f81
+E(K,Y4)=f8e3581441a1e950785c3ea1430c6fa6
+X3=9379e2feae14649c86cf2250e3a81916
+X4=65dde904c92a6b3db877c4817b50a5f4
+X5=48c53cf863b49a1b0bbfc48c3baaa89d
+X6=08c873f1c8cec3effc209a07468caab1
+len(A)||len(C)=00000000000000a000000000000001e0
+GHASH(H,A,C)=df586bb4c249b92cb6922877e444d37b
+C=61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c742373806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598
+T=3612d2e79e3b0785561be14aaca2fccb
+
+test="Test Case 6"
+K=feffe9928665731c6d6a8f9467308308
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+A=feedfacedeadbeeffeedfacedeadbeefabaddad2
+IV=9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b
+H=b83b533708bf535d0aa6e52980d53b78
+N1=004d6599d7fb1634756e1e299d81630f
+N2=88ffe8a3c8033df4b54d732f7f88408e
+N3=24e694cfab657beabba8055aad495e23
+N4=d8349a5eda24943c8fbb2ef5168b20cb
+len({})||len(IV)=000000000000000000000000000001e0
+Y0=3bab75780a31c059f83d2a44752f9864
+7dc63b399f2d98d57ab073b6baa4138e
+X1=ed56aaf8a72d67049fdb9228edba1322
+X2=cd47221ccef0554ee4bb044c88150352
+Y1=3bab75780a31c059f83d2a44752f9865
+E(K,Y1)=55d37bbd9ad21353a6f93a690eca9e0e
+Y2=3bab75780a31c059f83d2a44752f9866
+E(K,Y2)=3836bbf6d696e672946a1a01404fa6d5
+Y3=3bab75780a31c059f83d2a44752f9867
+E(K,Y3)=1dd8a5316ecc35c3e313bca59d2ac94a
+Y4=3bab75780a31c059f83d2a44752f9868
+E(K,Y4)=6742982706a9f154f657d5dc94b746db
+X3=31727669c63c6f078b5d22adbbbca384
+X4=480c00db2679065a7ed2f771a53acacd
+X5=1c1ae3c355e2214466a9923d2ba6ab35
+X6=0694c6f16bb0275a48891d06590344b0
+len(A)||len(C)=00000000000000a000000000000001e0
+GHASH(H,A,C)=1c5afe9760d3932f3c9a878aac3dc3de
+C=8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5
+T=619cc5aefffe0bfa462af43c1699d050
+
+test="Test Case 7"
+K=000000000000000000000000000000000000000000000000
+P=
+IV=000000000000000000000000
+H=aae06992acbf52a3e8f4a96ec9300bd7
+Y0=00000000000000000000000000000001
+E(K,Y0)=cd33b28ac773f74ba00ed1f312572435
+len(A)||len(C)=00000000000000000000000000000000
+GHASH(H,A,C)=00000000000000000000000000000000
+C=
+T=cd33b28ac773f74ba00ed1f312572435
+
+test="Test Case 8"
+K=000000000000000000000000000000000000000000000000
+P=00000000000000000000000000000000
+IV=000000000000000000000000
+H=aae06992acbf52a3e8f4a96ec9300bd7
+Y0=00000000000000000000000000000001
+E(K,Y0)=cd33b28ac773f74ba00ed1f312572435
+Y1=00000000000000000000000000000002
+E(K,Y1)=98e7247c07f0fe411c267e4384b0f600
+X1=90e87315fb7d4e1b4092ec0cbfda5d7d
+len(A)||len(C)=00000000000000000000000000000080
+GHASH(H,A,C)=e2c63f0ac44ad0e02efa05ab6743d4ce
+C=98e7247c07f0fe411c267e4384b0f600
+T=2ff58d80033927ab8ef4d4587514f0fb
+
+
+test="Test Case 9"
+K=feffe9928665731c6d6a8f9467308308feffe9928665731c
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255
+IV=cafebabefacedbaddecaf888
+H=466923ec9ae682214f2c082badb39249
+Y0=cafebabefacedbaddecaf88800000001
+E(K,Y0)=c835aa88aebbc94f5a02e179fdcfc3e4
+Y1=cafebabefacedbaddecaf88800000002
+E(K,Y1)=e0b1f82ec484eea44e5ff30128df01cd
+Y2=cafebabefacedbaddecaf88800000003
+E(K,Y2)=0339b5b9b3db2e5e4cc9a38986906bee
+Y3=cafebabefacedbaddecaf88800000004
+E(K,Y3)=614b3195542ccc7683ae933c81ec8a62
+Y4=cafebabefacedbaddecaf88800000005
+E(K,Y4)=a988a97e85eec28e76b95c29b6023003
+X1=dddca3f91c17821ffac4a6d0fed176f7
+X2=a4e84ac60e2730f4a7e0e1eef708b198
+X3=e67592048dd7153973a0dbbb8804bee2
+X4=503e86628536625fb746ce3cecea433f
+len(A)||len(C)=00000000000000000000000000000200
+GHASH(H,A,C)=51110d40f6c8fff0eb1ae33445a889f0
+C=3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710acade256
+T=9924a7c8587336bfb118024db8674a14
+
+test="Test Case 10"
+K=feffe9928665731c6d6a8f9467308308feffe9928665731c
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+A=feedfacedeadbeeffeedfacedeadbeefabaddad2
+IV=cafebabefacedbaddecaf888
+H=466923ec9ae682214f2c082badb39249
+Y0=cafebabefacedbaddecaf88800000001
+E(K,Y0)=c835aa88aebbc94f5a02e179fdcfc3e4
+X1=f3bf7ba3e305aeb05ed0d2e4fe076666
+X2=20a51fa2302e9c01b87c48f2c3d91a56
+Y1=cafebabefacedbaddecaf88800000002
+E(K,Y1)=e0b1f82ec484eea44e5ff30128df01cd
+Y2=cafebabefacedbaddecaf88800000003
+E(K,Y2)=0339b5b9b3db2e5e4cc9a38986906bee
+Y3=cafebabefacedbaddecaf88800000004
+E(K,Y3)=614b3195542ccc7683ae933c81ec8a62
+Y4=cafebabefacedbaddecaf88800000005
+E(K,Y4)=a988a97e85eec28e76b95c29b6023003
+X3=714f9700ddf520f20695f6180c6e669d
+X4=e858680b7b240d2ecf7e06bbad4524e2
+X5=3f4865abd6bb3fb9f5c4a816f0a9b778
+X6=4256f67fe87b4f49422ba11af857c973
+len(A)||len(C)=00000000000000a000000000000001e0
+GHASH(H,A,C)=ed2ce3062e4a8ec06db8b4c490e8a268
+C=3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710
+T=2519498e80f1478f37ba55bd6d27618c
+
+test="Test Case 11"
+K=feffe9928665731c6d6a8f9467308308feffe9928665731c
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+A=feedfacedeadbeeffeedfacedeadbeefabaddad2
+IV=cafebabefacedbad
+H=466923ec9ae682214f2c082badb39249
+N1=9473c07b02544299cf007c42c5778218
+len({})||len(IV)=00000000000000000000000000000040
+Y0=a14378078d27258a6292737e1802ada5
+E(K,Y0)=7bb6d647c902427ce7cf26563a337371
+X1=f3bf7ba3e305aeb05ed0d2e4fe076666
+X2=20a51fa2302e9c01b87c48f2c3d91a56
+Y1=a14378078d27258a6292737e1802ada6
+E(K,Y1)=d621c7bc5690a7b1487dbaab8ac76b22
+Y2=a14378078d27258a6292737e1802ada7
+E(K,Y2)=43c1ca7de78f4495ad0b18324e61fa25
+Y3=a14378078d27258a6292737e1802ada8
+E(K,Y3)=e1e0254a0f2f1626e9aa4ff09d7c64ec
+Y4=a14378078d27258a6292737e1802ada9
+E(K,Y4)=5850f4502486a1681a9319ce7d0afa59
+X3=8bdedafd6ee8e529689de3a269b8240d
+X4=6607feb377b49c9ecdbc696344fe22d8
+X5=8a19570a06500ba9405fcece4a73fb48
+X6=8532826e63ce4a5b89b70fa28f8070fe
+len(A)||len(C)=00000000000000a000000000000001e0
+GHASH(H,A,C)=1e6a133806607858ee80eaf237064089
+C=0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f7
+T=65dcc57fcf623a24094fcca40d3533f8
+
+test="Test Case 12"
+K=feffe9928665731c6d6a8f9467308308feffe9928665731c
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+A=feedfacedeadbeeffeedfacedeadbeefabaddad2
+IV=9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b
+H=466923ec9ae682214f2c082badb39249
+N1=19aef0f04763b0c87903c5a217d5314f
+N2=62120253f79efc978625d1feb03b5b5b
+N3=b6ce2a84e366de900fa78a1653df77fb
+N4=374ecad90487f0bb261ba817447e022c
+len({})||len(IV)=000000000000000000000000000001e0
+Y0=4505cdc367a054c5002820e96aebef27
+E(K,Y0)=5ea3194f9dd012a3b9bc5103d6e0284d
+X1=f3bf7ba3e305aeb05ed0d2e4fe076666
+X2=20a51fa2302e9c01b87c48f2c3d91a56
+Y1=4505cdc367a054c5002820e96aebef28
+E(K,Y1)=0b4fba4de46722d9ed691f9f2029df65
+Y2=4505cdc367a054c5002820e96aebef29
+E(K,Y2)=9b4e088bf380b03540bb87a5a257e437
+Y3=4505cdc367a054c5002820e96aebef2a
+E(K,Y3)=9ddb9c873a5cd48acd3f397cd28f9896
+Y4=4505cdc367a054c5002820e96aebef2b
+E(K,Y4)=5716ee92eff7c4b053d44c0294ea88cd
+X3=f70d61693ea7f53f08c866d6eedb1e4b
+X4=dc40bc9a181b35aed66488071ef282ae
+X5=85ffa424b87b35cac7be9c450f0d7aee
+X6=65233cbe5251f7d246bfc967a8678647
+len(A)||len(C)=00000000000000a000000000000001e0
+GHASH(H,A,C)=82567fb0b4cc371801eadec005968e94
+C=d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e4581e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373b
+T=dcf566ff291c25bbb8568fc3d376a6d9
+
+test="Test Case 13"
+K=0000000000000000000000000000000000000000000000000000000000000000
+P=
+IV=000000000000000000000000
+H=dc95c078a2408989ad48a21492842087
+Y0=00000000000000000000000000000001
+E(K,Y0)=530f8afbc74536b9a963b4f1c4cb738b
+len(A)||len(C)=00000000000000000000000000000000
+GHASH(H,A,C)=00000000000000000000000000000000
+C=
+T=530f8afbc74536b9a963b4f1c4cb738b
+
+
+test="Test Case 14"
+K=0000000000000000000000000000000000000000000000000000000000000000
+P=00000000000000000000000000000000
+IV=000000000000000000000000
+H=dc95c078a2408989ad48a21492842087
+Y0=00000000000000000000000000000001
+E(K,Y0)=530f8afbc74536b9a963b4f1c4cb738b
+Y1=00000000000000000000000000000002
+E(K,Y1)=cea7403d4d606b6e074ec5d3baf39d18
+X1=fd6ab7586e556dba06d69cfe6223b262
+len(A)||len(C)=00000000000000000000000000000080
+GHASH(H,A,C)=83de425c5edc5d498f382c441041ca92
+C=cea7403d4d606b6e074ec5d3baf39d18
+T=d0d1c8a799996bf0265b98b5d48ab919
+
+test="Test Case 15"
+K=feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255
+IV=cafebabefacedbaddecaf888
+H=acbef20579b4b8ebce889bac8732dad7
+Y0=cafebabefacedbaddecaf88800000001
+E(K,Y0)=fd2caa16a5832e76aa132c1453eeda7e
+Y1=cafebabefacedbaddecaf88800000002
+E(K,Y1)=8b1cf3d561d27be251263e66857164e7
+Y2=cafebabefacedbaddecaf88800000003
+E(K,Y2)=e29d258faad137135bd49280af645bd8
+Y3=cafebabefacedbaddecaf88800000004
+E(K,Y3)=908c82ddcc65b26e887f85341f243d1d
+Y4=cafebabefacedbaddecaf88800000005
+E(K,Y4)=749cf39639b79c5d06aa8d5b932fc7f8
+X1=fcbefb78635d598eddaf982310670f35
+X2=29de812309d3116a6eff7ec844484f3e
+X3=45fad9deeda9ea561b8f199c3613845b
+X4=ed95f8e164bf3213febc740f0bd9c6af
+len(A)||len(C)=00000000000000000000000000000200
+GHASH(H,A,C)=4db870d37cb75fcb46097c36230d1612
+C=522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad
+T=b094dac5d93471bdec1a502270e3cc6c
+
+test="Test Case 16"
+K=feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+A=feedfacedeadbeeffeedfacedeadbeefabaddad2
+IV=cafebabefacedbaddecaf888
+H=acbef20579b4b8ebce889bac8732dad7
+Y0=cafebabefacedbaddecaf88800000001
+E(K,Y0)=fd2caa16a5832e76aa132c1453eeda7e
+X1=5165d242c2592c0a6375e2622cf925d2
+X2=8efa30ce83298b85fe71abefc0cdd01d
+Y1=cafebabefacedbaddecaf88800000002
+E(K,Y1)=8b1cf3d561d27be251263e66857164e7
+Y2=cafebabefacedbaddecaf88800000003
+E(K,Y2)=e29d258faad137135bd49280af645bd8
+Y3=cafebabefacedbaddecaf88800000004
+E(K,Y3)=908c82ddcc65b26e887f85341f243d1d
+Y4=cafebabefacedbaddecaf88800000005
+E(K,Y4)=749cf39639b79c5d06aa8d5b932fc7f8
+X3=abe07e0bb62354177480b550f9f6cdcc
+X4=3978e4f141b95f3b4699756b1c3c2082
+X5=8abf3c48901debe76837d8a05c7d6e87
+X6=9249beaf520c48b912fa120bbf391dc8
+len(A)||len(C)=00000000000000a000000000000001e0
+GHASH(H,A,C)=8bd0c4d8aacd391e67cca447e8c38f65
+C=522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662
+T=76fc6ece0f4e1768cddf8853bb2d551b
+
+
+test="Test Case 17"
+K=feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+A=feedfacedeadbeeffeedfacedeadbeefabaddad2
+IV=cafebabefacedbad
+H=acbef20579b4b8ebce889bac8732dad7
+N1=90c22e3d2aca34b971e8bd09708fae5c
+len({})||len(IV)=00000000000000000000000000000040
+Y0=0095df49dd90abe3e4d252475748f5d4
+E(K,Y0)=4f903f37fe611d454217fbfa5cd7d791
+X1=5165d242c2592c0a6375e2622cf925d2
+X2=8efa30ce83298b85fe71abefc0cdd01d
+Y1=0095df49dd90abe3e4d252475748f5d5
+E(K,Y1)=1a471fd432fc7bd70b1ec8fe5e6d6251
+Y2=0095df49dd90abe3e4d252475748f5d6
+E(K,Y2)=29bd481e1ea39d20eb63c7ea118b1792
+Y3=0095df49dd90abe3e4d252475748f5d7
+E(K,Y3)=e2898e46ac5cada3ba83cc1272618a5d
+Y4=0095df49dd90abe3e4d252475748f5d8
+E(K,Y4)=d3c6aefbcea602ce4e1fe026065447bf
+X3=55e1ff68f9249e64b95223858e5cb936
+X4=cef1c034383dc96f733aaa4c99bd3e61
+X5=68588d004fd468f5854515039b08165d
+X6=2378943c034697f72a80fce5059bf3f3
+len(A)||len(C)=00000000000000a000000000000001e0
+GHASH(H,A,C)=75a34288b8c68f811c52b2e9a2f97f63
+C=c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f
+T=3a337dbf46a792c45e454913fe2ea8f2
+
+test="Test Case 18"
+K=feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308
+P=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+A=feedfacedeadbeeffeedfacedeadbeefabaddad2
+IV=9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b
+H=acbef20579b4b8ebce889bac8732dad7
+N1=0bfe66e2032f195516379f5fb710f987
+N2=f0631554d11409915feec8f9f5102aba
+N3=749b90dda19a1557fd9e9fd31fed1d14
+N4=7a6a833f260d848793b327cb07d1b190
+len({})||len(IV)=000000000000000000000000000001e0
+Y0=0cd953e2140a5976079f8e2406bc8eb4
+E(K,Y0)=71b54d092bb0c3d9ba94538d4096e691
+X1=5165d242c2592c0a6375e2622cf925d2
+X2=8efa30ce83298b85fe71abefc0cdd01d
+Y1=0cd953e2140a5976079f8e2406bc8eb5
+E(K,Y1)=83bcdd0af41a551452047196ca6b0cba
+Y2=0cd953e2140a5976079f8e2406bc8eb6
+E(K,Y2)=68151b79baea93c38e149b72e545e186
+Y3=0cd953e2140a5976079f8e2406bc8eb7
+E(K,Y3)=13fccf22159a4d16026ce5d58c7e99fb
+Y4=0cd953e2140a5976079f8e2406bc8eb8
+E(K,Y4)=132b64628a031e79fecd050675a64f07
+X3=e963941cfa8c417bdaa3b3d94ab4e905
+X4=2178d7f836e5fa105ce0fdf0fc8f0654
+X5=bac14eeba3216f966b3e7e011475b832
+X6=cc9ae9175729a649936e890bd971a8bf
+len(A)||len(C)=00000000000000a000000000000001e0
+GHASH(H,A,C)=d5ffcf6fc5ac4d69722187421a7f170b
+C=5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f
+T=a44a8266ee1c8eb0c8b5d4cf5ae9f19a
+
+
+
+
+
diff --git a/nss/cmd/bltest/tests/camellia_cbc/ciphertext0 b/nss/cmd/bltest/tests/camellia_cbc/ciphertext0
new file mode 100644
index 0000000..e789595
--- /dev/null
+++ b/nss/cmd/bltest/tests/camellia_cbc/ciphertext0
@@ -0,0 +1 @@
+taydfPlRJe3wf8Td0xJ9Tw==
diff --git a/nss/cmd/bltest/tests/camellia_cbc/ciphertext1 b/nss/cmd/bltest/tests/camellia_cbc/ciphertext1
new file mode 100644
index 0000000..7dbd9b0
--- /dev/null
+++ b/nss/cmd/bltest/tests/camellia_cbc/ciphertext1
@@ -0,0 +1 @@
+yoYCZwKnUMcS4ADHxnwObA==
diff --git a/nss/cmd/bltest/tests/camellia_cbc/ciphertext2 b/nss/cmd/bltest/tests/camellia_cbc/ciphertext2
new file mode 100644
index 0000000..007a2b0
--- /dev/null
+++ b/nss/cmd/bltest/tests/camellia_cbc/ciphertext2
@@ -0,0 +1 @@
+T+Wn4cs1Sbqrh/XtNd4vzQ==
diff --git a/nss/cmd/bltest/tests/camellia_cbc/iv0 b/nss/cmd/bltest/tests/camellia_cbc/iv0
new file mode 100644
index 0000000..4e65bc0
--- /dev/null
+++ b/nss/cmd/bltest/tests/camellia_cbc/iv0
@@ -0,0 +1 @@
+qwertyuiopasdfgh
diff --git a/nss/cmd/bltest/tests/camellia_cbc/key0 b/nss/cmd/bltest/tests/camellia_cbc/key0
new file mode 100644
index 0000000..13911cc
--- /dev/null
+++ b/nss/cmd/bltest/tests/camellia_cbc/key0
@@ -0,0 +1 @@
+fedcba9876543210
diff --git a/nss/cmd/bltest/tests/camellia_cbc/key1 b/nss/cmd/bltest/tests/camellia_cbc/key1
new file mode 100644
index 0000000..a9cb2f1
--- /dev/null
+++ b/nss/cmd/bltest/tests/camellia_cbc/key1
@@ -0,0 +1 @@
+fedcba9876543210fedcba98
diff --git a/nss/cmd/bltest/tests/camellia_cbc/key2 b/nss/cmd/bltest/tests/camellia_cbc/key2
new file mode 100644
index 0000000..ab55fe2
--- /dev/null
+++ b/nss/cmd/bltest/tests/camellia_cbc/key2
@@ -0,0 +1 @@
+fedcba9876543210fedcba9876543210
diff --git a/nss/cmd/bltest/tests/camellia_cbc/numtests b/nss/cmd/bltest/tests/camellia_cbc/numtests
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/nss/cmd/bltest/tests/camellia_cbc/numtests
@@ -0,0 +1 @@
+3
diff --git a/nss/cmd/bltest/tests/camellia_cbc/plaintext0 b/nss/cmd/bltest/tests/camellia_cbc/plaintext0
new file mode 100644
index 0000000..8d6a8d5
--- /dev/null
+++ b/nss/cmd/bltest/tests/camellia_cbc/plaintext0
@@ -0,0 +1 @@
+0123456789abcdef
diff --git a/nss/cmd/bltest/tests/camellia_ecb/ciphertext0 b/nss/cmd/bltest/tests/camellia_ecb/ciphertext0
new file mode 100644
index 0000000..084ba78
--- /dev/null
+++ b/nss/cmd/bltest/tests/camellia_ecb/ciphertext0
@@ -0,0 +1 @@
+6v0CGxSwow3AhsyhunfdbQ==
diff --git a/nss/cmd/bltest/tests/camellia_ecb/ciphertext1 b/nss/cmd/bltest/tests/camellia_ecb/ciphertext1
new file mode 100644
index 0000000..dbd6e5f
--- /dev/null
+++ b/nss/cmd/bltest/tests/camellia_ecb/ciphertext1
@@ -0,0 +1 @@
+Nf1GwJiBtZT+VPJp+gBhPA==
diff --git a/nss/cmd/bltest/tests/camellia_ecb/ciphertext2 b/nss/cmd/bltest/tests/camellia_ecb/ciphertext2
new file mode 100644
index 0000000..0b278ce
--- /dev/null
+++ b/nss/cmd/bltest/tests/camellia_ecb/ciphertext2
@@ -0,0 +1 @@
+ilB/0K3SI86Oecwh7cruGA==
diff --git a/nss/cmd/bltest/tests/camellia_ecb/key0 b/nss/cmd/bltest/tests/camellia_ecb/key0
new file mode 100644
index 0000000..13911cc
--- /dev/null
+++ b/nss/cmd/bltest/tests/camellia_ecb/key0
@@ -0,0 +1 @@
+fedcba9876543210
diff --git a/nss/cmd/bltest/tests/camellia_ecb/key1 b/nss/cmd/bltest/tests/camellia_ecb/key1
new file mode 100644
index 0000000..a9cb2f1
--- /dev/null
+++ b/nss/cmd/bltest/tests/camellia_ecb/key1
@@ -0,0 +1 @@
+fedcba9876543210fedcba98
diff --git a/nss/cmd/bltest/tests/camellia_ecb/key2 b/nss/cmd/bltest/tests/camellia_ecb/key2
new file mode 100644
index 0000000..ab55fe2
--- /dev/null
+++ b/nss/cmd/bltest/tests/camellia_ecb/key2
@@ -0,0 +1 @@
+fedcba9876543210fedcba9876543210
diff --git a/nss/cmd/bltest/tests/camellia_ecb/numtests b/nss/cmd/bltest/tests/camellia_ecb/numtests
new file mode 100644
index 0000000..00750ed
--- /dev/null
+++ b/nss/cmd/bltest/tests/camellia_ecb/numtests
@@ -0,0 +1 @@
+3
diff --git a/nss/cmd/bltest/tests/camellia_ecb/plaintext0 b/nss/cmd/bltest/tests/camellia_ecb/plaintext0
new file mode 100644
index 0000000..8d6a8d5
--- /dev/null
+++ b/nss/cmd/bltest/tests/camellia_ecb/plaintext0
@@ -0,0 +1 @@
+0123456789abcdef
diff --git a/nss/cmd/bltest/tests/chacha20_poly1305/aad0 b/nss/cmd/bltest/tests/chacha20_poly1305/aad0
new file mode 100644
index 0000000..a420ef1
--- /dev/null
+++ b/nss/cmd/bltest/tests/chacha20_poly1305/aad0
@@ -0,0 +1 @@
+PQRSÀÁÂÃÄÅÆÇ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/chacha20_poly1305/aad1 b/nss/cmd/bltest/tests/chacha20_poly1305/aad1
new file mode 100644
index 0000000000000000000000000000000000000000..91287a1a2e38397b4bd5081fadab286c1fbd971a
GIT binary patch
literal 12
Pcmext+|kAW27VI(7}Nt4
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/chacha20_poly1305/ciphertext0 b/nss/cmd/bltest/tests/chacha20_poly1305/ciphertext0
new file mode 100644
index 0000000..a06f68b
--- /dev/null
+++ b/nss/cmd/bltest/tests/chacha20_poly1305/ciphertext0
@@ -0,0 +1 @@
+0xqNNGSOYNt7hq+8U+9+wqSt7VEpbgj+qeK1pzbuYtY9vqRejKlnEoL6+2naknKLGnHeCp4GCykF1qW2fs07NpLdvX8td4uMmAOu4ygJG1j6syTk+tZ1lFWFgItIMde8P/Te8I5Lep3ldtJlhs7GS2EWGuELWU8J4mp+kC7L0GAGkQ==
diff --git a/nss/cmd/bltest/tests/chacha20_poly1305/ciphertext1 b/nss/cmd/bltest/tests/chacha20_poly1305/ciphertext1
new file mode 100644
index 0000000..e7f0d01
--- /dev/null
+++ b/nss/cmd/bltest/tests/chacha20_poly1305/ciphertext1
@@ -0,0 +1 @@
+ZKCGFXWGGvRg8GLHm+ZDvV6AXP00XPOJ8QhnCsdsjLJMbPwYdV1D7qCe6U44LSawvbe3PDIbAQDU8Dt/NViUzzMvgw5xC5fOmMioSr0LlIEUrRduAI0zvWD5grH/N8hVl5egbvTw72HBhjJOKzUGODYGkHtqfAKw+fYVe1PIZ+S5Fmx2e4BNRqWbUhbN56TpkEDFpAQzIl7igqGwoGxSPq9FNNf4P6EVWwBHcYy8VGoNBysEs1ZO6htCInP1SCcaC7IxYFP6dpkZVevWMVlDTs67TkZtrloQc6ZydicJehBJ5hfZHTYQlPpo8P93mHEwMFvqui7aBN+Ze3FNbG8sKaatXLQCKwJwm+6tnWeJDLsiOSM2/qGFHzg=
diff --git a/nss/cmd/bltest/tests/chacha20_poly1305/iv0 b/nss/cmd/bltest/tests/chacha20_poly1305/iv0
new file mode 100644
index 0000000000000000000000000000000000000000..7e8a175046dde8a759e54a088eac41101ebd5782
GIT binary patch
literal 12
TcmZQ)U|?`?baHlab#n&*3A6$v
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/chacha20_poly1305/iv1 b/nss/cmd/bltest/tests/chacha20_poly1305/iv1
new file mode 100644
index 0000000000000000000000000000000000000000..7c8b98f50daf0ac0902bf4c98da4c5f6a91ca994
GIT binary patch
literal 12
TcmZQzU|?WmVrF4wW9I+>0E7S~
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/chacha20_poly1305/key0 b/nss/cmd/bltest/tests/chacha20_poly1305/key0
new file mode 100644
index 0000000..503ecb8
--- /dev/null
+++ b/nss/cmd/bltest/tests/chacha20_poly1305/key0
@@ -0,0 +1 @@
+€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/chacha20_poly1305/key1 b/nss/cmd/bltest/tests/chacha20_poly1305/key1
new file mode 100644
index 0000000..002bf1b
--- /dev/null
+++ b/nss/cmd/bltest/tests/chacha20_poly1305/key1
@@ -0,0 +1 @@
+’@¥ëUÓŠó3ˆ†öµðG9Á@+€ Ê\¼ puÀ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/chacha20_poly1305/numtests b/nss/cmd/bltest/tests/chacha20_poly1305/numtests
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/nss/cmd/bltest/tests/chacha20_poly1305/numtests
@@ -0,0 +1 @@
+2
diff --git a/nss/cmd/bltest/tests/chacha20_poly1305/plaintext0 b/nss/cmd/bltest/tests/chacha20_poly1305/plaintext0
new file mode 100644
index 0000000..74c2229
--- /dev/null
+++ b/nss/cmd/bltest/tests/chacha20_poly1305/plaintext0
@@ -0,0 +1 @@
+Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/chacha20_poly1305/plaintext1 b/nss/cmd/bltest/tests/chacha20_poly1305/plaintext1
new file mode 100644
index 0000000..029317d
--- /dev/null
+++ b/nss/cmd/bltest/tests/chacha20_poly1305/plaintext1
@@ -0,0 +1 @@
+Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as /“work in progress./â€
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/des3_cbc/ciphertext0 b/nss/cmd/bltest/tests/des3_cbc/ciphertext0
new file mode 100644
index 0000000..61dae31
--- /dev/null
+++ b/nss/cmd/bltest/tests/des3_cbc/ciphertext0
@@ -0,0 +1 @@
+KV3MDNGKWOc=
diff --git a/nss/cmd/bltest/tests/des3_cbc/iv0 b/nss/cmd/bltest/tests/des3_cbc/iv0
new file mode 100644
index 0000000..97b5955
--- /dev/null
+++ b/nss/cmd/bltest/tests/des3_cbc/iv0
@@ -0,0 +1 @@
+12345678
diff --git a/nss/cmd/bltest/tests/des3_cbc/key0 b/nss/cmd/bltest/tests/des3_cbc/key0
new file mode 100644
index 0000000..588efd1
--- /dev/null
+++ b/nss/cmd/bltest/tests/des3_cbc/key0
@@ -0,0 +1 @@
+abcdefghijklmnopqrstuvwx
diff --git a/nss/cmd/bltest/tests/des3_cbc/numtests b/nss/cmd/bltest/tests/des3_cbc/numtests
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/nss/cmd/bltest/tests/des3_cbc/numtests
@@ -0,0 +1 @@
+1
diff --git a/nss/cmd/bltest/tests/des3_cbc/plaintext0 b/nss/cmd/bltest/tests/des3_cbc/plaintext0
new file mode 100644
index 0000000..5513e43
--- /dev/null
+++ b/nss/cmd/bltest/tests/des3_cbc/plaintext0
@@ -0,0 +1 @@
+Mozilla!
diff --git a/nss/cmd/bltest/tests/des3_ecb/ciphertext0 b/nss/cmd/bltest/tests/des3_ecb/ciphertext0
new file mode 100644
index 0000000..76dc820
--- /dev/null
+++ b/nss/cmd/bltest/tests/des3_ecb/ciphertext0
@@ -0,0 +1 @@
+RgckVNh4QcM=
diff --git a/nss/cmd/bltest/tests/des3_ecb/key0 b/nss/cmd/bltest/tests/des3_ecb/key0
new file mode 100644
index 0000000..588efd1
--- /dev/null
+++ b/nss/cmd/bltest/tests/des3_ecb/key0
@@ -0,0 +1 @@
+abcdefghijklmnopqrstuvwx
diff --git a/nss/cmd/bltest/tests/des3_ecb/numtests b/nss/cmd/bltest/tests/des3_ecb/numtests
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/nss/cmd/bltest/tests/des3_ecb/numtests
@@ -0,0 +1 @@
+1
diff --git a/nss/cmd/bltest/tests/des3_ecb/plaintext0 b/nss/cmd/bltest/tests/des3_ecb/plaintext0
new file mode 100644
index 0000000..5513e43
--- /dev/null
+++ b/nss/cmd/bltest/tests/des3_ecb/plaintext0
@@ -0,0 +1 @@
+Mozilla!
diff --git a/nss/cmd/bltest/tests/des_cbc/ciphertext0 b/nss/cmd/bltest/tests/des_cbc/ciphertext0
new file mode 100644
index 0000000..67d2ad1
--- /dev/null
+++ b/nss/cmd/bltest/tests/des_cbc/ciphertext0
@@ -0,0 +1 @@
+Perdg9FMYQ4=
diff --git a/nss/cmd/bltest/tests/des_cbc/iv0 b/nss/cmd/bltest/tests/des_cbc/iv0
new file mode 100644
index 0000000..97b5955
--- /dev/null
+++ b/nss/cmd/bltest/tests/des_cbc/iv0
@@ -0,0 +1 @@
+12345678
diff --git a/nss/cmd/bltest/tests/des_cbc/key0 b/nss/cmd/bltest/tests/des_cbc/key0
new file mode 100644
index 0000000..65513c1
--- /dev/null
+++ b/nss/cmd/bltest/tests/des_cbc/key0
@@ -0,0 +1 @@
+zyxwvuts
diff --git a/nss/cmd/bltest/tests/des_cbc/numtests b/nss/cmd/bltest/tests/des_cbc/numtests
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/nss/cmd/bltest/tests/des_cbc/numtests
@@ -0,0 +1 @@
+1
diff --git a/nss/cmd/bltest/tests/des_cbc/plaintext0 b/nss/cmd/bltest/tests/des_cbc/plaintext0
new file mode 100644
index 0000000..5513e43
--- /dev/null
+++ b/nss/cmd/bltest/tests/des_cbc/plaintext0
@@ -0,0 +1 @@
+Mozilla!
diff --git a/nss/cmd/bltest/tests/des_ecb/ciphertext0 b/nss/cmd/bltest/tests/des_ecb/ciphertext0
new file mode 100644
index 0000000..8be22fa
--- /dev/null
+++ b/nss/cmd/bltest/tests/des_ecb/ciphertext0
@@ -0,0 +1 @@
+3bNoWzzNiFc=
diff --git a/nss/cmd/bltest/tests/des_ecb/key0 b/nss/cmd/bltest/tests/des_ecb/key0
new file mode 100644
index 0000000..65513c1
--- /dev/null
+++ b/nss/cmd/bltest/tests/des_ecb/key0
@@ -0,0 +1 @@
+zyxwvuts
diff --git a/nss/cmd/bltest/tests/des_ecb/numtests b/nss/cmd/bltest/tests/des_ecb/numtests
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/nss/cmd/bltest/tests/des_ecb/numtests
@@ -0,0 +1 @@
+1
diff --git a/nss/cmd/bltest/tests/des_ecb/plaintext0 b/nss/cmd/bltest/tests/des_ecb/plaintext0
new file mode 100644
index 0000000..5513e43
--- /dev/null
+++ b/nss/cmd/bltest/tests/des_ecb/plaintext0
@@ -0,0 +1 @@
+Mozilla!
diff --git a/nss/cmd/bltest/tests/dsa/ciphertext0 b/nss/cmd/bltest/tests/dsa/ciphertext0
new file mode 100644
index 0000000..8e71505
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/ciphertext0
@@ -0,0 +1 @@
+fB0bnKWvjT6X5NIkZ5l/Y/DXZ6QNI6j0iPhR/ZERkfj67xRnTWY1cg==
diff --git a/nss/cmd/bltest/tests/dsa/ciphertext1 b/nss/cmd/bltest/tests/dsa/ciphertext1
new file mode 100644
index 0000000..4420dc7
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/ciphertext1
@@ -0,0 +1 @@
+UO0OgQ4/HHy2rGIzIFhEi9iyhMDGre0XIWtGt+S28ql8GtfMPag/3g==
diff --git a/nss/cmd/bltest/tests/dsa/ciphertext10 b/nss/cmd/bltest/tests/dsa/ciphertext10
new file mode 100644
index 0000000..55e975a
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/ciphertext10
@@ -0,0 +1,2 @@
+namWZQDenTtrf0QcpVAjP8RQlEvFB+Ac1KywMC1y8fZoHoZ/fYvq6+ukvFsjKHYE
+pkz+4cFkWVo=
diff --git a/nss/cmd/bltest/tests/dsa/ciphertext11 b/nss/cmd/bltest/tests/dsa/ciphertext11
new file mode 100644
index 0000000..62388f1
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/ciphertext11
@@ -0,0 +1,2 @@
+Nj4BxWTzgKJ9fSOyB68/lh1I/AmVSH9gBSd11ySrPRBJFtkbKScpTkKdU3wG3SRj
+0YRQGMyihz6Qpsg3tEX93g==
diff --git a/nss/cmd/bltest/tests/dsa/ciphertext12 b/nss/cmd/bltest/tests/dsa/ciphertext12
new file mode 100644
index 0000000..5a933e6
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/ciphertext12
@@ -0,0 +1,2 @@
+BZvunnCLfyDD95GmQO3ulk4KpnKJPEhHmXFYF7Oo9tRL1ByEpyTMhuTwGU7A+/N5
+5lTQ1/ah8IvUaBOUIqXDUw==
diff --git a/nss/cmd/bltest/tests/dsa/ciphertext13 b/nss/cmd/bltest/tests/dsa/ciphertext13
new file mode 100644
index 0000000..4a21643
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/ciphertext13
@@ -0,0 +1,2 @@
+YzBV4FXyN8OJmdgcOXhIw4zOgKVbZJ2eeQXCmOKlFEcrv2gxdmDsHksVSRUCewvA
+DuGc/Av3XQGTBQTyzhCosA==
diff --git a/nss/cmd/bltest/tests/dsa/ciphertext14 b/nss/cmd/bltest/tests/dsa/ciphertext14
new file mode 100644
index 0000000..ca7896f
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/ciphertext14
@@ -0,0 +1,2 @@
+T9jyXAWQMAJzgdQWfDF0tr4AiMFfClc9fr0Flg9aHrJfVoac7nv2T+xdXW6hW7H6
+EWkAOofszBYhuQobiSIm8g==
diff --git a/nss/cmd/bltest/tests/dsa/ciphertext15 b/nss/cmd/bltest/tests/dsa/ciphertext15
new file mode 100644
index 0000000..65e68f9
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/ciphertext15
@@ -0,0 +1,2 @@
+akfqV86uzBFtcZD/bG3Zgxq3W0v2yykQg+Qmi0hu0kUBc1X2mKMqvppNSn3afIWV
+DN3DSKuKZ1HnL93AGqXR8A==
diff --git a/nss/cmd/bltest/tests/dsa/ciphertext16 b/nss/cmd/bltest/tests/dsa/ciphertext16
new file mode 100644
index 0000000..e72ae9e
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/ciphertext16
@@ -0,0 +1,2 @@
+IcoUjN9EvkrpOy81O45RLQOtltr6gGI/3kkiqV8DJzJz5It3o6pEMHSDwt2JXLUd
+shEhd8GFxZyx3P8y/aAqTw==
diff --git a/nss/cmd/bltest/tests/dsa/ciphertext17 b/nss/cmd/bltest/tests/dsa/ciphertext17
new file mode 100644
index 0000000..8341730
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/ciphertext17
@@ -0,0 +1,2 @@
+LlnV8w9zeB04JVtw3t7rOK54308ALB90fAjercZTAVVhXFWy3wyijGCms4XFj6A2
+34xLL08ZNXML+PTwvtE2EA==
diff --git a/nss/cmd/bltest/tests/dsa/ciphertext18 b/nss/cmd/bltest/tests/dsa/ciphertext18
new file mode 100644
index 0000000..56e3ad3
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/ciphertext18
@@ -0,0 +1,2 @@
+U7rmxvM24usxHB6S2V/ESakpRE74HsQnlmCyANWUM95J86dOlT53p5Qa867+707U
+mb4gmXag7bP6Xny5YbDBEg==
diff --git a/nss/cmd/bltest/tests/dsa/ciphertext19 b/nss/cmd/bltest/tests/dsa/ciphertext19
new file mode 100644
index 0000000..16d0828
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/ciphertext19
@@ -0,0 +1,2 @@
+dpVpihR1XbQgboULT18ZxUCwfQfgiqxZHiAIFkbm7tw9rgEVTs/3sZAHqVPxhfBm
+PvfyU38LFeBPs0PJYfNt4g==
diff --git a/nss/cmd/bltest/tests/dsa/ciphertext2 b/nss/cmd/bltest/tests/dsa/ciphertext2
new file mode 100644
index 0000000..e2442d9
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/ciphertext2
@@ -0,0 +1 @@
+r+5xnn+Ei1Q0nMw7T7JgZYM6TY5zTv6ZIlbzEyXnSbwyokoflXs6Gw==
diff --git a/nss/cmd/bltest/tests/dsa/ciphertext20 b/nss/cmd/bltest/tests/dsa/ciphertext20
new file mode 100644
index 0000000..ead0ebb
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/ciphertext20
@@ -0,0 +1,2 @@
+pApskFZUxV/FjpnH0aP+6ixb5kgj1Ahs6BHzNM/cRI1keAUJd+xYWYBFTgovJqAw
+N7khyliKeKTa/36E1JqKbA==
diff --git a/nss/cmd/bltest/tests/dsa/ciphertext3 b/nss/cmd/bltest/tests/dsa/ciphertext3
new file mode 100644
index 0000000..072c996
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/ciphertext3
@@ -0,0 +1 @@
+dmg6CF1nQurflaYa91+IEnbP0mo7naf5km6qrQvr1IRcZ/zbZNEkUw==
diff --git a/nss/cmd/bltest/tests/dsa/ciphertext4 b/nss/cmd/bltest/tests/dsa/ciphertext4
new file mode 100644
index 0000000..4a5ebfa
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/ciphertext4
@@ -0,0 +1 @@
+d8TZn2KzrX3R/mSY20Wl2nPOe94jhxoAKuUD/auqaoTcyPOHaXN/AQ==
diff --git a/nss/cmd/bltest/tests/dsa/ciphertext5 b/nss/cmd/bltest/tests/dsa/ciphertext5
new file mode 100644
index 0000000..707fd56
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/ciphertext5
@@ -0,0 +1 @@
+pT8fjyC409RyDxSourUiawedmVMR9T9qTla1H2DiDUlXronhYq6mFg==
diff --git a/nss/cmd/bltest/tests/dsa/ciphertext6 b/nss/cmd/bltest/tests/dsa/ciphertext6
new file mode 100644
index 0000000..1bba787
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/ciphertext6
@@ -0,0 +1,2 @@
+Rd8vQj6UvxVd1OHZ5j8xXqYG3ThSfUz2Moc4yFmz6O+lvAzL9KPLtlFcS5v3hM+s
+3MEB3J+B0x8=
diff --git a/nss/cmd/bltest/tests/dsa/ciphertext7 b/nss/cmd/bltest/tests/dsa/ciphertext7
new file mode 100644
index 0000000..d1a66d3
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/ciphertext7
@@ -0,0 +1,2 @@
+ZRAuj2TssR8GAXsaDA3vPCmJfCd8SpSLH02muSGtCrsnvTwhFmy5au9wwNvV8wec
+qw3VQ9QSW9E=
diff --git a/nss/cmd/bltest/tests/dsa/ciphertext8 b/nss/cmd/bltest/tests/dsa/ciphertext8
new file mode 100644
index 0000000..87fa10c
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/ciphertext8
@@ -0,0 +1,2 @@
+nF+kaHndr1wU8H37UyBxX2em/sF5461TNC+20cPhfns8TQrI1J9N0PBMFqCU9C2g
+r8xskPXxu8g=
diff --git a/nss/cmd/bltest/tests/dsa/ciphertext9 b/nss/cmd/bltest/tests/dsa/ciphertext9
new file mode 100644
index 0000000..dad2c50
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/ciphertext9
@@ -0,0 +1,2 @@
+WrQ+3mahVogUbR9M1xZHAsDERXvU/d66wEgpU2xY6Ksn0oUSxGBjyWv1vOuPutIy
+2PWznEdV0LE=
diff --git a/nss/cmd/bltest/tests/dsa/dsa_fips.txt b/nss/cmd/bltest/tests/dsa/dsa_fips.txt
new file mode 100644
index 0000000..e657c08
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/dsa_fips.txt
@@ -0,0 +1,248 @@
+# CAVS 11.2
+# "SigGen" information for "dsa2_values"
+# Mod sizes selected: L=1024, N=160, SHA-1 L=1024, N=160, SHA-224 L=1024, N=160, SHA-256 L=1024, N=160, SHA-384 L=1024, N=160, SHA-512 L=2048, N=224, SHA-1 L=2048, N=224, SHA-224 L=2048, N=224, SHA-256 L=2048, N=224, SHA-384 L=2048, N=224, SHA-512 L=2048, N=256, SHA-1 L=2048, N=256, SHA-224 L=2048, N=256, SHA-256 L=2048, N=256, SHA-384 L=2048, N=256, SHA-512 L=3072, N=256, SHA-1 L=3072, N=256, SHA-224 L=3072, N=256, SHA-256 L=3072, N=256, SHA-384 L=3072, N=256, SHA-512
+# Generated on Tue Aug 16 11:21:08 2011
+#
+# These sample from NIST were used to generate dsa tests 1-20
+#
+
+[mod = L=1024, N=160, SHA-1]
+
+P = a8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283
+Q = f85f0f83ac4df7ea0cdf8f469bfeeaea14156495
+G = 2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33
+Msg = 3b46736d559bd4e0c2c1b2553a33ad3c6cf23cac998d3d0c0e8fa4b19bca06f2f386db2dcff9dca4f40ad8f561ffc308b46c5f31a7735b5fa7e0f9e6cb512e63d7eea05538d66a75cd0d4234b5ccf6c1715ccaaf9cdc0a2228135f716ee9bdee7fc13ec27a03a6d11c5c5b3685f51900b1337153bc6c4e8f52920c33fa37f4e7
+X = c53eae6d45323164c7d07af5715703744a63fc3a
+Y = 313fd9ebca91574e1c2eebe1517c57e0c21b0209872140c5328761bbb2450b33f1b18b409ce9ab7c4cd8fda3391e8e34868357c199e16a6b2eba06d6749def791d79e95d3a4d09b24c392ad89dbf100995ae19c01062056bb14bce005e8731efde175f95b975089bdcdaea562b32786d96f5a31aedf75364008ad4fffebb970b
+K = 98cbcc4969d845e2461b5f66383dd503712bbcfa
+R = 50ed0e810e3f1c7cb6ac62332058448bd8b284c0
+S = c6aded17216b46b7e4b6f2a97c1ad7cc3da83fde
+
+[mod = L=1024, N=160, SHA-224]
+
+P = 8b9b32f5ba38faad5e0d506eb555540d0d7963195558ca308b7466228d92a17b3b14b8e0ab77a9f3b2959a09848aa69f8df92cd9e9edef0adf792ce77bfceccadd9352700ca5faecf181fa0c326db1d6e5d352458011e51bd3248f4e3bd7c820d7e0a81932aca1eba390175e53eada197223674e3900263e90f72d94e7447bff
+Q = bc550e965647fb3a20f245ec8475624abbb26edd
+G = 11333a931fba503487777376859fdc12f7c687b0948ae889d287f1b7a712ad220ae4f1ce379d0dbb5c9abf419621f005fc123c327e5055d1850634c36d397e689e111d598c1c3636b940c84f42f436846e8e7fcad9012ceda398720f32fffd1a45ab6136ce417069207ac140675b8f86dd063915ae6f62b0cec729fbd509ac17
+Msg = fb2128052509488cad0745ed3e6312850dd96ddaf791f1e624e22a6b9beaa65319c325c78ef59cacba0ccfa722259f24f92c17b77a8f6d8e97c93d880d2d8dbbbedcf6acefa06b0e476ca2013d0394bd90d56c10626ef43cea79d1ef0bc7ac452bf9b9acaef70325e055ac006d34024b32204abea4be5faae0a6d46d365ed0d9
+X = 6e2e31bbfc670944d7a7120e39a981520614d8a8
+Y = 7e339f3757450390160e02291559f30bed0b2d758c5ccc2d8d456232bb435ae49de7e7957e3aad9bfdcf6fd5d9b6ee3b521bc2229a8421dc2aa59b9952345a8fc1de49b348003a9b18da642d7f6f56e3bc665131ae9762088a93786f7b4b72a4bcc308c67e2532a3a5bf09652055cc26bf3b18833598cffd7011f2285f794557
+K = 8cb35d255505a4c41421e562d10827266aa68663
+R = afee719e7f848b54349ccc3b4fb26065833a4d8e
+S = 734efe992256f31325e749bc32a24a1f957b3a1b
+
+[mod = L=1024, N=160, SHA-256]
+
+P = cba13e533637c37c0e80d9fcd052c1e41a88ac325c4ebe13b7170088d54eef4881f3d35eae47c210385a8485d2423a64da3ffda63a26f92cf5a304f39260384a9b7759d8ac1adc81d3f8bfc5e6cb10efb4e0f75867f4e848d1a338586dd0648feeb163647ffe7176174370540ee8a8f588da8cc143d939f70b114a7f981b8483
+Q = 95031b8aa71f29d525b773ef8b7c6701ad8a5d99
+G = 45bcaa443d4cd1602d27aaf84126edc73bd773de6ece15e97e7fef46f13072b7adcaf7b0053cf4706944df8c4568f26c997ee7753000fbe477a37766a4e970ff40008eb900b9de4b5f9ae06e06db6106e78711f3a67feca74dd5bddcdf675ae4014ee9489a42917fbee3bb9f2a24df67512c1c35c97bfbf2308eaacd28368c5c
+Msg = 812172f09cbae62517804885754125fc6066e9a902f9db2041eeddd7e8da67e4a2e65d0029c45ecacea6002f9540eb1004c883a8f900fd84a98b5c449ac49c56f3a91d8bed3f08f427935fbe437ce46f75cd666a0707265c61a096698dc2f36b28c65ec7b6e475c8b67ddfb444b2ee6a984e9d6d15233e25e44bd8d7924d129d
+X = 2eac4f4196fedb3e651b3b00040184cfd6da2ab4
+Y = 4cd6178637d0f0de1488515c3b12e203a3c0ca652f2fe30d088dc7278a87affa634a727a721932d671994a958a0f89223c286c3a9b10a96560542e2626b72e0cd28e5133fb57dc238b7fab2de2a49863ecf998751861ae668bf7cad136e6933f57dfdba544e3147ce0e7370fa6e8ff1de690c51b4aeedf0485183889205591e8
+K = 85976c5610a74959531040a5512b347eac587e48
+R = 76683a085d6742eadf95a61af75f881276cfd26a
+S = 3b9da7f9926eaaad0bebd4845c67fcdb64d12453
+
+[mod = L=1024, N=160, SHA-384]
+
+P = f24a4afc72c7e373a3c30962332fe5405c45930963909418c30792aaf135ddea561e94f24726716b75a18828982e4ce44c1fddcb746487b6b77a9a5a17f868ab50cd621b5bc9da470880b287d7398190a42a5ee22ed8d1ff147e2019810c8298ed68e1ca69d41d555f249e649fb1725ddb075c17b37beff467fdd1609243373f
+Q = da065a078ddb56ee5d2ad06cafab20820d2c4755
+G = 47b5591b79043e4e03ca78a0e277c9a21e2a6b543bf4f044104cd9ac93eff8e101bb6031efc8c596d5d2f92e3a3d0f1f74702dd54f77d3cd46c04dee7a5de9f00ad317691fddcefe4a220a2651acae7fcedda92bfcca855db6705e8d864f8192bf6bf860c00f08ad6493ecc1872e0028d5c86d44505db57422515c3825a6f78a
+Msg = b0dbbf4a421ba5c5b0e52f09629801c113258c252f29898c3354706e39ec5824be523d0e2f8cfe022cd61165301274d5d621a59755f50404d8b802371ce616defa962e3636ae934ec34e4bcf77a16c7eff8cf4cc08a0f4849d6ad4307e9f8df83f24ad16ab46d1a61d2d7d4e21681eb2ae281a1a5f9bca8573a3f5281d308a5a
+X = 649820168eb594f59cd9b28b9aefe8cc106a6c4f
+Y = 43a27b740f422cb2dc3eaa232315883a2f6a22927f997d024f5a638b507b17d3b1cbd3ec691cc674470960a0146efdecb95bb5fe249749e3c806cd5cc3e7f7bab845dadbe1f50b3366fb827a942ce6246dda7bd2c13e1b4a926c0c82c884639552d9d46036f9a4bc2a9e51c2d76e3074d1f53a63224c4279e0fa460474d4ffde
+K = 33c7ba88ff69707971b25ac344ae4a566e195f99
+R = 77c4d99f62b3ad7dd1fe6498db45a5da73ce7bde
+S = 23871a002ae503fdabaa6a84dcc8f38769737f01
+
+[mod = L=1024, N=160, SHA-512]
+
+P = 88d968e9602ecbda6d86f7c970a3ffbeb1da962f28c0afb9270ef05bc330ca98c3adf83c072feb05fb2e293b5065bbb0cbcc930c24d8d07869deaecd92a2604c0f5dd35c5b431fda6a222c52c3562bf7571c710209be8b3b858818788725fe8112b7d6bc82e0ff1cbbf5d6fe94690af2b510e41ad8207dc2c02fb9fa5cefaab5
+Q = a665689b9e5b9ce82fd1676006cf4cf67ecc56b7
+G = 267e282857417752113fba3fca7155b5ce89e7c8a33c1a29122e2b720965fc04245267ff87fc67a5730fe5b308013aa3266990fbb398185a87e055b443a868ce0ce13ae6aee330b9d25d3bbb362665c5881daf0c5aa75e9d4a82e8f04c91a9ad294822e33978ab0c13fadc45831f9d37da4efa0fc2c5eb01371fa85b7ddb1f82
+Msg = 3a84a5314e90fd33bb7cd6ca68720c69058da1da1b359046ae8922cac8afc5e025771635fb4735491521a728441b5cb087d60776ee0ecc2174a41985a82cf46d8f8d8b274a0cc439b00971077c745f8cf701cf56bf9914cc57209b555dc87ca8c13da063270c60fc2c988e692b75a7f2a669903b93d2e14e8efb6fb9f8694a78
+X = 07ce8862e64b7f6c7482046dbfc93907123e5214
+Y = 60f5341e48ca7a3bc5decee61211dd2727cd8e2fc7635f3aabea262366e458f5c51c311afda916cb0dcdc5d5a5729f573a532b594743199bcfa7454903e74b33ddfe65896306cec20ebd8427682fa501ee06bc4c5d1425cbe31828ba008b19c9da68136cf71840b205919e783a628a5a57cf91cf569b2854ffef7a096eda96c9
+K = 2f170907ac69726b14f22056dcb37b4df85f7424
+R = a53f1f8f20b8d3d4720f14a8bab5226b079d9953
+S = 11f53f6a4e56b51f60e20d4957ae89e162aea616
+
+[mod = L=2048, N=224, SHA-1]
+
+P = f2d39ed3062b13c916273600a0f2a029e86d7a4b9217b4f1815bf2b24d9710a57ab33f997294b014585b8d0198dfdccbcd75314da5ff85aa344b45adaeaa979b51a312a7bfa94472fb633f1a6f156bb4458867dfd38403f06b851f00fe2d3484077bded71ab7513d04a140220575fb693395480e4c8402b7a46cec2d37a778c305accd1f13e9f62e865315f4b22cc467c8986ec8e4961ddf810566b0c4ee369ac6aa15e43f4744005826f5bde8071a19e30b6909aac4b3d174237270dad02799d09b8a2cc5f22e66894b5422228b2c234f11f5a771c5b89cf465a2acecbbeeaa1725fe8f9b59422be8991052cb556ddf2c8ce8fa9206dbf39feadc194e00f8e5
+Q = 8000000000000000c118f49835e4ef733c4d15800fcf059e884d31b1
+G = e3a93c09da6f560e4d483a382a4c546f2335c36a4c35ac1463c08a3e6dd415df56fdc537f25fd5372be63e4f5300780b782f1acd01c8b4eb33414615fd0ea82573acba7ef83f5a943854151afc2d7dfe121fb8cd03335b065b549c5dcc606be9052483bc284e12ac3c8dba09b426e08402030e70bc1cc2bf8957c4ba0630f3f32ad689389ac47443176063f247d9e2296b3ea5b5bc2335828ea1a080ed35918dee212fd031279d1b894f01afec523833669eac031a420e540ba1320a59c424a3e5849a460a56bcb001647885b1433c4f992971746bfe2977ce7259c550b551a6c35761e4a41af764e8d92132fcc0a59d1684eab90d863f29f41cf7578faa908c
+Msg = edc6fd9b6c6e8a59f283016f7f29ee16deeaa609b5737927162aef34fed985d0bcb550275637ba67831a2d4efccb35296dfe730f4a0b4f4728d1d7d1bb8f4a36238a5c94311fa1134a93a6b4de39c085e9f60ae4e237c0416d58042bb36baa38cba8c896295b745d5376fd8ce42eb6ee5a1b38f87716b265b76e58cfb24a9170
+X = 6132e551cdac88409183bd37ee1452cd247d4834b08814b275be3ff5
+Y = 289ff18c32a56bb0b8839370647683a38a5a7e291410b93207212adc8088d30f93e9e4abc523f3d46936e7d5c90d88742b36afd37563408f15c8c1a4f7ac24bf05f01008ffee70c8825d57c3a9308bad8a095af2b53b2dda3cbed846d95e301eb9b84766415d11f6c33209a0d28571096ab04a79aa0dc465997529686b68e887cd8a205c2dc8195aef0422eba9979f549ac85548e419413643b7244361153ada1480d238cd00dc16527938955548dd5d027ded1029eeeb8ed6c61b4cd59341d8b15466e9da890a989996f4d7691e6072de136af28b5874bf08bd1f8a60cfb1c00888132909f515e04bce81b02951aa41baac68ffdb8c5dc77a1d32d8f2c10dd7
+K = 7197392d32d0af6a7183cc3398556f8f687d86a8ff742be6ad38562f
+R = 45df2f423e94bf155dd4e1d9e63f315ea606dd38527d4cf6328738c8
+S = 59b3e8efa5bc0ccbf4a3cbb6515c4b9bf784cfacdcc101dc9f81d31f
+
+[mod = L=2048, N=224, SHA-224]
+
+P = aa815c9db1c4d3d2773c7d0d4d1da75ecfc4a39e97d5fa191ffec8b1490a290ce335e5ce87ea620a8a17de0bb64714e2ec840bf00e6ebdb4ffb4e324ca07c3c8717309af1410362a772c9add838b2b0cae1e90ab448adabdacd2e5df59c4187a32a23719d6c57e9400885383bf8f066f23b941920d54c35b4f7cc5044f3b40f17046956307b748e840732844d00a9ce6ec5714293b6265147f15c67f4be38b082b55fdeadb6124689fb76f9d25cc28b8eaa98b562d5c1011e0dcf9b39923240d332d89dc9603b7bddd0c70b83caa2905631b1c83cabbae6c0c0c2efe8f58131ed8351bf93e875f6a73a93cbad470141a2687fbacf2d71c8ddee971ad660729ad
+Q = ea347e90be7c2875d1fe1db622b4763837c5e27a6037310348c1aa11
+G = 2042094ccbc8b8723fc928c12fda671b83295e99c743576f44504be1186323319b5002d24f173df909ea241d6ea5289904ee4636204b2fbe94b068fe093f7962579549551d3af219ad8ed19939eff86bcec834de2f2f78596e89e7cb52c524e177098a56c232eb1f563aa84bc6b026deee6ff51cb441e080f2dafaea1ced86427d1c346be55c66803d4b76d133cd445b4c3482fa415023463c9bf30f2f784223e26057d3aa0d7fbb660630c52e49d4a0325c7389e072aa349f13c966e159752fbb71e9336890f93243fa6e72d299365ee5b3fe266ebf1110568fee4425c847b50210bd484b97431a42856adca3e7d1a9c9c675c7e266918320dd5a78a48c48a9
+Msg = e920fc1610718f2b0213d301c0092a51f3c6b0107bbbd8243a9689c044e2d142f202d9d195a5faef4be5acadc9ff6f7d2261e58b517139bcb9489b110423c2e59eb181294ffdae8aad0e624fab974c97f9f5e7dc19d678a9cb3429cf05ec509072856f5adfec6e29bafe8e5ba95593e612843e343111d88a1eaff7dc0a2e277f
+X = 7b489021578e79e7bd3ee7ab456f659f3dc07c88f5c9a39e4f8cee81
+Y = 1ae10c786ad0902c5c685dae5c7121418a377b888b5f2f2bc76623570fd62bcb190b471ad5359c5f062f8819289e956d8aa6f90d1f8cf1ee72d3a1bdfd56c478dc29a19c4569b5a60e3a8f34f60656eac5b25dde5514a5c67b675423204f6ccaf0990617cc7355b9d3ed868978a252020a769ed59a6edaa6efe3377eef45f3f6f3e64179cc7db8b143fb835c5d71bfcfa1e2a9049bccf7fe9ab57546220fe3f4b7521c861739d138507e81a46a6993605441dcb90d6ee4afbc42cabe90a254444968109d7edd9694a023239f1d56175dd1fac115915e24fab563f4fc3f269bed2f300832d112596485a711417aa73bb4ac72a651a1fa5baed3636c720d397008
+K = 37fadd419fcbd2b073a06ae96b9eceb63e29aee9ac5fa2bdb31ab85d
+R = 65102e8f64ecb11f06017b1a0c0def3c29897c277c4a948b1f4da6b9
+S = 21ad0abb27bd3c21166cb96aef70c0dbd5f3079cab0dd543d4125bd1
+
+[mod = L=2048, N=224, SHA-256]
+
+P = a4c7eaab42c4c73b757770916489f17cd50725cd0a4bc4e1cf67f763b8c1de2d6dab9856baafb008f365b18a42e14dc51f350b88eca0209c5aa4fd71a7a96c765f5901c21e720570d7837bec7c76d2e49344731ca39405d0a879b9e0dcd1a8125fd130ec1e783e654b94e3002e6b629e904ab3877867720cbd54b4270a9e15cd028c7cc796f06c272a660951928fdbeb2dca061b41e932257305742ff16e2f429191d5e5f1a6ddf6e78c5d7722cff80a9c0bd5c8d7aeba8c04438992b075e307c1534c49ad380f477f5f7987dc172c161dca38dcaf3fb3846c72c9119a5299adc748951b3dce0d00d4a9013800b2008203b72465bc6a84ae059a30c4522dea57
+Q = ce89fe332b8e4eb3d1e8ddcea5d163a5bc13b63f16993755427aef43
+G = 8c465edf5a180730291e080dfc5385397a5006450dba2efe0129264fbd897bb5579ca0eab19aa278220424724b4f2a6f6ee6328432abf661380646097233505339c5519d357d7112b6eec938b85d5aa75cc2e38092f0a530acb54e50fe82c4d562fb0f3036b80b30334023ebbe6637a0010b00c7db86371168563671e1e0f028aedbd45d2d572621a609982a073e51aae27707afbeef29e2ecee84d7a6d5da382be3a35f42b6c66849202ab19d025b869d08776476d1ab981475ad2ad2f3e6fd07e30696d90a626816df60d6ca7afd7b482f942f83b45cc82933731f87faee320900f2aa3e70b1867e1430e40be67c07f9290299ef067b8b24a7515b3f992c07
+Msg = cec8d2843dee7cb5f9119b75562585e05c5ce2f4e6457e9bcc3c1c781ccd2c0442b6282aea610f7161dcede176e774861f7d2691be6c894ac3ebf80c0fab21e52a3e63ae0b35025762ccd6c9e1fecc7f9fe00aa55c0c3ae33ae88f66187f9598eba9f863171f3f56484625bf39d883427349b8671d9bb7d396180694e5b546ae
+X = 551595eccbb003b0bf8ddda184a59da51e459a0d28205e5592ca4cb1
+Y = 748a40237211a2d9852596e7a891f43d4eb0ee48826c9cfb336bbb68dbe5a5e16b2e1271d4d13de03644bb85ef6be523a4d4d88415bcd596ba8e0a3c4f6439e981ed013d7d9c70336febf7d420cfed02c267457bb3f3e7c82145d2af54830b942ec74a5d503e4226cd25dd75decd3f50f0a858155d7be799410836ddc559ce99e1ae513808fdaeac34843dd7258f16f67f19205f6f139251a4186da8496d5e90d3fecf8ed10be6c25ff5eb33d960c9a8f4c581c8c724ca43b761e9fdb5af66bffb9d2ebb11a6b504a1fbe4f834ecb6ac254cab513e943b9a953a7084b3305c661bfad434f6a835503c9ade7f4a57f5c965ec301ecde938ee31b4deb038af97b3
+K = 6f326546aa174b3d319ef7331ec8dfd363dd78ae583a920165ff7e54
+R = 9c5fa46879ddaf5c14f07dfb5320715f67a6fec179e3ad53342fb6d1
+S = c3e17e7b3c4d0ac8d49f4dd0f04c16a094f42da0afcc6c90f5f1bbc8
+
+[mod = L=2048, N=224, SHA-384]
+
+P = a6bb5333ce343c31c9b2c878ab91eef2fdea35c6db0e716762bfc0d436d87506e865a4d2c8cfbbd626ce8bfe64563ca5686cd8cf081490f02445b289087982495fb69976b10242d6d50fc23b4dbdb0bef78305d9a4d05d9eae65d87a893eaf397e04e39baa85a26c8ffbdef1233287b5f5b6ef6a90f27a69481a932ee47b18d5d27eb107ffb05025e646e8876b5cb567fec1dd35835d42082198531fafbe5ae280c575a1fb0e62e9b3ca37e197ad96d9dde1f33f2cec7d27deae261c83ee8e2002af7eb6e82f6a14796af037577a1032bbc709129caabd8addf870ae2d0595c8fdb37155748f0dea34b44d4f82ed58c2f5b1b8481662ac53473c693410082fbd
+Q = 8c3ee5bd9a2aaf068bd5845bd55ecf27417055307577bbc3770ec68b
+G = 43b5a6b6d0bb962ec9766a377c32cc4124f1311188c2ecf95c0cd4a4fa097225b7618cb1276c474578d3bf564c145199c092a1b14baa929c2f3f0f36e0c2dae91eba08be30992a889f2952e0442c37af484a4ecdc3243ccfcb9e3413cf5cdd6630b09fe17efbfde14d8725493019b7b73d1f782b48ef30bec36e00e02ba336d2254fc202a69612cd9446f91d76b739ffa6d8b86052f8dc5f1145801c56241af5ba9037241bd89e6338b58e01310671c268eb5e33acb57d1f99f16440a675827d4017754d601a17ada2fbedf904554a90b01530da8c93cd14ce293cb2bd3e7937e934b79e310fe4d80c13f92f63381355bd80a1abee1a73fdfb6da24ef28002a3
+Msg = df5d564db83592c1128be5d29b7036880d55e834a291a745ed8dcd438c4da6b1b9f39412b2c5110730db83c1ccdfe9059dd96ec7ea2bbcb34e3eba72ef0a1d4721c7c0221e29279f014d63facc5bc8f18c539b92ff2af89e568225d6b4cf599cb3dff5e3c6ddfac0a27f10f636ec220abb72630bae9a39c18fd3663e4651ccac
+X = 4efa5136eb6aa74e92bbfc913b0bfebb613db7a47221fb7b64f42e6f
+Y = 647979b7960ce7b971ff0e5f6435f42a41b18c9de09a301114a013a7cd01183f176f88838379dcb4efb67daea79def3f042cbcf9cc503b4c2151a2364f7c9437b19643e67e24a36bac4a4cfa293deedf8ec6b154a32aa72985f7d8de235334b546c29def458c55d0c5c0ac5d74e2024ec7d4abc2fda516a2a0b1a4d886ad92c204707828a4fc7794f60ee8a4be1101c9e5518f7e19eebd475f2de6f6ba89c28bd129f13993befe5818440319a79549833196342a31dbaf7d79497dec65ee7dbef70e58f99d0595f6a711409ade3151d45563d53c1cd0a8ab1a18beff6502cbb0c069b114ea7be77898d0f4e549991ba0b368971b1072ece4afc380e9ae329a50
+K = 7e0f1ce21d185ae65c0a00395567ea9cf217462b58b9c89c4e5ff9cf
+R = 5ab43ede66a15688146d1f4cd7164702c0c4457bd4fddebac0482953
+S = 6c58e8ab27d28512c46063c96bf5bceb8fbad232d8f5b39c4755d0b1
+
+[mod = L=2048, N=224, SHA-512]
+
+P = bfebd000b2d6cd4ab38efba35df334df721d6c2f2b3d956679cbad009f3dfbd002952cc899cc2356ec8769bd3d1ba5a73023729888da92ca48a5ee94c97f4f04a2e3acb4f33a2f0fb3783c31f2c70fa7c70f38214a27dadec8b12e67996a9e85ee3bb148803130147392dc5253c04d7063535e6cd646bfb186984e08b58b74a7be5b333bf32b0abfd5665360e9a923a0c528ff1c62c7253458f5678528719d436e50148741f45dc7dd2c6cac71c55231f12a83fefd2ed0a33ede1b8a51f566fcf7890682cdc1931dc207c92bf2ef4e28ab31661eeb77f1601eea941c9591f038d3f00d912857db05e64b2ad569320061c6f863ff3354d842e7e7ea715afef8d1
+Q = aa986df8a064278e9363316a9830bcfa490656faa6d5daa817d87949
+G = 8195ad9a478fd985216ee58368366d2edd13c12b3d62239169fa042d91156408b483122f44ed6236b8308a6cdb52f9af3de88ec89e039afad7da3aa66c1976049a8e0a7d18d567baf99fcefe315cada01548386b10b25e52f52ed78eb4d28082e5e1ffee9480c4fe2cc4aafd1efc9d4fd2cc6d155968931271ef15b3240e7fb043a80c8f628befe09d645077c1029d21e0ac8bf0ba9c27714d1b580ede594aa01b3b76f6e745fc1ec07db37e2fd7e98c6c8c6915228e422c309de9f5db168f50249d1be1ed3298090808e2ebb896bb79b8c4cbf94d4c2064e37e612ba4449d7ac210edde211416d64b051dd8046ab041732665411a7f154d31b3e11a51da7fc0
+Msg = e9f59c6a5cbe8f5b0cf75008d06a076a6739bdddb39b82143cd03939aa4738a287c2a6f31829bbe15f02cc2ee7d7122dbd132825970daddd8a4d851da86e7edc8940cb1188319218b8e0248a103eae34bc68d85f5a32830d7e5dc7718f74db5e4224c0debe1e841e1eea1a88fee0f85d9fb087cbcee55f86037a646e38346d2b
+X = 6a5b4ffc44238d1852fb9b74e4c1661be85984043cfeee023f57cac6
+Y = af6721bf75dec6a1b76ad35ca3750def31117c5b441c15a306835a1db74c003b86ae9099ebfb745b0aa9cb000cf43fb021513b8f197bc865b22bf949b491809ad752ffc1ca8e54bea16dc7f539e4c55fb70a7743dd28f262f60ef0f2fcaac29e8021a7938c18ffe03075d0b7e0a2b4dcabe46ed1953d33e37f113af519ab0bf0b6186c12b5f6488437f5193096e2fd6a6a1835604794c66b42ae5265c1cf1cb53ae84997975e0318a93ce41e3902e4ef54de3c56555bd19491acd53f3e57464e1f460389dbc5fa80648fa5a5a0f2956e9ec3b8dc441b535c641c362eed770da828649bfd146472b0f46a4c064e459f88bff90dede7ec56177a9a71d167948712
+K = 9ced89ea5050982222830efef26e7394f5ab7d837d4549962d285fae
+R = 9da9966500de9d3b6b7f441ca550233fc450944bc507e01cd4acb030
+S = 2d72f1f6681e867f7d8beaebeba4bc5b23287604a64cfee1c164595a
+
+[mod = L=2048, N=256, SHA-1]
+
+P = c1a59d215573949e0b20a974c2edf2e3137ff2463062f75f1d13df12aba1076bb2d013402b60af6c187fb0fa362167c976c2617c726f9077f09e18c11b60f65008825bd6c02a1f57d3eb0ad41cd547de43d87f2525f971d42b306506e7ca03be63b35f4ada172d0a06924440a14250d7822ac2d5aeafed4619e79d4158a7d5eb2d9f023db181a8f094b2c6cb87cb8535416ac19813f07144660c557745f44a01c6b1029092c129b0d27183e82c5a21a80177ee7476eb95c466fb472bd3d2dc286ce25847e93cbfa9ad39cc57035d0c7b64b926a9c7f5a7b2bc5abcbfbdc0b0e3fede3c1e02c44afc8aefc7957da07a0e5fd12339db8667616f62286df80d58ab
+Q = 8000000000000000000000001bd62c65e8b87c89797f8f0cbfa55e4a6810e2c7
+G = aea5878740f1424d3c6ea9c6b4799615d2749298a17e26207f76cef340ddd390e1b1ad6b6c0010ad015a103342ddd452cac024b36e42d9b8ed52fafae7a1d3ce9e4b21f910d1356eb163a3e5a8184c781bf14492afa2e4b0a56d8884fd01a628b9662739c42e5c5795ade2f5f27e6de1d963917ce8806fc40d021cd87aa3aa3a9e4f0c2c4c45d2959b2578b2fb1a2229c37e181059b9d5e7b7862fa82e2377a49ed0f9dca820a5814079dd6610714efaf8b0cc683d8e72e4c884e6f9d4946b3e8d4cbb92adbbe7d4c47cc30be7f8c37ca81883a1aac6860059ff4640a29ccae73de20b12e63b00a88b2ee9ba94b75eb40a656e15d9ec83731c85d0effcb9ef9f
+Msg = de3605dbefde353cbe05e0d6098647b6d041460dfd4c000312be1afe7551fd3b93fed76a9763c34e004564b8f7dcacbd99e85030632c94e9b0a032046523b7aacdf934a2dbbdcfceefe66b4e3d1cb29e994ff3a4648a8edd9d58ed71f12399d90624789c4e0eebb0fbd5080f7d730f875a1f290749334cb405e9fd2ae1b4ed65
+X = 5a42e77248358f06ae980a2c64f6a22bea2bf7b4fc0015745053c432b7132a67
+Y = 880e17c4ae8141750609d8251c0bbd7acf6d0b460ed3688e9a5f990e6c4b5b00875da750e0228a04102a35f57e74b8d2f9b6950f0d1db8d302c5c90a5b8786a82c68ff5b17a57a758496c5f8053e4484a253d9942204d9a1109f4bd2a3ec311a60cf69c685b586d986f565d33dbf5aab7091e31aa4102c4f4b53fbf872d700156465b6c075e7f778471a23502dc0fee41b271c837a1c26691699f3550d060a331099f64837cddec69caebf51bf4ec9f36f2a220fe773cb4d3c02d0446ddd46133532ef1c3c69d432e303502bd05a75279a7809a742ac4a7872b07f1908654049419350e37a95f2ef33361d8d8736d4083dc14c0bb972e14d4c7b97f3ddfccaef
+K = 2cb9c1d617e127a4770d0a946fb947c5100ed0ca59454ea80479f6885ec10534
+R = 363e01c564f380a27d7d23b207af3f961d48fc0995487f60052775d724ab3d10
+S = 4916d91b2927294e429d537c06dd2463d1845018cca2873e90a6c837b445fdde
+
+[mod = L=2048, N=256, SHA-224]
+
+P = d02276ebf3c22ffd666983183a47ae94c9bccbcbf95ddcb491d1f7ce643549199992d37c79e7b032d26ed031b6ba4489f3125826fafb2726a98333ebd9abdde592d8693d9859536d9cc3841a1d24e044d35aced6136256fc6d6b615cf4f4163aa381eb2b4c480825a8eccc56d8ddcf5fe637e38ad9b2974bd2cf68bf271e0d067d2465a8b6b660524f0082598945ada58ea649b9804eb4753408c2c59768c46abb82e3295f3d9ca469f84cc187f572dc4b5a3b39346ec839dfad6f07d6d1f0e215209bb0ecc05c767cf2e7943ac9cfb02eee1e9ef5946e8ce88316b5e15fdcf95a132ef2e4bb0817136528cfa5dd96532f9c3abe5c421620edb6bcbd52234ca9
+Q = 8000000012997e8285e4089708f528070c6d7af8a0bd01409e7a079cdb6fc5bb
+G = 778453049ef262147fed7b59b0ee6764607c51e7b5b5fc6fea7a7a7b1dd6bb283f4a9ae98efd3964b1556758cb15b2a53af8619e74d85898bec77d3b3f382494ae5961a13ffc745da386182291519800f99dd710e00aeb15adee088e2798ee2e46f598526cf0f4667055d1ba009750041dc5cdd2725ff1d97dd340c8518af7671b87d39d67aeced84b66f84e0701efc82a5c9ef954ee576d24c385b14d63037f0d866fd424b4975bdd5485ed740cb932e843f906683f7c7b2c74775d901c361b847b519c0da699638da40bd736b783d2710b2c2cc26ef91271bf4e2c1929f876e902e2057164223bc78d6a2b9f6c0c7a7cb85922f7d6c4287ae23861f8128848
+Msg = 39f2d8d503aae8cd17854456ecfad49a18900d4375412bc689181ed9c2ccafea98dca689a72dc75e5367d3d3abfc2169700d5891cff70f69d9aca093b061b9f5057f94636bc2783115254344fb12e33b167272e198838a8728e7744ea9a2e8248e34d5906e298302472637b879de91c1a6f9f331a5cf98a5af29132990d27416
+X = 6ba81e6cd4367798aaab8b7af1135183a37c42a766dbd68cd2dce78f2670ef0f
+Y = 7bb31e98c7a0437f978a73d5dcfbdfbb09cc2499dfaf1eb5256bccd6358cabb5f67d04a42823463b7e957f2b9213f1fa8e5a98d614484701abb8c7d67641fe6ed06fa4527b493ddab2e74640fde3de70da693f1db2b8e26417040af0eea6cab451a795a52e187d2ee241b93f65c86c6d66f45834cce165ac5eb670d4f0095c23ce9757e3bdc636f991ee0073d90a09202edb35cc3ea1cf9adca1617fa0bffd9c126229a604a1d3bf4931ddf0b9942dfc8a2f8c09fcc97032564a79ae1ebe1e2ce49ff57839e7c43fa60b1603d15a450898aa4e4a1ee8065794126d64f013367096a83686b9f158c33b10f5f3b36cf1f6358b3f34f84b101dc26d3db68bcc95c8
+K = 45030b79a395b1632700cbaffead97998d02bed8e0656876fc0174e4bdb96f79
+R = 059bee9e708b7f20c3f791a640edee964e0aa672893c484799715817b3a8f6d4
+S = 4bd41c84a724cc86e4f0194ec0fbf379e654d0d7f6a1f08bd468139422a5c353
+
+[mod = L=2048, N=256, SHA-256]
+
+P = a8adb6c0b4cf9588012e5deff1a871d383e0e2a85b5e8e03d814fe13a059705e663230a377bf7323a8fa117100200bfd5adf857393b0bbd67906c081e585410e38480ead51684dac3a38f7b64c9eb109f19739a4517cd7d5d6291e8af20a3fbf17336c7bf80ee718ee087e322ee41047dabefbcc34d10b66b644ddb3160a28c0639563d71993a26543eadb7718f317bf5d9577a6156561b082a10029cd44012b18de6844509fe058ba87980792285f2750969fe89c2cd6498db3545638d5379d125dccf64e06c1af33a6190841d223da1513333a7c9d78462abaab31b9f96d5f34445ceb6309f2f6d2c8dde06441e87980d303ef9a1ff007e8be2f0be06cc15f
+Q = e71f8567447f42e75f5ef85ca20fe557ab0343d37ed09edc3f6e68604d6b9dfb
+G = 5ba24de9607b8998e66ce6c4f812a314c6935842f7ab54cd82b19fa104abfb5d84579a623b2574b37d22ccae9b3e415e48f5c0f9bcbdff8071d63b9bb956e547af3a8df99e5d3061979652ff96b765cb3ee493643544c75dbe5bb39834531952a0fb4b0378b3fcbb4c8b5800a5330392a2a04e700bb6ed7e0b85795ea38b1b962741b3f33b9dde2f4ec1354f09e2eb78e95f037a5804b6171659f88715ce1a9b0cc90c27f35ef2f10ff0c7c7a2bb0154d9b8ebe76a3d764aa879af372f4240de8347937e5a90cec9f41ff2f26b8da9a94a225d1a913717d73f10397d2183f1ba3b7b45a68f1ff1893caf69a827802f7b6a48d51da6fbefb64fd9a6c5b75c4561
+Msg = 4e3a28bcf90d1d2e75f075d9fbe55b36c5529b17bc3a9ccaba6935c9e20548255b3dfae0f91db030c12f2c344b3a29c4151c5b209f5e319fdf1c23b190f64f1fe5b330cb7c8fa952f9d90f13aff1cb11d63181da9efc6f7e15bfed4862d1a62c7dcf3ba8bf1ff304b102b1ec3f1497dddf09712cf323f5610a9d10c3d9132659
+X = 446969025446247f84fdea74d02d7dd13672b2deb7c085be11111441955a377b
+Y = 5a55dceddd1134ee5f11ed85deb4d634a3643f5f36dc3a70689256469a0b651ad22880f14ab85719434f9c0e407e60ea420e2a0cd29422c4899c416359dbb1e592456f2b3cce233259c117542fd05f31ea25b015d9121c890b90e0bad033be1368d229985aac7226d1c8c2eab325ef3b2cd59d3b9f7de7dbc94af1a9339eb430ca36c26c46ecfa6c5481711496f624e188ad7540ef5df26f8efacb820bd17a1f618acb50c9bc197d4cb7ccac45d824a3bf795c234b556b06aeb929173453252084003f69fe98045fe74002ba658f93475622f76791d9b2623d1b5fff2cc16844746efd2d30a6a8134bfc4c8cc80a46107901fb973c28fc553130f3286c1489da
+K = 117a529e3fdfc79843a5a4c07539036b865214e014b4928c2a31f47bf62a4fdb
+R = 633055e055f237c38999d81c397848c38cce80a55b649d9e7905c298e2a51447
+S = 2bbf68317660ec1e4b154915027b0bc00ee19cfc0bf75d01930504f2ce10a8b0
+
+[mod = L=2048, N=256, SHA-384]
+
+P = a6167c16fff74e29342b8586aed3cd896f7b1635a2286ff16fdff41a06317ca6b05ca2ba7c060ad6db1561621ccb0c40b86a03619bfff32e204cbd90b79dcb5f86ebb493e3bd1988d8097fa23fa4d78fb3cddcb00c466423d8fa719873c37645fe4eecc57171bbedfe56fa9474c96385b8ba378c79972d7aaae69a2ba64cde8e5654f0f7b74550cd3447e7a472a33b4037db468dde31c348aa25e82b7fc41b837f7fc226a6103966ecd8f9d14c2d3149556d43829f137451b8d20f8520b0ce8e3d705f74d0a57ea872c2bdee9714e0b63906cddfdc28b6777d19325000f8ed5278ec5d912d102109319cba3b6469d4672909b4f0dbeec0bbb634b551ba0cf213
+Q = 8427529044d214c07574f7b359c2e01c23fd97701b328ac8c1385b81c5373895
+G = 6fc232415c31200cf523af3483f8e26ace808d2f1c6a8b863ab042cc7f6b7144b2d39472c3cb4c7681d0732843503d8f858cbe476e6740324aaa295950105978c335069b919ff9a6ff4b410581b80712fe5d3e04ddb4dfd26d5e7fbca2b0c52d8d404343d57b2f9b2a26daa7ece30ceab9e1789f9751aaa9387049965af32650c6ca5b374a5ae70b3f98e053f51857d6bbb17a670e6eaaf89844d641e1e13d5a1b24d053dc6b8fd101c624786951927e426310aba9498a0042b3dc7bbc59d705f80d9b807de415f7e94c5cf9d789992d3bb8336d1d808cb86b56dde09d934bb527033922de14bf307376ab7d22fbcd616f9eda479ab214a17850bdd0802a871c
+Msg = 8c78cffdcf25d8230b835b30512684c9b252115870b603d1b4ba2eb5d35b33f26d96b684126ec34fff67dfe5c8c856acfe3a9ff45ae11d415f30449bcdc3bf9a9fb5a7e48afeaba6d0b0fc9bce0197eb2bf7a840249d4e550c5a25dc1c71370e67933edad2362fae6fad1efba5c08dc1931ca2841b44b78c0c63a1665ffac860
+X = 459eb1588e9f7dd4f286677a7415cb25a1b46e7a7cfadc8a45100383e20da69d
+Y = 5ca7151bca0e457bbc46f59f71d81ab16688dc0eb7e4d17b166c3326c5b12c5bdebb3613224d1a754023c50b83cb5ecc139096cef28933b3b12ca31038e4089383597c59cc27b902be5da62cae7da5f4af90e9410ed1604082e2e38e25eb0b78dfac0aeb2ad3b19dc23539d2bcd755db1cc6c9805a7dd109e1c98667a5b9d52b21c2772121b8d0d2b246e5fd3da80728e85bbf0d7067d1c6baa64394a29e7fcbf80842bd4ab02b35d83f59805a104e0bd69d0079a065f59e3e6f21573a00da990b72ea537fa98caaa0a58800a7e7a0623e263d4fca65ebb8eded46efdfe7db92c9ebd38062d8f12534f015b186186ee2361d62c24e4f22b3e95da0f9062ce04d
+K = 2368037a1c7647c683d7e301ac79b7feebc736effe3ab1644b68308b4b28620d
+R = 4fd8f25c059030027381d4167c3174b6be0088c15f0a573d7ebd05960f5a1eb2
+S = 5f56869cee7bf64fec5d5d6ea15bb1fa1169003a87eccc1621b90a1b892226f2
+
+[mod = L=2048, N=256, SHA-512]
+
+P = f63da3be9a9616196c6556f3ce6fd8b98bdda9137473da46fed970e2b8d147387a81922065d528a7d6433ebc5e35b15c67ea35a5a5bff5b9cef1cd1e6fe31dda52838da3aa89b9b4e8d9d3c0732ccc4f238ce1b416c4ca93f2c6800e5f4ed41c4f7615cec5531b98680b20dc63f73e70d803aacfaece33d45fa0e39d77c8508209528b9046b5917010791234397e412d22bc0b8d67cbd1cd28a32c2460a0bd86aaba0eea80e16e3245643171e34221760c203a56b8207a1009e6c1a2f6cda85f85c4f9e410b9499233c0ee072e465af4fb4fb9282c5c10e8234fd630ea92f0aae6b97a520db34475707b79a4c175265c0356ccbca827e3837df3d6d0576d9079
+Q = 9b7463f8269f0b909abed10991684f36a64ac864e0d6d717c0ef21577a4c3907
+G = 972a75f606e8aa3a91ff08fd131a20f5963251304e3d1431b712fa0803d527fd710fb7eb27e52904971cd43ca977199a24dbeeb4b7bc2ba075d3b72eb6b2c5ad8f0e8b8f48c50b554c7e0711f4c7416330806672498f430292724bf98a8ea48c7f53d7b31d8b7528b1a6f087d2c27c335202835b1e314225b37aef8bfcec7d80920c4a460a3d68344ded75ed9ee867fa2a6945063894f563b68633b8b39f83a1aaaf5a96c7f422687e7c84cf8fb8cc5f4504dff087bcb26a95bbf8583f03b3a0e43a356b2bd7e25cdddf7a015300faecc6793c5ee99b6327cb8456e32d9115339d5a6b712b7f9d0301acb05133e3115e454d3a6dd24a1693c94aab5406504bf7
+Msg = 8ab01510cfa33cfa5bcff003bba39996fa727693abf6ac010bb959b0b59a15306c0c3a1921af2a76717aa55b39fa3723f4c3229ca9acf6b741614bb551cde8a7220ab97d4b453bec1e05a0eaa42e382bbc7b9b84f8237dc8964ee5b66e9b2a4ca61cf675140efef54fb327a665def8d57ab097e8c53c643fcb58209c4215b608
+X = 5f6e545daef6cd1b8d9848dd98758807236ac0b7ff053b32c703eaa3b1147557
+Y = 41197ce2233d7e48c803cd64c78f657923b9e36b871401f8661c21d8ba38c6b9b3239db767b11d1d401e5faecbf7a45860cc5f1a54d60286b7d6e1c99fd5b8c84ed851c5357d41ad60163f224d78c996143fff89dd3a8fe123dae1f621427fd8cce76ed138d68fa248f374ae233249625b93f3dd5937d15e541b7effa4df4fea7d52faced615bfe0348418ff93e69a20a52e55c76cc30f307f84e71e4aabc0825eca3a95b4bd58ebfb0029d23a169e9d80ba7d1c5fd35395e6602e089aa9918f08bae35ae1cac7af33694129e98f0dadadd90eaeb6eed25024390b1a60af794734c397b0f509865b134b2867c115d6f489b6dd7e3c82994b45dce2a23c6bc902
+K = 5fe61afddbdf04449b24295a52a1a037d3f31441a3cec138b7f0102db86ef132
+R = 6a47ea57ceaecc116d7190ff6c6dd9831ab75b4bf6cb291083e4268b486ed245
+S = 017355f698a32abe9a4d4a7dda7c85950cddc348ab8a6751e72fddc01aa5d1f0
+
+[mod = L=3072, N=256, SHA-1]
+
+P = fd5a6c56dd290f7dd84a29de17126eb4e4487b3eff0a44abe5c59792d2e1200b9c3db44d528b9f7d2248032e4ba0f7bfc4fafc706be511db2276c0b7ecffd38da2e1c2f237a75390c1e4d3239cba8e20e55840ecb05df5f01a1b6977ad1906f2cb544ccfb93b901ad0966b1832ad2dab526244a3156c905c01ac51cb73b9dcd9860d56175a425d846485d9b1f44a8a0c2578e6cf61947bc1a1392fdd320b16a9d70455fe436f2d47ded8e8e605f7486eb578ea7fc4ffd13c07f9996af159fd411e9451403278dd1141a8c926b35c96384bbd6bee09c46f44c36b1ffc7197f5e925dbe0544a68e6ab8c18e426a466b392f9c27dd79fefa9ca163cc5a375539a8559f277f657a535d1964c6a5e91683ef5698ebaa01ef818dbf72cb04c3ff092d188866f25cd405108f566b087f73d2d5beb51fac6de84ae5161a66af9602c7e4bfc146f4820bdfc092faeac69133e4a08a5b202a12498a22e57bad54674ed4b510109d52b5f74e70e1f6f82161718cd4cf00cc9f1958acc8bddcdfbd1fbe46cd1
+Q = 800000000000000000000000334a26dd8f49c6811ce81bb1342b06e980f64b75
+G = 99ab030a21a5c9818174872167641c81c1e03c9b274cfbc27bc472542927766de5fa0539b3b73f3f16ac866a9aec8b445ded97fbff08834ed98c77e7fc89e5dc657bef766ff7fbf8e76873e17bee412762d56fe1141760ab4d25bafd4b6ef25b49a3506632d1f8e10770930760ec1325932c5a4baf9e90154264ddf442ec5c41fed95d11525151dbcfb3758149bad81c62b9cff7816b8f953b8b7c022590d1584e921dc955f5328ac72983ed5cf0d04056fe0d531e62f8f6c9ab3c0fcd44e14860b7311d2561c77c1d32f6c69dc8f77968c9d881ad9db5e0c114fda8628bca0335eb7fb9e15e625aabab58fc01194c81bf6fb2ce54077b82250e57c6a7b25deb6ee39d4b686a5c307a7612b2d85ee92512413dea297e44f317be7ceb70a3328af0b401001a418562b8ffe4e9771b4b4a8e0b40c791349d5d4e459fe620a1a2fc72e2f6ca28567d4c2632bbde1b49864c06bb12619f132c1da8f571ef613eac739f66ab3914cb3fa1ab86e05e5082ebaa24ebeea4cf51beefc27df512fe3fee7d
+Msg = ca84af5c9adbc0044db00d7acfb1b493aab0388ffbad47b38cd3e9e3111cfe2cda2a45f751c46862f05bdcec4b698adfd2e1606e484c3be4ac0c379d4fbc7c2cda43e922811d7f6c33040e8e65d5f317684b90e26387cf931fe7c2f515058d753b08137ff2c6b79c910de8283149e6872cb66f7e02e66f2371785129569362f1
+X = 433cfd0532ccfd8cdd1b25920d2bb7396987b766240379035b0e86527ce9c52d
+Y = e7c2ee18c3aa362c0182c6a56c2584628083c73e045beda8d653690c9c2f6544edf9702c57c455273905336a5f5171107a313cd7d0b0f50f8d3342c60219f22a9023394059d05f464c4496d55dab6eb0898527ff4cf5678e7b5bfb5e18d92c4a9d73288cce14530fc4702f6d0397ec39a880c4a72d358730c56633386ede028023c1791f3164d1574e7823c79b8a3ca1343ea166ba6f02b7ff7e9ef2198db107f7cc159f3b6a1c00a78c355c566deb0ac6fde3f633cb9177a1fbc6c1766ca021d5fec470101abb440d2f06982181a8c92b7cdd765336b9a1e1ab70283d6db0a963fb648c37c4e29a74c37577291049ab47cdbc104c04db966681ea8ebb9f00cf4c4a5462117379575fbda4b801979451fa94b19b4e93656705c0f734f3e0914bb96c1e2b8a0fb68faf14296efdf3300ad95bcde8b67cc4b26e6488eef925cfaeac6f0d6567e8b41355f89d1c2b8fe687bfa2df5e287e1305b89b8c388c26196090ac0351abc561aadc797da8ccea4146c3e96095ebce353e0da4c55019052caa
+K = 40f503abd70fd49a76c67a83e08b062b3fd465ad92be433c080e5f295bb9f559
+R = 21ca148cdf44be4ae93b2f353b8e512d03ad96dafa80623fde4922a95f032732
+S = 73e48b77a3aa44307483c2dd895cb51db2112177c185c59cb1dcff32fda02a4f
+
+[mod = L=3072, N=256, SHA-224]
+
+P = f63b3cdd646d8e7ddb57216aa6eec2134d707488a1f29cfa9970645f1227ea5db2e318eea5da1687c7ed90509669345ed6134cff32203ab72aecbfa693d216aeb55d8d28a981f4abff07d1319a799be5dd746f84842817929c305b408598af12045daa2f1ccc8be4d81b513c630f017fec1658aca108a1af6120ec05e3018c4253c9dd35bce062b73d0f2a93d41c481a5c43bb97909682d39a9a60dc3c35e36375dec6ced0d2db3ba0d111bedea701a0e4753624977a9e75b70a74e2b81e38a52ab22da131b35416d3cec9663079746a763476e57598142e39861545daaf8d38a176f26c71f5afebd9c5620da80cf3452b55c37c661b4a1ec0351710b9de4a3cbe0b98b4d9ec89128d97aa7efb19db8ba43cc0be25c200f90e1506cb78ec0c336d7a95613d4204e8ed68d0f0a6c78420105a8d2d438fbd2551a64a1a0b03ffb878742f8c9979cfa87394150281998d51701d5fcfa9696a4989fd25f400955e626b1abe926c0afa69aa6981900effcdd030592f82b2042a47a9a5a8cb0283dc4d
+Q = 80000000ba4634b5fa4da054bd0ca48ae490e57711f381193842429159ba7ca1
+G = 8ad4553c4e49aa24728ab5024417b132d2ca53a55d959458f2f759adb0435beeefa3a2cfcd0038e2420643fc4a4deeb5d9feaa1edf21193b40e14b42982a94f35c58b81147d7189d263c9b12fe63ab9fa5f6f03a2860c186432e3ab04f2ab0f2fb6147bd9bf7ed5d20713b9da21383e2c3a168e7d09d3d8a5a058fd23095b5acfeb864a3306be2425fa1ad32ad6d9382e603b03c68af4af0246397102c4155cba811abf99da7839e77b2eac9970588ca1d0a2361723a164ac9229c2e80dcfa8db4f9e29803effb3168c7fed7a3a6de40dda19a0536af9b5b7afaefb9c70d6ae8df12da658f6236043aea873db29ceb6f07d108f5225687bd0c30e3084e2090b45ae2f92a97b8ecb7a9705c4956b8b31c4a3d61107c84e47adda6c80d5d22dab3d859220f9d5aab13677ae3df168f0c176d176b54506c639853f04ddef2722f39c18e5ce426e14562ad8ff26247af88870efb72c0cce836de8fee67a662378245b502bf1f83099988a093ce7cdc81364c78b1f4a51b800df6137c71d65e6b089a
+Msg = 957973fc3f3fe3f559065be5d4a0c281cf17959018b9a670d2b3706d41d5812e37301005f8b70ebd2fba3c40a3f377a751b6cb9693e3cb00d92888247d07921d3c1e9257ce08733b8926e0df7bdb6e855f1f851075d4e628d110d42b643b54876e5faa3611477ee68371562555269ed62a9271bad50cc4d46038de2dd41920c2
+X = 524a7ea5977f8102b3552930477f5f042401165d4637dcd8b9d13df4f3aae5d0
+Y = 42243539e49db9ea19d98d97f6f2a94b23529812df889eaabcfeda01ce4c759487fb89bc82da75fe1c9134361f86de47d16d8eee80e56ac502178e8ed8129477af8bfbd8262c5edd937e1a86c0f0e7b2afe7bcbddfcb5814ced0b756a76ca178423bb4d578c5da183712d968582640aa0ec7e9fb56bfd960d7a57549747d8fb7ade47cfe816c1e57da6633dacc537de060813964bb5b2757a312f9da3d84e60aff98170051d3d90e380b8bcc1986c58ff9dc91e8827d4f9f5fc4b2b2e743cf9389ff02dec01f5d434b430d162e891c3355f91855339f8df58300e4c993ae4df8c4318b5c4bd05283ca4b46b7d2fb0f6476bf15907f50dd4141aa7acac9daa62eccd3a67357122060b6cece0446a93eb230ad93bc9a4d1b1efeeca1e3fc83c119785035b439509ffb7968b1a448b7bd8315753fdf04a256eca1562a11b096c90a36b353659cbde4420e17e90b94c43c7519c60641ceec056f897b97d6bb1861268e0dc79b7c3b6b7639c255bf06865737459126cb465bc1da4a043a1963da7d63
+K = 29e4d7790e181b4767903fe0eb37757f33f13337c33588c1fdbfba0e655ab621
+R = 2e59d5f30f73781d38255b70dedeeb38ae78df4f002c1f747c08deadc6530155
+S = 615c55b2df0ca28c60a6b385c58fa036df8c4b2f4f1935730bf8f4f0bed13610
+
+[mod = L=3072, N=256, SHA-256]
+
+P = c7b86d7044218e367453d210e76433e4e27a983db1c560bb9755a8fb7d819912c56cfe002ab1ff3f72165b943c0b28ed46039a07de507d7a29f738603decd1270380a41f971f2592661a64ba2f351d9a69e51a888a05156b7fe1563c4b77ee93a44949138438a2ab8bdcfc49b4e78d1cde766e54984760057d76cd740c94a4dd25a46aa77b18e9d707d6738497d4eac364f4792d9766a16a0e234807e96b8c64d404bbdb876e39b5799ef53fe6cb9bab62ef19fdcc2bdd905beda13b9ef7ac35f1f557cb0dc458c019e2bc19a9f5dfc1e4eca9e6d466564124304a31f038605a3e342da01be1c2b545610edd2c1397a3c8396588c6329efeb4e165af5b368a39a88e4888e39f40bb3de4eb1416672f999fead37aef1ca9643ff32cdbc0fcebe628d7e46d281a989d43dd21432151af68be3f6d56acfbdb6c97d87fcb5e6291bf8b4ee1275ae0eb4383cc753903c8d29f4adb6a547e405decdff288c5f6c7aa30dcb12f84d392493a70933317c0f5e6552601fae18f17e6e5bb6bf396d32d8ab9
+Q = 876fa09e1dc62b236ce1c3155ba48b0ccfda29f3ac5a97f7ffa1bd87b68d2a4b
+G = 110afebb12c7f862b6de03d47fdbc3326e0d4d31b12a8ca95b2dee2123bcc667d4f72c1e7209767d2721f95fbd9a4d03236d54174fbfaff2c4ff7deae4738b20d9f37bf0a1134c288b420af0b5792e47a92513c0413f346a4edbab2c45bdca13f5341c2b55b8ba54932b9217b5a859e553f14bb8c120fbb9d99909dff5ea68e14b379964fd3f3861e5ba5cc970c4a180eef54428703961021e7bd68cb637927b8cbee6805fa27285bfee4d1ef70e02c1a18a7cd78bef1dd9cdad45dde9cd690755050fc4662937ee1d6f4db12807ccc95bc435f11b71e7086048b1dab5913c6055012de82e43a4e50cf93feff5dcab814abc224c5e0025bd868c3fc592041bba04747c10af513fc36e4d91c63ee5253422cf4063398d77c52fcb011427cbfcfa67b1b2c2d1aa4a3da72645cb1c767036054e2f31f88665a54461c885fb3219d5ad8748a01158f6c7c0df5a8c908ba8c3e536822428886c7b500bbc15b49df746b9de5a78fe3b4f6991d0110c3cbff458039dc36261cf46af4bc2515368f4abb7
+Msg = cb06e02234263c22b80e832d6dc5a1bee5ea8af3bc2da752441c04027f176158bfe68372bd67f84d489c0d49b07d4025962976be60437be1a2d01d3be0992afa5abe0980e26a9da4ae72f827b423665195cc4eed6fe85c335b32d9c03c945a86e7fa99373f0a30c6eca938b3afb6dff67adb8bece6f8cfec4b6a12ea281e2323
+X = 3470832055dade94e14cd8777171d18e5d06f66aeff4c61471e4eba74ee56164
+Y = 456a105c713566234838bc070b8a751a0b57767cb75e99114a1a46641e11da1fa9f22914d808ad7148612c1ea55d25301781e9ae0c9ae36a69d87ba039ec7cd864c3ad094873e6e56709fd10d966853d611b1cff15d37fdee424506c184d62c7033358be78c2250943b6f6d043d63b317de56e5ad8d1fd97dd355abe96452f8e435485fb3b907b51900aa3f24418df50b4fcdafbf6137548c39373b8bc4ba3dabb4746ebd17b87fcd6a2f197c107b18ec5b465e6e4cb430d9c0ce78da5988441054a370792b730da9aba41a3169af26176f74e6f7c0c9c9b55b62bbe7ce38d4695d48157e660c2acb63f482f55418150e5fee43ace84c540c3ba7662ae80835c1a2d51890ea96ba206427c41ef8c38aa07d2a365e7e58380d8f4782e22ac2101af732ee22758337b253637838e16f50f56d313d07981880d685557f7d79a6db823c61f1bb3dbc5d50421a4843a6f29690e78aa0f0cff304231818b81fc4a243fc00f09a54c466d6a8c73d32a55e1abd5ec8b4e1afa32a79b01df85a81f3f5cfe
+K = 3d7c068a3978b2d8fe9034bcad65ad7c300c4440e4085de280e577eea72c1207
+R = 53bae6c6f336e2eb311c1e92d95fc449a929444ef81ec4279660b200d59433de
+S = 49f3a74e953e77a7941af3aefeef4ed499be209976a0edb3fa5e7cb961b0c112
+
+[mod = L=3072, N=256, SHA-384]
+
+P = a410d23ed9ad9964d3e401cb9317a25213f75712acbc5c12191abf3f1c0e723e2333b49eb1f95b0f9748d952f04a5ae358859d384403ce364aa3f58dd9769909b45048548c55872a6afbb3b15c54882f96c20df1b2df164f0bac849ca17ad2df63abd75c881922e79a5009f00b7d631622e90e7fa4e980618575e1d6bd1a72d5b6a50f4f6a68b793937c4af95fc11541759a1736577d9448b87792dff07232415512e933755e12250d466e9cc8df150727d747e51fea7964158326b1365d580cb190f4518291598221fdf36c6305c8b8a8ed05663dd7b006e945f592abbecae460f77c71b6ec649d3fd5394202ed7bbbd040f7b8fd57cb06a99be254fa25d71a3760734046c2a0db383e02397913ae67ce65870d9f6c6f67a9d00497be1d763b21937cf9cbf9a24ef97bbcaa07916f8894e5b7fb03258821ac46140965b23c5409ca49026efb2bf95bce025c4183a5f659bf6aaeef56d7933bb29697d7d541348c871fa01f869678b2e34506f6dc0a4c132b689a0ed27dc3c8d53702aa584877
+Q = abc67417725cf28fc7640d5de43825f416ebfa80e191c42ee886303338f56045
+G = 867d5fb72f5936d1a14ed3b60499662f3124686ef108c5b3da6663a0e86197ec2cc4c9460193a74ff16028ac9441b0c7d27c2272d483ac7cd794d598416c4ff9099a61679d417d478ce5dd974bf349a14575afe74a88b12dd5f6d1cbd3f91ddd597ed68e79eba402613130c224b94ac28714a1f1c552475a5d29cfcdd8e08a6b1d65661e28ef313514d1408f5abd3e06ebe3a7d814d1ede316bf495273ca1d574f42b482eea30db53466f454b51a175a0b89b3c05dda006e719a2e6371669080d768cc038cdfb8098e9aad9b8d83d4b759f43ac9d22b353ed88a33723550150de0361b7a376f37b45d437f71cb711f2847de671ad1059516a1d45755224a15d37b4aeada3f58c69a136daef0636fe38e3752064afe598433e80089fda24b144a462734bef8f77638845b00e59ce7fa4f1daf487a2cada11eaba72bb23e1df6b66a183edd226c440272dd9b06bec0e57f1a0822d2e00212064b6dba64562085f5a75929afa5fe509e0b78e630aaf12f91e4980c9b0d6f7e059a2ea3e23479d930
+Msg = ed9a64d3109ef8a9292956b946873ca4bd887ce624b81be81b82c69c67aaddf5655f70fe4768114db2834c71787f858e5165da1a7fa961d855ad7e5bc4b7be31b97dbe770798ef7966152b14b86ae35625a28aee5663b9ef3067cbdfbabd87197e5c842d3092eb88dca57c6c8ad4c00a19ddf2e1967b59bd06ccaef933bc28e7
+X = 6d4c934391b7f6fb6e19e3141f8c0018ef5726118a11064358c7d35b37737377
+Y = 1f0a5c75e7985d6e70e4fbfda51a10b925f6accb600d7c6510db90ec367b93bb069bd286e8f979b22ef0702f717a8755c18309c87dae3fe82cc3dc8f4b7aa3d5f3876f4d4b3eb68bfe910c43076d6cd0d39fc88dde78f09480db55234e6c8ca59fe2700efec04feee6b4e8ee2413721858be7190dbe905f456edcab55b2dc2916dc1e8731988d9ef8b619abcf8955aa960ef02b3f02a8dc649369222af50f1338ed28d667f3f10cae2a3c28a3c1d08df639c81ada13c8fd198c6dae3d62a3fe9f04c985c65f610c06cb8faea68edb80de6cf07a8e89c00218185a952b23572e34df07ce5b4261e5de427eb503ee1baf5992db6d438b47434c40c22657bc163e7953fa33eff39dc2734607039aadd6ac27e4367131041f845ffa1a13f556bfba2307a5c78f2ccf11298c762e08871968e48dc3d1569d09965cd09da43cf0309a16af1e20fee7da3dc21b364c4615cd5123fa5f9b23cfc4ffd9cfdcea670623840b062d4648d2eba786ad3f7ae337a4284324ace236f9f7174fbf442b99043002f
+K = 40b5cc685c3d1f59072228af9551683b5b8c8ff65240114ad2dacfccf3928057
+R = 7695698a14755db4206e850b4f5f19c540b07d07e08aac591e20081646e6eedc
+S = 3dae01154ecff7b19007a953f185f0663ef7f2537f0b15e04fb343c961f36de2
+
+[mod = L=3072, N=256, SHA-512]
+
+P = c1d0a6d0b5ed615dee76ac5a60dd35ecb000a202063018b1ba0a06fe7a00f765db1c59a680cecfe3ad41475badb5ad50b6147e2596b88d34656052aca79486ea6f6ec90b23e363f3ab8cdc8b93b62a070e02688ea877843a4685c2ba6db111e9addbd7ca4bce65bb10c9ceb69bf806e2ebd7e54edeb7f996a65c907b50efdf8e575bae462a219c302fef2ae81d73cee75274625b5fc29c6d60c057ed9e7b0d46ad2f57fe01f823230f31422722319ce0abf1f141f326c00fbc2be4cdb8944b6fd050bd300bdb1c5f4da72537e553e01d51239c4d461860f1fb4fd8fa79f5d5263ff62fed7008e2e0a2d36bf7b9062d0d75db226c3464b67ba24101b085f2c670c0f87ae530d98ee60c5472f4aa15fb25041e19106354da06bc2b1d322d40ed97b21fd1cdad3025c69da6ce9c7ddf3dcf1ea4d56577bfdec23071c1f05ee4077b5391e9a404eaffe12d1ea62d06acd6bf19e91a158d2066b4cd20e4c4e52ffb1d5204cd022bc7108f2c799fb468866ef1cb09bce09dfd49e4740ff8140497be61
+Q = bf65441c987b7737385eadec158dd01614da6f15386248e59f3cddbefc8e9dd1
+G = c02ac85375fab80ba2a784b94e4d145b3be0f92090eba17bd12358cf3e03f4379584f8742252f76b1ede3fc37281420e74a963e4c088796ff2bab8db6e9a4530fc67d51f88b905ab43995aab46364cb40c1256f0466f3dbce36203ef228b35e90247e95e5115e831b126b628ee984f349911d30ffb9d613b50a84dfa1f042ba536b82d5101e711c629f9f2096dc834deec63b70f2a2315a6d27323b995aa20d3d0737075186f5049af6f512a0c38a9da06817f4b619b94520edfac85c4a6e2e186225c95a04ec3c3422b8deb284e98d24b31465802008a097c25969e826c2baa59d2cba33d6c1d9f3962330c1fcda7cfb18508fea7d0555e3a169daed353f3ee6f4bb30244319161dff6438a37ca793b24bbb1b1bc2194fc6e6ef60278157899cb03c5dd6fc91a836eb20a25c09945643d95f7bd50d206684d6ffc14d16d82d5f781225bff908392a5793b803f9b70b4dfcb394f9ed81c18e391a09eb3f93a032d81ba670cabfd6f64aa5e3374cb7c2029f45200e4f0bfd820c8bd58dc5eeb34
+Msg = 494180eed0951371bbaf0a850ef13679df49c1f13fe3770b6c13285bf3ad93dc4ab018aab9139d74200808e9c55bf88300324cc697efeaa641d37f3acf72d8c97bff0182a35b940150c98a03ef41a3e1487440c923a988e53ca3ce883a2fb532bb7441c122f1dc2f9d0b0bc07f26ba29a35cdf0da846a9d8eab405cbf8c8e77f
+X = 150b5c51ea6402276bc912322f0404f6d57ff7d32afcaa83b6dfde11abb48181
+Y = 6da54f2b0ddb4dcce2da1edfa16ba84953d8429ce60cd111a5c65edcf7ba5b8d9387ab6881c24880b2afbdb437e9ed7ffb8e96beca7ea80d1d90f24d546112629df5c9e9661742cc872fdb3d409bc77b75b17c7e6cfff86261071c4b5c9f9898be1e9e27349b933c34fb345685f8fc6c12470d124cecf51b5d5adbf5e7a2490f8d67aac53a82ed6a2110686cf631c348bcbc4cf156f3a6980163e2feca72a45f6b3d68c10e5a2283b470b7292674490383f75fa26ccf93c0e1c8d0628ca35f2f3d9b6876505d118988957237a2fc8051cb47b410e8b7a619e73b1350a9f6a260c5f16841e7c4db53d8eaa0b4708d62f95b2a72e2f04ca14647bca6b5e3ee707fcdf758b925eb8d4e6ace4fc7443c9bc5819ff9e555be098aa055066828e21b818fedc3aac517a0ee8f9060bd86e0d4cce212ab6a3a243c5ec0274563353ca7103af085e8f41be524fbb75cda88903907df94bfd69373e288949bd0626d85c1398b3073a139d5c747d24afdae7a3e745437335d0ee993eef36a3041c912f7eb58
+K = b599111b9f78402cefe7bde8bf553b6ca00d5abaf9a158aa42f2607bf78510bc
+R = a40a6c905654c55fc58e99c7d1a3feea2c5be64823d4086ce811f334cfdc448d
+S = 6478050977ec585980454e0a2f26a03037b921ca588a78a4daff7e84d49a8a6c
+
diff --git a/nss/cmd/bltest/tests/dsa/key0 b/nss/cmd/bltest/tests/dsa/key0
new file mode 100644
index 0000000..e582eeb
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/key0
@@ -0,0 +1,6 @@
+AAAAQI3ypJRJInaqPSV1m7BoacvqwNg6+40M98u4Mk8NeILl0HYvxbchDq/C6a2s
+Mqt6rElpPfv4NyTC7Ac27jHIApEAAAAUx3MhjHN+yO6ZO08t7TD0jtrOkV8AAABA
+Ym0CeDnqChNBMWOlW0y1ACmdVSKVbO/LO/8Q85nOLC5xy53l+iS6v1jlt5Uhklyc
+xC6fb0ZLCIzFcq9T5teIAgAAAEAZExhx11sWEqgZ8p140bDXNG96p3u2KoWb/WxW
+ddqdIS06Nu8Wcu9mC4x8JVzA7HSFj7oz9EwGaZYwp2sDDuMzAAAAFCBwsyI9ujcv
+3hwP/HsuO0mLJgYU
diff --git a/nss/cmd/bltest/tests/dsa/key1 b/nss/cmd/bltest/tests/dsa/key1
new file mode 100644
index 0000000..8ba3118
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/key1
@@ -0,0 +1,10 @@
+AAAAgKj5zSAeXjXYkvhfgOTbJZmlZ2o7HU8ZAzDtMlaybQ6AoOSaj/+qrSok9HLS
+VzJB1NbWx0gMgLTGe7RHnBWtp+qEJNJQL6AUcudgJBcT2rAlrhsC4XA6FDX2Ld9O
+5MG2ZAZusi8uO/KLtwoqduT9Xr4tEiloG1sGQ5rJx+nYveKDAAAAFPhfD4OsTffq
+DN+PRpv+6uoUFWSVAAAAgCsxUv9sYvFGIrj0jln4r0aIOzjnm4x03urp3xMfi4Vu
+OtbIRV2rh8wNqKyXNBfOT3h4VX1s30CzW0oMo+sxDGqV1ozihK1OJeooWRYR7gi4
+REvWSyXz98VyQQ3fs5zHKLnJNvhfQZEphpkpzbkJpqOpm74IkhY2gXG9C6gd5P4z
+AAAAgDE/2evKkVdOHC7r4VF8V+DCGwIJhyFAxTKHYbuyRQsz8bGLQJzpq3xM2P2j
+OR6ONIaDV8GZ4WprLroG1nSd73kdeeldOk0Jskw5KtidvxAJla4ZwBBiBWuxS84A
+Xocx794XX5W5dQib3NrqVisyeG2W9aMa7fdTZACK1P/+u5cLAAAAFMU+rm1FMjFk
+x9B69XFXA3RKY/w6
diff --git a/nss/cmd/bltest/tests/dsa/key10 b/nss/cmd/bltest/tests/dsa/key10
new file mode 100644
index 0000000..166f9bd
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/key10
@@ -0,0 +1,18 @@
+AAABAL/r0ACy1s1Ks477o13zNN9yHWwvKz2VZnnLrQCfPfvQApUsyJnMI1bsh2m9
+PRulpzAjcpiI2pLKSKXulMl/TwSi46y08zovD7N4PDHyxw+nxw84IUon2t7IsS5n
+mWqehe47sUiAMTAUc5LcUlPATXBjU15s1ka/sYaYTgi1i3SnvlszO/MrCr/VZlNg
+6akjoMUo/xxixyU0WPVnhShxnUNuUBSHQfRdx90sbKxxxVIx8SqD/v0u0KM+3huK
+UfVm/PeJBoLNwZMdwgfJK/LvTiirMWYe63fxYB7qlByVkfA40/ANkShX2wXmSyrV
+aTIAYcb4Y/8zVNhC5+fqcVr++NEAAAAcqpht+KBkJ46TYzFqmDC8+kkGVvqm1dqo
+F9h5SQAAAQCBla2aR4/ZhSFu5YNoNm0u3RPBKz1iI5Fp+gQtkRVkCLSDEi9E7WI2
+uDCKbNtS+a896I7IngOa+tfaOqZsGXYEmo4KfRjVZ7r5n87+MVytoBVIOGsQsl5S
+9S7XjrTSgILl4f/ulIDE/izEqv0e/J1P0sxtFVlokxJx7xWzJA5/sEOoDI9ii+/g
+nWRQd8ECnSHgrIvwupwncU0bWA7eWUqgGzt29udF/B7AfbN+L9fpjGyMaRUijkIs
+MJ3p9dsWj1AknRvh7TKYCQgI4uu4lrt5uMTL+U1MIGTjfmErpESdesIQ7d4hFBbW
+SwUd2ARqsEFzJmVBGn8VTTGz4RpR2n/AAAABAK9nIb913saht2rTXKN1De8xEXxb
+RBwVowaDWh23TAA7hq6Qmev7dFsKqcsADPQ/sCFRO48Ze8hlsiv5SbSRgJrXUv/B
+yo5UvqFtx/U55MVftwp3Q90o8mL2DvDy/KrCnoAhp5OMGP/gMHXQt+CitNyr5G7R
+lT0z438ROvUZqwvwthhsErX2SIQ39RkwluL9amoYNWBHlMZrQq5SZcHPHLU66EmX
+l14DGKk85B45AuTvVN48VlVb0ZSRrNU/PldGTh9GA4nbxfqAZI+lpaDylW6ew7jc
+RBtTXGQcNi7tdw2oKGSb/RRkcrD0akwGTkWfiL/5De3n7FYXeppx0WeUhxIAAAAc
+altP/EQjjRhS+5t05MFmG+hZhAQ8/u4CP1fKxg==
diff --git a/nss/cmd/bltest/tests/dsa/key11 b/nss/cmd/bltest/tests/dsa/key11
new file mode 100644
index 0000000..086f493
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/key11
@@ -0,0 +1,18 @@
+AAABAMGlnSFVc5SeCyCpdMLt8uMTf/JGMGL3Xx0T3xKroQdrstATQCtgr2wYf7D6
+NiFnyXbCYXxyb5B38J4YwRtg9lAIglvWwCofV9PrCtQc1UfeQ9h/JSX5cdQrMGUG
+58oDvmOzX0raFy0KBpJEQKFCUNeCKsLVrq/tRhnnnUFYp9XrLZ8CPbGBqPCUssbL
+h8uFNUFqwZgT8HFEZgxVd0X0SgHGsQKQksEpsNJxg+gsWiGoAXfudHbrlcRm+0cr
+09LcKGziWEfpPL+prTnMVwNdDHtkuSapx/WnsrxavL+9wLDj/t48HgLESvyK78eV
+faB6Dl/RIznbhmdhb2IobfgNWKsAAAAggAAAAAAAAAAAAAAAG9YsZei4fIl5f48M
+v6VeSmgQ4scAAAEArqWHh0DxQk08bqnGtHmWFdJ0kpihfiYgf3bO80Dd05Dhsa1r
+bAAQrQFaEDNC3dRSysAks25C2bjtUvr656HTzp5LIfkQ0TVusWOj5agYTHgb8USS
+r6LksKVtiIT9AaYouWYnOcQuXFeVreL18n5t4dljkXzogG/EDQIc2HqjqjqeTwws
+TEXSlZsleLL7GiIpw34YEFm51ee3hi+oLiN3pJ7Q+dyoIKWBQHndZhBxTvr4sMxo
+PY5y5MiE5vnUlGs+jUy7kq2759TEfMML5/jDfKgYg6GqxoYAWf9GQKKcyuc94gsS
+5jsAqIsu6bqUt160CmVuFdnsg3MchdDv/LnvnwAAAQCIDhfEroFBdQYJ2CUcC716
+z20LRg7TaI6aX5kObEtbAIddp1DgIooEECo19X50uNL5tpUPDR240wLFyQpbh4ao
+LGj/WxelenWElsX4BT5EhKJT2ZQiBNmhEJ9L0qPsMRpgz2nGhbWG2Yb1ZdM9v1qr
+cJHjGqQQLE9LU/v4ctcAFWRltsB15/d4RxojUC3A/uQbJxyDehwmaRaZ81UNBgoz
+EJn2SDfN3sacrr9Rv07J828qIg/nc8tNPALQRG3dRhM1Mu8cPGnUMuMDUCvQWnUn
+mngJp0KsSnhysH8ZCGVASUGTUON6lfLvMzYdjYc21Ag9wUwLuXLhTUx7l/Pd/Mrv
+AAAAIFpC53JINY8GrpgKLGT2oivqK/e0/AAVdFBTxDK3Eypn
diff --git a/nss/cmd/bltest/tests/dsa/key12 b/nss/cmd/bltest/tests/dsa/key12
new file mode 100644
index 0000000..bb2cba1
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/key12
@@ -0,0 +1,18 @@
+AAABANAiduvzwi/9ZmmDGDpHrpTJvMvL+V3ctJHR985kNUkZmZLTfHnnsDLSbtAx
+trpEifMSWCb6+ycmqYMz69mr3eWS2Gk9mFlTbZzDhBodJOBE01rO1hNiVvxta2Fc
+9PQWOqOB6ytMSAglqOzMVtjdz1/mN+OK2bKXS9LPaL8nHg0GfSRlqLa2YFJPAIJZ
+iUWtpY6mSbmATrR1NAjCxZdoxGq7guMpXz2cpGn4TMGH9XLcS1o7OTRuyDnfrW8H
+1tHw4hUgm7DswFx2fPLnlDrJz7Au7h6e9ZRujOiDFrXhX9z5WhMu8uS7CBcTZSjP
+pd2WUy+cOr5cQhYg7ba8vVIjTKkAAAAggAAAABKZfoKF5AiXCPUoBwxtevigvQFA
+nnoHnNtvxbsAAAEAd4RTBJ7yYhR/7XtZsO5nZGB8Uee1tfxv6np6ex3Wuyg/Sprp
+jv05ZLFVZ1jLFbKlOvhhnnTYWJi+x307PzgklK5ZYaE//HRdo4YYIpFRmAD5ndcQ
+4ArrFa3uCI4nmO4uRvWYUmzw9GZwVdG6AJdQBB3FzdJyX/HZfdNAyFGK92cbh9Od
+Z67O2Etm+E4HAe/IKlye+VTuV20kw4WxTWMDfw2Gb9QktJdb3VSF7XQMuTLoQ/kG
+aD98eyx0d12QHDYbhHtRnA2mmWONpAvXNreD0nELLCzCbvkScb9OLBkp+HbpAuIF
+cWQiO8eNaiufbAx6fLhZIvfWxCh64jhh+BKISAAAAQB7sx6Yx6BDf5eKc9Xc+9+7
+Ccwkmd+vHrUla8zWNYyrtfZ9BKQoI0Y7fpV/K5IT8fqOWpjWFEhHAau4x9Z2Qf5u
+0G+kUntJPdqy50ZA/ePecNppPx2yuOJkFwQK8O6myrRRp5WlLhh9LuJBuT9lyGxt
+ZvRYNMzhZaxetnDU8AlcI86XV+O9xjb5ke4Ac9kKCSAu2zXMPqHPmtyhYX+gv/2c
+EmIppgSh079JMd3wuZQt/IovjAn8yXAyVkp5rh6+Hizkn/V4OefEP6YLFgPRWkUI
+mKpOSh7oBleUEm1k8BM2cJaoNoa58VjDOxD187Ns8fY1iz80+EsQHcJtPbaLzJXI
+AAAAIGuoHmzUNneYqquLevETUYOjfEKnZtvWjNLc548mcO8P
diff --git a/nss/cmd/bltest/tests/dsa/key13 b/nss/cmd/bltest/tests/dsa/key13
new file mode 100644
index 0000000..b3e25c7
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/key13
@@ -0,0 +1,18 @@
+AAABAKittsC0z5WIAS5d7/GocdOD4OKoW16OA9gU/hOgWXBeZjIwo3e/cyOo+hFx
+ACAL/VrfhXOTsLvWeQbAgeWFQQ44SA6tUWhNrDo497ZMnrEJ8Zc5pFF819XWKR6K
+8go/vxczbHv4DucY7gh+Mi7kEEfavvvMNNELZrZE3bMWCijAY5Vj1xmTomVD6tt3
+GPMXv12Vd6YVZWGwgqEAKc1EASsY3mhEUJ/gWLqHmAeSKF8nUJaf6Jws1kmNs1RW
+ONU3nRJdzPZOBsGvM6YZCEHSI9oVEzM6fJ14Riq6qzG5+W1fNERc62MJ8vbSyN3g
+ZEHoeYDTA++aH/AH6L4vC+BswV8AAAAg5x+FZ0R/QudfXvhcog/lV6sDQ9N+0J7c
+P25oYE1rnfsAAAEAW6JN6WB7iZjmbObE+BKjFMaTWEL3q1TNgrGfoQSr+12EV5pi
+OyV0s30izK6bPkFeSPXA+by9/4Bx1jubuVblR686jfmeXTBhl5ZS/5a3Zcs+5JNk
+NUTHXb5bs5g0UxlSoPtLA3iz/LtMi1gApTMDkqKgTnALtu1+C4V5XqOLG5YnQbPz
+O53eL07BNU8J4ut46V8DelgEthcWWfiHFc4amwzJDCfzXvLxD/DHx6K7AVTZuOvn
+aj12Sqh5rzcvQkDeg0eTflqQzsn0H/Lya42pqUoiXRqRNxfXPxA5fSGD8bo7e0Wm
+jx/xiTyvaagngC97akjVHab777ZP2abFt1xFYQAAAQBaVdzt3RE07l8R7YXetNY0
+o2Q/XzbcOnBoklZGmgtlGtIogPFKuFcZQ0+cDkB+YOpCDioM0pQixImcQWNZ27Hl
+kkVvKzzOIzJZwRdUL9BfMeolsBXZEhyJC5DgutAzvhNo0imYWqxyJtHIwuqzJe87
+LNWdO59959vJSvGpM560MMo2wmxG7PpsVIFxFJb2JOGIrXVA713yb476y4IL0Xof
+YYrLUMm8GX1Mt8ysRdgko795XCNLVWsGrrkpFzRTJSCEAD9p/pgEX+dAArplj5NH
+ViL3Z5HZsmI9G1//LMFoRHRu/S0wpqgTS/xMjMgKRhB5AfuXPCj8VTEw8yhsFIna
+AAAAIERpaQJURiR/hP3qdNAtfdE2crLet8CFvhERFEGVWjd7
diff --git a/nss/cmd/bltest/tests/dsa/key14 b/nss/cmd/bltest/tests/dsa/key14
new file mode 100644
index 0000000..759c602
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/key14
@@ -0,0 +1,18 @@
+AAABAKYWfBb/904pNCuFhq7TzYlvexY1oihv8W/f9BoGMXymsFyiunwGCtbbFWFi
+HMsMQLhqA2Gb//MuIEy9kLedy1+G67ST470ZiNgJf6I/pNePs83csAxGZCPY+nGY
+c8N2Rf5O7MVxcbvt/lb6lHTJY4W4ujeMeZcteqrmmiumTN6OVlTw97dFUM00R+ek
+cqM7QDfbRo3eMcNIqiXoK3/EG4N/f8ImphA5ZuzY+dFMLTFJVW1Dgp8TdFG40g+F
+ILDOjj1wX3TQpX6ocsK97pcU4LY5Bs3f3Ci2d30ZMlAA+O1SeOxdkS0QIQkxnLo7
+ZGnUZykJtPDb7sC7tjS1UboM8hMAAAAghCdSkETSFMB1dPezWcLgHCP9l3AbMorI
+wThbgcU3OJUAAAEAb8IyQVwxIAz1I680g/jias6AjS8caouGOrBCzH9rcUSy05Ry
+w8tMdoHQcyhDUD2PhYy+R25nQDJKqilZUBBZeMM1BpuRn/mm/0tBBYG4BxL+XT4E
+3bTf0m1ef7yisMUtjUBDQ9V7L5sqJtqn7OMM6rnheJ+XUaqpOHBJllrzJlDGyls3
+SlrnCz+Y4FP1GFfWu7F6Zw5uqviYRNZB4eE9Whsk0FPca4/RAcYkeGlRkn5CYxCr
+qUmKAEKz3Hu8WdcF+A2bgH3kFffpTFz514mZLTu4M20dgIy4a1bd4J2TS7UnAzki
+3hS/MHN2q30i+81hb57aR5qyFKF4UL3QgCqHHAAAAQBcpxUbyg5Fe7xG9Z9x2Bqx
+ZojcDrfk0XsWbDMmxbEsW967NhMiTRp1QCPFC4PLXswTkJbO8okzs7EsoxA45AiT
+g1l8WcwnuQK+XaYsrn2l9K+Q6UEO0WBAguLjjiXrC3jfrArrKtOxncI1OdK811Xb
+HMbJgFp90QnhyYZnpbnVKyHCdyEhuNDSskbl/T2oByjoW78NcGfRxrqmQ5Sinn/L
++AhCvUqwKzXYP1mAWhBOC9adAHmgZfWePm8hVzoA2pkLcupTf6mMqqCliACn56Bi
+PiY9T8pl67jt7Ubv3+fbksnr04Bi2PElNPAVsYYYbuI2HWLCTk8is+ldoPkGLOBN
+AAAAIEWesViOn33U8oZnenQVyyWhtG56fPrcikUQA4PiDaad
diff --git a/nss/cmd/bltest/tests/dsa/key15 b/nss/cmd/bltest/tests/dsa/key15
new file mode 100644
index 0000000..dee9a8a
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/key15
@@ -0,0 +1,18 @@
+AAABAPY9o76alhYZbGVW885v2LmL3akTdHPaRv7ZcOK40Uc4eoGSIGXVKKfWQz68
+XjWxXGfqNaWlv/W5zvHNHm/jHdpSg42jqom5tOjZ08BzLMxPI4zhtBbEypPyxoAO
+X07UHE92Fc7FUxuYaAsg3GP3PnDYA6rPrs4z1F+g4513yFCCCVKLkEa1kXAQeRI0
+OX5BLSK8C41ny9HNKKMsJGCgvYaqug7qgOFuMkVkMXHjQiF2DCA6VrggehAJ5sGi
+9s2oX4XE+eQQuUmSM8DuBy5GWvT7T7koLFwQ6CNP1jDqkvCq5rl6Ug2zRHVwe3mk
+wXUmXANWzLyoJ+ODffPW0FdtkHkAAAAgm3Rj+CafC5CavtEJkWhPNqZKyGTg1tcX
+wO8hV3pMOQcAAAEAlyp19gboqjqR/wj9Exog9ZYyUTBOPRQxtxL6CAPVJ/1xD7fr
+J+UpBJcc1DypdxmaJNvutLe8K6B107cutrLFrY8Oi49IxQtVTH4HEfTHQWMwgGZy
+SY9DApJyS/mKjqSMf1PXsx2LdSixpvCH0sJ8M1ICg1seMUIls3rvi/zsfYCSDEpG
+Cj1oNE3tde2e6Gf6KmlFBjiU9WO2hjO4s5+DoaqvWpbH9CJofnyEz4+4zF9FBN/w
+h7yyapW7+Fg/A7Og5Do1ayvX4lzd33oBUwD67MZ5PF7pm2Mny4RW4y2RFTOdWmtx
+K3+dAwGssFEz4xFeRU06bdJKFpPJSqtUBlBL9wAAAQBBGXziIz1+SMgDzWTHj2V5
+I7nja4cUAfhmHCHYujjGubMjnbdnsR0dQB5frsv3pFhgzF8aVNYChrfW4cmf1bjI
+TthRxTV9Qa1gFj8iTXjJlhQ//4ndOo/hI9rh9iFCf9jM527RONaPokjzdK4jMkli
+W5Pz3Vk30V5UG37/pN9P6n1S+s7WFb/gNIQY/5PmmiClLlXHbMMPMH+E5x5Kq8CC
+Xso6lbS9WOv7ACnSOhaenYC6fRxf01OV5mAuCJqpkY8IuuNa4crHrzNpQSnpjw2t
+rdkOrrbu0lAkOQsaYK95RzTDl7D1CYZbE0soZ8EV1vSJtt1+PIKZS0Xc4qI8a8kC
+AAAAIF9uVF2u9s0bjZhI3Zh1iAcjasC3/wU7MscD6qOxFHVX
diff --git a/nss/cmd/bltest/tests/dsa/key16 b/nss/cmd/bltest/tests/dsa/key16
new file mode 100644
index 0000000..704d76c
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/key16
@@ -0,0 +1,26 @@
+AAABgP1abFbdKQ992Eop3hcSbrTkSHs+/wpEq+XFl5LS4SALnD20TVKLn30iSAMu
+S6D3v8T6/HBr5RHbInbAt+z/042i4cLyN6dTkMHk0yOcuo4g5VhA7LBd9fAaG2l3
+rRkG8stUTM+5O5Aa0JZrGDKtLatSYkSjFWyQXAGsUctzudzZhg1WF1pCXYRkhdmx
+9EqKDCV45s9hlHvBoTkv3TILFqnXBFX+Q28tR97Y6OYF90hutXjqf8T/0TwH+Zlq
+8Vn9QR6UUUAyeN0RQajJJrNcljhLvWvuCcRvRMNrH/xxl/XpJdvgVEpo5quMGOQm
+pGazkvnCfdef76nKFjzFo3VTmoVZ8nf2V6U10ZZMal6RaD71aY66oB74GNv3LLBM
+P/CS0YiGbyXNQFEI9Wawh/c9LVvrUfrG3oSuUWGmavlgLH5L/BRvSCC9/Akvrqxp
+Ez5KCKWyAqEkmKIuV7rVRnTtS1EBCdUrX3TnDh9vghYXGM1M8AzJ8ZWKzIvdzfvR
+++Rs0QAAACCAAAAAAAAAAAAAAAAzSibdj0nGgRzoG7E0KwbpgPZLdQAAAYCZqwMK
+IaXJgYF0hyFnZByBweA8mydM+8J7xHJUKSd2beX6BTmztz8/FqyGaprsi0Rd7Zf7
+/wiDTtmMd+f8ieXcZXvvdm/3+/jnaHPhe+5BJ2LVb+EUF2CrTSW6/Utu8ltJo1Bm
+MtH44Qdwkwdg7BMlkyxaS6+ekBVCZN30QuxcQf7ZXRFSUVHbz7N1gUm62Bxiuc/3
+gWuPlTuLfAIlkNFYTpIdyVX1MorHKYPtXPDQQFb+DVMeYvj2yas8D81E4UhgtzEd
+JWHHfB0y9sadyPd5aMnYga2dteDBFP2oYovKAzXrf7nhXmJaq6tY/AEZTIG/b7LO
+VAd7giUOV8ansl3rbuOdS2hqXDB6dhKy2F7pJRJBPeopfkTzF75863CjMorwtAEA
+GkGFYrj/5Ol3G0tKjgtAx5E0nV1ORZ/mIKGi/HLi9sooVn1MJjK73htJhkwGuxJh
+nxMsHaj1ce9hPqxzn2arORTLP6GrhuBeUILrqiTr7qTPUb7vwn31Ev4/7n0AAAGA
+58LuGMOqNiwBgsalbCWEYoCDxz4EW+2o1lNpDJwvZUTt+XAsV8RVJzkFM2pfUXEQ
+ejE819Cw9Q+NM0LGAhnyKpAjOUBZ0F9GTESW1V2rbrCJhSf/TPVnjntb+14Y2SxK
+nXMojM4UUw/EcC9tA5fsOaiAxKctNYcwxWYzOG7eAoAjwXkfMWTRV054I8ebijyh
+ND6hZrpvArf/fp7yGY2xB/fMFZ87ahwAp4w1XFZt6wrG/eP2M8uRd6H7xsF2bKAh
+1f7EcBAau0QNLwaYIYGoySt83XZTNrmh4atwKD1tsKlj+2SMN8TimnTDdXcpEEmr
+R828EEwE25ZmgeqOu58Az0xKVGIRc3lXX72kuAGXlFH6lLGbTpNlZwXA9zTz4JFL
+uWweK4oPto+vFClu/fMwCtlbzei2fMSybmSI7vklz66sbw1lZ+i0E1X4nRwrj+aH
+v6LfXih+EwW4m4w4jCYZYJCsA1GrxWGq3Hl9qMzqQUbD6WCV6841Pg2kxVAZBSyq
+AAAAIEM8/QUyzP2M3Rslkg0rtzlph7dmJAN5A1sOhlJ86cUt
diff --git a/nss/cmd/bltest/tests/dsa/key17 b/nss/cmd/bltest/tests/dsa/key17
new file mode 100644
index 0000000..d5b0144
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/key17
@@ -0,0 +1,26 @@
+AAABgPY7PN1kbY5921chaqbuwhNNcHSIofKc+plwZF8SJ+pdsuMY7qXaFofH7ZBQ
+lmk0XtYTTP8yIDq3Kuy/ppPSFq61XY0oqYH0q/8H0TGaeZvl3XRvhIQoF5KcMFtA
+hZivEgRdqi8czIvk2BtRPGMPAX/sFlisoQihr2Eg7AXjAYxCU8ndNbzgYrc9DyqT
+1BxIGlxDu5eQloLTmppg3Dw142N13sbO0NLbO6DREb7epwGg5HU2JJd6nnW3CnTi
+uB44pSqyLaExs1QW087JZjB5dGp2NHbldZgULjmGFUXar404oXbybHH1r+vZxWIN
+qAzzRStVw3xmG0oewDUXELneSjy+C5i02eyJEo2Xqn77GduLpDzAviXCAPkOFQbL
+eOwMM216lWE9QgTo7WjQ8KbHhCAQWo0tQ4+9JVGmShoLA/+4eHQvjJl5z6hzlBUC
+gZmNUXAdX8+paWpJif0l9ACVXmJrGr6SbAr6aappgZAO/83QMFkvgrIEKkeppajL
+AoPcTQAAACCAAAAAukY0tfpNoFS9DKSK5JDldxHzgRk4QkKRWbp8oQAAAYCK1FU8
+TkmqJHKKtQJEF7Ey0spTpV2VlFjy91mtsENb7u+jos/NADjiQgZD/EpN7rXZ/qoe
+3yEZO0DhS0KYKpTzXFi4EUfXGJ0mPJsS/mOrn6X28DooYMGGQy46sE8qsPL7YUe9
+m/ftXSBxO52iE4Piw6Fo59CdPYpaBY/SMJW1rP64ZKMwa+JCX6GtMq1tk4LmA7A8
+aK9K8CRjlxAsQVXLqBGr+Z2ng553surJlwWIyh0KI2FyOhZKySKcLoDc+o20+eKY
+A+/7MWjH/tejpt5A3aGaBTavm1t6+u+5xw1q6N8S2mWPYjYEOuqHPbKc628H0Qj1
+IlaHvQww4whOIJC0WuL5Kpe47LepcFxJVrizHEo9YRB8hOR63abIDV0i2rPYWSIP
+nVqrE2d6498WjwwXbRdrVFBsY5hT8E3e8nIvOcGOXOQm4UVirY/yYkeviIcO+3LA
+zOg23o/uZ6ZiN4JFtQK/H4MJmYigk8583IE2THix9KUbgA32E3xx1l5rCJoAAAGA
+QiQ1OeSdueoZ2Y2X9vKpSyNSmBLfiJ6qvP7aAc5MdZSH+4m8gtp1/hyRNDYfht5H
+0W2O7oDlasUCF46O2BKUd6+L+9gmLF7dk34ahsDw57Kv57y938tYFM7Qt1anbKF4
+Qju01XjF2hg3EtloWCZAqg7H6ftWv9lg16V1SXR9j7et5Hz+gWweV9pmM9rMU33g
+YIE5ZLtbJ1ejEvnaPYTmCv+YFwBR09kOOAuLzBmGxY/53JHogn1Pn1/EsrLnQ8+T
+if8C3sAfXUNLQw0WLokcM1X5GFUzn431gwDkyZOuTfjEMYtcS9BSg8pLRrfS+w9k
+dr8VkH9Q3UFBqnrKydqmLszTpnNXEiBgts7OBEapPrIwrZO8mk0bHv7soeP8g8EZ
+eFA1tDlQn/t5aLGkSLe9gxV1P98EolbsoVYqEbCWyQo2s1NlnL3kQg4X6QuUxDx1
+GcYGQc7sBW+Je5fWuxhhJo4Nx5t8O2t2OcJVvwaGVzdFkSbLRlvB2koEOhlj2n1j
+AAAAIFJKfqWXf4ECs1UpMEd/XwQkARZdRjfc2LnRPfTzquXQ
diff --git a/nss/cmd/bltest/tests/dsa/key18 b/nss/cmd/bltest/tests/dsa/key18
new file mode 100644
index 0000000..fe841bb
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/key18
@@ -0,0 +1,26 @@
+AAABgMe4bXBEIY42dFPSEOdkM+Tiepg9scVgu5dVqPt9gZkSxWz+ACqx/z9yFluU
+PAso7UYDmgfeUH16Kfc4YD3s0ScDgKQflx8lkmYaZLovNR2aaeUaiIoFFWt/4VY8
+S3fuk6RJSROEOKKri9z8SbTnjRzedm5UmEdgBX12zXQMlKTdJaRqp3sY6dcH1nOE
+l9Tqw2T0eS2XZqFqDiNIB+lrjGTUBLvbh245tXme9T/my5urYu8Z/cwr3ZBb7aE7
+nvesNfH1V8sNxFjAGeK8Gan138Hk7Knm1GZWQSQwSjHwOGBaPjQtoBvhwrVFYQ7d
+LBOXo8g5ZYjGMp7+tOFlr1s2ijmojkiI459Auz3k6xQWZy+Zn+rTeu8cqWQ/8yzb
+wPzr5ijX5G0oGpidQ90hQyFRr2i+P21WrPvbbJfYf8teYpG/i07hJ1rg60ODzHU5
+A8jSn0rbalR+QF3s3/KIxfbHqjDcsS+E05JJOnCTMxfA9eZVJgH64Y8X5uW7a/OW
+0y2KuQAAACCHb6CeHcYrI2zhwxVbpIsMz9op86xal/f/ob2Hto0qSwAAAYARCv67
+Esf4YrbeA9R/28Mybg1NMbEqjKlbLe4hI7zGZ9T3LB5yCXZ9JyH5X72aTQMjbVQX
+T7+v8sT/ferkc4sg2fN78KETTCiLQgrwtXkuR6klE8BBPzRqTturLEW9yhP1NBwr
+Vbi6VJMrkhe1qFnlU/FLuMEg+7nZmQnf9epo4Us3mWT9Pzhh5bpcyXDEoYDu9UQo
+cDlhAh571oy2N5J7jL7mgF+icoW/7k0e9w4CwaGKfNeL7x3Zza1F3enNaQdVBQ/E
+Zik37h1vTbEoB8zJW8Q18Rtx5whgSLHatZE8YFUBLeguQ6TlDPk/7/Xcq4FKvCJM
+XgAlvYaMP8WSBBu6BHR8EK9RP8NuTZHGPuUlNCLPQGM5jXfFL8sBFCfL/PpnsbLC
+0apKPacmRcscdnA2BU4vMfiGZaVEYciF+zIZ1a2HSKARWPbHwN9ajJCLqMPlNoIk
+KIhse1ALvBW0nfdGud5aeP47T2mR0BEMPL/0WAOdw2Jhz0avS8JRU2j0q7cAAAGA
+RWoQXHE1ZiNIOLwHC4p1GgtXdny3XpkRShpGZB4R2h+p8ikU2AitcUhhLB6lXSUw
+F4Hprgya42pp2HugOex82GTDrQlIc+blZwn9ENlmhT1hGxz/FdN/3uQkUGwYTWLH
+AzNYvnjCJQlDtvbQQ9Y7MX3lblrY0f2X3TVavpZFL45DVIX7O5B7UZAKo/JEGN9Q
+tPza+/YTdUjDk3O4vEuj2rtHRuvRe4f81qLxl8EHsY7FtGXm5MtDDZwM542lmIRB
+BUo3B5K3MNqaukGjFpryYXb3Tm98DJybVbYrvnzjjUaV1IFX5mDCrLY/SC9VQYFQ
+5f7kOs6ExUDDunZiroCDXBotUYkOqWuiBkJ8Qe+MOKoH0qNl5+WDgNj0eC4irCEB
+r3Mu4idYM3slNjeDjhb1D1bTE9B5gYgNaFVX99eabbgjxh8bs9vF1QQhpIQ6bylp
+DniqDwz/MEIxgYuB/EokP8APCaVMRm1qjHPTKlXhq9Xsi04a+jKnmwHfhagfP1z+
+AAAAIDRwgyBV2t6U4UzYd3Fx0Y5dBvZq7/TGFHHk66dO5WFk
diff --git a/nss/cmd/bltest/tests/dsa/key19 b/nss/cmd/bltest/tests/dsa/key19
new file mode 100644
index 0000000..5f769be
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/key19
@@ -0,0 +1,26 @@
+AAABgKQQ0j7ZrZlk0+QBy5MXolIT91cSrLxcEhkavz8cDnI+IzO0nrH5Ww+XSNlS
+8Epa41iFnThEA842SqP1jdl2mQm0UEhUjFWHKmr7s7FcVIgvlsIN8bLfFk8LrISc
+oXrS32Or11yIGSLnmlAJ8At9YxYi6Q5/pOmAYYV14da9GnLVtqUPT2pot5OTfEr5
+X8EVQXWaFzZXfZRIuHeS3/ByMkFVEukzdV4SJQ1GbpzI3xUHJ9dH5R/qeWQVgyax
+Nl1YDLGQ9FGCkVmCIf3zbGMFyLio7QVmPdewBulF9ZKrvsrkYPd8cbbsZJ0/1TlC
+Au17u9BA97j9V8sGqZviVPol1xo3YHNARsKg2zg+Ajl5E65nzmWHDZ9sb2ep0ASX
+vh12OyGTfPnL+aJO+Xu8qgeRb4iU5bf7AyWIIaxGFAllsjxUCcpJAm77K/lbzgJc
+QYOl9lm/aq7vVteTO7KWl9fVQTSMhx+gH4aWeLLjRQb23ApMEytomg7SfcPI1TcC
+qlhIdwAAACCrxnQXclzyj8dkDV3kOCX0Fuv6gOGRxC7ohjAzOPVgRQAAAYCGfV+3
+L1k20aFO07YEmWYvMSRobvEIxbPaZmOg6GGX7CzEyUYBk6dP8WAorJRBsMfSfCJy
+1IOsfNeU1ZhBbE/5CZphZ51BfUeM5d2XS/NJoUV1r+dKiLEt1fbRy9P5Hd1ZftaO
+eeukAmExMMIkuUrChxSh8cVSR1pdKc/N2OCKax1lZh4o7zE1FNFAj1q9Pgbr46fY
+FNHt4xa/SVJzyh1XT0K0gu6jDbU0ZvRUtRoXWguJs8Bd2gBucZouY3FmkIDXaMwD
+jN+4CY6arZuNg9S3WfQ6ydIrNT7YijNyNVAVDeA2G3o3bze0XUN/cctxHyhH3mca
+0QWVFqHUV1UiShXTe0rq2j9YxpoTba7wY2/jjjdSBkr+WYQz6ACJ/aJLFEpGJzS+
++Pd2OIRbAOWc5/pPHa9IeiytoR6rpyuyPh32tmoYPt0ibEQCct2bBr7A5X8aCCLS
+4AISBkttumRWIIX1p1kpr6X+UJ4LeOYwqvEvkeSYDJsNb34Fmi6j4jR52TAAAAGA
+HwpcdeeYXW5w5Pv9pRoQuSX2rMtgDXxlENuQ7DZ7k7sGm9KG6Pl5si7wcC9xeodV
+wYMJyH2uP+gsw9yPS3qj1fOHb01LPraL/pEMQwdtbNDTn8iN3njwlIDbVSNObIyl
+n+JwDv7AT+7mtOjuJBNyGFi+cZDb6QX0Vu3KtVstwpFtwehzGYjZ74thmrz4lVqp
+YO8Cs/AqjcZJNpIir1DxM47SjWZ/PxDK4qPCijwdCN9jnIGtoTyP0ZjG2uPWKj/p
+8EyYXGX2EMBsuPrqaO24DebPB6jonAAhgYWpUrI1cuNN8HzltCYeXeQn61A+4br1
+mS221Di0dDTEDCJle8Fj55U/oz7/OdwnNGBwOardasJ+Q2cTEEH4Rf+hoT9Va/ui
+MHpcePLM8RKYx2LgiHGWjkjcPRVp0JllzQnaQ88DCaFq8eIP7n2j3CGzZMRhXNUS
+P6X5sjz8T/2c/c6mcGI4QLBi1GSNLrp4atP3rjN6QoQySs4jb59xdPv0QrmQQwAv
+AAAAIG1Mk0ORt/b7bhnjFB+MABjvVyYRihEGQ1jH01s3c3N3
diff --git a/nss/cmd/bltest/tests/dsa/key2 b/nss/cmd/bltest/tests/dsa/key2
new file mode 100644
index 0000000..7df1a90
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/key2
@@ -0,0 +1,10 @@
+AAAAgIubMvW6OPqtXg1QbrVVVA0NeWMZVVjKMIt0ZiKNkqF7OxS44Kt3qfOylZoJ
+hIqmn435LNnp7e8K33ks53v87Mrdk1JwDKX67PGB+gwybbHW5dNSRYAR5RvTJI9O
+O9fIINfgqBkyrKHro5AXXlPq2hlyI2dOOQAmPpD3LZTnRHv/AAAAFLxVDpZWR/s6
+IPJF7IR1Ykq7sm7dAAAAgBEzOpMfulA0h3dzdoWf3BL3xoewlIroidKH8benEq0i
+CuTxzjedDbtcmr9BliHwBfwSPDJ+UFXRhQY0w205fmieER1ZjBw2NrlAyE9C9DaE
+bo5/ytkBLO2jmHIPMv/9GkWrYTbOQXBpIHrBQGdbj4bdBjkVrm9isM7HKfvVCawX
+AAAAgH4znzdXRQOQFg4CKRVZ8wvtCy11jFzMLY1FYjK7Q1rknefnlX46rZv9z2/V
+2bbuO1IbwiKahCHcKqWbmVI0Wo/B3kmzSAA6mxjaZC1/b1bjvGZRMa6XYgiKk3hv
+e0typLzDCMZ+JTKjpb8JZSBVzCa/OxiDNZjP/XAR8ihfeUVXAAAAFG4uMbv8ZwlE
+16cSDjmpgVIGFNio
diff --git a/nss/cmd/bltest/tests/dsa/key20 b/nss/cmd/bltest/tests/dsa/key20
new file mode 100644
index 0000000..5a5dbfd
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/key20
@@ -0,0 +1,26 @@
+AAABgMHQptC17WFd7nasWmDdNeywAKICBjAYsboKBv56APdl2xxZpoDOz+OtQUdb
+rbWtULYUfiWWuI00ZWBSrKeUhupvbskLI+Nj86uM3IuTtioHDgJojqh3hDpGhcK6
+bbER6a3b18pLzmW7EMnOtpv4BuLr1+VO3rf5lqZckHtQ79+OV1uuRiohnDAv7yro
+HXPO51J0YltfwpxtYMBX7Z57DUatL1f+AfgjIw8xQiciMZzgq/HxQfMmwA+8K+TN
+uJRLb9BQvTAL2xxfTaclN+VT4B1RI5xNRhhg8ftP2Pp59dUmP/Yv7XAI4uCi02v3
+uQYtDXXbImw0ZLZ7okEBsIXyxnDA+HrlMNmO5gxUcvSqFfslBB4ZEGNU2ga8Kx0y
+LUDtl7If0c2tMCXGnabOnH3fPc8epNVld7/ewjBxwfBe5Ad7U5HppATq/+EtHqYt
+BqzWvxnpGhWNIGa0zSDkxOUv+x1SBM0CK8cQjyx5n7Rohm7xywm84J39SeR0D/gU
+BJe+YQAAACC/ZUQcmHt3NzherewVjdAWFNpvFThiSOWfPN2+/I6d0QAAAYDAKshT
+dfq4C6KnhLlOTRRbO+D5IJDroXvRI1jPPgP0N5WE+HQiUvdrHt4/w3KBQg50qWPk
+wIh5b/K6uNtumkUw/GfVH4i5BatDmVqrRjZMtAwSVvBGbz2842ID7yKLNekCR+le
+URXoMbEmtijumE80mRHTD/udYTtQqE36HwQrpTa4LVEB5xHGKfnyCW3INN7sY7cP
+KiMVptJzI7mVqiDT0HNwdRhvUEmvb1EqDDip2gaBf0thm5RSDt+shcSm4uGGIlyV
+oE7Dw0IrjesoTpjSSzFGWAIAigl8JZaegmwrqlnSy6M9bB2fOWIzDB/Np8+xhQj+
+p9BVXjoWna7TU/Pub0uzAkQxkWHf9kOKN8p5OyS7sbG8IZT8bm72AngVeJnLA8Xd
+b8kag26yCiXAmUVkPZX3vVDSBmhNb/wU0W2C1feBIlv/kIOSpXk7gD+bcLTfyzlP
+ntgcGOORoJ6z+ToDLYG6Zwyr/W9kql4zdMt8ICn0UgDk8L/YIMi9WNxe6zQAAAGA
+baVPKw3bTczi2h7foWuoSVPYQpzmDNERpcZe3Pe6W42Th6togcJIgLKvvbQ36e1/
++46Wvsp+qA0dkPJNVGESYp31yelmF0LMhy/bPUCbx3t1sXx+bP/4YmEHHEtcn5iY
+vh6eJzSbkzw0+zRWhfj8bBJHDRJM7PUbXVrb9eeiSQ+NZ6rFOoLtaiEQaGz2McNI
+vLxM8VbzppgBY+L+ynKkX2s9aMEOWiKDtHC3KSZ0SQOD91+ibM+TwOHI0GKMo18v
+PZtodlBdEYmIlXI3ovyAUctHtBDot6YZ5zsTUKn2omDF8WhB58TbU9jqoLRwjWL5
+Wypy4vBMoUZHvKa14+5wf833WLkl641Oas5Px0Q8m8WBn/nlVb4JiqBVBmgo4huB
+j+3DqsUXoO6PkGC9huDUzOISq2o6JDxewCdFYzU8pxA68IXo9BvlJPu3XNqIkDkH
+35S/1pNz4oiUm9BibYXBOYswc6E51cdH0kr9rno+dFQ3M10O6ZPu82owQckS9+tY
+AAAAIBULXFHqZAIna8kSMi8EBPbVf/fTKvyqg7bf3hGrtIGB
diff --git a/nss/cmd/bltest/tests/dsa/key3 b/nss/cmd/bltest/tests/dsa/key3
new file mode 100644
index 0000000..50c0a9b
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/key3
@@ -0,0 +1,10 @@
+AAAAgMuhPlM2N8N8DoDZ/NBSweQaiKwyXE6+E7cXAIjVTu9IgfPTXq5HwhA4WoSF
+0kI6ZNo//aY6Jvks9aME85JgOEqbd1nYrBrcgdP4v8XmyxDvtOD3WGf06EjRozhY
+bdBkj+6xY2R//nF2F0NwVA7oqPWI2ozBQ9k59wsRSn+YG4SDAAAAFJUDG4qnHynV
+Jbdz74t8ZwGtil2ZAAAAgEW8qkQ9TNFgLSeq+EEm7cc713Pebs4V6X5/70bxMHK3
+rcr3sAU89HBpRN+MRWjybJl+53UwAPvkd6N3ZqTpcP9AAI65ALneS1+a4G4G22EG
+54cR86Z/7KdN1b3c32da5AFO6UiaQpF/vuO7nyok32dRLBw1yXv78jCOqs0oNoxc
+AAAAgEzWF4Y30PDeFIhRXDsS4gOjwMplLy/jDQiNxyeKh6/6Y0pyenIZMtZxmUqV
+ig+JIjwobDqbEKllYFQuJia3LgzSjlEz+1fcI4t/qy3ipJhj7PmYdRhhrmaL98rR
+NuaTP1ff26VE4xR84Oc3D6bo/x3mkMUbSu7fBIUYOIkgVZHoAAAAFC6sT0GW/ts+
+ZRs7AAQBhM/W2iq0
diff --git a/nss/cmd/bltest/tests/dsa/key4 b/nss/cmd/bltest/tests/dsa/key4
new file mode 100644
index 0000000..657abc8
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/key4
@@ -0,0 +1,10 @@
+AAAAgPJKSvxyx+Nzo8MJYjMv5UBcRZMJY5CUGMMHkqrxNd3qVh6U8kcmcWt1oYgo
+mC5M5Ewf3ct0ZIe2t3qaWhf4aKtQzWIbW8naRwiAsofXOYGQpCpe4i7Y0f8UfiAZ
+gQyCmO1o4cpp1B1VXySeZJ+xcl3bB1wXs3vv9Gf90WCSQzc/AAAAFNoGWgeN21bu
+XSrQbK+rIIINLEdVAAAAgEe1WRt5BD5OA8p4oOJ3yaIeKmtUO/TwRBBM2ayT7/jh
+AbtgMe/IxZbV0vkuOj0PH3RwLdVPd9PNRsBN7npd6fAK0xdpH93O/koiCiZRrK5/
+zt2pK/zKhV22cF6Nhk+Bkr9r+GDADwitZJPswYcuACjVyG1EUF21dCJRXDglpveK
+AAAAgEOie3QPQiyy3D6qIyMViDovaiKSf5l9Ak9aY4tQexfTscvT7GkcxnRHCWCg
+FG797Llbtf4kl0njyAbNXMPn97q4Rdrb4fULM2b7gnqULOYkbdp70sE+G0qSbAyC
+yIRjlVLZ1GA2+aS8Kp5RwtduMHTR9TpjIkxCeeD6RgR01P/eAAAAFGSYIBaOtZT1
+nNmyi5rv6MwQamxP
diff --git a/nss/cmd/bltest/tests/dsa/key5 b/nss/cmd/bltest/tests/dsa/key5
new file mode 100644
index 0000000..8d94d7f
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/key5
@@ -0,0 +1,10 @@
+AAAAgIjZaOlgLsvabYb3yXCj/76x2pYvKMCvuScO8FvDMMqYw634PAcv6wX7Lik7
+UGW7sMvMkwwk2NB4ad6uzZKiYEwPXdNcW0Mf2moiLFLDViv3VxxxAgm+izuFiBh4
+hyX+gRK31ryC4P8cu/XW/pRpCvK1EOQa2CB9wsAvufpc76q1AAAAFKZlaJueW5zo
+L9FnYAbPTPZ+zFa3AAAAgCZ+KChXQXdSET+6P8pxVbXOiefIozwaKRIuK3IJZfwE
+JFJn/4f8Z6VzD+WzCAE6oyZpkPuzmBhah+BVtEOoaM4M4TrmruMwudJdO7s2JmXF
+iB2vDFqnXp1KgujwTJGprSlIIuM5eKsME/rcRYMfnTfaTvoPwsXrATcfqFt92x+C
+AAAAgGD1NB5Iyno7xd7O5hIR3ScnzY4vx2NfOqvqJiNm5Fj1xRwxGv2pFssNzcXV
+pXKfVzpTK1lHQxmbz6dFSQPnSzPd/mWJYwbOwg69hCdoL6UB7ga8TF0UJcvjGCi6
+AIsZydpoE2z3GECyBZGeeDpiilpXz5HPVpsoVP/veglu2pbJAAAAFAfOiGLmS39s
+dIIEbb/JOQcSPlIU
diff --git a/nss/cmd/bltest/tests/dsa/key6 b/nss/cmd/bltest/tests/dsa/key6
new file mode 100644
index 0000000..3408d5c
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/key6
@@ -0,0 +1,18 @@
+AAABAPLTntMGKxPJFic2AKDyoCnobXpLkhe08YFb8rJNlxClerM/mXKUsBRYW40B
+mN/cy811MU2l/4WqNEtFra6ql5tRoxKnv6lEcvtjPxpvFWu0RYhn39OEA/BrhR8A
+/i00hAd73tcat1E9BKFAIgV1+2kzlUgOTIQCt6Rs7C03p3jDBazNHxPp9i6GUxX0
+sizEZ8iYbsjklh3fgQVmsMTuNprGqhXkP0dEAFgm9b3oBxoZ4wtpCarEs9F0I3Jw
+2tAnmdCbiizF8i5miUtUIiKLLCNPEfWnccW4nPRloqzsu+6qFyX+j5tZQivomRBS
+y1Vt3yyM6PqSBtvzn+rcGU4A+OUAAAAcgAAAAAAAAADBGPSYNeTvczxNFYAPzwWe
+iE0xsQAAAQDjqTwJ2m9WDk1IOjgqTFRvIzXDakw1rBRjwIo+bdQV31b9xTfyX9U3
+K+Y+T1MAeAt4LxrNAci06zNBRhX9Dqglc6y6fvg/WpQ4VBUa/C19/hIfuM0DM1sG
+W1ScXcxga+kFJIO8KE4SrDyNugm0JuCEAgMOcLwcwr+JV8S6BjDz8yrWiTiaxHRD
+F2Bj8kfZ4ilrPqW1vCM1go6hoIDtNZGN7iEv0DEnnRuJTwGv7FI4M2aerAMaQg5U
+C6EyClnEJKPlhJpGCla8sAFkeIWxQzxPmSlxdGv+KXfOclnFULVRpsNXYeSkGvdk
+6NkhMvzApZ0WhOq5DYY/KfQc91ePqpCMAAABACif8YwypWuwuIOTcGR2g6OKWn4p
+FBC5MgchKtyAiNMPk+nkq8Uj89RpNufVyQ2IdCs2r9N1Y0CPFcjBpPesJL8F8BAI
+/+5wyIJdV8OpMIutigla8rU7Ldo8vthG2V4wHrm4R2ZBXRH2wzIJoNKFcQlqsEp5
+qg3EZZl1KWhraOiHzYogXC3IGVrvBCLrqZefVJrIVUjkGUE2Q7ckQ2EVOtoUgNI4
+zQDcFlJ5OJVVSN1dAn3tECnu647WxhtM1ZNB2LFUZunaiQqYmZb012keYHLeE2ry
+i1h0vwi9H4pgz7HACIgTKQn1FeBLzoGwKVGqQbqsaP/bjF3Heh0y2PLBDdcAAAAc
+YTLlUc2siECRg7037hRSzSR9SDSwiBSydb4/9Q==
diff --git a/nss/cmd/bltest/tests/dsa/key7 b/nss/cmd/bltest/tests/dsa/key7
new file mode 100644
index 0000000..e7830fb
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/key7
@@ -0,0 +1,18 @@
+AAABAKqBXJ2xxNPSdzx9DU0dp17PxKOel9X6GR/+yLFJCikM4zXlzofqYgqKF94L
+tkcU4uyEC/AObr20/7TjJMoHw8hxcwmvFBA2Kncsmt2DiysMrh6Qq0SK2r2s0uXf
+WcQYejKiNxnWxX6UAIhTg7+PBm8juUGSDVTDW098xQRPO0DxcEaVYwe3SOhAcyhE
+0Aqc5uxXFCk7YmUUfxXGf0vjiwgrVf3q22EkaJ+3b50lzCi46qmLVi1cEBHg3Pmz
+mSMkDTMtidyWA7e93QxwuDyqKQVjGxyDyruubAwMLv6PWBMe2DUb+T6HX2pzqTy6
+1HAUGiaH+6zy1xyN3ulxrWYHKa0AAAAc6jR+kL58KHXR/h22IrR2ODfF4npgNzED
+SMGqEQAAAQAgQglMy8i4cj/JKMEv2mcbgylemcdDV29EUEvhGGMjMZtQAtJPFz35
+CeokHW6lKJkE7kY2IEsvvpSwaP4JP3liV5VJVR068hmtjtGZOe/4a87INN4vL3hZ
+bonny1LFJOF3CYpWwjLrH1Y6qEvGsCbe7m/1HLRB4IDy2vrqHO2GQn0cNGvlXGaA
+PUt20TPNRFtMNIL6QVAjRjyb8w8veEIj4mBX06oNf7tmBjDFLknUoDJcc4ngcqo0
+nxPJZuFZdS+7cekzaJD5MkP6bnLSmTZe5bP+Jm6/ERBWj+5EJchHtQIQvUhLl0Ma
+QoVq3KPn0anJxnXH4maRgyDdWnikjEipAAABABrhDHhq0JAsXGhdrlxxIUGKN3uI
+i18vK8dmI1cP1ivLGQtHGtU1nF8GL4gZKJ6VbYqm+Q0fjPHuctOhvf1WxHjcKaGc
+RWm1pg46jzT2BlbqxbJd3lUUpcZ7Z1QjIE9syvCZBhfMc1W50+2GiXiiUgIKdp7V
+mm7apu/jN37vRfP28+ZBecx9uLFD+4NcXXG/z6HiqQSbzPf+mrV1RiIP4/S3UhyG
+FznROFB+gaRqaZNgVEHcuQ1u5K+8Qsq+kKJUREloEJ1+3ZaUoCMjnx1WF13R+sEV
+kV4k+rVj9Pw/JpvtLzAIMtESWWSFpxFBeqc7tKxyplGh+luu02Nscg05cAgAAAAc
+e0iQIVeOeee9PuerRW9lnz3AfIj1yaOeT4zugQ==
diff --git a/nss/cmd/bltest/tests/dsa/key8 b/nss/cmd/bltest/tests/dsa/key8
new file mode 100644
index 0000000..e7e72bd
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/key8
@@ -0,0 +1,18 @@
+AAABAKTH6qtCxMc7dXdwkWSJ8XzVByXNCkvE4c9n92O4wd4tbauYVrqvsAjzZbGK
+QuFNxR81C4jsoCCcWqT9caepbHZfWQHCHnIFcNeDe+x8dtLkk0RzHKOUBdCoebng
+3NGoEl/RMOweeD5lS5TjAC5rYp6QSrOHeGdyDL1UtCcKnhXNAox8x5bwbCcqZglR
+ko/b6y3KBhtB6TIlcwV0L/FuL0KRkdXl8abd9ueMXXciz/gKnAvVyNeuuowEQ4mS
+sHXjB8FTTEmtOA9Hf195h9wXLBYdyjjcrz+zhGxyyRGaUpmtx0iVGz3ODQDUqQE4
+ALIAggO3JGW8aoSuBZowxFIt6lcAAAAczon+MyuOTrPR6N3OpdFjpbwTtj8WmTdV
+QnrvQwAAAQCMRl7fWhgHMCkeCA38U4U5elAGRQ26Lv4BKSZPvYl7tVecoOqxmqJ4
+IgQkcktPKm9u5jKEMqv2YTgGRglyM1BTOcVRnTV9cRK27sk4uF1ap1zC44CS8KUw
+rLVOUP6CxNVi+w8wNrgLMDNAI+u+ZjegAQsAx9uGNxFoVjZx4eDwKK7b1F0tVyYh
+pgmYKgc+Uaridwevvu8p4uzuhNem1do4K+OjX0K2xmhJICqxnQJbhp0Id2R20auY
+FHWtKtLz5v0H4waW2QpiaBbfYNbKev17SC+UL4O0XMgpM3Mfh/ruMgkA8qo+cLGG
+fhQw5AvmfAf5KQKZ7wZ7iySnUVs/mSwHAAABAHSKQCNyEaLZhSWW56iR9D1OsO5I
+gmyc+zNru2jb5aXhay4ScdTRPeA2RLuF72vlI6TU2IQVvNWWuo4KPE9kOemB7QE9
+fZxwM2/r99Qgz+0CwmdFe7Pz58ghRdKvVIMLlC7HSl1QPkImzSXddd7NP1DwqFgV
+XXvnmUEINt3FWc6Z4a5ROAj9rqw0hD3XJY8W9n8ZIF9vE5JRpBhtqEltXpDT/s+O
+0Qvmwl/16zPZYMmo9MWByMckykO3Yen9ta9mv/udLrsRprUEofvk+DTstqwlTKtR
+PpQ7mpU6cISzMFxmG/rUNPaoNVA8mt5/Slf1yWXsMB7N6TjuMbTesDivl7MAAAAc
+VRWV7MuwA7C/jd2hhKWdpR5Fmg0oIF5VkspMsQ==
diff --git a/nss/cmd/bltest/tests/dsa/key9 b/nss/cmd/bltest/tests/dsa/key9
new file mode 100644
index 0000000..1ab8a0c
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/key9
@@ -0,0 +1,18 @@
+AAABAKa7UzPONDwxybLIeKuR7vL96jXG2w5xZ2K/wNQ22HUG6GWk0sjPu9Ymzov+
+ZFY8pWhs2M8IFJDwJEWyiQh5gklftpl2sQJC1tUPwjtNvbC+94MF2aTQXZ6uZdh6
+iT6vOX4E45uqhaJsj/ve8SMyh7X1tu9qkPJ6aUgaky7kexjV0n6xB/+wUCXmRuiH
+a1y1Z/7B3TWDXUIIIZhTH6++WuKAxXWh+w5i6bPKN+GXrZbZ3eHzPyzsfSferiYc
+g+6OIAKvfrboL2oUeWrwN1d6EDK7xwkSnKq9it34cK4tBZXI/bNxVXSPDeo0tE1P
+gu1YwvWxuEgWYqxTRzxpNBAIL70AAAAcjD7lvZoqrwaL1YRb1V7PJ0FwVTB1d7vD
+dw7GiwAAAQBDtaa20LuWLsl2ajd8MsxBJPExEYjC7PlcDNSk+glyJbdhjLEnbEdF
+eNO/VkwUUZnAkqGxS6qSnC8/DzbgwtrpHroIvjCZKoifKVLgRCw3r0hKTs3DJDzP
+y540E89c3WYwsJ/hfvv94U2HJUkwGbe3PR94K0jvML7DbgDgK6M20iVPwgKmlhLN
+lEb5HXa3Of+m2LhgUvjcXxFFgBxWJBr1upA3JBvYnmM4tY4BMQZxwmjrXjOstX0f
+mfFkQKZ1gn1AF3VNYBoXraL77fkEVUqQsBUw2oyTzRTOKTyyvT55N+k0t54xD+TY
+DBP5L2M4E1W9gKGr7hpz/fttok7ygAKjAAABAGR5ebeWDOe5cf8OX2Q19CpBsYyd
+4JowERSgE6fNARg/F2+Ig4N53LTvtn2up53vPwQsvPnMUDtMIVGiNk98lDexlkPm
+fiSja6xKTPopPe7fjsaxVKMqpymF99jeI1M0tUbCne9FjFXQxcCsXXTiAk7H1KvC
+/aUWoqCxpNiGrZLCBHB4KKT8d5T2DuikvhEByeVRj34Z7r1HXy3m9rqJwovRKfE5
+k77+WBhEAxmnlUmDMZY0KjHbr315SX3sZe59vvcOWPmdBZX2pxFAmt4xUdRVY9U8
+HNCoqxoYvv9lAsuwwGmxFOp753iY0PTlSZkboLNolxsQcuzkr8OA6a4ymlAAAAAc
+TvpRNutqp06Su/yROwv+u2E9t6RyIft7ZPQubw==
diff --git a/nss/cmd/bltest/tests/dsa/keyseed0 b/nss/cmd/bltest/tests/dsa/keyseed0
new file mode 100644
index 0000000..6eea359
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/keyseed0
@@ -0,0 +1 @@
+AAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/nss/cmd/bltest/tests/dsa/keyseed1 b/nss/cmd/bltest/tests/dsa/keyseed1
new file mode 100644
index 0000000..6eea359
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/keyseed1
@@ -0,0 +1 @@
+AAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/nss/cmd/bltest/tests/dsa/keyseed10 b/nss/cmd/bltest/tests/dsa/keyseed10
new file mode 100644
index 0000000..054c192
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/keyseed10
@@ -0,0 +1 @@
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
diff --git a/nss/cmd/bltest/tests/dsa/keyseed11 b/nss/cmd/bltest/tests/dsa/keyseed11
new file mode 100644
index 0000000..cde1798
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/keyseed11
@@ -0,0 +1 @@
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/nss/cmd/bltest/tests/dsa/keyseed12 b/nss/cmd/bltest/tests/dsa/keyseed12
new file mode 100644
index 0000000..cde1798
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/keyseed12
@@ -0,0 +1 @@
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/nss/cmd/bltest/tests/dsa/keyseed13 b/nss/cmd/bltest/tests/dsa/keyseed13
new file mode 100644
index 0000000..cde1798
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/keyseed13
@@ -0,0 +1 @@
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/nss/cmd/bltest/tests/dsa/keyseed14 b/nss/cmd/bltest/tests/dsa/keyseed14
new file mode 100644
index 0000000..cde1798
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/keyseed14
@@ -0,0 +1 @@
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/nss/cmd/bltest/tests/dsa/keyseed15 b/nss/cmd/bltest/tests/dsa/keyseed15
new file mode 100644
index 0000000..cde1798
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/keyseed15
@@ -0,0 +1 @@
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/nss/cmd/bltest/tests/dsa/keyseed16 b/nss/cmd/bltest/tests/dsa/keyseed16
new file mode 100644
index 0000000..cde1798
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/keyseed16
@@ -0,0 +1 @@
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/nss/cmd/bltest/tests/dsa/keyseed17 b/nss/cmd/bltest/tests/dsa/keyseed17
new file mode 100644
index 0000000..cde1798
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/keyseed17
@@ -0,0 +1 @@
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/nss/cmd/bltest/tests/dsa/keyseed18 b/nss/cmd/bltest/tests/dsa/keyseed18
new file mode 100644
index 0000000..cde1798
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/keyseed18
@@ -0,0 +1 @@
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/nss/cmd/bltest/tests/dsa/keyseed19 b/nss/cmd/bltest/tests/dsa/keyseed19
new file mode 100644
index 0000000..cde1798
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/keyseed19
@@ -0,0 +1 @@
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/nss/cmd/bltest/tests/dsa/keyseed2 b/nss/cmd/bltest/tests/dsa/keyseed2
new file mode 100644
index 0000000..6eea359
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/keyseed2
@@ -0,0 +1 @@
+AAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/nss/cmd/bltest/tests/dsa/keyseed20 b/nss/cmd/bltest/tests/dsa/keyseed20
new file mode 100644
index 0000000..cde1798
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/keyseed20
@@ -0,0 +1 @@
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/nss/cmd/bltest/tests/dsa/keyseed3 b/nss/cmd/bltest/tests/dsa/keyseed3
new file mode 100644
index 0000000..6eea359
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/keyseed3
@@ -0,0 +1 @@
+AAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/nss/cmd/bltest/tests/dsa/keyseed4 b/nss/cmd/bltest/tests/dsa/keyseed4
new file mode 100644
index 0000000..6eea359
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/keyseed4
@@ -0,0 +1 @@
+AAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/nss/cmd/bltest/tests/dsa/keyseed5 b/nss/cmd/bltest/tests/dsa/keyseed5
new file mode 100644
index 0000000..6eea359
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/keyseed5
@@ -0,0 +1 @@
+AAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/nss/cmd/bltest/tests/dsa/keyseed6 b/nss/cmd/bltest/tests/dsa/keyseed6
new file mode 100644
index 0000000..054c192
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/keyseed6
@@ -0,0 +1 @@
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
diff --git a/nss/cmd/bltest/tests/dsa/keyseed7 b/nss/cmd/bltest/tests/dsa/keyseed7
new file mode 100644
index 0000000..054c192
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/keyseed7
@@ -0,0 +1 @@
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
diff --git a/nss/cmd/bltest/tests/dsa/keyseed8 b/nss/cmd/bltest/tests/dsa/keyseed8
new file mode 100644
index 0000000..054c192
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/keyseed8
@@ -0,0 +1 @@
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
diff --git a/nss/cmd/bltest/tests/dsa/keyseed9 b/nss/cmd/bltest/tests/dsa/keyseed9
new file mode 100644
index 0000000..054c192
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/keyseed9
@@ -0,0 +1 @@
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
diff --git a/nss/cmd/bltest/tests/dsa/numtests b/nss/cmd/bltest/tests/dsa/numtests
new file mode 100644
index 0000000..aabe6ec
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/numtests
@@ -0,0 +1 @@
+21
diff --git a/nss/cmd/bltest/tests/dsa/plaintext0 b/nss/cmd/bltest/tests/dsa/plaintext0
new file mode 100644
index 0000000..48fbdb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/plaintext0
@@ -0,0 +1 @@
+qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
diff --git a/nss/cmd/bltest/tests/dsa/plaintext1 b/nss/cmd/bltest/tests/dsa/plaintext1
new file mode 100644
index 0000000..f7b1bad
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/plaintext1
@@ -0,0 +1 @@
+WEKejzcfnh1ppb+WpVTWJ8/VSFw=
diff --git a/nss/cmd/bltest/tests/dsa/plaintext10 b/nss/cmd/bltest/tests/dsa/plaintext10
new file mode 100644
index 0000000..08d653e
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/plaintext10
@@ -0,0 +1,2 @@
+rBhknAaqqqlnKm/advb86OGGUVWFcbz9ihmsNZcQniSGMCNRB1ROUVCb5azZuiZ+
+4ImIYj1aymGnxDoIS+YZng==
diff --git a/nss/cmd/bltest/tests/dsa/plaintext11 b/nss/cmd/bltest/tests/dsa/plaintext11
new file mode 100644
index 0000000..05f0054
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/plaintext11
@@ -0,0 +1 @@
+PlUtQFJV4fg6RHC9IFSw1nSy/dY=
diff --git a/nss/cmd/bltest/tests/dsa/plaintext12 b/nss/cmd/bltest/tests/dsa/plaintext12
new file mode 100644
index 0000000..639a7cc
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/plaintext12
@@ -0,0 +1 @@
+tGiqjB9KQERHn6GvDD8iHrgM5nYcmcaGbRp9nQ==
diff --git a/nss/cmd/bltest/tests/dsa/plaintext13 b/nss/cmd/bltest/tests/dsa/plaintext13
new file mode 100644
index 0000000..924d0ed
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/plaintext13
@@ -0,0 +1 @@
+CrhLNBzxdeOM06JwSiDHlsHH0AlCJKHkdpQvJw4OTio=
diff --git a/nss/cmd/bltest/tests/dsa/plaintext14 b/nss/cmd/bltest/tests/dsa/plaintext14
new file mode 100644
index 0000000..967d952
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/plaintext14
@@ -0,0 +1 @@
+4II54Zw0xvxpgkZbrlGIWAPGug2Ih8VgwXb+NG3cRkcdkNR5SHsy/jDgrlTYQGn/
diff --git a/nss/cmd/bltest/tests/dsa/plaintext15 b/nss/cmd/bltest/tests/dsa/plaintext15
new file mode 100644
index 0000000..a702f7e
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/plaintext15
@@ -0,0 +1,2 @@
+OfmOLA3KSs6DsKB+owDqX4JKdU9bT3xwUOJzPGkrsyKo3mur8w2dklEbOObDF5zg
+XxEGB/8DFIp8sCqeP2qewg==
diff --git a/nss/cmd/bltest/tests/dsa/plaintext16 b/nss/cmd/bltest/tests/dsa/plaintext16
new file mode 100644
index 0000000..dfa0cda
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/plaintext16
@@ -0,0 +1 @@
+mbNzEDnv9o8UR+5qjp+UCBlCe70=
diff --git a/nss/cmd/bltest/tests/dsa/plaintext17 b/nss/cmd/bltest/tests/dsa/plaintext17
new file mode 100644
index 0000000..ec01a51
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/plaintext17
@@ -0,0 +1 @@
+INmoiblVarLpT/1EghXog/90qXfqHhqcQlUsmg==
diff --git a/nss/cmd/bltest/tests/dsa/plaintext18 b/nss/cmd/bltest/tests/dsa/plaintext18
new file mode 100644
index 0000000..84a9856
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/plaintext18
@@ -0,0 +1 @@
+b5h4y7cMDS2TQtEP6tSlMuxCp3q1hlT3LLt7noMBKrA=
diff --git a/nss/cmd/bltest/tests/dsa/plaintext19 b/nss/cmd/bltest/tests/dsa/plaintext19
new file mode 100644
index 0000000..aa054c5
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/plaintext19
@@ -0,0 +1 @@
+kYTu+RQoZJZSUNshOvoBQxBj2N7aAyjFYJzs0WWVBdRaLlujVOVu2dlxGwJktm9M
diff --git a/nss/cmd/bltest/tests/dsa/plaintext2 b/nss/cmd/bltest/tests/dsa/plaintext2
new file mode 100644
index 0000000..bf54afc
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/plaintext2
@@ -0,0 +1 @@
+IDdekD+X/lylh+t2yXvLHboeHUZAZUozsUU48g==
diff --git a/nss/cmd/bltest/tests/dsa/plaintext20 b/nss/cmd/bltest/tests/dsa/plaintext20
new file mode 100644
index 0000000..20c8ee2
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/plaintext20
@@ -0,0 +1,2 @@
+Q6bpLpUVhU3Sjdd4YG4BnAfUf4u6TrwCAzmSB0q66YryvQBzf3fQ3H4fp4GVuYRV
+ftjzEtAhCf9OYBtR4GSnvA==
diff --git a/nss/cmd/bltest/tests/dsa/plaintext3 b/nss/cmd/bltest/tests/dsa/plaintext3
new file mode 100644
index 0000000..a8ec5df
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/plaintext3
@@ -0,0 +1 @@
+Mqqlk48AsWXhRAWNXCGQuvRpPAwqfbTlmnfsFKcKblA=
diff --git a/nss/cmd/bltest/tests/dsa/plaintext4 b/nss/cmd/bltest/tests/dsa/plaintext4
new file mode 100644
index 0000000..46644c0
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/plaintext4
@@ -0,0 +1 @@
+w8+3pOAcqljMh1bLGnWAWlZvlgnJhOJDBC2C0M3mTFrCeylP+FfUSfGfRD2uDS2f
diff --git a/nss/cmd/bltest/tests/dsa/plaintext5 b/nss/cmd/bltest/tests/dsa/plaintext5
new file mode 100644
index 0000000..631d1eb
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/plaintext5
@@ -0,0 +1,2 @@
+PiPosk1QVF3Ck1taH0AunEzHuPxBHnFMTKPWBsxTI9YdZ5XAEzt5QPHQKm7ja20+
+bmsWwSw++jcz8N2DY6WW2g==
diff --git a/nss/cmd/bltest/tests/dsa/plaintext6 b/nss/cmd/bltest/tests/dsa/plaintext6
new file mode 100644
index 0000000..f62997b
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/plaintext6
@@ -0,0 +1 @@
+uCkA/iALiJlpG34VqA2JNi5cqJY=
diff --git a/nss/cmd/bltest/tests/dsa/plaintext7 b/nss/cmd/bltest/tests/dsa/plaintext7
new file mode 100644
index 0000000..c0f0aa0
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/plaintext7
@@ -0,0 +1 @@
+KfVXa9k+jC0vrKPpgWQNMrHmPXpYTROh7YXBMw==
diff --git a/nss/cmd/bltest/tests/dsa/plaintext8 b/nss/cmd/bltest/tests/dsa/plaintext8
new file mode 100644
index 0000000..9c053cb
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/plaintext8
@@ -0,0 +1 @@
+GC7dULJ04jKDdn7fzRjVyUZm7aDbl31cEJU6STyznuA=
diff --git a/nss/cmd/bltest/tests/dsa/plaintext9 b/nss/cmd/bltest/tests/dsa/plaintext9
new file mode 100644
index 0000000..c0378ae
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/plaintext9
@@ -0,0 +1 @@
+hV6v7+GSeeSI2lL+Nu9CJCNoU2pR8eyGkOsfOxb2lBZ42gDIglCTvg88E4ocTsam
diff --git a/nss/cmd/bltest/tests/dsa/pqg0 b/nss/cmd/bltest/tests/dsa/pqg0
new file mode 100644
index 0000000..f16326c
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/pqg0
@@ -0,0 +1,4 @@
+AAAAQI3ypJRJInaqPSV1m7BoacvqwNg6+40M98u4Mk8NeILl0HYvxbchDq/C6a2s
+Mqt6rElpPfv4NyTC7Ac27jHIApEAAAAUx3MhjHN+yO6ZO08t7TD0jtrOkV8AAABA
+Ym0CeDnqChNBMWOlW0y1ACmdVSKVbO/LO/8Q85nOLC5xy53l+iS6v1jlt5Uhklyc
+xC6fb0ZLCIzFcq9T5teIAg==
diff --git a/nss/cmd/bltest/tests/dsa/pqg1 b/nss/cmd/bltest/tests/dsa/pqg1
new file mode 100644
index 0000000..0c09290
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/pqg1
@@ -0,0 +1,6 @@
+AAAAgKj5zSAeXjXYkvhfgOTbJZmlZ2o7HU8ZAzDtMlaybQ6AoOSaj/+qrSok9HLS
+VzJB1NbWx0gMgLTGe7RHnBWtp+qEJNJQL6AUcudgJBcT2rAlrhsC4XA6FDX2Ld9O
+5MG2ZAZusi8uO/KLtwoqduT9Xr4tEiloG1sGQ5rJx+nYveKDAAAAFPhfD4OsTffq
+DN+PRpv+6uoUFWSVAAAAgCsxUv9sYvFGIrj0jln4r0aIOzjnm4x03urp3xMfi4Vu
+OtbIRV2rh8wNqKyXNBfOT3h4VX1s30CzW0oMo+sxDGqV1ozihK1OJeooWRYR7gi4
+REvWSyXz98VyQQ3fs5zHKLnJNvhfQZEphpkpzbkJpqOpm74IkhY2gXG9C6gd5P4z
diff --git a/nss/cmd/bltest/tests/dsa/pqg10 b/nss/cmd/bltest/tests/dsa/pqg10
new file mode 100644
index 0000000..6654a09
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/pqg10
@@ -0,0 +1,12 @@
+AAABAL/r0ACy1s1Ks477o13zNN9yHWwvKz2VZnnLrQCfPfvQApUsyJnMI1bsh2m9
+PRulpzAjcpiI2pLKSKXulMl/TwSi46y08zovD7N4PDHyxw+nxw84IUon2t7IsS5n
+mWqehe47sUiAMTAUc5LcUlPATXBjU15s1ka/sYaYTgi1i3SnvlszO/MrCr/VZlNg
+6akjoMUo/xxixyU0WPVnhShxnUNuUBSHQfRdx90sbKxxxVIx8SqD/v0u0KM+3huK
+UfVm/PeJBoLNwZMdwgfJK/LvTiirMWYe63fxYB7qlByVkfA40/ANkShX2wXmSyrV
+aTIAYcb4Y/8zVNhC5+fqcVr++NEAAAAcqpht+KBkJ46TYzFqmDC8+kkGVvqm1dqo
+F9h5SQAAAQCBla2aR4/ZhSFu5YNoNm0u3RPBKz1iI5Fp+gQtkRVkCLSDEi9E7WI2
+uDCKbNtS+a896I7IngOa+tfaOqZsGXYEmo4KfRjVZ7r5n87+MVytoBVIOGsQsl5S
+9S7XjrTSgILl4f/ulIDE/izEqv0e/J1P0sxtFVlokxJx7xWzJA5/sEOoDI9ii+/g
+nWRQd8ECnSHgrIvwupwncU0bWA7eWUqgGzt29udF/B7AfbN+L9fpjGyMaRUijkIs
+MJ3p9dsWj1AknRvh7TKYCQgI4uu4lrt5uMTL+U1MIGTjfmErpESdesIQ7d4hFBbW
+SwUd2ARqsEFzJmVBGn8VTTGz4RpR2n/A
diff --git a/nss/cmd/bltest/tests/dsa/pqg11 b/nss/cmd/bltest/tests/dsa/pqg11
new file mode 100644
index 0000000..a0a47d4
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/pqg11
@@ -0,0 +1,12 @@
+AAABAMGlnSFVc5SeCyCpdMLt8uMTf/JGMGL3Xx0T3xKroQdrstATQCtgr2wYf7D6
+NiFnyXbCYXxyb5B38J4YwRtg9lAIglvWwCofV9PrCtQc1UfeQ9h/JSX5cdQrMGUG
+58oDvmOzX0raFy0KBpJEQKFCUNeCKsLVrq/tRhnnnUFYp9XrLZ8CPbGBqPCUssbL
+h8uFNUFqwZgT8HFEZgxVd0X0SgHGsQKQksEpsNJxg+gsWiGoAXfudHbrlcRm+0cr
+09LcKGziWEfpPL+prTnMVwNdDHtkuSapx/WnsrxavL+9wLDj/t48HgLESvyK78eV
+faB6Dl/RIznbhmdhb2IobfgNWKsAAAAggAAAAAAAAAAAAAAAG9YsZei4fIl5f48M
+v6VeSmgQ4scAAAEArqWHh0DxQk08bqnGtHmWFdJ0kpihfiYgf3bO80Dd05Dhsa1r
+bAAQrQFaEDNC3dRSysAks25C2bjtUvr656HTzp5LIfkQ0TVusWOj5agYTHgb8USS
+r6LksKVtiIT9AaYouWYnOcQuXFeVreL18n5t4dljkXzogG/EDQIc2HqjqjqeTwws
+TEXSlZsleLL7GiIpw34YEFm51ee3hi+oLiN3pJ7Q+dyoIKWBQHndZhBxTvr4sMxo
+PY5y5MiE5vnUlGs+jUy7kq2759TEfMML5/jDfKgYg6GqxoYAWf9GQKKcyuc94gsS
+5jsAqIsu6bqUt160CmVuFdnsg3MchdDv/Lnvnw==
diff --git a/nss/cmd/bltest/tests/dsa/pqg12 b/nss/cmd/bltest/tests/dsa/pqg12
new file mode 100644
index 0000000..b62db4b
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/pqg12
@@ -0,0 +1,12 @@
+AAABANAiduvzwi/9ZmmDGDpHrpTJvMvL+V3ctJHR985kNUkZmZLTfHnnsDLSbtAx
+trpEifMSWCb6+ycmqYMz69mr3eWS2Gk9mFlTbZzDhBodJOBE01rO1hNiVvxta2Fc
+9PQWOqOB6ytMSAglqOzMVtjdz1/mN+OK2bKXS9LPaL8nHg0GfSRlqLa2YFJPAIJZ
+iUWtpY6mSbmATrR1NAjCxZdoxGq7guMpXz2cpGn4TMGH9XLcS1o7OTRuyDnfrW8H
+1tHw4hUgm7DswFx2fPLnlDrJz7Au7h6e9ZRujOiDFrXhX9z5WhMu8uS7CBcTZSjP
+pd2WUy+cOr5cQhYg7ba8vVIjTKkAAAAggAAAABKZfoKF5AiXCPUoBwxtevigvQFA
+nnoHnNtvxbsAAAEAd4RTBJ7yYhR/7XtZsO5nZGB8Uee1tfxv6np6ex3Wuyg/Sprp
+jv05ZLFVZ1jLFbKlOvhhnnTYWJi+x307PzgklK5ZYaE//HRdo4YYIpFRmAD5ndcQ
+4ArrFa3uCI4nmO4uRvWYUmzw9GZwVdG6AJdQBB3FzdJyX/HZfdNAyFGK92cbh9Od
+Z67O2Etm+E4HAe/IKlye+VTuV20kw4WxTWMDfw2Gb9QktJdb3VSF7XQMuTLoQ/kG
+aD98eyx0d12QHDYbhHtRnA2mmWONpAvXNreD0nELLCzCbvkScb9OLBkp+HbpAuIF
+cWQiO8eNaiufbAx6fLhZIvfWxCh64jhh+BKISA==
diff --git a/nss/cmd/bltest/tests/dsa/pqg13 b/nss/cmd/bltest/tests/dsa/pqg13
new file mode 100644
index 0000000..3f01b91
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/pqg13
@@ -0,0 +1,12 @@
+AAABAKittsC0z5WIAS5d7/GocdOD4OKoW16OA9gU/hOgWXBeZjIwo3e/cyOo+hFx
+ACAL/VrfhXOTsLvWeQbAgeWFQQ44SA6tUWhNrDo497ZMnrEJ8Zc5pFF819XWKR6K
+8go/vxczbHv4DucY7gh+Mi7kEEfavvvMNNELZrZE3bMWCijAY5Vj1xmTomVD6tt3
+GPMXv12Vd6YVZWGwgqEAKc1EASsY3mhEUJ/gWLqHmAeSKF8nUJaf6Jws1kmNs1RW
+ONU3nRJdzPZOBsGvM6YZCEHSI9oVEzM6fJ14Riq6qzG5+W1fNERc62MJ8vbSyN3g
+ZEHoeYDTA++aH/AH6L4vC+BswV8AAAAg5x+FZ0R/QudfXvhcog/lV6sDQ9N+0J7c
+P25oYE1rnfsAAAEAW6JN6WB7iZjmbObE+BKjFMaTWEL3q1TNgrGfoQSr+12EV5pi
+OyV0s30izK6bPkFeSPXA+by9/4Bx1jubuVblR686jfmeXTBhl5ZS/5a3Zcs+5JNk
+NUTHXb5bs5g0UxlSoPtLA3iz/LtMi1gApTMDkqKgTnALtu1+C4V5XqOLG5YnQbPz
+O53eL07BNU8J4ut46V8DelgEthcWWfiHFc4amwzJDCfzXvLxD/DHx6K7AVTZuOvn
+aj12Sqh5rzcvQkDeg0eTflqQzsn0H/Lya42pqUoiXRqRNxfXPxA5fSGD8bo7e0Wm
+jx/xiTyvaagngC97akjVHab777ZP2abFt1xFYQ==
diff --git a/nss/cmd/bltest/tests/dsa/pqg14 b/nss/cmd/bltest/tests/dsa/pqg14
new file mode 100644
index 0000000..5b04b1e
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/pqg14
@@ -0,0 +1,12 @@
+AAABAKYWfBb/904pNCuFhq7TzYlvexY1oihv8W/f9BoGMXymsFyiunwGCtbbFWFi
+HMsMQLhqA2Gb//MuIEy9kLedy1+G67ST470ZiNgJf6I/pNePs83csAxGZCPY+nGY
+c8N2Rf5O7MVxcbvt/lb6lHTJY4W4ujeMeZcteqrmmiumTN6OVlTw97dFUM00R+ek
+cqM7QDfbRo3eMcNIqiXoK3/EG4N/f8ImphA5ZuzY+dFMLTFJVW1Dgp8TdFG40g+F
+ILDOjj1wX3TQpX6ocsK97pcU4LY5Bs3f3Ci2d30ZMlAA+O1SeOxdkS0QIQkxnLo7
+ZGnUZykJtPDb7sC7tjS1UboM8hMAAAAghCdSkETSFMB1dPezWcLgHCP9l3AbMorI
+wThbgcU3OJUAAAEAb8IyQVwxIAz1I680g/jias6AjS8caouGOrBCzH9rcUSy05Ry
+w8tMdoHQcyhDUD2PhYy+R25nQDJKqilZUBBZeMM1BpuRn/mm/0tBBYG4BxL+XT4E
+3bTf0m1ef7yisMUtjUBDQ9V7L5sqJtqn7OMM6rnheJ+XUaqpOHBJllrzJlDGyls3
+SlrnCz+Y4FP1GFfWu7F6Zw5uqviYRNZB4eE9Whsk0FPca4/RAcYkeGlRkn5CYxCr
+qUmKAEKz3Hu8WdcF+A2bgH3kFffpTFz514mZLTu4M20dgIy4a1bd4J2TS7UnAzki
+3hS/MHN2q30i+81hb57aR5qyFKF4UL3QgCqHHA==
diff --git a/nss/cmd/bltest/tests/dsa/pqg15 b/nss/cmd/bltest/tests/dsa/pqg15
new file mode 100644
index 0000000..ecc45f3
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/pqg15
@@ -0,0 +1,12 @@
+AAABAPY9o76alhYZbGVW885v2LmL3akTdHPaRv7ZcOK40Uc4eoGSIGXVKKfWQz68
+XjWxXGfqNaWlv/W5zvHNHm/jHdpSg42jqom5tOjZ08BzLMxPI4zhtBbEypPyxoAO
+X07UHE92Fc7FUxuYaAsg3GP3PnDYA6rPrs4z1F+g4513yFCCCVKLkEa1kXAQeRI0
+OX5BLSK8C41ny9HNKKMsJGCgvYaqug7qgOFuMkVkMXHjQiF2DCA6VrggehAJ5sGi
+9s2oX4XE+eQQuUmSM8DuBy5GWvT7T7koLFwQ6CNP1jDqkvCq5rl6Ug2zRHVwe3mk
+wXUmXANWzLyoJ+ODffPW0FdtkHkAAAAgm3Rj+CafC5CavtEJkWhPNqZKyGTg1tcX
+wO8hV3pMOQcAAAEAlyp19gboqjqR/wj9Exog9ZYyUTBOPRQxtxL6CAPVJ/1xD7fr
+J+UpBJcc1DypdxmaJNvutLe8K6B107cutrLFrY8Oi49IxQtVTH4HEfTHQWMwgGZy
+SY9DApJyS/mKjqSMf1PXsx2LdSixpvCH0sJ8M1ICg1seMUIls3rvi/zsfYCSDEpG
+Cj1oNE3tde2e6Gf6KmlFBjiU9WO2hjO4s5+DoaqvWpbH9CJofnyEz4+4zF9FBN/w
+h7yyapW7+Fg/A7Og5Do1ayvX4lzd33oBUwD67MZ5PF7pm2Mny4RW4y2RFTOdWmtx
+K3+dAwGssFEz4xFeRU06bdJKFpPJSqtUBlBL9w==
diff --git a/nss/cmd/bltest/tests/dsa/pqg16 b/nss/cmd/bltest/tests/dsa/pqg16
new file mode 100644
index 0000000..e298647
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/pqg16
@@ -0,0 +1,17 @@
+AAABgP1abFbdKQ992Eop3hcSbrTkSHs+/wpEq+XFl5LS4SALnD20TVKLn30iSAMu
+S6D3v8T6/HBr5RHbInbAt+z/042i4cLyN6dTkMHk0yOcuo4g5VhA7LBd9fAaG2l3
+rRkG8stUTM+5O5Aa0JZrGDKtLatSYkSjFWyQXAGsUctzudzZhg1WF1pCXYRkhdmx
+9EqKDCV45s9hlHvBoTkv3TILFqnXBFX+Q28tR97Y6OYF90hutXjqf8T/0TwH+Zlq
+8Vn9QR6UUUAyeN0RQajJJrNcljhLvWvuCcRvRMNrH/xxl/XpJdvgVEpo5quMGOQm
+pGazkvnCfdef76nKFjzFo3VTmoVZ8nf2V6U10ZZMal6RaD71aY66oB74GNv3LLBM
+P/CS0YiGbyXNQFEI9Wawh/c9LVvrUfrG3oSuUWGmavlgLH5L/BRvSCC9/Akvrqxp
+Ez5KCKWyAqEkmKIuV7rVRnTtS1EBCdUrX3TnDh9vghYXGM1M8AzJ8ZWKzIvdzfvR
+++Rs0QAAACCAAAAAAAAAAAAAAAAzSibdj0nGgRzoG7E0KwbpgPZLdQAAAYCZqwMK
+IaXJgYF0hyFnZByBweA8mydM+8J7xHJUKSd2beX6BTmztz8/FqyGaprsi0Rd7Zf7
+/wiDTtmMd+f8ieXcZXvvdm/3+/jnaHPhe+5BJ2LVb+EUF2CrTSW6/Utu8ltJo1Bm
+MtH44Qdwkwdg7BMlkyxaS6+ekBVCZN30QuxcQf7ZXRFSUVHbz7N1gUm62Bxiuc/3
+gWuPlTuLfAIlkNFYTpIdyVX1MorHKYPtXPDQQFb+DVMeYvj2yas8D81E4UhgtzEd
+JWHHfB0y9sadyPd5aMnYga2dteDBFP2oYovKAzXrf7nhXmJaq6tY/AEZTIG/b7LO
+VAd7giUOV8ansl3rbuOdS2hqXDB6dhKy2F7pJRJBPeopfkTzF75863CjMorwtAEA
+GkGFYrj/5Ol3G0tKjgtAx5E0nV1ORZ/mIKGi/HLi9sooVn1MJjK73htJhkwGuxJh
+nxMsHaj1ce9hPqxzn2arORTLP6GrhuBeUILrqiTr7qTPUb7vwn31Ev4/7n0=
diff --git a/nss/cmd/bltest/tests/dsa/pqg17 b/nss/cmd/bltest/tests/dsa/pqg17
new file mode 100644
index 0000000..fa1b638
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/pqg17
@@ -0,0 +1,17 @@
+AAABgPY7PN1kbY5921chaqbuwhNNcHSIofKc+plwZF8SJ+pdsuMY7qXaFofH7ZBQ
+lmk0XtYTTP8yIDq3Kuy/ppPSFq61XY0oqYH0q/8H0TGaeZvl3XRvhIQoF5KcMFtA
+hZivEgRdqi8czIvk2BtRPGMPAX/sFlisoQihr2Eg7AXjAYxCU8ndNbzgYrc9DyqT
+1BxIGlxDu5eQloLTmppg3Dw142N13sbO0NLbO6DREb7epwGg5HU2JJd6nnW3CnTi
+uB44pSqyLaExs1QW087JZjB5dGp2NHbldZgULjmGFUXar404oXbybHH1r+vZxWIN
+qAzzRStVw3xmG0oewDUXELneSjy+C5i02eyJEo2Xqn77GduLpDzAviXCAPkOFQbL
+eOwMM216lWE9QgTo7WjQ8KbHhCAQWo0tQ4+9JVGmShoLA/+4eHQvjJl5z6hzlBUC
+gZmNUXAdX8+paWpJif0l9ACVXmJrGr6SbAr6aappgZAO/83QMFkvgrIEKkeppajL
+AoPcTQAAACCAAAAAukY0tfpNoFS9DKSK5JDldxHzgRk4QkKRWbp8oQAAAYCK1FU8
+TkmqJHKKtQJEF7Ey0spTpV2VlFjy91mtsENb7u+jos/NADjiQgZD/EpN7rXZ/qoe
+3yEZO0DhS0KYKpTzXFi4EUfXGJ0mPJsS/mOrn6X28DooYMGGQy46sE8qsPL7YUe9
+m/ftXSBxO52iE4Piw6Fo59CdPYpaBY/SMJW1rP64ZKMwa+JCX6GtMq1tk4LmA7A8
+aK9K8CRjlxAsQVXLqBGr+Z2ng553surJlwWIyh0KI2FyOhZKySKcLoDc+o20+eKY
+A+/7MWjH/tejpt5A3aGaBTavm1t6+u+5xw1q6N8S2mWPYjYEOuqHPbKc628H0Qj1
+IlaHvQww4whOIJC0WuL5Kpe47LepcFxJVrizHEo9YRB8hOR63abIDV0i2rPYWSIP
+nVqrE2d6498WjwwXbRdrVFBsY5hT8E3e8nIvOcGOXOQm4UVirY/yYkeviIcO+3LA
+zOg23o/uZ6ZiN4JFtQK/H4MJmYigk8583IE2THix9KUbgA32E3xx1l5rCJo=
diff --git a/nss/cmd/bltest/tests/dsa/pqg18 b/nss/cmd/bltest/tests/dsa/pqg18
new file mode 100644
index 0000000..cd7ed66
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/pqg18
@@ -0,0 +1,17 @@
+AAABgMe4bXBEIY42dFPSEOdkM+Tiepg9scVgu5dVqPt9gZkSxWz+ACqx/z9yFluU
+PAso7UYDmgfeUH16Kfc4YD3s0ScDgKQflx8lkmYaZLovNR2aaeUaiIoFFWt/4VY8
+S3fuk6RJSROEOKKri9z8SbTnjRzedm5UmEdgBX12zXQMlKTdJaRqp3sY6dcH1nOE
+l9Tqw2T0eS2XZqFqDiNIB+lrjGTUBLvbh245tXme9T/my5urYu8Z/cwr3ZBb7aE7
+nvesNfH1V8sNxFjAGeK8Gan138Hk7Knm1GZWQSQwSjHwOGBaPjQtoBvhwrVFYQ7d
+LBOXo8g5ZYjGMp7+tOFlr1s2ijmojkiI459Auz3k6xQWZy+Zn+rTeu8cqWQ/8yzb
+wPzr5ijX5G0oGpidQ90hQyFRr2i+P21WrPvbbJfYf8teYpG/i07hJ1rg60ODzHU5
+A8jSn0rbalR+QF3s3/KIxfbHqjDcsS+E05JJOnCTMxfA9eZVJgH64Y8X5uW7a/OW
+0y2KuQAAACCHb6CeHcYrI2zhwxVbpIsMz9op86xal/f/ob2Hto0qSwAAAYARCv67
+Esf4YrbeA9R/28Mybg1NMbEqjKlbLe4hI7zGZ9T3LB5yCXZ9JyH5X72aTQMjbVQX
+T7+v8sT/ferkc4sg2fN78KETTCiLQgrwtXkuR6klE8BBPzRqTturLEW9yhP1NBwr
+Vbi6VJMrkhe1qFnlU/FLuMEg+7nZmQnf9epo4Us3mWT9Pzhh5bpcyXDEoYDu9UQo
+cDlhAh571oy2N5J7jL7mgF+icoW/7k0e9w4CwaGKfNeL7x3Zza1F3enNaQdVBQ/E
+Zik37h1vTbEoB8zJW8Q18Rtx5whgSLHatZE8YFUBLeguQ6TlDPk/7/Xcq4FKvCJM
+XgAlvYaMP8WSBBu6BHR8EK9RP8NuTZHGPuUlNCLPQGM5jXfFL8sBFCfL/PpnsbLC
+0apKPacmRcscdnA2BU4vMfiGZaVEYciF+zIZ1a2HSKARWPbHwN9ajJCLqMPlNoIk
+KIhse1ALvBW0nfdGud5aeP47T2mR0BEMPL/0WAOdw2Jhz0avS8JRU2j0q7c=
diff --git a/nss/cmd/bltest/tests/dsa/pqg19 b/nss/cmd/bltest/tests/dsa/pqg19
new file mode 100644
index 0000000..cacd4e4
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/pqg19
@@ -0,0 +1,17 @@
+AAABgKQQ0j7ZrZlk0+QBy5MXolIT91cSrLxcEhkavz8cDnI+IzO0nrH5Ww+XSNlS
+8Epa41iFnThEA842SqP1jdl2mQm0UEhUjFWHKmr7s7FcVIgvlsIN8bLfFk8LrISc
+oXrS32Or11yIGSLnmlAJ8At9YxYi6Q5/pOmAYYV14da9GnLVtqUPT2pot5OTfEr5
+X8EVQXWaFzZXfZRIuHeS3/ByMkFVEukzdV4SJQ1GbpzI3xUHJ9dH5R/qeWQVgyax
+Nl1YDLGQ9FGCkVmCIf3zbGMFyLio7QVmPdewBulF9ZKrvsrkYPd8cbbsZJ0/1TlC
+Au17u9BA97j9V8sGqZviVPol1xo3YHNARsKg2zg+Ajl5E65nzmWHDZ9sb2ep0ASX
+vh12OyGTfPnL+aJO+Xu8qgeRb4iU5bf7AyWIIaxGFAllsjxUCcpJAm77K/lbzgJc
+QYOl9lm/aq7vVteTO7KWl9fVQTSMhx+gH4aWeLLjRQb23ApMEytomg7SfcPI1TcC
+qlhIdwAAACCrxnQXclzyj8dkDV3kOCX0Fuv6gOGRxC7ohjAzOPVgRQAAAYCGfV+3
+L1k20aFO07YEmWYvMSRobvEIxbPaZmOg6GGX7CzEyUYBk6dP8WAorJRBsMfSfCJy
+1IOsfNeU1ZhBbE/5CZphZ51BfUeM5d2XS/NJoUV1r+dKiLEt1fbRy9P5Hd1ZftaO
+eeukAmExMMIkuUrChxSh8cVSR1pdKc/N2OCKax1lZh4o7zE1FNFAj1q9Pgbr46fY
+FNHt4xa/SVJzyh1XT0K0gu6jDbU0ZvRUtRoXWguJs8Bd2gBucZouY3FmkIDXaMwD
+jN+4CY6arZuNg9S3WfQ6ydIrNT7YijNyNVAVDeA2G3o3bze0XUN/cctxHyhH3mca
+0QWVFqHUV1UiShXTe0rq2j9YxpoTba7wY2/jjjdSBkr+WYQz6ACJ/aJLFEpGJzS+
++Pd2OIRbAOWc5/pPHa9IeiytoR6rpyuyPh32tmoYPt0ibEQCct2bBr7A5X8aCCLS
+4AISBkttumRWIIX1p1kpr6X+UJ4LeOYwqvEvkeSYDJsNb34Fmi6j4jR52TA=
diff --git a/nss/cmd/bltest/tests/dsa/pqg2 b/nss/cmd/bltest/tests/dsa/pqg2
new file mode 100644
index 0000000..4bde8ec
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/pqg2
@@ -0,0 +1,6 @@
+AAAAgIubMvW6OPqtXg1QbrVVVA0NeWMZVVjKMIt0ZiKNkqF7OxS44Kt3qfOylZoJ
+hIqmn435LNnp7e8K33ks53v87Mrdk1JwDKX67PGB+gwybbHW5dNSRYAR5RvTJI9O
+O9fIINfgqBkyrKHro5AXXlPq2hlyI2dOOQAmPpD3LZTnRHv/AAAAFLxVDpZWR/s6
+IPJF7IR1Ykq7sm7dAAAAgBEzOpMfulA0h3dzdoWf3BL3xoewlIroidKH8benEq0i
+CuTxzjedDbtcmr9BliHwBfwSPDJ+UFXRhQY0w205fmieER1ZjBw2NrlAyE9C9DaE
+bo5/ytkBLO2jmHIPMv/9GkWrYTbOQXBpIHrBQGdbj4bdBjkVrm9isM7HKfvVCawX
diff --git a/nss/cmd/bltest/tests/dsa/pqg20 b/nss/cmd/bltest/tests/dsa/pqg20
new file mode 100644
index 0000000..f782840
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/pqg20
@@ -0,0 +1,17 @@
+AAABgMHQptC17WFd7nasWmDdNeywAKICBjAYsboKBv56APdl2xxZpoDOz+OtQUdb
+rbWtULYUfiWWuI00ZWBSrKeUhupvbskLI+Nj86uM3IuTtioHDgJojqh3hDpGhcK6
+bbER6a3b18pLzmW7EMnOtpv4BuLr1+VO3rf5lqZckHtQ79+OV1uuRiohnDAv7yro
+HXPO51J0YltfwpxtYMBX7Z57DUatL1f+AfgjIw8xQiciMZzgq/HxQfMmwA+8K+TN
+uJRLb9BQvTAL2xxfTaclN+VT4B1RI5xNRhhg8ftP2Pp59dUmP/Yv7XAI4uCi02v3
+uQYtDXXbImw0ZLZ7okEBsIXyxnDA+HrlMNmO5gxUcvSqFfslBB4ZEGNU2ga8Kx0y
+LUDtl7If0c2tMCXGnabOnH3fPc8epNVld7/ewjBxwfBe5Ad7U5HppATq/+EtHqYt
+BqzWvxnpGhWNIGa0zSDkxOUv+x1SBM0CK8cQjyx5n7Rohm7xywm84J39SeR0D/gU
+BJe+YQAAACC/ZUQcmHt3NzherewVjdAWFNpvFThiSOWfPN2+/I6d0QAAAYDAKshT
+dfq4C6KnhLlOTRRbO+D5IJDroXvRI1jPPgP0N5WE+HQiUvdrHt4/w3KBQg50qWPk
+wIh5b/K6uNtumkUw/GfVH4i5BatDmVqrRjZMtAwSVvBGbz2842ID7yKLNekCR+le
+URXoMbEmtijumE80mRHTD/udYTtQqE36HwQrpTa4LVEB5xHGKfnyCW3INN7sY7cP
+KiMVptJzI7mVqiDT0HNwdRhvUEmvb1EqDDip2gaBf0thm5RSDt+shcSm4uGGIlyV
+oE7Dw0IrjesoTpjSSzFGWAIAigl8JZaegmwrqlnSy6M9bB2fOWIzDB/Np8+xhQj+
+p9BVXjoWna7TU/Pub0uzAkQxkWHf9kOKN8p5OyS7sbG8IZT8bm72AngVeJnLA8Xd
+b8kag26yCiXAmUVkPZX3vVDSBmhNb/wU0W2C1feBIlv/kIOSpXk7gD+bcLTfyzlP
+ntgcGOORoJ6z+ToDLYG6Zwyr/W9kql4zdMt8ICn0UgDk8L/YIMi9WNxe6zQ=
diff --git a/nss/cmd/bltest/tests/dsa/pqg3 b/nss/cmd/bltest/tests/dsa/pqg3
new file mode 100644
index 0000000..1f92161
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/pqg3
@@ -0,0 +1,6 @@
+AAAAgMuhPlM2N8N8DoDZ/NBSweQaiKwyXE6+E7cXAIjVTu9IgfPTXq5HwhA4WoSF
+0kI6ZNo//aY6Jvks9aME85JgOEqbd1nYrBrcgdP4v8XmyxDvtOD3WGf06EjRozhY
+bdBkj+6xY2R//nF2F0NwVA7oqPWI2ozBQ9k59wsRSn+YG4SDAAAAFJUDG4qnHynV
+Jbdz74t8ZwGtil2ZAAAAgEW8qkQ9TNFgLSeq+EEm7cc713Pebs4V6X5/70bxMHK3
+rcr3sAU89HBpRN+MRWjybJl+53UwAPvkd6N3ZqTpcP9AAI65ALneS1+a4G4G22EG
+54cR86Z/7KdN1b3c32da5AFO6UiaQpF/vuO7nyok32dRLBw1yXv78jCOqs0oNoxc
diff --git a/nss/cmd/bltest/tests/dsa/pqg4 b/nss/cmd/bltest/tests/dsa/pqg4
new file mode 100644
index 0000000..0446942
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/pqg4
@@ -0,0 +1,6 @@
+AAAAgPJKSvxyx+Nzo8MJYjMv5UBcRZMJY5CUGMMHkqrxNd3qVh6U8kcmcWt1oYgo
+mC5M5Ewf3ct0ZIe2t3qaWhf4aKtQzWIbW8naRwiAsofXOYGQpCpe4i7Y0f8UfiAZ
+gQyCmO1o4cpp1B1VXySeZJ+xcl3bB1wXs3vv9Gf90WCSQzc/AAAAFNoGWgeN21bu
+XSrQbK+rIIINLEdVAAAAgEe1WRt5BD5OA8p4oOJ3yaIeKmtUO/TwRBBM2ayT7/jh
+AbtgMe/IxZbV0vkuOj0PH3RwLdVPd9PNRsBN7npd6fAK0xdpH93O/koiCiZRrK5/
+zt2pK/zKhV22cF6Nhk+Bkr9r+GDADwitZJPswYcuACjVyG1EUF21dCJRXDglpveK
diff --git a/nss/cmd/bltest/tests/dsa/pqg5 b/nss/cmd/bltest/tests/dsa/pqg5
new file mode 100644
index 0000000..6a091c5
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/pqg5
@@ -0,0 +1,6 @@
+AAAAgIjZaOlgLsvabYb3yXCj/76x2pYvKMCvuScO8FvDMMqYw634PAcv6wX7Lik7
+UGW7sMvMkwwk2NB4ad6uzZKiYEwPXdNcW0Mf2moiLFLDViv3VxxxAgm+izuFiBh4
+hyX+gRK31ryC4P8cu/XW/pRpCvK1EOQa2CB9wsAvufpc76q1AAAAFKZlaJueW5zo
+L9FnYAbPTPZ+zFa3AAAAgCZ+KChXQXdSET+6P8pxVbXOiefIozwaKRIuK3IJZfwE
+JFJn/4f8Z6VzD+WzCAE6oyZpkPuzmBhah+BVtEOoaM4M4TrmruMwudJdO7s2JmXF
+iB2vDFqnXp1KgujwTJGprSlIIuM5eKsME/rcRYMfnTfaTvoPwsXrATcfqFt92x+C
diff --git a/nss/cmd/bltest/tests/dsa/pqg6 b/nss/cmd/bltest/tests/dsa/pqg6
new file mode 100644
index 0000000..e1220d7
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/pqg6
@@ -0,0 +1,12 @@
+AAABAPLTntMGKxPJFic2AKDyoCnobXpLkhe08YFb8rJNlxClerM/mXKUsBRYW40B
+mN/cy811MU2l/4WqNEtFra6ql5tRoxKnv6lEcvtjPxpvFWu0RYhn39OEA/BrhR8A
+/i00hAd73tcat1E9BKFAIgV1+2kzlUgOTIQCt6Rs7C03p3jDBazNHxPp9i6GUxX0
+sizEZ8iYbsjklh3fgQVmsMTuNprGqhXkP0dEAFgm9b3oBxoZ4wtpCarEs9F0I3Jw
+2tAnmdCbiizF8i5miUtUIiKLLCNPEfWnccW4nPRloqzsu+6qFyX+j5tZQivomRBS
+y1Vt3yyM6PqSBtvzn+rcGU4A+OUAAAAcgAAAAAAAAADBGPSYNeTvczxNFYAPzwWe
+iE0xsQAAAQDjqTwJ2m9WDk1IOjgqTFRvIzXDakw1rBRjwIo+bdQV31b9xTfyX9U3
+K+Y+T1MAeAt4LxrNAci06zNBRhX9Dqglc6y6fvg/WpQ4VBUa/C19/hIfuM0DM1sG
+W1ScXcxga+kFJIO8KE4SrDyNugm0JuCEAgMOcLwcwr+JV8S6BjDz8yrWiTiaxHRD
+F2Bj8kfZ4ilrPqW1vCM1go6hoIDtNZGN7iEv0DEnnRuJTwGv7FI4M2aerAMaQg5U
+C6EyClnEJKPlhJpGCla8sAFkeIWxQzxPmSlxdGv+KXfOclnFULVRpsNXYeSkGvdk
+6NkhMvzApZ0WhOq5DYY/KfQc91ePqpCM
diff --git a/nss/cmd/bltest/tests/dsa/pqg7 b/nss/cmd/bltest/tests/dsa/pqg7
new file mode 100644
index 0000000..f65cc5c
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/pqg7
@@ -0,0 +1,12 @@
+AAABAKqBXJ2xxNPSdzx9DU0dp17PxKOel9X6GR/+yLFJCikM4zXlzofqYgqKF94L
+tkcU4uyEC/AObr20/7TjJMoHw8hxcwmvFBA2Kncsmt2DiysMrh6Qq0SK2r2s0uXf
+WcQYejKiNxnWxX6UAIhTg7+PBm8juUGSDVTDW098xQRPO0DxcEaVYwe3SOhAcyhE
+0Aqc5uxXFCk7YmUUfxXGf0vjiwgrVf3q22EkaJ+3b50lzCi46qmLVi1cEBHg3Pmz
+mSMkDTMtidyWA7e93QxwuDyqKQVjGxyDyruubAwMLv6PWBMe2DUb+T6HX2pzqTy6
+1HAUGiaH+6zy1xyN3ulxrWYHKa0AAAAc6jR+kL58KHXR/h22IrR2ODfF4npgNzED
+SMGqEQAAAQAgQglMy8i4cj/JKMEv2mcbgylemcdDV29EUEvhGGMjMZtQAtJPFz35
+CeokHW6lKJkE7kY2IEsvvpSwaP4JP3liV5VJVR068hmtjtGZOe/4a87INN4vL3hZ
+bonny1LFJOF3CYpWwjLrH1Y6qEvGsCbe7m/1HLRB4IDy2vrqHO2GQn0cNGvlXGaA
+PUt20TPNRFtMNIL6QVAjRjyb8w8veEIj4mBX06oNf7tmBjDFLknUoDJcc4ngcqo0
+nxPJZuFZdS+7cekzaJD5MkP6bnLSmTZe5bP+Jm6/ERBWj+5EJchHtQIQvUhLl0Ma
+QoVq3KPn0anJxnXH4maRgyDdWnikjEip
diff --git a/nss/cmd/bltest/tests/dsa/pqg8 b/nss/cmd/bltest/tests/dsa/pqg8
new file mode 100644
index 0000000..93b5700
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/pqg8
@@ -0,0 +1,12 @@
+AAABAKTH6qtCxMc7dXdwkWSJ8XzVByXNCkvE4c9n92O4wd4tbauYVrqvsAjzZbGK
+QuFNxR81C4jsoCCcWqT9caepbHZfWQHCHnIFcNeDe+x8dtLkk0RzHKOUBdCoebng
+3NGoEl/RMOweeD5lS5TjAC5rYp6QSrOHeGdyDL1UtCcKnhXNAox8x5bwbCcqZglR
+ko/b6y3KBhtB6TIlcwV0L/FuL0KRkdXl8abd9ueMXXciz/gKnAvVyNeuuowEQ4mS
+sHXjB8FTTEmtOA9Hf195h9wXLBYdyjjcrz+zhGxyyRGaUpmtx0iVGz3ODQDUqQE4
+ALIAggO3JGW8aoSuBZowxFIt6lcAAAAczon+MyuOTrPR6N3OpdFjpbwTtj8WmTdV
+QnrvQwAAAQCMRl7fWhgHMCkeCA38U4U5elAGRQ26Lv4BKSZPvYl7tVecoOqxmqJ4
+IgQkcktPKm9u5jKEMqv2YTgGRglyM1BTOcVRnTV9cRK27sk4uF1ap1zC44CS8KUw
+rLVOUP6CxNVi+w8wNrgLMDNAI+u+ZjegAQsAx9uGNxFoVjZx4eDwKK7b1F0tVyYh
+pgmYKgc+Uaridwevvu8p4uzuhNem1do4K+OjX0K2xmhJICqxnQJbhp0Id2R20auY
+FHWtKtLz5v0H4waW2QpiaBbfYNbKev17SC+UL4O0XMgpM3Mfh/ruMgkA8qo+cLGG
+fhQw5AvmfAf5KQKZ7wZ7iySnUVs/mSwH
diff --git a/nss/cmd/bltest/tests/dsa/pqg9 b/nss/cmd/bltest/tests/dsa/pqg9
new file mode 100644
index 0000000..8cec6fa
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/pqg9
@@ -0,0 +1,12 @@
+AAABAKa7UzPONDwxybLIeKuR7vL96jXG2w5xZ2K/wNQ22HUG6GWk0sjPu9Ymzov+
+ZFY8pWhs2M8IFJDwJEWyiQh5gklftpl2sQJC1tUPwjtNvbC+94MF2aTQXZ6uZdh6
+iT6vOX4E45uqhaJsj/ve8SMyh7X1tu9qkPJ6aUgaky7kexjV0n6xB/+wUCXmRuiH
+a1y1Z/7B3TWDXUIIIZhTH6++WuKAxXWh+w5i6bPKN+GXrZbZ3eHzPyzsfSferiYc
+g+6OIAKvfrboL2oUeWrwN1d6EDK7xwkSnKq9it34cK4tBZXI/bNxVXSPDeo0tE1P
+gu1YwvWxuEgWYqxTRzxpNBAIL70AAAAcjD7lvZoqrwaL1YRb1V7PJ0FwVTB1d7vD
+dw7GiwAAAQBDtaa20LuWLsl2ajd8MsxBJPExEYjC7PlcDNSk+glyJbdhjLEnbEdF
+eNO/VkwUUZnAkqGxS6qSnC8/DzbgwtrpHroIvjCZKoifKVLgRCw3r0hKTs3DJDzP
+y540E89c3WYwsJ/hfvv94U2HJUkwGbe3PR94K0jvML7DbgDgK6M20iVPwgKmlhLN
+lEb5HXa3Of+m2LhgUvjcXxFFgBxWJBr1upA3JBvYnmM4tY4BMQZxwmjrXjOstX0f
+mfFkQKZ1gn1AF3VNYBoXraL77fkEVUqQsBUw2oyTzRTOKTyyvT55N+k0t54xD+TY
+DBP5L2M4E1W9gKGr7hpz/fttok7ygAKj
diff --git a/nss/cmd/bltest/tests/dsa/sigseed0 b/nss/cmd/bltest/tests/dsa/sigseed0
new file mode 100644
index 0000000..05d7fd2
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/sigseed0
@@ -0,0 +1 @@
+aHpm2QZI+ZOGfhIfTd+d2wEgVYQ=
diff --git a/nss/cmd/bltest/tests/dsa/sigseed1 b/nss/cmd/bltest/tests/dsa/sigseed1
new file mode 100644
index 0000000..83a7ecf
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/sigseed1
@@ -0,0 +1 @@
+mMvMSWnYReJGG19mOD3VA3ErvPo=
diff --git a/nss/cmd/bltest/tests/dsa/sigseed10 b/nss/cmd/bltest/tests/dsa/sigseed10
new file mode 100644
index 0000000..7ddd4ea
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/sigseed10
@@ -0,0 +1 @@
+nO2J6lBQmCIigw7+8m5zlPWrfYN9RUmWLShfrg==
diff --git a/nss/cmd/bltest/tests/dsa/sigseed11 b/nss/cmd/bltest/tests/dsa/sigseed11
new file mode 100644
index 0000000..a12adcb
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/sigseed11
@@ -0,0 +1 @@
+LLnB1hfhJ6R3DQqUb7lHxRAO0MpZRU6oBHn2iF7BBTQ=
diff --git a/nss/cmd/bltest/tests/dsa/sigseed12 b/nss/cmd/bltest/tests/dsa/sigseed12
new file mode 100644
index 0000000..d51eaf3
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/sigseed12
@@ -0,0 +1 @@
+RQMLeaOVsWMnAMuv/q2XmY0CvtjgZWh2/AF05L25b3k=
diff --git a/nss/cmd/bltest/tests/dsa/sigseed13 b/nss/cmd/bltest/tests/dsa/sigseed13
new file mode 100644
index 0000000..77c773a
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/sigseed13
@@ -0,0 +1 @@
+EXpSnj/fx5hDpaTAdTkDa4ZSFOAUtJKMKjH0e/YqT9s=
diff --git a/nss/cmd/bltest/tests/dsa/sigseed14 b/nss/cmd/bltest/tests/dsa/sigseed14
new file mode 100644
index 0000000..8178d4b
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/sigseed14
@@ -0,0 +1 @@
+I2gDehx2R8aD1+MBrHm3/uvHNu/+OrFkS2gwi0soYg0=
diff --git a/nss/cmd/bltest/tests/dsa/sigseed15 b/nss/cmd/bltest/tests/dsa/sigseed15
new file mode 100644
index 0000000..8bfb678
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/sigseed15
@@ -0,0 +1 @@
+X+Ya/dvfBESbJClaUqGgN9PzFEGjzsE4t/AQLbhu8TI=
diff --git a/nss/cmd/bltest/tests/dsa/sigseed16 b/nss/cmd/bltest/tests/dsa/sigseed16
new file mode 100644
index 0000000..06c4c1b
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/sigseed16
@@ -0,0 +1 @@
+QPUDq9cP1Jp2xnqD4IsGKz/UZa2SvkM8CA5fKVu59Vk=
diff --git a/nss/cmd/bltest/tests/dsa/sigseed17 b/nss/cmd/bltest/tests/dsa/sigseed17
new file mode 100644
index 0000000..43148bf
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/sigseed17
@@ -0,0 +1 @@
+KeTXeQ4YG0dnkD/g6zd1fzPxMzfDNYjB/b+6DmVatiE=
diff --git a/nss/cmd/bltest/tests/dsa/sigseed18 b/nss/cmd/bltest/tests/dsa/sigseed18
new file mode 100644
index 0000000..370f857
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/sigseed18
@@ -0,0 +1 @@
+PXwGijl4stj+kDS8rWWtfDAMREDkCF3igOV37qcsEgc=
diff --git a/nss/cmd/bltest/tests/dsa/sigseed19 b/nss/cmd/bltest/tests/dsa/sigseed19
new file mode 100644
index 0000000..edb0bf8
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/sigseed19
@@ -0,0 +1 @@
+QLXMaFw9H1kHIiivlVFoO1uMj/ZSQBFK0trPzPOSgFc=
diff --git a/nss/cmd/bltest/tests/dsa/sigseed2 b/nss/cmd/bltest/tests/dsa/sigseed2
new file mode 100644
index 0000000..814709f
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/sigseed2
@@ -0,0 +1 @@
+jLNdJVUFpMQUIeVi0QgnJmqmhmM=
diff --git a/nss/cmd/bltest/tests/dsa/sigseed20 b/nss/cmd/bltest/tests/dsa/sigseed20
new file mode 100644
index 0000000..de625fd
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/sigseed20
@@ -0,0 +1 @@
+tZkRG594QCzv573ov1U7bKANWrr5oViqQvJge/eFELw=
diff --git a/nss/cmd/bltest/tests/dsa/sigseed3 b/nss/cmd/bltest/tests/dsa/sigseed3
new file mode 100644
index 0000000..d2c7339
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/sigseed3
@@ -0,0 +1 @@
+hZdsVhCnSVlTEEClUSs0fqxYfkg=
diff --git a/nss/cmd/bltest/tests/dsa/sigseed4 b/nss/cmd/bltest/tests/dsa/sigseed4
new file mode 100644
index 0000000..036d29a
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/sigseed4
@@ -0,0 +1 @@
+M8e6iP9pcHlxslrDRK5KVm4ZX5k=
diff --git a/nss/cmd/bltest/tests/dsa/sigseed5 b/nss/cmd/bltest/tests/dsa/sigseed5
new file mode 100644
index 0000000..7d80d66
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/sigseed5
@@ -0,0 +1 @@
+LxcJB6xpcmsU8iBW3LN7TfhfdCQ=
diff --git a/nss/cmd/bltest/tests/dsa/sigseed6 b/nss/cmd/bltest/tests/dsa/sigseed6
new file mode 100644
index 0000000..2f8d8df
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/sigseed6
@@ -0,0 +1 @@
+cZc5LTLQr2pxg8wzmFVvj2h9hqj/dCvmrThWLw==
diff --git a/nss/cmd/bltest/tests/dsa/sigseed7 b/nss/cmd/bltest/tests/dsa/sigseed7
new file mode 100644
index 0000000..eda9323
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/sigseed7
@@ -0,0 +1 @@
+N/rdQZ/L0rBzoGrpa57Otj4prumsX6K9sxq4XQ==
diff --git a/nss/cmd/bltest/tests/dsa/sigseed8 b/nss/cmd/bltest/tests/dsa/sigseed8
new file mode 100644
index 0000000..03997e0
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/sigseed8
@@ -0,0 +1 @@
+bzJlRqoXSz0xnvczHsjf02PdeK5YOpIBZf9+VA==
diff --git a/nss/cmd/bltest/tests/dsa/sigseed9 b/nss/cmd/bltest/tests/dsa/sigseed9
new file mode 100644
index 0000000..0ce4ead
--- /dev/null
+++ b/nss/cmd/bltest/tests/dsa/sigseed9
@@ -0,0 +1 @@
+fg8c4h0YWuZcCgA5VWfqnPIXRitYucicTl/5zw==
diff --git a/nss/cmd/bltest/tests/ecdsa/README b/nss/cmd/bltest/tests/ecdsa/README
new file mode 100644
index 0000000..0a6ece6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/README
@@ -0,0 +1,4 @@
+0 nistp256
+1 nistp384
+# the following tests are not yet implemented
+2 nistp521
diff --git a/nss/cmd/bltest/tests/ecdsa/ciphertext0 b/nss/cmd/bltest/tests/ecdsa/ciphertext0
new file mode 100644
index 0000000..14d8e0e
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/ciphertext0
@@ -0,0 +1 @@
+GoWqve3YezF7HOABQjioFL/3oq32oM9pHsGTQTJE7aFE62nItVqAdg==
diff --git a/nss/cmd/bltest/tests/ecdsa/ciphertext1 b/nss/cmd/bltest/tests/ecdsa/ciphertext1
new file mode 100644
index 0000000..4484aae
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/ciphertext1
@@ -0,0 +1 @@
+PM6xHbiwP6Xcb44mg7BHtaJvd8PkxgvHAB1sh2cF0so3naFf0Tj6vQ==
diff --git a/nss/cmd/bltest/tests/ecdsa/ciphertext10 b/nss/cmd/bltest/tests/ecdsa/ciphertext10
new file mode 100644
index 0000000..a956d53
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/ciphertext10
@@ -0,0 +1,2 @@
+AF3bbyED08NTrUgKmag9HiuUbaW0skXA/Bp9RPjRAD6M0rp3nvLDKozI940jxPP1
+nWpHF7VcyCVzJeV6
diff --git a/nss/cmd/bltest/tests/ecdsa/ciphertext11 b/nss/cmd/bltest/tests/ecdsa/ciphertext11
new file mode 100644
index 0000000..8cc2c26
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/ciphertext11
@@ -0,0 +1,2 @@
+AOLrxy4FWd29ToUjOwLs6GyQ+dYZN6NkZ8oVO6dsAEXt55ePlCWZbOtmk6v9PrNG
+JOsY/MHnGhDeAGRl
diff --git a/nss/cmd/bltest/tests/ecdsa/ciphertext12 b/nss/cmd/bltest/tests/ecdsa/ciphertext12
new file mode 100644
index 0000000..5a05a78
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/ciphertext12
@@ -0,0 +1,2 @@
+aQHMte9cFByD9Ff3rZOPOtPI75luPoxemmgjXIgh/9jEeoTdDk8xuAYQUkayCfs+
+DpDaGnOLkfAyZ8GcuaCujg==
diff --git a/nss/cmd/bltest/tests/ecdsa/ciphertext13 b/nss/cmd/bltest/tests/ecdsa/ciphertext13
new file mode 100644
index 0000000..690c00a
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/ciphertext13
@@ -0,0 +1,2 @@
+AaeVCRJQPbpTqa1+zLd/8xAbkz3KKTr0dlS4tuGC8hc9j5esAeEv+7IklbA3v5Jz
+jC+nJy4p81iNO5E9H8nfGGckfQSiFzHG
diff --git a/nss/cmd/bltest/tests/ecdsa/ciphertext14 b/nss/cmd/bltest/tests/ecdsa/ciphertext14
new file mode 100644
index 0000000..fe527c6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/ciphertext14
@@ -0,0 +1,2 @@
+AgU0N7zJPg/1UxmCWD5Z+DqDqkRKjy4heFgayCyopb/u4XErAZArgsjashAxzMKC
+PSDJasPT90T5Va8sNtjXtSpHWxc2roV9
diff --git a/nss/cmd/bltest/tests/ecdsa/ciphertext15 b/nss/cmd/bltest/tests/ecdsa/ciphertext15
new file mode 100644
index 0000000..d109094
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/ciphertext15
@@ -0,0 +1,2 @@
+NXo8is+7lAoOwWGt7+GBbT/UX8LGs8TXEHBI+tX9311pJ4J3pfBYobgN0ZK6ZBtp
+dS6PkrPaQp0S9nrfTOS5uAH95eD1eymRfCbOnjTUKzLuIn53V17vRjdcDtLzrhzX
diff --git a/nss/cmd/bltest/tests/ecdsa/ciphertext16 b/nss/cmd/bltest/tests/ecdsa/ciphertext16
new file mode 100644
index 0000000..d5fe144
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/ciphertext16
@@ -0,0 +1,3 @@
+ADhxjBz/ACTy4GJlL0tYZpyNpC4DsXND9lJuU7x9N7g6gkpJyBPw3vBYU1olw6PH
+dnegpgAm4Gh6MCsZB4KBcLwl1wjt4B3p2eqEqDYn5fiie5f4XuRomvI92jR5Sb+I
+nBLCHIppt/Q=
diff --git a/nss/cmd/bltest/tests/ecdsa/ciphertext17 b/nss/cmd/bltest/tests/ecdsa/ciphertext17
new file mode 100644
index 0000000..486bf66
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/ciphertext17
@@ -0,0 +1,3 @@
+AGhHQ6kfdZRgu1svQTXEIewvFVglnUy6ANPumyUbM14AEfRkCUNa1uzvhV1sbWYj
+qT3egQCA9MTjThDNJeDOvvL6hVVOryUv4+C3RtkpQGCtdml+CSsjVTej8h9JbMds
+Dme40b2G6fE=
diff --git a/nss/cmd/bltest/tests/ecdsa/ciphertext18 b/nss/cmd/bltest/tests/ecdsa/ciphertext18
new file mode 100644
index 0000000..7eeef38
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/ciphertext18
@@ -0,0 +1,3 @@
+AGBuqk48tufy0bKEWpu+xEHsmi+6KCfdwOSRwLDnpVetGe9AWknHDzeTSwe0QxcE
+RsEkUZGDpxfzUlCLSSSU+ErrYY/uyLV2AJTb3prB6A2YNwdmFGeRbDoxeOu7FuQA
+3gxBQhR+TGMuskeM+BdHFmFrwvTTdHCGzjTBa5S8mbgEJTfeik/it28T/9i+duZ8
diff --git a/nss/cmd/bltest/tests/ecdsa/ciphertext19 b/nss/cmd/bltest/tests/ecdsa/ciphertext19
new file mode 100644
index 0000000..ef8e5f3
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/ciphertext19
@@ -0,0 +1,3 @@
+AaiotJfCiWU1d2LFe+t0CcWHDSF7EOlApWYJ+RNRSq8TbkXJIzi6abbb7BovtRwf
+i/COYwjS7OnkFQ6x5Pdrb7OZ0dTAdDRXAKtXWSKR20Y4fhnx/HUxisFwKrsCEQ3O
+uVtwDG8rh5V8zjBnCEcs5Iy9CsklucibR0PIyglVmW+ZuY42YNebuOC2VUKqHNF7
diff --git a/nss/cmd/bltest/tests/ecdsa/ciphertext2 b/nss/cmd/bltest/tests/ecdsa/ciphertext2
new file mode 100644
index 0000000..a3837a4
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/ciphertext2
@@ -0,0 +1 @@
+Vli8Hau3xL8oder6ZdM9Y3fMd92jbguiMq6F+9CUjlUQXy5EwAVGeg==
diff --git a/nss/cmd/bltest/tests/ecdsa/ciphertext20 b/nss/cmd/bltest/tests/ecdsa/ciphertext20
new file mode 100644
index 0000000..67c9924
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/ciphertext20
@@ -0,0 +1,3 @@
+ALAM5hGnex7TvBbSEzDlfv+n5g7aWyRyZsBbl2Y6wW1plSovbq2GcV6w1ZV1Vlot
+70zbqkKyNApvTi3xoD4Ens6pAeLMYDILwaQhnyJZWQv3etbWqUKJZNgfH1IDj03k
+n9hbjYLX3y4bc4CnrhOiv5Ab34s7M8wUYcjC+DbHwhLl/S6N
diff --git a/nss/cmd/bltest/tests/ecdsa/ciphertext3 b/nss/cmd/bltest/tests/ecdsa/ciphertext3
new file mode 100644
index 0000000..e9a4808
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/ciphertext3
@@ -0,0 +1 @@
+AFohw5TN/dpmqbhp/T4z1Rl1boAUA6r9eEPJbYN0zf+eHZzyvezxqjxU
diff --git a/nss/cmd/bltest/tests/ecdsa/ciphertext4 b/nss/cmd/bltest/tests/ecdsa/ciphertext4
new file mode 100644
index 0000000..57ce239
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/ciphertext4
@@ -0,0 +1 @@
+AtJdCPXn5yQW34jekhsnsNmaMOeeA3KIVl1d2+7pb6QycUAzYccgwSrp
diff --git a/nss/cmd/bltest/tests/ecdsa/ciphertext5 b/nss/cmd/bltest/tests/ecdsa/ciphertext5
new file mode 100644
index 0000000..e476c80
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/ciphertext5
@@ -0,0 +1 @@
+AzEg0sOGHwxd0o3cv+o9dsRPOzXMAdpgtI6O0uUmVN2+a5qI5FYQlItz
diff --git a/nss/cmd/bltest/tests/ecdsa/ciphertext6 b/nss/cmd/bltest/tests/ecdsa/ciphertext6
new file mode 100644
index 0000000..bdea717
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/ciphertext6
@@ -0,0 +1 @@
+5+HDXH/ieN8Bzxd3dfxKZoqbbhsm7jyeqWdemt6Xy0kx+7zwSYsh9Ng5KRdy6wtA
diff --git a/nss/cmd/bltest/tests/ecdsa/ciphertext7 b/nss/cmd/bltest/tests/ecdsa/ciphertext7
new file mode 100644
index 0000000..3273fd9
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/ciphertext7
@@ -0,0 +1 @@
+WcS9umnUASP0X6lHvkWJwPY37ZVvAMLBERHLjL3Vzg6QVjwcS8kDVortTFei3aTx
diff --git a/nss/cmd/bltest/tests/ecdsa/ciphertext8 b/nss/cmd/bltest/tests/ecdsa/ciphertext8
new file mode 100644
index 0000000..636392e
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/ciphertext8
@@ -0,0 +1,2 @@
+ItpmPaGAaoe2feXPbh5+EASLGnEzyYbEnwJ+JFNSOQcoY4a/cMV2rn8FYyBsEDiZ
+LPDBU0i2uOg=
diff --git a/nss/cmd/bltest/tests/ecdsa/ciphertext9 b/nss/cmd/bltest/tests/ecdsa/ciphertext9
new file mode 100644
index 0000000..0c43fa3
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/ciphertext9
@@ -0,0 +1,2 @@
+QjzCVGRUjulOLqeBqC5xpY0GWomOrmQUCtImY0czn98a/jHrdgsSRKiMHukBUxM1
+TIRGjkV2L+A=
diff --git a/nss/cmd/bltest/tests/ecdsa/key0 b/nss/cmd/bltest/tests/ecdsa/key0
new file mode 100644
index 0000000..491fdba
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/key0
@@ -0,0 +1,3 @@
+AAAACgYIKoZIzj0DAQcAAABBBNGB7n4kH15tKA/SMpetaQVqg6WxIuuUuMQT2tDX
+NN5jKZfaxD47NsTjTr3x3D5t1qRBYuL6VtdgIuxBIHGG9dcAAAAgaGjyZBL+LN3a
+7NkGiHJBfqh7XKNH0AnPF3vFWpostIQ=
diff --git a/nss/cmd/bltest/tests/ecdsa/key1 b/nss/cmd/bltest/tests/ecdsa/key1
new file mode 100644
index 0000000..a062f1f
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/key1
@@ -0,0 +1,4 @@
+AAAABwYFK4EEACIAAABhBLWMJG3t4khPYcsl3H492rAqukJ1RqJm27pqpN54rFGG
+r2VDwOfqb9tMninq8IyOh42eaaVOEPXXu4Q/ATWBEfrbTRBjTpzAE2SSPuQma0lM
+q0RSVECCgdBOKIhB0H6VxAAAADA3WPjUaMWCS9E5KbVDrEcf5CV5tCNNWJQkwjsA
+yALMCiXJqRVXwbq42WMuaELMW+g=
diff --git a/nss/cmd/bltest/tests/ecdsa/key10 b/nss/cmd/bltest/tests/ecdsa/key10
new file mode 100644
index 0000000..3e33417
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/key10
@@ -0,0 +1,3 @@
+AAAABwYFK4EEABoAAAA9BACmzalMQJBOWV2FoyV0tXSpT07Xajq4bB1SUwSY7QGn
+dgGC3GBqjPs9vEpqfMMQ2M9k3+5oubWnexNFhQAAAB4BRha/6sE7VSHl92ZqCj5p
+LYtBpK23jzfdVWO8SAY=
diff --git a/nss/cmd/bltest/tests/ecdsa/key11 b/nss/cmd/bltest/tests/ecdsa/key11
new file mode 100644
index 0000000..6111d52
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/key11
@@ -0,0 +1,3 @@
+AAAABwYFK4EEABsAAAA9BAD2/x9HSYYVEQ9AU4MivlIKPypJjsm0sTrp8BftlQGv
+KaYrKpZCg/CEw3C2kqvke7HAu+10hafK9asRxQAAAB4AXyFCurtsXhahkyJpkb5J
+LUg3xVL00vviR0KyFZY=
diff --git a/nss/cmd/bltest/tests/ecdsa/key12 b/nss/cmd/bltest/tests/ecdsa/key12
new file mode 100644
index 0000000..491fdba
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/key12
@@ -0,0 +1,3 @@
+AAAACgYIKoZIzj0DAQcAAABBBNGB7n4kH15tKA/SMpetaQVqg6WxIuuUuMQT2tDX
+NN5jKZfaxD47NsTjTr3x3D5t1qRBYuL6VtdgIuxBIHGG9dcAAAAgaGjyZBL+LN3a
+7NkGiHJBfqh7XKNH0AnPF3vFWpostIQ=
diff --git a/nss/cmd/bltest/tests/ecdsa/key13 b/nss/cmd/bltest/tests/ecdsa/key13
new file mode 100644
index 0000000..fc8057a
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/key13
@@ -0,0 +1,3 @@
+AAAABwYFK4EEABAAAABJBAT3klWkt7+1Pr6QGEcvEIZplopwt1alrsJUThDOxvUF
+7KvBpQLVjB+DQTwYQnEREb/WFyRgUBuIbII0+zd/g0fLHE4PQ8SNlAAAACQFPsMX
+mqSVRreUVasUOIZQFB2jnpwCUyoq+xa9SRril5LeOCY=
diff --git a/nss/cmd/bltest/tests/ecdsa/key14 b/nss/cmd/bltest/tests/ecdsa/key14
new file mode 100644
index 0000000..2e15823
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/key14
@@ -0,0 +1,3 @@
+AAAABwYFK4EEABEAAABJBAf/ei/XCrFrMZLBp5BFkKZ3Odn+ZJu7QIAK32Ubuxmi
+xgWTewf2vv+KY5kHwsBYuBXmmnKe9Ak9zGP4Lykvgk5n5J6iUz5ycQAAACQAQHXa
+d29OqGxoDNCl9xETW3tAL/2hfZzstNuOPLm5kj4j1Dc=
diff --git a/nss/cmd/bltest/tests/ecdsa/key15 b/nss/cmd/bltest/tests/ecdsa/key15
new file mode 100644
index 0000000..a062f1f
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/key15
@@ -0,0 +1,4 @@
+AAAABwYFK4EEACIAAABhBLWMJG3t4khPYcsl3H492rAqukJ1RqJm27pqpN54rFGG
+r2VDwOfqb9tMninq8IyOh42eaaVOEPXXu4Q/ATWBEfrbTRBjTpzAE2SSPuQma0lM
+q0RSVECCgdBOKIhB0H6VxAAAADA3WPjUaMWCS9E5KbVDrEcf5CV5tCNNWJQkwjsA
+yALMCiXJqRVXwbq42WMuaELMW+g=
diff --git a/nss/cmd/bltest/tests/ecdsa/key16 b/nss/cmd/bltest/tests/ecdsa/key16
new file mode 100644
index 0000000..d2694ae
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/key16
@@ -0,0 +1,4 @@
+AAAABwYFK4EEACQAAABpBADkgknFgTPuirxQxFlqIK+vcARWzlpJR+qmyRyQsBiz
+Nh6Ws036xUKY9M8LxMIWXFNM6aIA2wxKsBF+HHD6oy27EAJSJOGbke/9F9Kv5AiW
+2RXA4mllUaxCNsuQ36PqUdqv4FeXxWTpAAAANAHTZloqhR0V4bfyaeo2hojcvY3T
+NO04ewNryBpsHZ0bhID0EfewYuwQmX00GYNfuV3mJ2w=
diff --git a/nss/cmd/bltest/tests/ecdsa/key17 b/nss/cmd/bltest/tests/ecdsa/key17
new file mode 100644
index 0000000..30be057
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/key17
@@ -0,0 +1,4 @@
+AAAABwYFK4EEACUAAABpBAAEE/bAmqCjO3FLvN93Q/UjDyDp2sj+F//buuf1hZ0K
+1rSOGXMLcBrqVa8R6UJ57F9/Yc0BCTylpJMXjfCr4eDczG4WOQk+5x8kpKQs5Q9U
+V3IolHDiQY/Nhn7o4UFn5/mF71T3qUqwAAAANAH/o7jEl9Bw+Arj9uQ7ZHkoPGgx
+t92UJg1r/lxa7UUd66iJfRI8n8yQH/sw56D1+CweeII=
diff --git a/nss/cmd/bltest/tests/ecdsa/key18 b/nss/cmd/bltest/tests/ecdsa/key18
new file mode 100644
index 0000000..bbdcb13
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/key18
@@ -0,0 +1,5 @@
+AAAABwYFK4EEACYAAACRBAffZTrfwIl0dciO2fui3UhZw6r+jnFh7gyER92gXL7+
+LzPgTHagd1vdQiIX4K8Dv76KN0BldiFuX5odP7qC26MUaiURDdWT0AWcPmumSSBH
+NXZYLLx5hQjW3BTNwV7v5bmUjezfgtuOCC30dQGs2GMgExAmiWRjTkiPrHg1SFKF
+3RklauOyMWauaVpEzh3c+wAAAEgAZvLs4/Rx7tS+QGH92fGGIxPWPbVYOpDKwabY
+poV2i1BD5Fxvw+eHlvxVOLmRPqRCPTfOLwAeNbHyt17U/BVZ8+svTChlzuA=
diff --git a/nss/cmd/bltest/tests/ecdsa/key19 b/nss/cmd/bltest/tests/ecdsa/key19
new file mode 100644
index 0000000..31b4071
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/key19
@@ -0,0 +1,5 @@
+AAAABwYFK4EEACcAAACRBASpPvOfQVqiMD+cBL/nulFit5pk/5beJ6/KpeIltg4s
+6/s7PPggJA59BP7RJwak6rgY3PsRqXVPjyM/1UkUfRUR2BJgOfNTkQe9WF7Y5zXy
+TM76cWhOP+sLSoUcscy/HTLCpHqRLLvWZPDzgjrfJqSlydMEDZjWsJRVPk9IfeQ/
+amGiWOhJIQd/bSrAazZn6AAAAEgFz1qZzjHuhuP1boJ7gzndJhQslx1efbESxHSc
+wbOpeBpw2MsCAwjtgo3Y8pviFIC8+5MStkFjE8uHQ0ngXc02wm3G0xj8XGQ=
diff --git a/nss/cmd/bltest/tests/ecdsa/key2 b/nss/cmd/bltest/tests/ecdsa/key2
new file mode 100644
index 0000000..c4da348
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/key2
@@ -0,0 +1,5 @@
+AAAABwYFK4EEACMAAACFBAHLMSpMFVyG6mXE7SZ5O5Bwv4d8/QiAB3BzpXkyrU1W
+jJ9O9uOYTXM+cFtF5v56+LsI4yGkaAl9+RF6lFPjrhpIswCmBmEqMBgZpjoz38my
+nLHBI9MaFF8AHkRQwD3LJLo4eSZHOVkdIvDYLwicdlgr0zD3Nf76/HB1+0DkBGqE
+MyG22gAAAEIAFah7z179UbqqdH68pzdZsP1ChXjtYZ11rBM0+HP7yLirxH3ahKTt
+DjsY19GEjz4gKsaLfLiQ1/Dp+VKVLcBKpk0=
diff --git a/nss/cmd/bltest/tests/ecdsa/key20 b/nss/cmd/bltest/tests/ecdsa/key20
new file mode 100644
index 0000000..c4da348
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/key20
@@ -0,0 +1,5 @@
+AAAABwYFK4EEACMAAACFBAHLMSpMFVyG6mXE7SZ5O5Bwv4d8/QiAB3BzpXkyrU1W
+jJ9O9uOYTXM+cFtF5v56+LsI4yGkaAl9+RF6lFPjrhpIswCmBmEqMBgZpjoz38my
+nLHBI9MaFF8AHkRQwD3LJLo4eSZHOVkdIvDYLwicdlgr0zD3Nf76/HB1+0DkBGqE
+MyG22gAAAEIAFah7z179UbqqdH68pzdZsP1ChXjtYZ11rBM0+HP7yLirxH3ahKTt
+DjsY19GEjz4gKsaLfLiQ1/Dp+VKVLcBKpk0=
diff --git a/nss/cmd/bltest/tests/ecdsa/key3 b/nss/cmd/bltest/tests/ecdsa/key3
new file mode 100644
index 0000000..689e06b
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/key3
@@ -0,0 +1,2 @@
+AAAABwYFK4EEAAEAAAArBAe4qW9DTVGRVIYYznwJZbn8mWXLugA2A+Mv112Bu+y7
+gxI8E4/fEdLTsQAAABUGEQDNcbxi0JhwALA8FCCxvmWYM3E=
diff --git a/nss/cmd/bltest/tests/ecdsa/key4 b/nss/cmd/bltest/tests/ecdsa/key4
new file mode 100644
index 0000000..90ecb72
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/key4
@@ -0,0 +1,2 @@
+AAAABwYFK4EEAAIAAAArBAXw45Pc59l1QWmAB1W6M30lyFzQmAH/0FIFKYgEOYIa
+dnEXMwKNwaRdsQAAABUCErj052f+Rth5OxAm376LOAQyvBY=
diff --git a/nss/cmd/bltest/tests/ecdsa/key5 b/nss/cmd/bltest/tests/ecdsa/key5
new file mode 100644
index 0000000..b9d221f
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/key5
@@ -0,0 +1,2 @@
+AAAABwYFK4EEAA8AAAArBAFhm71N2wsUOYCwDNr/6rFvNX1okAbki1SNlHq2TQDO
+Bktd1M0jlApWVQAAABUCILsraWg3Qi5nBsXQ1pGmZk0YuSA=
diff --git a/nss/cmd/bltest/tests/ecdsa/key6 b/nss/cmd/bltest/tests/ecdsa/key6
new file mode 100644
index 0000000..92fb463
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/key6
@@ -0,0 +1,2 @@
+AAAABwYFK4EEAB8AAAAxBHOYACoc9XsLk5n8NZZKV2U9CDoMj/VRDvqbf+myloR7
+uBfVNm+uVN33Sa65phAfXQAAABitxs6KZtkqU4tglcdQ1Rmk2U74vjYP0JM=
diff --git a/nss/cmd/bltest/tests/ecdsa/key7 b/nss/cmd/bltest/tests/ecdsa/key7
new file mode 100644
index 0000000..83fced1
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/key7
@@ -0,0 +1,2 @@
+AAAACgYIKoZIzj0DAQEAAAAxBOyOI+rIs3x+jsChxQqSVblnoZGqhIM1WX0FMfw+
+D8Dz6Y25iPcAQFpIAWh29FxnrgAAABh+uEQYXwMB783sULxE6PEd1t/MNZ9HSHI=
diff --git a/nss/cmd/bltest/tests/ecdsa/key8 b/nss/cmd/bltest/tests/ecdsa/key8
new file mode 100644
index 0000000..cc7c610
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/key8
@@ -0,0 +1,3 @@
+AAAABwYFK4EEACAAAAA5BKQnZoj4VtlPqrJ5dekM4haG+7PjfgO4wNNIqD7JnrKI
+gTUd+oUQ41d517xCObyBaHNzdVPty9DvAAAAHIrG9+FE+OJV5UV2l/op7PCDPI4G
+qkpgzPIwe7U=
diff --git a/nss/cmd/bltest/tests/ecdsa/key9 b/nss/cmd/bltest/tests/ecdsa/key9
new file mode 100644
index 0000000..ab8f43b
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/key9
@@ -0,0 +1,3 @@
+AAAABwYFK4EEACEAAAA5BGCNDWldzQCbI83PMR96tqR6JnIUpvfIO8l6hIf/QfMc
+rx2BbrSLoy6EJmP++Jyw5yNyaoVaNYl6AAAAHDnjgcUSIshTSLuejnSsvtvU363b
+1NJv4ULUbIs=
diff --git a/nss/cmd/bltest/tests/ecdsa/numtests b/nss/cmd/bltest/tests/ecdsa/numtests
new file mode 100644
index 0000000..aabe6ec
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/numtests
@@ -0,0 +1 @@
+21
diff --git a/nss/cmd/bltest/tests/ecdsa/plaintext0 b/nss/cmd/bltest/tests/ecdsa/plaintext0
new file mode 100644
index 0000000..48fbdb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/plaintext0
@@ -0,0 +1 @@
+qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
diff --git a/nss/cmd/bltest/tests/ecdsa/plaintext1 b/nss/cmd/bltest/tests/ecdsa/plaintext1
new file mode 100644
index 0000000..48fbdb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/plaintext1
@@ -0,0 +1 @@
+qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
diff --git a/nss/cmd/bltest/tests/ecdsa/plaintext10 b/nss/cmd/bltest/tests/ecdsa/plaintext10
new file mode 100644
index 0000000..48fbdb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/plaintext10
@@ -0,0 +1 @@
+qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
diff --git a/nss/cmd/bltest/tests/ecdsa/plaintext11 b/nss/cmd/bltest/tests/ecdsa/plaintext11
new file mode 100644
index 0000000..48fbdb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/plaintext11
@@ -0,0 +1 @@
+qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
diff --git a/nss/cmd/bltest/tests/ecdsa/plaintext12 b/nss/cmd/bltest/tests/ecdsa/plaintext12
new file mode 100644
index 0000000..48fbdb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/plaintext12
@@ -0,0 +1 @@
+qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
diff --git a/nss/cmd/bltest/tests/ecdsa/plaintext13 b/nss/cmd/bltest/tests/ecdsa/plaintext13
new file mode 100644
index 0000000..48fbdb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/plaintext13
@@ -0,0 +1 @@
+qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
diff --git a/nss/cmd/bltest/tests/ecdsa/plaintext14 b/nss/cmd/bltest/tests/ecdsa/plaintext14
new file mode 100644
index 0000000..48fbdb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/plaintext14
@@ -0,0 +1 @@
+qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
diff --git a/nss/cmd/bltest/tests/ecdsa/plaintext15 b/nss/cmd/bltest/tests/ecdsa/plaintext15
new file mode 100644
index 0000000..48fbdb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/plaintext15
@@ -0,0 +1 @@
+qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
diff --git a/nss/cmd/bltest/tests/ecdsa/plaintext16 b/nss/cmd/bltest/tests/ecdsa/plaintext16
new file mode 100644
index 0000000..48fbdb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/plaintext16
@@ -0,0 +1 @@
+qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
diff --git a/nss/cmd/bltest/tests/ecdsa/plaintext17 b/nss/cmd/bltest/tests/ecdsa/plaintext17
new file mode 100644
index 0000000..48fbdb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/plaintext17
@@ -0,0 +1 @@
+qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
diff --git a/nss/cmd/bltest/tests/ecdsa/plaintext18 b/nss/cmd/bltest/tests/ecdsa/plaintext18
new file mode 100644
index 0000000..48fbdb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/plaintext18
@@ -0,0 +1 @@
+qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
diff --git a/nss/cmd/bltest/tests/ecdsa/plaintext19 b/nss/cmd/bltest/tests/ecdsa/plaintext19
new file mode 100644
index 0000000..48fbdb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/plaintext19
@@ -0,0 +1 @@
+qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
diff --git a/nss/cmd/bltest/tests/ecdsa/plaintext2 b/nss/cmd/bltest/tests/ecdsa/plaintext2
new file mode 100644
index 0000000..48fbdb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/plaintext2
@@ -0,0 +1 @@
+qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
diff --git a/nss/cmd/bltest/tests/ecdsa/plaintext20 b/nss/cmd/bltest/tests/ecdsa/plaintext20
new file mode 100644
index 0000000..48fbdb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/plaintext20
@@ -0,0 +1 @@
+qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
diff --git a/nss/cmd/bltest/tests/ecdsa/plaintext3 b/nss/cmd/bltest/tests/ecdsa/plaintext3
new file mode 100644
index 0000000..48fbdb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/plaintext3
@@ -0,0 +1 @@
+qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
diff --git a/nss/cmd/bltest/tests/ecdsa/plaintext4 b/nss/cmd/bltest/tests/ecdsa/plaintext4
new file mode 100644
index 0000000..48fbdb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/plaintext4
@@ -0,0 +1 @@
+qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
diff --git a/nss/cmd/bltest/tests/ecdsa/plaintext5 b/nss/cmd/bltest/tests/ecdsa/plaintext5
new file mode 100644
index 0000000..48fbdb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/plaintext5
@@ -0,0 +1 @@
+qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
diff --git a/nss/cmd/bltest/tests/ecdsa/plaintext6 b/nss/cmd/bltest/tests/ecdsa/plaintext6
new file mode 100644
index 0000000..48fbdb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/plaintext6
@@ -0,0 +1 @@
+qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
diff --git a/nss/cmd/bltest/tests/ecdsa/plaintext7 b/nss/cmd/bltest/tests/ecdsa/plaintext7
new file mode 100644
index 0000000..48fbdb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/plaintext7
@@ -0,0 +1 @@
+qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
diff --git a/nss/cmd/bltest/tests/ecdsa/plaintext8 b/nss/cmd/bltest/tests/ecdsa/plaintext8
new file mode 100644
index 0000000..48fbdb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/plaintext8
@@ -0,0 +1 @@
+qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
diff --git a/nss/cmd/bltest/tests/ecdsa/plaintext9 b/nss/cmd/bltest/tests/ecdsa/plaintext9
new file mode 100644
index 0000000..48fbdb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/plaintext9
@@ -0,0 +1 @@
+qZk+NkcGgWq6PiVxeFDCbJzQ2J0=
diff --git a/nss/cmd/bltest/tests/ecdsa/sigseed0 b/nss/cmd/bltest/tests/ecdsa/sigseed0
new file mode 100644
index 0000000..05d7fd2
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/sigseed0
@@ -0,0 +1 @@
+aHpm2QZI+ZOGfhIfTd+d2wEgVYQ=
diff --git a/nss/cmd/bltest/tests/ecdsa/sigseed1 b/nss/cmd/bltest/tests/ecdsa/sigseed1
new file mode 100644
index 0000000..05d7fd2
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/sigseed1
@@ -0,0 +1 @@
+aHpm2QZI+ZOGfhIfTd+d2wEgVYQ=
diff --git a/nss/cmd/bltest/tests/ecdsa/sigseed10 b/nss/cmd/bltest/tests/ecdsa/sigseed10
new file mode 100644
index 0000000..6983e5f
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/sigseed10
@@ -0,0 +1 @@
+fjIzMWJpdHNPZlRleHQwMTAyMDMwNDA1MDYwNzA=
diff --git a/nss/cmd/bltest/tests/ecdsa/sigseed11 b/nss/cmd/bltest/tests/ecdsa/sigseed11
new file mode 100644
index 0000000..6983e5f
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/sigseed11
@@ -0,0 +1 @@
+fjIzMWJpdHNPZlRleHQwMTAyMDMwNDA1MDYwNzA=
diff --git a/nss/cmd/bltest/tests/ecdsa/sigseed12 b/nss/cmd/bltest/tests/ecdsa/sigseed12
new file mode 100644
index 0000000..92aa40c
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/sigseed12
@@ -0,0 +1 @@
+/jI1NmJpdHNPZlRleHQwMTAyMDMwNDA1MDYwNzA4MDk=
diff --git a/nss/cmd/bltest/tests/ecdsa/sigseed13 b/nss/cmd/bltest/tests/ecdsa/sigseed13
new file mode 100644
index 0000000..4ac0765
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/sigseed13
@@ -0,0 +1 @@
+ATI4MWJpdHNPZlRleHQwMTAyMDMwNDA1MDYwNzA4MDkwYTBi
diff --git a/nss/cmd/bltest/tests/ecdsa/sigseed14 b/nss/cmd/bltest/tests/ecdsa/sigseed14
new file mode 100644
index 0000000..4ac0765
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/sigseed14
@@ -0,0 +1 @@
+ATI4MWJpdHNPZlRleHQwMTAyMDMwNDA1MDYwNzA4MDkwYTBi
diff --git a/nss/cmd/bltest/tests/ecdsa/sigseed15 b/nss/cmd/bltest/tests/ecdsa/sigseed15
new file mode 100644
index 0000000..0975230
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/sigseed15
@@ -0,0 +1 @@
+/jM4NGJpdHNPZlRleHQwMTAyMDMwNDA1MDYwNzA4MDkwYTBiMGMwZDBlMGYxMDEx
diff --git a/nss/cmd/bltest/tests/ecdsa/sigseed16 b/nss/cmd/bltest/tests/ecdsa/sigseed16
new file mode 100644
index 0000000..36fbf09
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/sigseed16
@@ -0,0 +1 @@
+fjQwN2JpdHNPZlRleHQwMTAyMDMwNDA1MDYwNzA4MDkwYTBiMGMwZDBlMGYxMDExMTIx
diff --git a/nss/cmd/bltest/tests/ecdsa/sigseed17 b/nss/cmd/bltest/tests/ecdsa/sigseed17
new file mode 100644
index 0000000..36fbf09
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/sigseed17
@@ -0,0 +1 @@
+fjQwN2JpdHNPZlRleHQwMTAyMDMwNDA1MDYwNzA4MDkwYTBiMGMwZDBlMGYxMDExMTIx
diff --git a/nss/cmd/bltest/tests/ecdsa/sigseed18 b/nss/cmd/bltest/tests/ecdsa/sigseed18
new file mode 100644
index 0000000..7be8ce6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/sigseed18
@@ -0,0 +1,2 @@
+PjU2NmJpdHNPZlRleHQwMDAxMDIwMzA0MDUwNjA3MDgwOTBhMGIwYzBkMGUwZjEwMTExMjEz
+MTQxNTE2MTcxODE5MWExYjE=
diff --git a/nss/cmd/bltest/tests/ecdsa/sigseed19 b/nss/cmd/bltest/tests/ecdsa/sigseed19
new file mode 100644
index 0000000..7be8ce6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/sigseed19
@@ -0,0 +1,2 @@
+PjU2NmJpdHNPZlRleHQwMDAxMDIwMzA0MDUwNjA3MDgwOTBhMGIwYzBkMGUwZjEwMTExMjEz
+MTQxNTE2MTcxODE5MWExYjE=
diff --git a/nss/cmd/bltest/tests/ecdsa/sigseed2 b/nss/cmd/bltest/tests/ecdsa/sigseed2
new file mode 100644
index 0000000..05d7fd2
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/sigseed2
@@ -0,0 +1 @@
+aHpm2QZI+ZOGfhIfTd+d2wEgVYQ=
diff --git a/nss/cmd/bltest/tests/ecdsa/sigseed20 b/nss/cmd/bltest/tests/ecdsa/sigseed20
new file mode 100644
index 0000000..f0dddb6
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/sigseed20
@@ -0,0 +1,2 @@
+/jUyMGJpdHNPZlRleHQwMDAxMDIwMzA0MDUwNjA3MDgwOTBhMGIwYzBkMGUwZjEwMTExMjEz
+MTQxNTE2MTcxODE=
diff --git a/nss/cmd/bltest/tests/ecdsa/sigseed3 b/nss/cmd/bltest/tests/ecdsa/sigseed3
new file mode 100644
index 0000000..05d7fd2
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/sigseed3
@@ -0,0 +1 @@
+aHpm2QZI+ZOGfhIfTd+d2wEgVYQ=
diff --git a/nss/cmd/bltest/tests/ecdsa/sigseed4 b/nss/cmd/bltest/tests/ecdsa/sigseed4
new file mode 100644
index 0000000..05d7fd2
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/sigseed4
@@ -0,0 +1 @@
+aHpm2QZI+ZOGfhIfTd+d2wEgVYQ=
diff --git a/nss/cmd/bltest/tests/ecdsa/sigseed5 b/nss/cmd/bltest/tests/ecdsa/sigseed5
new file mode 100644
index 0000000..05d7fd2
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/sigseed5
@@ -0,0 +1 @@
+aHpm2QZI+ZOGfhIfTd+d2wEgVYQ=
diff --git a/nss/cmd/bltest/tests/ecdsa/sigseed6 b/nss/cmd/bltest/tests/ecdsa/sigseed6
new file mode 100644
index 0000000..a068719
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/sigseed6
@@ -0,0 +1 @@
+/jE5MmJpdHNPZlRleHQwMDAwMDAwMDAw
diff --git a/nss/cmd/bltest/tests/ecdsa/sigseed7 b/nss/cmd/bltest/tests/ecdsa/sigseed7
new file mode 100644
index 0000000..a068719
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/sigseed7
@@ -0,0 +1 @@
+/jE5MmJpdHNPZlRleHQwMDAwMDAwMDAw
diff --git a/nss/cmd/bltest/tests/ecdsa/sigseed8 b/nss/cmd/bltest/tests/ecdsa/sigseed8
new file mode 100644
index 0000000..01ae265
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/sigseed8
@@ -0,0 +1 @@
+/jIyNGJpdHNPZlRleHQwMDAwMDAwMDAwMDAwMA==
diff --git a/nss/cmd/bltest/tests/ecdsa/sigseed9 b/nss/cmd/bltest/tests/ecdsa/sigseed9
new file mode 100644
index 0000000..01ae265
--- /dev/null
+++ b/nss/cmd/bltest/tests/ecdsa/sigseed9
@@ -0,0 +1 @@
+/jIyNGJpdHNPZlRleHQwMDAwMDAwMDAwMDAwMA==
diff --git a/nss/cmd/bltest/tests/md2/ciphertext0 b/nss/cmd/bltest/tests/md2/ciphertext0
new file mode 100644
index 0000000..22e1fc4
--- /dev/null
+++ b/nss/cmd/bltest/tests/md2/ciphertext0
@@ -0,0 +1 @@
+CS/UNcrWhB5Knt7Gf8Tz3Q==
diff --git a/nss/cmd/bltest/tests/md2/numtests b/nss/cmd/bltest/tests/md2/numtests
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/nss/cmd/bltest/tests/md2/numtests
@@ -0,0 +1 @@
+1
diff --git a/nss/cmd/bltest/tests/md2/plaintext0 b/nss/cmd/bltest/tests/md2/plaintext0
new file mode 100644
index 0000000..dce2994
--- /dev/null
+++ b/nss/cmd/bltest/tests/md2/plaintext0
@@ -0,0 +1 @@
+16-bytes to MD2.
diff --git a/nss/cmd/bltest/tests/md5/ciphertext0 b/nss/cmd/bltest/tests/md5/ciphertext0
new file mode 100644
index 0000000..ea11ee5
--- /dev/null
+++ b/nss/cmd/bltest/tests/md5/ciphertext0
@@ -0,0 +1 @@
+XN8lnQuWAiMqmSGfvd8Hdw==
diff --git a/nss/cmd/bltest/tests/md5/numtests b/nss/cmd/bltest/tests/md5/numtests
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/nss/cmd/bltest/tests/md5/numtests
@@ -0,0 +1 @@
+1
diff --git a/nss/cmd/bltest/tests/md5/plaintext0 b/nss/cmd/bltest/tests/md5/plaintext0
new file mode 100644
index 0000000..5ae3875
--- /dev/null
+++ b/nss/cmd/bltest/tests/md5/plaintext0
@@ -0,0 +1 @@
+63-byte input to MD5 can be a bit tricky, but no problems here.
diff --git a/nss/cmd/bltest/tests/rc2_cbc/ciphertext0 b/nss/cmd/bltest/tests/rc2_cbc/ciphertext0
new file mode 100644
index 0000000..d964ef8
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc2_cbc/ciphertext0
@@ -0,0 +1 @@
+3ki6eVsWpY8=
diff --git a/nss/cmd/bltest/tests/rc2_cbc/iv0 b/nss/cmd/bltest/tests/rc2_cbc/iv0
new file mode 100644
index 0000000..97b5955
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc2_cbc/iv0
@@ -0,0 +1 @@
+12345678
diff --git a/nss/cmd/bltest/tests/rc2_cbc/key0 b/nss/cmd/bltest/tests/rc2_cbc/key0
new file mode 100644
index 0000000..65513c1
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc2_cbc/key0
@@ -0,0 +1 @@
+zyxwvuts
diff --git a/nss/cmd/bltest/tests/rc2_cbc/numtests b/nss/cmd/bltest/tests/rc2_cbc/numtests
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc2_cbc/numtests
@@ -0,0 +1 @@
+1
diff --git a/nss/cmd/bltest/tests/rc2_cbc/plaintext0 b/nss/cmd/bltest/tests/rc2_cbc/plaintext0
new file mode 100644
index 0000000..5513e43
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc2_cbc/plaintext0
@@ -0,0 +1 @@
+Mozilla!
diff --git a/nss/cmd/bltest/tests/rc2_ecb/ciphertext0 b/nss/cmd/bltest/tests/rc2_ecb/ciphertext0
new file mode 100644
index 0000000..337d307
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc2_ecb/ciphertext0
@@ -0,0 +1 @@
+WT+tc4fANhQ=
diff --git a/nss/cmd/bltest/tests/rc2_ecb/key0 b/nss/cmd/bltest/tests/rc2_ecb/key0
new file mode 100644
index 0000000..65513c1
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc2_ecb/key0
@@ -0,0 +1 @@
+zyxwvuts
diff --git a/nss/cmd/bltest/tests/rc2_ecb/numtests b/nss/cmd/bltest/tests/rc2_ecb/numtests
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc2_ecb/numtests
@@ -0,0 +1 @@
+1
diff --git a/nss/cmd/bltest/tests/rc2_ecb/plaintext0 b/nss/cmd/bltest/tests/rc2_ecb/plaintext0
new file mode 100644
index 0000000..5513e43
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc2_ecb/plaintext0
@@ -0,0 +1 @@
+Mozilla!
diff --git a/nss/cmd/bltest/tests/rc4/ciphertext0 b/nss/cmd/bltest/tests/rc4/ciphertext0
new file mode 100644
index 0000000..004f134
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc4/ciphertext0
@@ -0,0 +1 @@
+34sTZJtr20k=
diff --git a/nss/cmd/bltest/tests/rc4/ciphertext1 b/nss/cmd/bltest/tests/rc4/ciphertext1
new file mode 100644
index 0000000..6050da4
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc4/ciphertext1
@@ -0,0 +1 @@
+34sTZJtr20nGP6VxS3BIBxxIYm6QGIa1rehFHn51z9M=
diff --git a/nss/cmd/bltest/tests/rc4/key0 b/nss/cmd/bltest/tests/rc4/key0
new file mode 100644
index 0000000..65513c1
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc4/key0
@@ -0,0 +1 @@
+zyxwvuts
diff --git a/nss/cmd/bltest/tests/rc4/key1 b/nss/cmd/bltest/tests/rc4/key1
new file mode 100644
index 0000000..65513c1
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc4/key1
@@ -0,0 +1 @@
+zyxwvuts
diff --git a/nss/cmd/bltest/tests/rc4/numtests b/nss/cmd/bltest/tests/rc4/numtests
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc4/numtests
@@ -0,0 +1 @@
+2
diff --git a/nss/cmd/bltest/tests/rc4/plaintext0 b/nss/cmd/bltest/tests/rc4/plaintext0
new file mode 100644
index 0000000..5513e43
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc4/plaintext0
@@ -0,0 +1 @@
+Mozilla!
diff --git a/nss/cmd/bltest/tests/rc4/plaintext1 b/nss/cmd/bltest/tests/rc4/plaintext1
new file mode 100644
index 0000000..d41abc7
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc4/plaintext1
@@ -0,0 +1 @@
+Mozilla!Mozilla!Mozilla!Mozilla!
diff --git a/nss/cmd/bltest/tests/rc5_cbc/ciphertext0 b/nss/cmd/bltest/tests/rc5_cbc/ciphertext0
new file mode 100644
index 0000000..544713b
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc5_cbc/ciphertext0
@@ -0,0 +1 @@
+qsv4Fn2J6d0=
diff --git a/nss/cmd/bltest/tests/rc5_cbc/iv0 b/nss/cmd/bltest/tests/rc5_cbc/iv0
new file mode 100644
index 0000000..97b5955
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc5_cbc/iv0
@@ -0,0 +1 @@
+12345678
diff --git a/nss/cmd/bltest/tests/rc5_cbc/key0 b/nss/cmd/bltest/tests/rc5_cbc/key0
new file mode 100644
index 0000000..65513c1
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc5_cbc/key0
@@ -0,0 +1 @@
+zyxwvuts
diff --git a/nss/cmd/bltest/tests/rc5_cbc/numtests b/nss/cmd/bltest/tests/rc5_cbc/numtests
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc5_cbc/numtests
@@ -0,0 +1 @@
+1
diff --git a/nss/cmd/bltest/tests/rc5_cbc/params0 b/nss/cmd/bltest/tests/rc5_cbc/params0
new file mode 100644
index 0000000..d68e036
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc5_cbc/params0
@@ -0,0 +1,2 @@
+rounds=10
+wordsize=4
diff --git a/nss/cmd/bltest/tests/rc5_cbc/plaintext0 b/nss/cmd/bltest/tests/rc5_cbc/plaintext0
new file mode 100644
index 0000000..5513e43
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc5_cbc/plaintext0
@@ -0,0 +1 @@
+Mozilla!
diff --git a/nss/cmd/bltest/tests/rc5_ecb/ciphertext0 b/nss/cmd/bltest/tests/rc5_ecb/ciphertext0
new file mode 100644
index 0000000..133777d
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc5_ecb/ciphertext0
@@ -0,0 +1 @@
+4ZKK/1v5Ohc=
diff --git a/nss/cmd/bltest/tests/rc5_ecb/key0 b/nss/cmd/bltest/tests/rc5_ecb/key0
new file mode 100644
index 0000000..65513c1
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc5_ecb/key0
@@ -0,0 +1 @@
+zyxwvuts
diff --git a/nss/cmd/bltest/tests/rc5_ecb/numtests b/nss/cmd/bltest/tests/rc5_ecb/numtests
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc5_ecb/numtests
@@ -0,0 +1 @@
+1
diff --git a/nss/cmd/bltest/tests/rc5_ecb/params0 b/nss/cmd/bltest/tests/rc5_ecb/params0
new file mode 100644
index 0000000..d68e036
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc5_ecb/params0
@@ -0,0 +1,2 @@
+rounds=10
+wordsize=4
diff --git a/nss/cmd/bltest/tests/rc5_ecb/plaintext0 b/nss/cmd/bltest/tests/rc5_ecb/plaintext0
new file mode 100644
index 0000000..5513e43
--- /dev/null
+++ b/nss/cmd/bltest/tests/rc5_ecb/plaintext0
@@ -0,0 +1 @@
+Mozilla!
diff --git a/nss/cmd/bltest/tests/rsa/ciphertext0 b/nss/cmd/bltest/tests/rsa/ciphertext0
new file mode 100644
index 0000000..943ea59
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa/ciphertext0
@@ -0,0 +1 @@
+qPVrXv0y3SC5rY44bIi6GE4Aec8uDpHH7/cCg0FU5as=
diff --git a/nss/cmd/bltest/tests/rsa/key0 b/nss/cmd/bltest/tests/rsa/key0
new file mode 100644
index 0000000..1352fe9
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa/key0
@@ -0,0 +1,4 @@
+AAAAAAAAACC5lyu2K2ro8YGnvOCKaL1sFX1HEIblIVbuMXsa8oeFSwAAAAERAAAA
+IBXVjKwFG6LvPG4WOIjBBzmxGNpkQwDs3W5qZcXVzqahAAAAEOEOH/WnhZCJyM39
+oNfhf18AAAAQ0xvmxqXXs3L62xxogUl9lQAAABAaeiHgqkvy4wiQtG1Gkv/tAAAA
+EMaw2TNu6SFdKFXAYluQdjEAAAAQi0u+IlgKCt/hatGAsTrfzQ==
diff --git a/nss/cmd/bltest/tests/rsa/numtests b/nss/cmd/bltest/tests/rsa/numtests
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa/numtests
@@ -0,0 +1 @@
+1
diff --git a/nss/cmd/bltest/tests/rsa/plaintext0 b/nss/cmd/bltest/tests/rsa/plaintext0
new file mode 100644
index 0000000..d915bc8
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa/plaintext0
@@ -0,0 +1 @@
+512bitsforRSAPublicKeyEncryption
diff --git a/nss/cmd/bltest/tests/rsa_oaep/ciphertext0 b/nss/cmd/bltest/tests/rsa_oaep/ciphertext0
new file mode 100644
index 0000000..7037fa2
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/ciphertext0
@@ -0,0 +1,3 @@
+NU/me0oSbV01/jbHd3kaP3uhPe9ITi05CK/3IvrUaPshaW3pXQvpEcLTF0+K/MIBA197bY5pQC3l
+RRYYwhpTX6nXv8W43Z/CQ/jPkn2zEyLW6IHqqRqZYXDmV6BaJmQm2YyIAD+Ed8EicJSg2foejEAk
+MJzh7My1IQA11HrHLoo=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/ciphertext1 b/nss/cmd/bltest/tests/rsa_oaep/ciphertext1
new file mode 100644
index 0000000..4cece48
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/ciphertext1
@@ -0,0 +1,3 @@
+ZA2xrMWOBWj+VAfl+bcB3/jDyR5xbFNvx/zsbLW3HBFlmI1KJ54Vd9cw/Hopky4/AMgVFSNtjY4x
+AXp6Cd9DUtkEzet5qlg63MMeppikwFKD2rqQib5UkfZ8Gk7kjcdLu+ZkOu+EZnm0yzlaNS1e0RWR
+LfaW/+BwKTKUbXFJK0Q=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/ciphertext10 b/nss/cmd/bltest/tests/rsa_oaep/ciphertext10
new file mode 100644
index 0000000..6007b8d
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/ciphertext10
@@ -0,0 +1,4 @@
+Iyr7ySf6CML2onuH1KXLCcB9wm+uc9c6kFWIOfT9ZtKBuH7HNLziN7oWZpjtgpEGp95pQs1s3OeP
+7Y0uTYFCjmZJDQNiZM75KvlB0+NQVf45geFNKcu5pPZ0cwY7rseaEXn1oXycGDLyg4/X1eWbuWWd
+VtzooBnt7xuzrMxpfMbMenePYKBkx/b11SnGIQJi4APeWD6B4xZ7iZcfuMDhXUT//vibU9jWTdeX
+0Vm1bSsI6lMH6hLCQb1Y1O4nih8u
diff --git a/nss/cmd/bltest/tests/rsa_oaep/ciphertext11 b/nss/cmd/bltest/tests/rsa_oaep/ciphertext11
new file mode 100644
index 0000000..43b65a6
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/ciphertext11
@@ -0,0 +1,4 @@
+Q4zH3AimjaJJ5CUF+Fc7pg4sJ3PVspD0z53/cY6EIIHDg+ZwJKDylZTqmHudJeS3OPKFlw0ZWrs6
+jIBU49eda5yagye6WW8SWeJxJmdHZpB9jVgv86hHYVSSmtsebRI1ssy07I9mO6nMZwqSvr2FPI2/
+acZDbQFvYa3YNulHMkUENCB/n9TEPewqEqlY76Ae/iZpiZteYEwlXFX7cWbeVYnjaVl7sJFowG3V
+2xd+BqF0DrLVyC+uym2S/O6ZMbqf
diff --git a/nss/cmd/bltest/tests/rsa_oaep/ciphertext12 b/nss/cmd/bltest/tests/rsa_oaep/ciphertext12
new file mode 100644
index 0000000..9d0da8a
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/ciphertext12
@@ -0,0 +1,5 @@
+U+pdwIzSYPs7hYVnKH+pFVLDCy/r+6IT8K6HcC0GjRm6sH/ldFI9+0ITnWjDxa/u4L/ky3lpy/OC
+uATW5hOWFE4tDmB0H4mTwwFLWLmxlXqLq80jr4VPTDVvsWYqpyv8x+WGVZ3EKA0WDBJnhacj6+6+
+/3HxFZRECq74fRB5Ood0ojnUoEyH/hRnudr4UgjsbHJVeUqWzCkUL5qL1Bjjwf1nNEsM0IKd87K+
+xgJTGWKTxrNNP3XTLyE91Fxic9UFrfTM7RBXy3WPwmru+kQSVe1OZMGZ7gdefxZkYYL9tGRzm2ir
+Xa/w5j6VUgFoJPBUv008jJCpe7a2VTKE60KfzA==
diff --git a/nss/cmd/bltest/tests/rsa_oaep/ciphertext13 b/nss/cmd/bltest/tests/rsa_oaep/ciphertext13
new file mode 100644
index 0000000..3ecd857
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/ciphertext13
@@ -0,0 +1,5 @@
+orGkMKnWV+L6HCu17UP/slwFowj+kJPAEDF5X1h0QAEQgorlj7m1gc6d3dPlSa4EoJhUWb3mxiZZ
+TnsF3EJ4sqFGXBNoQIgjyF6W3GbDowmDxjlmT8RWmjf+IeWhlbV3bu0t+NjTYa9obnUCKbvWY/Fh
+hopQYV4MM3vsDKNf7AuxnDbrLgu8wFgvodk6rNsGEGP1nyzh7kNgXl2J7KGD0qzf6fgQEQIq07Q6
+PdQX2slLThHqgbGSlm6WaxgggucZZGB7T4AC82KZhEoR8q4PrqwurnD49PmAiKzc0KxVbp/MxRFS
+GQj60m8ExkIBRQMFd4dYsFOL+LW7FEqCjmKXlQ==
diff --git a/nss/cmd/bltest/tests/rsa_oaep/ciphertext14 b/nss/cmd/bltest/tests/rsa_oaep/ciphertext14
new file mode 100644
index 0000000..09d8a85
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/ciphertext14
@@ -0,0 +1,5 @@
+mIbD5nZKi5qE6EFI69jDsaqAUDgaePZocUwW2c/Spu3FaXnFNdne47RLhcGL6JKJkjcXEUciFtld
+2pjS7oNHybFN/9/4SqSNJawG99fmU5islnsc6Qkl9n3OBJt/gS2wdCmXp01E/oHb4Oej/q8uXECv
+iI1VDdu+O8IGV6KVQ/j8KRO5vRphsqsiVuxAm719wNF3F+olxD9C7Sffhzi/SvxnZv96/whZVV7i
+g5IPTIpjxKc0DLr93DOezbSwUVAC+WyTK1t5Fnr2mcCtP8z98PROhacCYr8uGP40uFBYmXXoZ/+W
+nUjqvyEicVRs3AWmnstSblKHDINvMHvXmHgO3g==
diff --git a/nss/cmd/bltest/tests/rsa_oaep/ciphertext15 b/nss/cmd/bltest/tests/rsa_oaep/ciphertext15
new file mode 100644
index 0000000..bae2acb
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/ciphertext15
@@ -0,0 +1,5 @@
+Yxjp+1wNBeUwfhaDQ26QMpOsRkI1iqoiPXFjATq6h+Lf2o5gxoYOKaHpJoYWPqC5F18ynKOxMaHt
+06d3Wai5e61qT49DlvKM9vOcpYES5IFg1uID2qWFbzrKX/7Vd69JlAjj39Iz4+YE2+NKnEyQgt5l
+UnysYzHSncgOBQig+nEi5/Mp9sylz6NNTR2kF4BUV+AIvsVJ5Hj/nhKnY8R30Vu7ePW2m9V4MPws
+TtaG15vHKpXYX4gTTGsK/laozPvIVYKLszm9F5Cc8dcN4zNa4HA5CT5gbWVTZd5lULhyzW3h1EDu
+AxthlF9imtijU7DUCTnpajxFDSqNXu6fZ4CTyA==
diff --git a/nss/cmd/bltest/tests/rsa_oaep/ciphertext16 b/nss/cmd/bltest/tests/rsa_oaep/ciphertext16
new file mode 100644
index 0000000..6226b0e
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/ciphertext16
@@ -0,0 +1,5 @@
+dSkIcsz9SkUFZg1lH1babaoJyhMB2JBjL2qZLz1WXO5GSv3tQO07W+k1ZxTqWqdlX0oTZsLxfHKP
+byxaXR+OKEKbxOb48s/42o3A4KmAjkX9CeovpAyyts5v//XA4VnRG2jZCoX3uE4QOwnmgmZkgMZX
+UFwJKSWUaKMUeG106rExVzzyNL9X232eZsxnSBkuAC3A3uqTBYXwgx/c2bwz1R957S/8Frz01ZgS
+/OvKo/kGmw5EVobWRMJcz2O0Vu5fpv/pbxnN91H+2erzWVd1Tb9L/qUhaqGETcUHyy0IDnIuuhUD
+CMK1/xGTYg8XZuz0SBuvuUO9KSh38hNspJSroA==
diff --git a/nss/cmd/bltest/tests/rsa_oaep/ciphertext17 b/nss/cmd/bltest/tests/rsa_oaep/ciphertext17
new file mode 100644
index 0000000..9095393
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/ciphertext17
@@ -0,0 +1,5 @@
+LSB6c0Mqj7TAMFGz9zsophdkCY36NMR6IJlfgRWqaBZnm1V+gtvuWEkIxuaXgtfes029Za8GPVf8
+p2pf0GlJL9YGjZmE0gk1BWWmLlx38jA4wSyxDGY0cJtUfEb2tKcJvYXKEi10Rl75d2LCl2Pgbbx6
+nnOMeL/KAQLcXnnWW5c/KCQMqrLhYaeLV9JiRX7YGV1T48eunaAhiDxtt8JK/dIyLqyXKtPDVMX8
+7x4UbDoCkPtnrfAHBm4AQo0s7BjOWPkyhpje/vSy617HaRj94cGYy7OLevxnYmqa7+xDIr/ZDSVj
+SByaIh94yCcsgtG2KrkU4cafavbvMMpSYNtKRg==
diff --git a/nss/cmd/bltest/tests/rsa_oaep/ciphertext2 b/nss/cmd/bltest/tests/rsa_oaep/ciphertext2
new file mode 100644
index 0000000..8eb40cd
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/ciphertext2
@@ -0,0 +1,3 @@
+Qjc27QNfYCavJ2w1wLN0GzZeX3bKCRtOjCni8L7+5gNZWqgyLWAtLmJeleuBsvHJck6CLsp224YY
+zwnFNDUDpDYINbWQO8Y344efsF4O8yaF1a7FBnzXzJb+SyZwturDBmsfz1aGtoWJqvt9YpsC2Phi
+XKODNiTUgA+wgbHPlOs=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/ciphertext3 b/nss/cmd/bltest/tests/rsa_oaep/ciphertext3
new file mode 100644
index 0000000..1e86bb0
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/ciphertext3
@@ -0,0 +1,3 @@
+RerUylUeZiyYAPGsqCg7BSXmq64wvktKunYvpA/T044iq+/Gl5T267vAXduxEhYkfS9BL9D7qHxu
+Os2IiBNkb9DkjnhSBPnD9z1tgjlWJyLd3Ydx/sSLg6Me5vWSxM/UvIgXTzsToRKq47n3uA4Pxvcl
+W6iA3H2AIeIq1qhfB1U=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/ciphertext4 b/nss/cmd/bltest/tests/rsa_oaep/ciphertext4
new file mode 100644
index 0000000..3f87612
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/ciphertext4
@@ -0,0 +1,3 @@
+NvbjTZSo002qy6M6ITnQCthak0WoYFHnMHFiAFa5IOIZAFhVohOg8jiXzc1zG0UlfHd/6QggK+/d
+C1g4axJE6gz1OaBdXRAynaROEwMP12Dc1kTP7yCU0ZENP0M+HHxt0YvB8t9/ZD1mL7ndN+rZBZGQ
+9PpmyjnoacTrRJy9xDk=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/ciphertext5 b/nss/cmd/bltest/tests/rsa_oaep/ciphertext5
new file mode 100644
index 0000000..64a5f4f
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/ciphertext5
@@ -0,0 +1,3 @@
+Qs7iYXsezqTbP0gpOG+9Ydr78DjhgNg3yWNm3yTAl7SrD6xr31kNghyfEGQuaBrQW414s3jA9Gzi
++tY/dOCtPfBrB11+tfVjb41AO5BZynYbXGK7UqpFAC6nC6rOCN7SQ7nYy9YqaK3iZYMrVlZOQ6b6
+Qu0ZmgmXaXQt8VOeglU=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/ciphertext6 b/nss/cmd/bltest/tests/rsa_oaep/ciphertext6
new file mode 100644
index 0000000..9af9805
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/ciphertext6
@@ -0,0 +1,4 @@
+JnvNEYrKsfyLqByF1zADy4YQ+lXB2X2o1Ip8fwaJak23UaooQlW502rWXzdlPYKfGzf5e4ABlCVF
+svwsVac3bKehvksXYMjgWjPlqiUmuNmOMXCI54NMdVsqWbEmMaGCwF1dQ6sXeSZPhFb1Fc5X399R
+LVST2re3M43Et9eNucCRrDuvU3pp/H9UnZefDv+alP2kFpvU0dGaacmeM8O1VJDVAbObHtrhGP9n
+k6FTJhWE06Xzn25oLj0XyM0SYfpy
diff --git a/nss/cmd/bltest/tests/rsa_oaep/ciphertext7 b/nss/cmd/bltest/tests/rsa_oaep/ciphertext7
new file mode 100644
index 0000000..4396ffb
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/ciphertext7
@@ -0,0 +1,4 @@
+k6yfBnHsKay7RE7/waV0E1HWD9sOOT+/dUrPDeSXYaFIQd93cum8gnc5ZqFYTE1yuuoAEY+D81zK
+blN8vU2BH1WDspeD2KbZTNMb5w1vUmwQ/wnG+nzgaXlaP80FEf1fy1ZLzIDqnHjzi4ABJTnYpN32
+/oHpzdt/UNu7vMfl2GCXzPTsSRifuL8xi+bVoHFdUWtJrxkSWM0y3IM85utGc8A6Gbus6IzFSJX2
+NswMHsiQltEc4jWiZcoXZCMqaJro
diff --git a/nss/cmd/bltest/tests/rsa_oaep/ciphertext8 b/nss/cmd/bltest/tests/rsa_oaep/ciphertext8
new file mode 100644
index 0000000..5d53ef0
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/ciphertext8
@@ -0,0 +1,4 @@
+gevdlQVLDIIu+a12k/Woet+0tMTOcN8t+E7UnATaWLpfwgoZ4abot6OQCyJ5bcToae5rQnktFajs
+61bAnGmRToE86o9pMeS47W9CGvKY1ZXJf0eJx8qmEsfvNgmEwhuT7cVAEGi1r0x4qHcbmE1TuOqK
+3y9qfUoLp2x14d2fZY8g3tSkYHHUbXeRtWgD2P6n8LD45Brj8JODpvlYX+d1Pqr/0r+UVjEIvuzC
+B7u1NfX8xwXw3en3CMYvSanJA3HT
diff --git a/nss/cmd/bltest/tests/rsa_oaep/ciphertext9 b/nss/cmd/bltest/tests/rsa_oaep/ciphertext9
new file mode 100644
index 0000000..6e865ff
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/ciphertext9
@@ -0,0 +1,4 @@
+vMNflM3mbLETZiXWJblEMqNbIvPS+hGmE/8PylvVf4e5AszcHNCuvLBxXuhp0dH+OV9nkwA/XspG
+UFnIhmDURv9fCBhVICJVfjjAimfq2ZEmIlTxBoKXXsVjl3aFN/SXevbV9qrOt/sl3sWTcjAjH9iX
+ivSRGaKfKeQkq4JytHVieS1clPd0uIKdCw2fGoye3fN1dNX6JI7vqcUnH8XsJXnIG91htBD6Yf42
+5CQiHBE63bJ1ZkyAHTTKjGNR5KhY
diff --git a/nss/cmd/bltest/tests/rsa_oaep/hash0 b/nss/cmd/bltest/tests/rsa_oaep/hash0
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/hash0
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/hash1 b/nss/cmd/bltest/tests/rsa_oaep/hash1
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/hash1
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/hash10 b/nss/cmd/bltest/tests/rsa_oaep/hash10
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/hash10
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/hash11 b/nss/cmd/bltest/tests/rsa_oaep/hash11
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/hash11
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/hash12 b/nss/cmd/bltest/tests/rsa_oaep/hash12
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/hash12
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/hash13 b/nss/cmd/bltest/tests/rsa_oaep/hash13
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/hash13
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/hash14 b/nss/cmd/bltest/tests/rsa_oaep/hash14
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/hash14
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/hash15 b/nss/cmd/bltest/tests/rsa_oaep/hash15
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/hash15
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/hash16 b/nss/cmd/bltest/tests/rsa_oaep/hash16
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/hash16
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/hash17 b/nss/cmd/bltest/tests/rsa_oaep/hash17
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/hash17
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/hash2 b/nss/cmd/bltest/tests/rsa_oaep/hash2
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/hash2
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/hash3 b/nss/cmd/bltest/tests/rsa_oaep/hash3
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/hash3
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/hash4 b/nss/cmd/bltest/tests/rsa_oaep/hash4
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/hash4
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/hash5 b/nss/cmd/bltest/tests/rsa_oaep/hash5
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/hash5
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/hash6 b/nss/cmd/bltest/tests/rsa_oaep/hash6
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/hash6
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/hash7 b/nss/cmd/bltest/tests/rsa_oaep/hash7
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/hash7
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/hash8 b/nss/cmd/bltest/tests/rsa_oaep/hash8
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/hash8
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/hash9 b/nss/cmd/bltest/tests/rsa_oaep/hash9
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/hash9
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/key0 b/nss/cmd/bltest/tests/rsa_oaep/key0
new file mode 100644
index 0000000..61684be
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/key0
@@ -0,0 +1 @@
+AAAAAQAAAACAqLOyhK+OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx+CwgtaTpef87Wdc9GaFEncsDLxkp0LGxjD1M8jMcvYq6DPEC/JYQumEu3i9v5fAEH1VvbZi9cTg+rmEXLUUjvc5LdOq/5OuHmtme7PUJHYW1PW6ENTP0ibeiNOfFvsAAAADAQABAAAAgFMznP23n8hGamVccxasqFxV/Y9t2Jj9rxGVF+9PUuj9jiWN+T/uGA+g5KspaTzYOxUqVT1KxNGBK4ufpa8Of1X+cwTfQVcJJvMxHxXE1lpzLEgxFu49PS0K81Sa2b98v7eK2IT4TVvrBHJNxzabMd7zfQz1OenPzdPeZTcp6tXRAAAAQNMnN+cmf/4TQbLVwNFQqBtYb7MTK+0vjVJihkqcufMK84vkSFmNQToXLvuALCGs8cEcUgwvJqRx3K0hLqx8o50AAABAzIhT0dVNpjD6wAT0cfKBx7iYLYIkpJDtvrM9Pj1cyTxHZXA9HdeRZC8fEWoN2FK+JBmyr3K/6aAw6GCwKItddwAAAEAOEr8XGOnO9VmbocOIL+gEapCHTu/OjyzMIOTydB+wozo4SK7JyTBfvsvS12gZln1GcazGQx5AN5aNs3h45pXBAAAAQJUpew+Vovpn0AcH1gnf1PwFyJ2vwu9tbqVb7HceozNzTZJR55CC7NqGbv7xPEWeGmMThrfjVMiZ9fESyoXXFYMAAABAT0VsUCSTvcDtKrdWo6btTWc1Kml9QhbpMhKxJ6Y9VBHOb6mNXb79cyY+NygUJ0OBgWbtfdY2h90qjKHS9PvY4Q==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/key1 b/nss/cmd/bltest/tests/rsa_oaep/key1
new file mode 100644
index 0000000..61684be
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/key1
@@ -0,0 +1 @@
+AAAAAQAAAACAqLOyhK+OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx+CwgtaTpef87Wdc9GaFEncsDLxkp0LGxjD1M8jMcvYq6DPEC/JYQumEu3i9v5fAEH1VvbZi9cTg+rmEXLUUjvc5LdOq/5OuHmtme7PUJHYW1PW6ENTP0ibeiNOfFvsAAAADAQABAAAAgFMznP23n8hGamVccxasqFxV/Y9t2Jj9rxGVF+9PUuj9jiWN+T/uGA+g5KspaTzYOxUqVT1KxNGBK4ufpa8Of1X+cwTfQVcJJvMxHxXE1lpzLEgxFu49PS0K81Sa2b98v7eK2IT4TVvrBHJNxzabMd7zfQz1OenPzdPeZTcp6tXRAAAAQNMnN+cmf/4TQbLVwNFQqBtYb7MTK+0vjVJihkqcufMK84vkSFmNQToXLvuALCGs8cEcUgwvJqRx3K0hLqx8o50AAABAzIhT0dVNpjD6wAT0cfKBx7iYLYIkpJDtvrM9Pj1cyTxHZXA9HdeRZC8fEWoN2FK+JBmyr3K/6aAw6GCwKItddwAAAEAOEr8XGOnO9VmbocOIL+gEapCHTu/OjyzMIOTydB+wozo4SK7JyTBfvsvS12gZln1GcazGQx5AN5aNs3h45pXBAAAAQJUpew+Vovpn0AcH1gnf1PwFyJ2vwu9tbqVb7HceozNzTZJR55CC7NqGbv7xPEWeGmMThrfjVMiZ9fESyoXXFYMAAABAT0VsUCSTvcDtKrdWo6btTWc1Kml9QhbpMhKxJ6Y9VBHOb6mNXb79cyY+NygUJ0OBgWbtfdY2h90qjKHS9PvY4Q==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/key10 b/nss/cmd/bltest/tests/rsa_oaep/key10
new file mode 100644
index 0000000..3c9f874
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/key10
@@ -0,0 +1 @@
+AAAAAQAAAADAzyzUHjTKOnKOpcuK/2TDbSe971Nk4zb9aNMSPFoZaowocBPoU9UVbVjRUZVFIPtPbXsXq7aBd2WQnFdhGWWdkCsZBu2KKxDBVcJNEkUo2rnurjeb6sZuSkEXhty4/QBi68Aw3hIZoEwqjBt90xMeTWtsruLjGl7UGsFQmy7x7iqxg2S+VoypQcJezIT/nWQ7XsGqrhAqINc/R5t4D9bakQdSEtnqwDoGdNiZ66LkMfTES2Fba6IjK9SzO67XPWJdAAAAAwEAAQAAAMAZjBQeI3FakrzPahGaW8ETiUaNKBH1SNcn4XtKsOuYbW8hHvtTtx98y+qH7mnHXuYVAIxTMt61K/OQq9+/431yBTaBWbJjjB3jJuIdIiUfD7WEizvxUAXSp0Mw8K/pFu5izME0TR2DpwnmBnYnOED383dCSl4KTadfAbMf92gZz5y/3SFSQ8ORfAPvOBmTEuVns7967Tq0V/Nx74oUI/RbaMbiguwRG7ooM7mH/Wn62DvBuMYTxeHqFsEe0SXqfsEAAABg/I1sBL7E65qBksp5AMvlNuLotRnezzOyRZeYxpCd9PF2230jGQ/HK4hlpxiviV8bzZFFKYAnQjtgXnCkfPWDkKjD6I/IxI6LMuPaIQ374+iB6lZ0tqNIwh6T+eVepl79AAAAYNIA1F54iqzqYGpAHQRg+H3VwQJ+EtwaDXWG6JOdnPeJtA9RrARClh3n0hzCHgXIMVXB8qqRkzh8/flWy0jRU7onBAb5u7pTfUmH2eL5lC16FMv//qdP7N2pKNI+JZ9e4QAAAGDbFoAveaLw1F81jWn9M+RLgfroKGIuk6VCU+mX0BsHQ3WdoOgStKpObIvqsjKNVDGVWkGKZ/8mqMXIB6XaNU4F7zHMjPdY9GNzKVCwPiZXJvuU451qVyomJEqwjbdXUq0AAABgoKMXz+ffFCP4em3uhFH04rSmflSX8ptPHk6DC5+t2UARZwJvVZblo5yXgX4PXxbifhnsmQLgHX6m+5qjx2Cv7h44G2neasnAdYWgatnEugC/dcitL6iYpHnoCuKU/tKhAAAAYAsh8zXDUzQutEw6okRFeAwtZVuUAXTK44x8ik5kk8C6n9MDdIJnsIO5p6bLYeQts2K4yYlttwZOAq1a5hWH2hW0ZJyQWUkJ/rN9vLZUvrcmjsgB5ai0qjkRvr2IVC8Fvg==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/key11 b/nss/cmd/bltest/tests/rsa_oaep/key11
new file mode 100644
index 0000000..3c9f874
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/key11
@@ -0,0 +1 @@
+AAAAAQAAAADAzyzUHjTKOnKOpcuK/2TDbSe971Nk4zb9aNMSPFoZaowocBPoU9UVbVjRUZVFIPtPbXsXq7aBd2WQnFdhGWWdkCsZBu2KKxDBVcJNEkUo2rnurjeb6sZuSkEXhty4/QBi68Aw3hIZoEwqjBt90xMeTWtsruLjGl7UGsFQmy7x7iqxg2S+VoypQcJezIT/nWQ7XsGqrhAqINc/R5t4D9bakQdSEtnqwDoGdNiZ66LkMfTES2Fba6IjK9SzO67XPWJdAAAAAwEAAQAAAMAZjBQeI3FakrzPahGaW8ETiUaNKBH1SNcn4XtKsOuYbW8hHvtTtx98y+qH7mnHXuYVAIxTMt61K/OQq9+/431yBTaBWbJjjB3jJuIdIiUfD7WEizvxUAXSp0Mw8K/pFu5izME0TR2DpwnmBnYnOED383dCSl4KTadfAbMf92gZz5y/3SFSQ8ORfAPvOBmTEuVns7967Tq0V/Nx74oUI/RbaMbiguwRG7ooM7mH/Wn62DvBuMYTxeHqFsEe0SXqfsEAAABg/I1sBL7E65qBksp5AMvlNuLotRnezzOyRZeYxpCd9PF2230jGQ/HK4hlpxiviV8bzZFFKYAnQjtgXnCkfPWDkKjD6I/IxI6LMuPaIQ374+iB6lZ0tqNIwh6T+eVepl79AAAAYNIA1F54iqzqYGpAHQRg+H3VwQJ+EtwaDXWG6JOdnPeJtA9RrARClh3n0hzCHgXIMVXB8qqRkzh8/flWy0jRU7onBAb5u7pTfUmH2eL5lC16FMv//qdP7N2pKNI+JZ9e4QAAAGDbFoAveaLw1F81jWn9M+RLgfroKGIuk6VCU+mX0BsHQ3WdoOgStKpObIvqsjKNVDGVWkGKZ/8mqMXIB6XaNU4F7zHMjPdY9GNzKVCwPiZXJvuU451qVyomJEqwjbdXUq0AAABgoKMXz+ffFCP4em3uhFH04rSmflSX8ptPHk6DC5+t2UARZwJvVZblo5yXgX4PXxbifhnsmQLgHX6m+5qjx2Cv7h44G2neasnAdYWgatnEugC/dcitL6iYpHnoCuKU/tKhAAAAYAsh8zXDUzQutEw6okRFeAwtZVuUAXTK44x8ik5kk8C6n9MDdIJnsIO5p6bLYeQts2K4yYlttwZOAq1a5hWH2hW0ZJyQWUkJ/rN9vLZUvrcmjsgB5ai0qjkRvr2IVC8Fvg==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/key12 b/nss/cmd/bltest/tests/rsa_oaep/key12
new file mode 100644
index 0000000..a2ad3ff
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/key12
@@ -0,0 +1 @@
+AAAAAQAAAAEArkXtVgHOxrjMBfgDk1xnTdvg11xMCf15UfxrDK7DE6jfOZcMUYv/ul7Wjz8NfyKkAp1BPxrgfk6+nkF3ziPn9UBLVp5O4b3PPB+wPvETgC1PhV65tRNLWnyAha3K5vovoUF+w3Y74XGwxit2Dt4jwSrZK5gIhMZB9aj6wmva1KAzgaIv4bdUiFCUyCUG1AGaU1ooav6ycbubpZLeGNz2AMKu6uVuAvfPefwUzzvcfNhP67v5UMqQMEsiGaeqBjrvosPBmA5WDNZK/neVhbYQdle5V4V+/eYBCYirfeQX/IjY84TE5ucsP5Q+DDHAxKXMNvh52KOsnX1Zhg6q2muDuwAAAAMBAAEAAAEABWsEIW/l81SsdyUKS2sMhSWoXFmwvYDFZFCiLV9DjllqMzqodeKR3UP0jLiLnV/A1Jn5/NHDl/mvwHDNnjmMjRnmHbfHQQprJnXfv100W4BNIBrdUC1c4t/LCRzpmXu+vlcwbzg+TViBA/A29+hdGTTRUqMj5KjbRR1vSlsbDxAswVDgL+7iuI3qStTBusyyTYQHLRTh0kpncfdAjuMFZPuG1Dk6NLzwt4hQHRkzA/E6IoSwAfD2Ser3kyjUrFxDCrRBSSCpRg7Rt7xA7GU+h20Jq8UJrkW1JRkBFqDCYQGEgphQnBw786SD5ydAVOFelwdQNumJ9gkygHtSV3UeeQAAAIDs9a7NHlUV//rL11ooFsbr9JAYzftGOOGF1mpzlrb4CQ+AGMf9lcw0uFfcF/DMZRa7E0arTVgsra17QQM1I4e3AzjQhAR8nZU5tkliBLPdbqRCSZIHvsAflkKH/2M2w5hGWDNoRvVuRoYYgcECM9IXa/FaXpbdx4C8hoqnfTznaQAAAIC8RsRk/GrEyng7DrCKPIQbdy9+my8our1YiuiF4aDGHkhYoPslrCmZkPNb6FFkwlm6EXXN1xknBxNRhJkrbCm3Rt0NLKvhQoNffRSMwWFSS0oJlG1IuChHPxzna2y2iGw0XAPgX0HVG1w6kKPyQHPH10pP4l2c8hx1lg8/w4YxgwAAAIDHNWRXHQD7FdCKPemVelCRXXEm6UQtrPQryC6GLlZz/2oAjtTS43RhffifF6FgtDt/2py2trdCGGCYFffUXKJjwVmqMtJy0Sf69LyMotdzeOiusZsK19o8s94K5zFJgPYrbUsKh10d8DwbrjnM2DPvbNfi2VKL8ITR+WnnlOn2wQAAAIAmWLN/bfnBAwvh22gRf6nYfjnqK2k7fm06L3CUdBPuxhQuGPuN/LasVF18hqCtSPhFcXDw77JrxIEmxT79HRaSAZjcKhEH3CgttqgM0wYjYLo/oT9w5DEv8abNa4/EzZxcPbF8bWpXIS9zrin2GTJ7rVmxU4WFhbpOKLYKYqReSQAAAIBvOFJrOSUIVTTvPkFag27ei4YViix8v+zLC9g0ME/saDuo1PR5xDPUNBbmMmliPOoQB3bYWv9AHT//YQ7mVBHOOxNj1jqXCe7eQmR86lYUk9VFcKh5wYaCzZdxC5YgXsMRF9c7XzYiP63W6LqQ3XwO5h1E4WMlHiDH9m6zBRF8uA==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/key13 b/nss/cmd/bltest/tests/rsa_oaep/key13
new file mode 100644
index 0000000..a2ad3ff
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/key13
@@ -0,0 +1 @@
+AAAAAQAAAAEArkXtVgHOxrjMBfgDk1xnTdvg11xMCf15UfxrDK7DE6jfOZcMUYv/ul7Wjz8NfyKkAp1BPxrgfk6+nkF3ziPn9UBLVp5O4b3PPB+wPvETgC1PhV65tRNLWnyAha3K5vovoUF+w3Y74XGwxit2Dt4jwSrZK5gIhMZB9aj6wmva1KAzgaIv4bdUiFCUyCUG1AGaU1ooav6ycbubpZLeGNz2AMKu6uVuAvfPefwUzzvcfNhP67v5UMqQMEsiGaeqBjrvosPBmA5WDNZK/neVhbYQdle5V4V+/eYBCYirfeQX/IjY84TE5ucsP5Q+DDHAxKXMNvh52KOsnX1Zhg6q2muDuwAAAAMBAAEAAAEABWsEIW/l81SsdyUKS2sMhSWoXFmwvYDFZFCiLV9DjllqMzqodeKR3UP0jLiLnV/A1Jn5/NHDl/mvwHDNnjmMjRnmHbfHQQprJnXfv100W4BNIBrdUC1c4t/LCRzpmXu+vlcwbzg+TViBA/A29+hdGTTRUqMj5KjbRR1vSlsbDxAswVDgL+7iuI3qStTBusyyTYQHLRTh0kpncfdAjuMFZPuG1Dk6NLzwt4hQHRkzA/E6IoSwAfD2Ser3kyjUrFxDCrRBSSCpRg7Rt7xA7GU+h20Jq8UJrkW1JRkBFqDCYQGEgphQnBw786SD5ydAVOFelwdQNumJ9gkygHtSV3UeeQAAAIDs9a7NHlUV//rL11ooFsbr9JAYzftGOOGF1mpzlrb4CQ+AGMf9lcw0uFfcF/DMZRa7E0arTVgsra17QQM1I4e3AzjQhAR8nZU5tkliBLPdbqRCSZIHvsAflkKH/2M2w5hGWDNoRvVuRoYYgcECM9IXa/FaXpbdx4C8hoqnfTznaQAAAIC8RsRk/GrEyng7DrCKPIQbdy9+my8our1YiuiF4aDGHkhYoPslrCmZkPNb6FFkwlm6EXXN1xknBxNRhJkrbCm3Rt0NLKvhQoNffRSMwWFSS0oJlG1IuChHPxzna2y2iGw0XAPgX0HVG1w6kKPyQHPH10pP4l2c8hx1lg8/w4YxgwAAAIDHNWRXHQD7FdCKPemVelCRXXEm6UQtrPQryC6GLlZz/2oAjtTS43RhffifF6FgtDt/2py2trdCGGCYFffUXKJjwVmqMtJy0Sf69LyMotdzeOiusZsK19o8s94K5zFJgPYrbUsKh10d8DwbrjnM2DPvbNfi2VKL8ITR+WnnlOn2wQAAAIAmWLN/bfnBAwvh22gRf6nYfjnqK2k7fm06L3CUdBPuxhQuGPuN/LasVF18hqCtSPhFcXDw77JrxIEmxT79HRaSAZjcKhEH3CgttqgM0wYjYLo/oT9w5DEv8abNa4/EzZxcPbF8bWpXIS9zrin2GTJ7rVmxU4WFhbpOKLYKYqReSQAAAIBvOFJrOSUIVTTvPkFag27ei4YViix8v+zLC9g0ME/saDuo1PR5xDPUNBbmMmliPOoQB3bYWv9AHT//YQ7mVBHOOxNj1jqXCe7eQmR86lYUk9VFcKh5wYaCzZdxC5YgXsMRF9c7XzYiP63W6LqQ3XwO5h1E4WMlHiDH9m6zBRF8uA==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/key14 b/nss/cmd/bltest/tests/rsa_oaep/key14
new file mode 100644
index 0000000..a2ad3ff
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/key14
@@ -0,0 +1 @@
+AAAAAQAAAAEArkXtVgHOxrjMBfgDk1xnTdvg11xMCf15UfxrDK7DE6jfOZcMUYv/ul7Wjz8NfyKkAp1BPxrgfk6+nkF3ziPn9UBLVp5O4b3PPB+wPvETgC1PhV65tRNLWnyAha3K5vovoUF+w3Y74XGwxit2Dt4jwSrZK5gIhMZB9aj6wmva1KAzgaIv4bdUiFCUyCUG1AGaU1ooav6ycbubpZLeGNz2AMKu6uVuAvfPefwUzzvcfNhP67v5UMqQMEsiGaeqBjrvosPBmA5WDNZK/neVhbYQdle5V4V+/eYBCYirfeQX/IjY84TE5ucsP5Q+DDHAxKXMNvh52KOsnX1Zhg6q2muDuwAAAAMBAAEAAAEABWsEIW/l81SsdyUKS2sMhSWoXFmwvYDFZFCiLV9DjllqMzqodeKR3UP0jLiLnV/A1Jn5/NHDl/mvwHDNnjmMjRnmHbfHQQprJnXfv100W4BNIBrdUC1c4t/LCRzpmXu+vlcwbzg+TViBA/A29+hdGTTRUqMj5KjbRR1vSlsbDxAswVDgL+7iuI3qStTBusyyTYQHLRTh0kpncfdAjuMFZPuG1Dk6NLzwt4hQHRkzA/E6IoSwAfD2Ser3kyjUrFxDCrRBSSCpRg7Rt7xA7GU+h20Jq8UJrkW1JRkBFqDCYQGEgphQnBw786SD5ydAVOFelwdQNumJ9gkygHtSV3UeeQAAAIDs9a7NHlUV//rL11ooFsbr9JAYzftGOOGF1mpzlrb4CQ+AGMf9lcw0uFfcF/DMZRa7E0arTVgsra17QQM1I4e3AzjQhAR8nZU5tkliBLPdbqRCSZIHvsAflkKH/2M2w5hGWDNoRvVuRoYYgcECM9IXa/FaXpbdx4C8hoqnfTznaQAAAIC8RsRk/GrEyng7DrCKPIQbdy9+my8our1YiuiF4aDGHkhYoPslrCmZkPNb6FFkwlm6EXXN1xknBxNRhJkrbCm3Rt0NLKvhQoNffRSMwWFSS0oJlG1IuChHPxzna2y2iGw0XAPgX0HVG1w6kKPyQHPH10pP4l2c8hx1lg8/w4YxgwAAAIDHNWRXHQD7FdCKPemVelCRXXEm6UQtrPQryC6GLlZz/2oAjtTS43RhffifF6FgtDt/2py2trdCGGCYFffUXKJjwVmqMtJy0Sf69LyMotdzeOiusZsK19o8s94K5zFJgPYrbUsKh10d8DwbrjnM2DPvbNfi2VKL8ITR+WnnlOn2wQAAAIAmWLN/bfnBAwvh22gRf6nYfjnqK2k7fm06L3CUdBPuxhQuGPuN/LasVF18hqCtSPhFcXDw77JrxIEmxT79HRaSAZjcKhEH3CgttqgM0wYjYLo/oT9w5DEv8abNa4/EzZxcPbF8bWpXIS9zrin2GTJ7rVmxU4WFhbpOKLYKYqReSQAAAIBvOFJrOSUIVTTvPkFag27ei4YViix8v+zLC9g0ME/saDuo1PR5xDPUNBbmMmliPOoQB3bYWv9AHT//YQ7mVBHOOxNj1jqXCe7eQmR86lYUk9VFcKh5wYaCzZdxC5YgXsMRF9c7XzYiP63W6LqQ3XwO5h1E4WMlHiDH9m6zBRF8uA==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/key15 b/nss/cmd/bltest/tests/rsa_oaep/key15
new file mode 100644
index 0000000..a2ad3ff
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/key15
@@ -0,0 +1 @@
+AAAAAQAAAAEArkXtVgHOxrjMBfgDk1xnTdvg11xMCf15UfxrDK7DE6jfOZcMUYv/ul7Wjz8NfyKkAp1BPxrgfk6+nkF3ziPn9UBLVp5O4b3PPB+wPvETgC1PhV65tRNLWnyAha3K5vovoUF+w3Y74XGwxit2Dt4jwSrZK5gIhMZB9aj6wmva1KAzgaIv4bdUiFCUyCUG1AGaU1ooav6ycbubpZLeGNz2AMKu6uVuAvfPefwUzzvcfNhP67v5UMqQMEsiGaeqBjrvosPBmA5WDNZK/neVhbYQdle5V4V+/eYBCYirfeQX/IjY84TE5ucsP5Q+DDHAxKXMNvh52KOsnX1Zhg6q2muDuwAAAAMBAAEAAAEABWsEIW/l81SsdyUKS2sMhSWoXFmwvYDFZFCiLV9DjllqMzqodeKR3UP0jLiLnV/A1Jn5/NHDl/mvwHDNnjmMjRnmHbfHQQprJnXfv100W4BNIBrdUC1c4t/LCRzpmXu+vlcwbzg+TViBA/A29+hdGTTRUqMj5KjbRR1vSlsbDxAswVDgL+7iuI3qStTBusyyTYQHLRTh0kpncfdAjuMFZPuG1Dk6NLzwt4hQHRkzA/E6IoSwAfD2Ser3kyjUrFxDCrRBSSCpRg7Rt7xA7GU+h20Jq8UJrkW1JRkBFqDCYQGEgphQnBw786SD5ydAVOFelwdQNumJ9gkygHtSV3UeeQAAAIDs9a7NHlUV//rL11ooFsbr9JAYzftGOOGF1mpzlrb4CQ+AGMf9lcw0uFfcF/DMZRa7E0arTVgsra17QQM1I4e3AzjQhAR8nZU5tkliBLPdbqRCSZIHvsAflkKH/2M2w5hGWDNoRvVuRoYYgcECM9IXa/FaXpbdx4C8hoqnfTznaQAAAIC8RsRk/GrEyng7DrCKPIQbdy9+my8our1YiuiF4aDGHkhYoPslrCmZkPNb6FFkwlm6EXXN1xknBxNRhJkrbCm3Rt0NLKvhQoNffRSMwWFSS0oJlG1IuChHPxzna2y2iGw0XAPgX0HVG1w6kKPyQHPH10pP4l2c8hx1lg8/w4YxgwAAAIDHNWRXHQD7FdCKPemVelCRXXEm6UQtrPQryC6GLlZz/2oAjtTS43RhffifF6FgtDt/2py2trdCGGCYFffUXKJjwVmqMtJy0Sf69LyMotdzeOiusZsK19o8s94K5zFJgPYrbUsKh10d8DwbrjnM2DPvbNfi2VKL8ITR+WnnlOn2wQAAAIAmWLN/bfnBAwvh22gRf6nYfjnqK2k7fm06L3CUdBPuxhQuGPuN/LasVF18hqCtSPhFcXDw77JrxIEmxT79HRaSAZjcKhEH3CgttqgM0wYjYLo/oT9w5DEv8abNa4/EzZxcPbF8bWpXIS9zrin2GTJ7rVmxU4WFhbpOKLYKYqReSQAAAIBvOFJrOSUIVTTvPkFag27ei4YViix8v+zLC9g0ME/saDuo1PR5xDPUNBbmMmliPOoQB3bYWv9AHT//YQ7mVBHOOxNj1jqXCe7eQmR86lYUk9VFcKh5wYaCzZdxC5YgXsMRF9c7XzYiP63W6LqQ3XwO5h1E4WMlHiDH9m6zBRF8uA==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/key16 b/nss/cmd/bltest/tests/rsa_oaep/key16
new file mode 100644
index 0000000..a2ad3ff
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/key16
@@ -0,0 +1 @@
+AAAAAQAAAAEArkXtVgHOxrjMBfgDk1xnTdvg11xMCf15UfxrDK7DE6jfOZcMUYv/ul7Wjz8NfyKkAp1BPxrgfk6+nkF3ziPn9UBLVp5O4b3PPB+wPvETgC1PhV65tRNLWnyAha3K5vovoUF+w3Y74XGwxit2Dt4jwSrZK5gIhMZB9aj6wmva1KAzgaIv4bdUiFCUyCUG1AGaU1ooav6ycbubpZLeGNz2AMKu6uVuAvfPefwUzzvcfNhP67v5UMqQMEsiGaeqBjrvosPBmA5WDNZK/neVhbYQdle5V4V+/eYBCYirfeQX/IjY84TE5ucsP5Q+DDHAxKXMNvh52KOsnX1Zhg6q2muDuwAAAAMBAAEAAAEABWsEIW/l81SsdyUKS2sMhSWoXFmwvYDFZFCiLV9DjllqMzqodeKR3UP0jLiLnV/A1Jn5/NHDl/mvwHDNnjmMjRnmHbfHQQprJnXfv100W4BNIBrdUC1c4t/LCRzpmXu+vlcwbzg+TViBA/A29+hdGTTRUqMj5KjbRR1vSlsbDxAswVDgL+7iuI3qStTBusyyTYQHLRTh0kpncfdAjuMFZPuG1Dk6NLzwt4hQHRkzA/E6IoSwAfD2Ser3kyjUrFxDCrRBSSCpRg7Rt7xA7GU+h20Jq8UJrkW1JRkBFqDCYQGEgphQnBw786SD5ydAVOFelwdQNumJ9gkygHtSV3UeeQAAAIDs9a7NHlUV//rL11ooFsbr9JAYzftGOOGF1mpzlrb4CQ+AGMf9lcw0uFfcF/DMZRa7E0arTVgsra17QQM1I4e3AzjQhAR8nZU5tkliBLPdbqRCSZIHvsAflkKH/2M2w5hGWDNoRvVuRoYYgcECM9IXa/FaXpbdx4C8hoqnfTznaQAAAIC8RsRk/GrEyng7DrCKPIQbdy9+my8our1YiuiF4aDGHkhYoPslrCmZkPNb6FFkwlm6EXXN1xknBxNRhJkrbCm3Rt0NLKvhQoNffRSMwWFSS0oJlG1IuChHPxzna2y2iGw0XAPgX0HVG1w6kKPyQHPH10pP4l2c8hx1lg8/w4YxgwAAAIDHNWRXHQD7FdCKPemVelCRXXEm6UQtrPQryC6GLlZz/2oAjtTS43RhffifF6FgtDt/2py2trdCGGCYFffUXKJjwVmqMtJy0Sf69LyMotdzeOiusZsK19o8s94K5zFJgPYrbUsKh10d8DwbrjnM2DPvbNfi2VKL8ITR+WnnlOn2wQAAAIAmWLN/bfnBAwvh22gRf6nYfjnqK2k7fm06L3CUdBPuxhQuGPuN/LasVF18hqCtSPhFcXDw77JrxIEmxT79HRaSAZjcKhEH3CgttqgM0wYjYLo/oT9w5DEv8abNa4/EzZxcPbF8bWpXIS9zrin2GTJ7rVmxU4WFhbpOKLYKYqReSQAAAIBvOFJrOSUIVTTvPkFag27ei4YViix8v+zLC9g0ME/saDuo1PR5xDPUNBbmMmliPOoQB3bYWv9AHT//YQ7mVBHOOxNj1jqXCe7eQmR86lYUk9VFcKh5wYaCzZdxC5YgXsMRF9c7XzYiP63W6LqQ3XwO5h1E4WMlHiDH9m6zBRF8uA==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/key17 b/nss/cmd/bltest/tests/rsa_oaep/key17
new file mode 100644
index 0000000..a2ad3ff
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/key17
@@ -0,0 +1 @@
+AAAAAQAAAAEArkXtVgHOxrjMBfgDk1xnTdvg11xMCf15UfxrDK7DE6jfOZcMUYv/ul7Wjz8NfyKkAp1BPxrgfk6+nkF3ziPn9UBLVp5O4b3PPB+wPvETgC1PhV65tRNLWnyAha3K5vovoUF+w3Y74XGwxit2Dt4jwSrZK5gIhMZB9aj6wmva1KAzgaIv4bdUiFCUyCUG1AGaU1ooav6ycbubpZLeGNz2AMKu6uVuAvfPefwUzzvcfNhP67v5UMqQMEsiGaeqBjrvosPBmA5WDNZK/neVhbYQdle5V4V+/eYBCYirfeQX/IjY84TE5ucsP5Q+DDHAxKXMNvh52KOsnX1Zhg6q2muDuwAAAAMBAAEAAAEABWsEIW/l81SsdyUKS2sMhSWoXFmwvYDFZFCiLV9DjllqMzqodeKR3UP0jLiLnV/A1Jn5/NHDl/mvwHDNnjmMjRnmHbfHQQprJnXfv100W4BNIBrdUC1c4t/LCRzpmXu+vlcwbzg+TViBA/A29+hdGTTRUqMj5KjbRR1vSlsbDxAswVDgL+7iuI3qStTBusyyTYQHLRTh0kpncfdAjuMFZPuG1Dk6NLzwt4hQHRkzA/E6IoSwAfD2Ser3kyjUrFxDCrRBSSCpRg7Rt7xA7GU+h20Jq8UJrkW1JRkBFqDCYQGEgphQnBw786SD5ydAVOFelwdQNumJ9gkygHtSV3UeeQAAAIDs9a7NHlUV//rL11ooFsbr9JAYzftGOOGF1mpzlrb4CQ+AGMf9lcw0uFfcF/DMZRa7E0arTVgsra17QQM1I4e3AzjQhAR8nZU5tkliBLPdbqRCSZIHvsAflkKH/2M2w5hGWDNoRvVuRoYYgcECM9IXa/FaXpbdx4C8hoqnfTznaQAAAIC8RsRk/GrEyng7DrCKPIQbdy9+my8our1YiuiF4aDGHkhYoPslrCmZkPNb6FFkwlm6EXXN1xknBxNRhJkrbCm3Rt0NLKvhQoNffRSMwWFSS0oJlG1IuChHPxzna2y2iGw0XAPgX0HVG1w6kKPyQHPH10pP4l2c8hx1lg8/w4YxgwAAAIDHNWRXHQD7FdCKPemVelCRXXEm6UQtrPQryC6GLlZz/2oAjtTS43RhffifF6FgtDt/2py2trdCGGCYFffUXKJjwVmqMtJy0Sf69LyMotdzeOiusZsK19o8s94K5zFJgPYrbUsKh10d8DwbrjnM2DPvbNfi2VKL8ITR+WnnlOn2wQAAAIAmWLN/bfnBAwvh22gRf6nYfjnqK2k7fm06L3CUdBPuxhQuGPuN/LasVF18hqCtSPhFcXDw77JrxIEmxT79HRaSAZjcKhEH3CgttqgM0wYjYLo/oT9w5DEv8abNa4/EzZxcPbF8bWpXIS9zrin2GTJ7rVmxU4WFhbpOKLYKYqReSQAAAIBvOFJrOSUIVTTvPkFag27ei4YViix8v+zLC9g0ME/saDuo1PR5xDPUNBbmMmliPOoQB3bYWv9AHT//YQ7mVBHOOxNj1jqXCe7eQmR86lYUk9VFcKh5wYaCzZdxC5YgXsMRF9c7XzYiP63W6LqQ3XwO5h1E4WMlHiDH9m6zBRF8uA==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/key2 b/nss/cmd/bltest/tests/rsa_oaep/key2
new file mode 100644
index 0000000..61684be
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/key2
@@ -0,0 +1 @@
+AAAAAQAAAACAqLOyhK+OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx+CwgtaTpef87Wdc9GaFEncsDLxkp0LGxjD1M8jMcvYq6DPEC/JYQumEu3i9v5fAEH1VvbZi9cTg+rmEXLUUjvc5LdOq/5OuHmtme7PUJHYW1PW6ENTP0ibeiNOfFvsAAAADAQABAAAAgFMznP23n8hGamVccxasqFxV/Y9t2Jj9rxGVF+9PUuj9jiWN+T/uGA+g5KspaTzYOxUqVT1KxNGBK4ufpa8Of1X+cwTfQVcJJvMxHxXE1lpzLEgxFu49PS0K81Sa2b98v7eK2IT4TVvrBHJNxzabMd7zfQz1OenPzdPeZTcp6tXRAAAAQNMnN+cmf/4TQbLVwNFQqBtYb7MTK+0vjVJihkqcufMK84vkSFmNQToXLvuALCGs8cEcUgwvJqRx3K0hLqx8o50AAABAzIhT0dVNpjD6wAT0cfKBx7iYLYIkpJDtvrM9Pj1cyTxHZXA9HdeRZC8fEWoN2FK+JBmyr3K/6aAw6GCwKItddwAAAEAOEr8XGOnO9VmbocOIL+gEapCHTu/OjyzMIOTydB+wozo4SK7JyTBfvsvS12gZln1GcazGQx5AN5aNs3h45pXBAAAAQJUpew+Vovpn0AcH1gnf1PwFyJ2vwu9tbqVb7HceozNzTZJR55CC7NqGbv7xPEWeGmMThrfjVMiZ9fESyoXXFYMAAABAT0VsUCSTvcDtKrdWo6btTWc1Kml9QhbpMhKxJ6Y9VBHOb6mNXb79cyY+NygUJ0OBgWbtfdY2h90qjKHS9PvY4Q==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/key3 b/nss/cmd/bltest/tests/rsa_oaep/key3
new file mode 100644
index 0000000..61684be
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/key3
@@ -0,0 +1 @@
+AAAAAQAAAACAqLOyhK+OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx+CwgtaTpef87Wdc9GaFEncsDLxkp0LGxjD1M8jMcvYq6DPEC/JYQumEu3i9v5fAEH1VvbZi9cTg+rmEXLUUjvc5LdOq/5OuHmtme7PUJHYW1PW6ENTP0ibeiNOfFvsAAAADAQABAAAAgFMznP23n8hGamVccxasqFxV/Y9t2Jj9rxGVF+9PUuj9jiWN+T/uGA+g5KspaTzYOxUqVT1KxNGBK4ufpa8Of1X+cwTfQVcJJvMxHxXE1lpzLEgxFu49PS0K81Sa2b98v7eK2IT4TVvrBHJNxzabMd7zfQz1OenPzdPeZTcp6tXRAAAAQNMnN+cmf/4TQbLVwNFQqBtYb7MTK+0vjVJihkqcufMK84vkSFmNQToXLvuALCGs8cEcUgwvJqRx3K0hLqx8o50AAABAzIhT0dVNpjD6wAT0cfKBx7iYLYIkpJDtvrM9Pj1cyTxHZXA9HdeRZC8fEWoN2FK+JBmyr3K/6aAw6GCwKItddwAAAEAOEr8XGOnO9VmbocOIL+gEapCHTu/OjyzMIOTydB+wozo4SK7JyTBfvsvS12gZln1GcazGQx5AN5aNs3h45pXBAAAAQJUpew+Vovpn0AcH1gnf1PwFyJ2vwu9tbqVb7HceozNzTZJR55CC7NqGbv7xPEWeGmMThrfjVMiZ9fESyoXXFYMAAABAT0VsUCSTvcDtKrdWo6btTWc1Kml9QhbpMhKxJ6Y9VBHOb6mNXb79cyY+NygUJ0OBgWbtfdY2h90qjKHS9PvY4Q==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/key4 b/nss/cmd/bltest/tests/rsa_oaep/key4
new file mode 100644
index 0000000..61684be
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/key4
@@ -0,0 +1 @@
+AAAAAQAAAACAqLOyhK+OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx+CwgtaTpef87Wdc9GaFEncsDLxkp0LGxjD1M8jMcvYq6DPEC/JYQumEu3i9v5fAEH1VvbZi9cTg+rmEXLUUjvc5LdOq/5OuHmtme7PUJHYW1PW6ENTP0ibeiNOfFvsAAAADAQABAAAAgFMznP23n8hGamVccxasqFxV/Y9t2Jj9rxGVF+9PUuj9jiWN+T/uGA+g5KspaTzYOxUqVT1KxNGBK4ufpa8Of1X+cwTfQVcJJvMxHxXE1lpzLEgxFu49PS0K81Sa2b98v7eK2IT4TVvrBHJNxzabMd7zfQz1OenPzdPeZTcp6tXRAAAAQNMnN+cmf/4TQbLVwNFQqBtYb7MTK+0vjVJihkqcufMK84vkSFmNQToXLvuALCGs8cEcUgwvJqRx3K0hLqx8o50AAABAzIhT0dVNpjD6wAT0cfKBx7iYLYIkpJDtvrM9Pj1cyTxHZXA9HdeRZC8fEWoN2FK+JBmyr3K/6aAw6GCwKItddwAAAEAOEr8XGOnO9VmbocOIL+gEapCHTu/OjyzMIOTydB+wozo4SK7JyTBfvsvS12gZln1GcazGQx5AN5aNs3h45pXBAAAAQJUpew+Vovpn0AcH1gnf1PwFyJ2vwu9tbqVb7HceozNzTZJR55CC7NqGbv7xPEWeGmMThrfjVMiZ9fESyoXXFYMAAABAT0VsUCSTvcDtKrdWo6btTWc1Kml9QhbpMhKxJ6Y9VBHOb6mNXb79cyY+NygUJ0OBgWbtfdY2h90qjKHS9PvY4Q==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/key5 b/nss/cmd/bltest/tests/rsa_oaep/key5
new file mode 100644
index 0000000..61684be
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/key5
@@ -0,0 +1 @@
+AAAAAQAAAACAqLOyhK+OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx+CwgtaTpef87Wdc9GaFEncsDLxkp0LGxjD1M8jMcvYq6DPEC/JYQumEu3i9v5fAEH1VvbZi9cTg+rmEXLUUjvc5LdOq/5OuHmtme7PUJHYW1PW6ENTP0ibeiNOfFvsAAAADAQABAAAAgFMznP23n8hGamVccxasqFxV/Y9t2Jj9rxGVF+9PUuj9jiWN+T/uGA+g5KspaTzYOxUqVT1KxNGBK4ufpa8Of1X+cwTfQVcJJvMxHxXE1lpzLEgxFu49PS0K81Sa2b98v7eK2IT4TVvrBHJNxzabMd7zfQz1OenPzdPeZTcp6tXRAAAAQNMnN+cmf/4TQbLVwNFQqBtYb7MTK+0vjVJihkqcufMK84vkSFmNQToXLvuALCGs8cEcUgwvJqRx3K0hLqx8o50AAABAzIhT0dVNpjD6wAT0cfKBx7iYLYIkpJDtvrM9Pj1cyTxHZXA9HdeRZC8fEWoN2FK+JBmyr3K/6aAw6GCwKItddwAAAEAOEr8XGOnO9VmbocOIL+gEapCHTu/OjyzMIOTydB+wozo4SK7JyTBfvsvS12gZln1GcazGQx5AN5aNs3h45pXBAAAAQJUpew+Vovpn0AcH1gnf1PwFyJ2vwu9tbqVb7HceozNzTZJR55CC7NqGbv7xPEWeGmMThrfjVMiZ9fESyoXXFYMAAABAT0VsUCSTvcDtKrdWo6btTWc1Kml9QhbpMhKxJ6Y9VBHOb6mNXb79cyY+NygUJ0OBgWbtfdY2h90qjKHS9PvY4Q==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/key6 b/nss/cmd/bltest/tests/rsa_oaep/key6
new file mode 100644
index 0000000..3c9f874
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/key6
@@ -0,0 +1 @@
+AAAAAQAAAADAzyzUHjTKOnKOpcuK/2TDbSe971Nk4zb9aNMSPFoZaowocBPoU9UVbVjRUZVFIPtPbXsXq7aBd2WQnFdhGWWdkCsZBu2KKxDBVcJNEkUo2rnurjeb6sZuSkEXhty4/QBi68Aw3hIZoEwqjBt90xMeTWtsruLjGl7UGsFQmy7x7iqxg2S+VoypQcJezIT/nWQ7XsGqrhAqINc/R5t4D9bakQdSEtnqwDoGdNiZ66LkMfTES2Fba6IjK9SzO67XPWJdAAAAAwEAAQAAAMAZjBQeI3FakrzPahGaW8ETiUaNKBH1SNcn4XtKsOuYbW8hHvtTtx98y+qH7mnHXuYVAIxTMt61K/OQq9+/431yBTaBWbJjjB3jJuIdIiUfD7WEizvxUAXSp0Mw8K/pFu5izME0TR2DpwnmBnYnOED383dCSl4KTadfAbMf92gZz5y/3SFSQ8ORfAPvOBmTEuVns7967Tq0V/Nx74oUI/RbaMbiguwRG7ooM7mH/Wn62DvBuMYTxeHqFsEe0SXqfsEAAABg/I1sBL7E65qBksp5AMvlNuLotRnezzOyRZeYxpCd9PF2230jGQ/HK4hlpxiviV8bzZFFKYAnQjtgXnCkfPWDkKjD6I/IxI6LMuPaIQ374+iB6lZ0tqNIwh6T+eVepl79AAAAYNIA1F54iqzqYGpAHQRg+H3VwQJ+EtwaDXWG6JOdnPeJtA9RrARClh3n0hzCHgXIMVXB8qqRkzh8/flWy0jRU7onBAb5u7pTfUmH2eL5lC16FMv//qdP7N2pKNI+JZ9e4QAAAGDbFoAveaLw1F81jWn9M+RLgfroKGIuk6VCU+mX0BsHQ3WdoOgStKpObIvqsjKNVDGVWkGKZ/8mqMXIB6XaNU4F7zHMjPdY9GNzKVCwPiZXJvuU451qVyomJEqwjbdXUq0AAABgoKMXz+ffFCP4em3uhFH04rSmflSX8ptPHk6DC5+t2UARZwJvVZblo5yXgX4PXxbifhnsmQLgHX6m+5qjx2Cv7h44G2neasnAdYWgatnEugC/dcitL6iYpHnoCuKU/tKhAAAAYAsh8zXDUzQutEw6okRFeAwtZVuUAXTK44x8ik5kk8C6n9MDdIJnsIO5p6bLYeQts2K4yYlttwZOAq1a5hWH2hW0ZJyQWUkJ/rN9vLZUvrcmjsgB5ai0qjkRvr2IVC8Fvg==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/key7 b/nss/cmd/bltest/tests/rsa_oaep/key7
new file mode 100644
index 0000000..3c9f874
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/key7
@@ -0,0 +1 @@
+AAAAAQAAAADAzyzUHjTKOnKOpcuK/2TDbSe971Nk4zb9aNMSPFoZaowocBPoU9UVbVjRUZVFIPtPbXsXq7aBd2WQnFdhGWWdkCsZBu2KKxDBVcJNEkUo2rnurjeb6sZuSkEXhty4/QBi68Aw3hIZoEwqjBt90xMeTWtsruLjGl7UGsFQmy7x7iqxg2S+VoypQcJezIT/nWQ7XsGqrhAqINc/R5t4D9bakQdSEtnqwDoGdNiZ66LkMfTES2Fba6IjK9SzO67XPWJdAAAAAwEAAQAAAMAZjBQeI3FakrzPahGaW8ETiUaNKBH1SNcn4XtKsOuYbW8hHvtTtx98y+qH7mnHXuYVAIxTMt61K/OQq9+/431yBTaBWbJjjB3jJuIdIiUfD7WEizvxUAXSp0Mw8K/pFu5izME0TR2DpwnmBnYnOED383dCSl4KTadfAbMf92gZz5y/3SFSQ8ORfAPvOBmTEuVns7967Tq0V/Nx74oUI/RbaMbiguwRG7ooM7mH/Wn62DvBuMYTxeHqFsEe0SXqfsEAAABg/I1sBL7E65qBksp5AMvlNuLotRnezzOyRZeYxpCd9PF2230jGQ/HK4hlpxiviV8bzZFFKYAnQjtgXnCkfPWDkKjD6I/IxI6LMuPaIQ374+iB6lZ0tqNIwh6T+eVepl79AAAAYNIA1F54iqzqYGpAHQRg+H3VwQJ+EtwaDXWG6JOdnPeJtA9RrARClh3n0hzCHgXIMVXB8qqRkzh8/flWy0jRU7onBAb5u7pTfUmH2eL5lC16FMv//qdP7N2pKNI+JZ9e4QAAAGDbFoAveaLw1F81jWn9M+RLgfroKGIuk6VCU+mX0BsHQ3WdoOgStKpObIvqsjKNVDGVWkGKZ/8mqMXIB6XaNU4F7zHMjPdY9GNzKVCwPiZXJvuU451qVyomJEqwjbdXUq0AAABgoKMXz+ffFCP4em3uhFH04rSmflSX8ptPHk6DC5+t2UARZwJvVZblo5yXgX4PXxbifhnsmQLgHX6m+5qjx2Cv7h44G2neasnAdYWgatnEugC/dcitL6iYpHnoCuKU/tKhAAAAYAsh8zXDUzQutEw6okRFeAwtZVuUAXTK44x8ik5kk8C6n9MDdIJnsIO5p6bLYeQts2K4yYlttwZOAq1a5hWH2hW0ZJyQWUkJ/rN9vLZUvrcmjsgB5ai0qjkRvr2IVC8Fvg==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/key8 b/nss/cmd/bltest/tests/rsa_oaep/key8
new file mode 100644
index 0000000..3c9f874
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/key8
@@ -0,0 +1 @@
+AAAAAQAAAADAzyzUHjTKOnKOpcuK/2TDbSe971Nk4zb9aNMSPFoZaowocBPoU9UVbVjRUZVFIPtPbXsXq7aBd2WQnFdhGWWdkCsZBu2KKxDBVcJNEkUo2rnurjeb6sZuSkEXhty4/QBi68Aw3hIZoEwqjBt90xMeTWtsruLjGl7UGsFQmy7x7iqxg2S+VoypQcJezIT/nWQ7XsGqrhAqINc/R5t4D9bakQdSEtnqwDoGdNiZ66LkMfTES2Fba6IjK9SzO67XPWJdAAAAAwEAAQAAAMAZjBQeI3FakrzPahGaW8ETiUaNKBH1SNcn4XtKsOuYbW8hHvtTtx98y+qH7mnHXuYVAIxTMt61K/OQq9+/431yBTaBWbJjjB3jJuIdIiUfD7WEizvxUAXSp0Mw8K/pFu5izME0TR2DpwnmBnYnOED383dCSl4KTadfAbMf92gZz5y/3SFSQ8ORfAPvOBmTEuVns7967Tq0V/Nx74oUI/RbaMbiguwRG7ooM7mH/Wn62DvBuMYTxeHqFsEe0SXqfsEAAABg/I1sBL7E65qBksp5AMvlNuLotRnezzOyRZeYxpCd9PF2230jGQ/HK4hlpxiviV8bzZFFKYAnQjtgXnCkfPWDkKjD6I/IxI6LMuPaIQ374+iB6lZ0tqNIwh6T+eVepl79AAAAYNIA1F54iqzqYGpAHQRg+H3VwQJ+EtwaDXWG6JOdnPeJtA9RrARClh3n0hzCHgXIMVXB8qqRkzh8/flWy0jRU7onBAb5u7pTfUmH2eL5lC16FMv//qdP7N2pKNI+JZ9e4QAAAGDbFoAveaLw1F81jWn9M+RLgfroKGIuk6VCU+mX0BsHQ3WdoOgStKpObIvqsjKNVDGVWkGKZ/8mqMXIB6XaNU4F7zHMjPdY9GNzKVCwPiZXJvuU451qVyomJEqwjbdXUq0AAABgoKMXz+ffFCP4em3uhFH04rSmflSX8ptPHk6DC5+t2UARZwJvVZblo5yXgX4PXxbifhnsmQLgHX6m+5qjx2Cv7h44G2neasnAdYWgatnEugC/dcitL6iYpHnoCuKU/tKhAAAAYAsh8zXDUzQutEw6okRFeAwtZVuUAXTK44x8ik5kk8C6n9MDdIJnsIO5p6bLYeQts2K4yYlttwZOAq1a5hWH2hW0ZJyQWUkJ/rN9vLZUvrcmjsgB5ai0qjkRvr2IVC8Fvg==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/key9 b/nss/cmd/bltest/tests/rsa_oaep/key9
new file mode 100644
index 0000000..3c9f874
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/key9
@@ -0,0 +1 @@
+AAAAAQAAAADAzyzUHjTKOnKOpcuK/2TDbSe971Nk4zb9aNMSPFoZaowocBPoU9UVbVjRUZVFIPtPbXsXq7aBd2WQnFdhGWWdkCsZBu2KKxDBVcJNEkUo2rnurjeb6sZuSkEXhty4/QBi68Aw3hIZoEwqjBt90xMeTWtsruLjGl7UGsFQmy7x7iqxg2S+VoypQcJezIT/nWQ7XsGqrhAqINc/R5t4D9bakQdSEtnqwDoGdNiZ66LkMfTES2Fba6IjK9SzO67XPWJdAAAAAwEAAQAAAMAZjBQeI3FakrzPahGaW8ETiUaNKBH1SNcn4XtKsOuYbW8hHvtTtx98y+qH7mnHXuYVAIxTMt61K/OQq9+/431yBTaBWbJjjB3jJuIdIiUfD7WEizvxUAXSp0Mw8K/pFu5izME0TR2DpwnmBnYnOED383dCSl4KTadfAbMf92gZz5y/3SFSQ8ORfAPvOBmTEuVns7967Tq0V/Nx74oUI/RbaMbiguwRG7ooM7mH/Wn62DvBuMYTxeHqFsEe0SXqfsEAAABg/I1sBL7E65qBksp5AMvlNuLotRnezzOyRZeYxpCd9PF2230jGQ/HK4hlpxiviV8bzZFFKYAnQjtgXnCkfPWDkKjD6I/IxI6LMuPaIQ374+iB6lZ0tqNIwh6T+eVepl79AAAAYNIA1F54iqzqYGpAHQRg+H3VwQJ+EtwaDXWG6JOdnPeJtA9RrARClh3n0hzCHgXIMVXB8qqRkzh8/flWy0jRU7onBAb5u7pTfUmH2eL5lC16FMv//qdP7N2pKNI+JZ9e4QAAAGDbFoAveaLw1F81jWn9M+RLgfroKGIuk6VCU+mX0BsHQ3WdoOgStKpObIvqsjKNVDGVWkGKZ/8mqMXIB6XaNU4F7zHMjPdY9GNzKVCwPiZXJvuU451qVyomJEqwjbdXUq0AAABgoKMXz+ffFCP4em3uhFH04rSmflSX8ptPHk6DC5+t2UARZwJvVZblo5yXgX4PXxbifhnsmQLgHX6m+5qjx2Cv7h44G2neasnAdYWgatnEugC/dcitL6iYpHnoCuKU/tKhAAAAYAsh8zXDUzQutEw6okRFeAwtZVuUAXTK44x8ik5kk8C6n9MDdIJnsIO5p6bLYeQts2K4yYlttwZOAq1a5hWH2hW0ZJyQWUkJ/rN9vLZUvrcmjsgB5ai0qjkRvr2IVC8Fvg==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/maskhash0 b/nss/cmd/bltest/tests/rsa_oaep/maskhash0
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/maskhash0
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/maskhash1 b/nss/cmd/bltest/tests/rsa_oaep/maskhash1
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/maskhash1
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/maskhash10 b/nss/cmd/bltest/tests/rsa_oaep/maskhash10
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/maskhash10
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/maskhash11 b/nss/cmd/bltest/tests/rsa_oaep/maskhash11
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/maskhash11
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/maskhash12 b/nss/cmd/bltest/tests/rsa_oaep/maskhash12
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/maskhash12
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/maskhash13 b/nss/cmd/bltest/tests/rsa_oaep/maskhash13
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/maskhash13
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/maskhash14 b/nss/cmd/bltest/tests/rsa_oaep/maskhash14
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/maskhash14
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/maskhash15 b/nss/cmd/bltest/tests/rsa_oaep/maskhash15
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/maskhash15
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/maskhash16 b/nss/cmd/bltest/tests/rsa_oaep/maskhash16
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/maskhash16
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/maskhash17 b/nss/cmd/bltest/tests/rsa_oaep/maskhash17
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/maskhash17
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/maskhash2 b/nss/cmd/bltest/tests/rsa_oaep/maskhash2
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/maskhash2
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/maskhash3 b/nss/cmd/bltest/tests/rsa_oaep/maskhash3
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/maskhash3
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/maskhash4 b/nss/cmd/bltest/tests/rsa_oaep/maskhash4
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/maskhash4
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/maskhash5 b/nss/cmd/bltest/tests/rsa_oaep/maskhash5
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/maskhash5
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/maskhash6 b/nss/cmd/bltest/tests/rsa_oaep/maskhash6
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/maskhash6
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/maskhash7 b/nss/cmd/bltest/tests/rsa_oaep/maskhash7
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/maskhash7
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/maskhash8 b/nss/cmd/bltest/tests/rsa_oaep/maskhash8
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/maskhash8
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/maskhash9 b/nss/cmd/bltest/tests/rsa_oaep/maskhash9
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/maskhash9
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_oaep/numtests b/nss/cmd/bltest/tests/rsa_oaep/numtests
new file mode 100644
index 0000000..3c03207
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/numtests
@@ -0,0 +1 @@
+18
diff --git a/nss/cmd/bltest/tests/rsa_oaep/plaintext0 b/nss/cmd/bltest/tests/rsa_oaep/plaintext0
new file mode 100644
index 0000000000000000000000000000000000000000..5961feea3d47407f8b2be5ccc39ba3f7928a99d6
GIT binary patch
literal 28
kcmYe(kn|H`x7}d9(&yH^pTWx0uk!Ay+}Y0H_3xhv0G$2|c>n+a
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/rsa_oaep/plaintext1 b/nss/cmd/bltest/tests/rsa_oaep/plaintext1
new file mode 100644
index 0000000..bd17cf9
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/plaintext1
@@ -0,0 +1 @@
+u@GõGèä…e#)ŠÉºâEﯗûåoÕ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/plaintext10 b/nss/cmd/bltest/tests/rsa_oaep/plaintext10
new file mode 100644
index 0000000..d07c85b
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/plaintext10
@@ -0,0 +1 @@
+SæèÇ)ÖùÃÝ1~t°ÛŽLÌ¢_<ƒtnzÆ:cï79絕«¹nUåO{Ô´37û‘
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/plaintext11 b/nss/cmd/bltest/tests/rsa_oaep/plaintext11
new file mode 100644
index 0000000..fcd6baa
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/plaintext11
@@ -0,0 +1 @@
+¶²Ž¢¼d
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/plaintext12 b/nss/cmd/bltest/tests/rsa_oaep/plaintext12
new file mode 100644
index 0000000..a154e41
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/plaintext12
@@ -0,0 +1 @@
+‹ºkø*l†Õñun—•hp°‰S°kN²¼”î
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/plaintext13 b/nss/cmd/bltest/tests/rsa_oaep/plaintext13
new file mode 100644
index 0000000..8af8ac6
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/plaintext13
@@ -0,0 +1 @@
+æ;X©òEu7>W
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/plaintext14 b/nss/cmd/bltest/tests/rsa_oaep/plaintext14
new file mode 100644
index 0000000..b302369
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/plaintext14
@@ -0,0 +1,2 @@
+Q
+,ö†o¢4SÉN£Ÿ¼%cè>”EKA$
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/plaintext15 b/nss/cmd/bltest/tests/rsa_oaep/plaintext15
new file mode 100644
index 0000000000000000000000000000000000000000..36812091de63f6bc664e4b80344adb93975c21a5
GIT binary patch
literal 36
ucmV+<0Nek(-5Cv|x6=UMng-%5s^X_#5Xm3*XScy?-iuQPN+wCEKt;({8xghu
literal 0
HcmV?d00001
diff --git a/nss/cmd/bltest/tests/rsa_oaep/plaintext16 b/nss/cmd/bltest/tests/rsa_oaep/plaintext16
new file mode 100644
index 0000000..7449ac6
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/plaintext16
@@ -0,0 +1 @@
+§Ýl}ÂKFùÝ_‘¤Ã³ß”~‡r2©
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/plaintext17 b/nss/cmd/bltest/tests/rsa_oaep/plaintext17
new file mode 100644
index 0000000..f3945c8
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/plaintext17
@@ -0,0 +1 @@
+êñ§:F S}æœÙ"‹¼ûšŒ¨ÆÃï¯oä§ôcNÐ|9ìi"׸ê,ë¬
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/plaintext2 b/nss/cmd/bltest/tests/rsa_oaep/plaintext2
new file mode 100644
index 0000000..6c08a2a
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/plaintext2
@@ -0,0 +1 @@
+ÙJàƒ.dEÎB3°mS‚±ÛKªÓtmÉß$ÔãÂEÿY¦B>°áÐ-OæFÏiýŒn—°Q
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/plaintext3 b/nss/cmd/bltest/tests/rsa_oaep/plaintext3
new file mode 100644
index 0000000..efd84ad
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/plaintext3
@@ -0,0 +1 @@
+RæPÙŽ*‹O†…!S¹~Ý1o4jöz…
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/plaintext4 b/nss/cmd/bltest/tests/rsa_oaep/plaintext4
new file mode 100644
index 0000000..1796336
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/plaintext4
@@ -0,0 +1 @@
+¨ŸÙåùt¢ŸïûF+Ilùè
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/plaintext5 b/nss/cmd/bltest/tests/rsa_oaep/plaintext5
new file mode 100644
index 0000000..38913e9
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/plaintext5
@@ -0,0 +1 @@
+&RP„Bq
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/plaintext6 b/nss/cmd/bltest/tests/rsa_oaep/plaintext6
new file mode 100644
index 0000000..5d4bf7c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/plaintext6
@@ -0,0 +1 @@
+÷5ýUº’Y,;R¸ùÄöšª¾øþˆÐ•YTFœôì‰lYí¡bçTœŠ»Í¼!¡.ɶµ¸ý/9ž¶
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/plaintext7 b/nss/cmd/bltest/tests/rsa_oaep/plaintext7
new file mode 100644
index 0000000..d1bf800
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/plaintext7
@@ -0,0 +1 @@
+¹`P¦:«ä-ßá—‰õ@Ltt²mÎ>Ô‚¿–Ì‹ô ÅFY
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/plaintext8 b/nss/cmd/bltest/tests/rsa_oaep/plaintext8
new file mode 100644
index 0000000..bb96c95
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/plaintext8
@@ -0,0 +1 @@
+ý2d)ß›‰ µK¸óO$
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/plaintext9 b/nss/cmd/bltest/tests/rsa_oaep/plaintext9
new file mode 100644
index 0000000..8a71ad8
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/plaintext9
@@ -0,0 +1,3 @@
+ñE›_’ðr:.VbHMŒ
+ ü)ÚÖ¬Ô;µóïýôá¶>ýþf(Ð×L¡›òÖžJ
+¿†Ò“’ZygrøŽ
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_oaep/seed0 b/nss/cmd/bltest/tests/rsa_oaep/seed0
new file mode 100644
index 0000000..8b990a2
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/seed0
@@ -0,0 +1 @@
+GLd26iEGnWl3ajPpa61I4d2gpe8=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/seed1 b/nss/cmd/bltest/tests/rsa_oaep/seed1
new file mode 100644
index 0000000..afb497d
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/seed1
@@ -0,0 +1 @@
+DMdCzkqbfzL5UbyyUe/ZJf5P418=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/seed10 b/nss/cmd/bltest/tests/rsa_oaep/seed10
new file mode 100644
index 0000000..762ceaf
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/seed10
@@ -0,0 +1 @@
+/LxCFALp7KvGCCr6QLpfJlIshA4=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/seed11 b/nss/cmd/bltest/tests/rsa_oaep/seed11
new file mode 100644
index 0000000..5cfd292
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/seed11
@@ -0,0 +1 @@
+I6reDh4Iu5uaeNIwKlL5whsuG6I=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/seed12 b/nss/cmd/bltest/tests/rsa_oaep/seed12
new file mode 100644
index 0000000..516e13d
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/seed12
@@ -0,0 +1 @@
+R+GrcRn+5WyV7l6q2G9A0KpjvTM=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/seed13 b/nss/cmd/bltest/tests/rsa_oaep/seed13
new file mode 100644
index 0000000..680ddbd
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/seed13
@@ -0,0 +1 @@
+bRf1tMH/rDUdGVv3sJ0J8JpAec8=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/seed14 b/nss/cmd/bltest/tests/rsa_oaep/seed14
new file mode 100644
index 0000000..f41e51c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/seed14
@@ -0,0 +1 @@
+OFOHUU3szHx0DdjN+druSaHL/VQ=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/seed15 b/nss/cmd/bltest/tests/rsa_oaep/seed15
new file mode 100644
index 0000000..9a825c9
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/seed15
@@ -0,0 +1 @@
+XKymoPdkFhqWhPhdkrbg7zfKi2U=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/seed16 b/nss/cmd/bltest/tests/rsa_oaep/seed16
new file mode 100644
index 0000000..dcf464d
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/seed16
@@ -0,0 +1 @@
+lbyp44WYlLPdhp+n7NW7xkAb8+Q=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/seed17 b/nss/cmd/bltest/tests/rsa_oaep/seed17
new file mode 100644
index 0000000..90133c7
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/seed17
@@ -0,0 +1 @@
+n0fd9C6X7qhWqb28cU6zrCL26zI=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/seed2 b/nss/cmd/bltest/tests/rsa_oaep/seed2
new file mode 100644
index 0000000..0c82aab
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/seed2
@@ -0,0 +1 @@
+JRTfRpV1WmeyiOr0kFw27sZv0v0=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/seed3 b/nss/cmd/bltest/tests/rsa_oaep/seed3
new file mode 100644
index 0000000..4cd022e
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/seed3
@@ -0,0 +1 @@
+xENaPhoYpotoIENikKN877hds/s=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/seed4 b/nss/cmd/bltest/tests/rsa_oaep/seed4
new file mode 100644
index 0000000..275f908
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/seed4
@@ -0,0 +1 @@
+sxjELfO+D4P+qCP1p7R+1eQlo7U=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/seed5 b/nss/cmd/bltest/tests/rsa_oaep/seed5
new file mode 100644
index 0000000..3406494
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/seed5
@@ -0,0 +1 @@
+5OwJgsIzbzpnf2o1YXTrDOiHq8I=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/seed6 b/nss/cmd/bltest/tests/rsa_oaep/seed6
new file mode 100644
index 0000000..c7316f9
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/seed6
@@ -0,0 +1 @@
+jsll8TSj7Jkx6SocoNyBadXqcFw=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/seed7 b/nss/cmd/bltest/tests/rsa_oaep/seed7
new file mode 100644
index 0000000..a4cbd16
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/seed7
@@ -0,0 +1 @@
+7LG4sl+lDNqwjlYEKGf0r1gm0Ww=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/seed8 b/nss/cmd/bltest/tests/rsa_oaep/seed8
new file mode 100644
index 0000000..d4a76a0
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/seed8
@@ -0,0 +1 @@
+6JuwMsbOYiy9tTvJRmAU6nf3d8A=
diff --git a/nss/cmd/bltest/tests/rsa_oaep/seed9 b/nss/cmd/bltest/tests/rsa_oaep/seed9
new file mode 100644
index 0000000..8cd39a9
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_oaep/seed9
@@ -0,0 +1 @@
+YG87mcC5zNdx6qKeoOTIhPMYnMw=
diff --git a/nss/cmd/bltest/tests/rsa_pss/ciphertext0 b/nss/cmd/bltest/tests/rsa_pss/ciphertext0
new file mode 100644
index 0000000..0ed7e8c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/ciphertext0
@@ -0,0 +1,3 @@
+kHQwj7WY6XAbIpQ4jlL5cfqsK2ClFFrxhd9Sh7XtKIflfOf9RNyGNOQHyODkNgvCJvPsIn+dnlRj
+jo0x9QUSFd9uu5wvlXmqd1mKOPkUtbnBvYPE4vnzgqDQqjVC/+5lmEpgG8aeso3rJ9yhLILC1MP2
+bNUA8f8rmU2KTjDLszw=
diff --git a/nss/cmd/bltest/tests/rsa_pss/ciphertext1 b/nss/cmd/bltest/tests/rsa_pss/ciphertext1
new file mode 100644
index 0000000..01aa061
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/ciphertext1
@@ -0,0 +1,3 @@
+Pvf0boMb+SsyJ0FCpYX/zvvcp7Mq6Q0Q+w8McpmE8E7ymp3weAd1zkNzm5eDg5DbClUF5j3pJwKN
+nSmyGcosRReDJVilXWlKbSW52rZgA8TMzZB4Ahk75RcNJhR9N7k1kCQb5RwlBV9H72J1LPviFBj6
+/pjCLE1NR3JP21Zp6EM=
diff --git a/nss/cmd/bltest/tests/rsa_pss/ciphertext10 b/nss/cmd/bltest/tests/rsa_pss/ciphertext10
new file mode 100644
index 0000000..f31ec8e
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/ciphertext10
@@ -0,0 +1,4 @@
+ghAt+MuR5xeZGaBNJtM11k+8L4csRIM5QyQd6EVIECdM3z219C1CPbFSr3E19wFCDjm0lKZ8v9Gf
+kRnaIzoj2lxkObW6DSvDc+7jUHABN41KQHOFa3/iq6C17pOyf0r+x9TRIJIcg/YGdlsCwZ5Naho7
+lfpMQilRvk9SExB37xcXlynN3721aVDbrO7+eMsWZAoJnqVtJDie7xD4/ssxuj6jsifAqGaYu4nj
+6TY5Bb8id3sqOqUhtltM73bYO95M
diff --git a/nss/cmd/bltest/tests/rsa_pss/ciphertext11 b/nss/cmd/bltest/tests/rsa_pss/ciphertext11
new file mode 100644
index 0000000..2e67c03
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/ciphertext11
@@ -0,0 +1,4 @@
+p/2w0lkWXKLIjQC78QKKhn0zdpnQYRk7F6lkjhTMu6rerKrN7IFedXEpTruKEXryBfoHi0ewcSwZ
+njrQUTXFBMJLgXBRFXQIAkh5kv/VEdSvxrhUSR6z8N1SMTlUL/FcMQHuhVQ1F8ajx5QXxn4t2ap0
+HpopsG3LWTwjNrNnCuOvusfD524hVHPoZuM4yiRN4AtiYk1rlCaCLOrp+MxGCJX0ElAHP9RcWh57
+QlwgSkI6aZFZ9pA+cQs3p7sryASf
diff --git a/nss/cmd/bltest/tests/rsa_pss/ciphertext12 b/nss/cmd/bltest/tests/rsa_pss/ciphertext12
new file mode 100644
index 0000000..7f3530c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/ciphertext12
@@ -0,0 +1,5 @@
+gsKxYAk7iqPA91IrGfhzVAZsd4R6vyqfzlQtDoTpIMWvtJ/9/azhZWDulKE2lgEUjrrXoOFRzxYz
+F5Glcn0F8h505+uBFEAgaTXXRHZaFeefAVy2bFMsh6agWWHIv610GppmVwIolDk+ciNzl5bAKndF
+XQ9VWw7AHd8lm2IH/Q/VdhTO8aVXO6r/TsAAaZUWWbhfJDAKJRYMqFItxuZyflfQGdfmNim4/l6J
+4lzBW+s6ZHV3VZKZKAubKPebBAkAC+JbvZZAi6O0PMSGGE3RyOYlU/oa9AQPYGY95/XknAQ4jiV/
+HOicldq0ijFdm2axt2KCM4dv8jhSMNBw0H4WZg==
diff --git a/nss/cmd/bltest/tests/rsa_pss/ciphertext13 b/nss/cmd/bltest/tests/rsa_pss/ciphertext13
new file mode 100644
index 0000000..2d87915
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/ciphertext13
@@ -0,0 +1,5 @@
+FK412d0GupL387iXl4rtfNS/X/C1haQL1GzhtCzScDBTu5BE1k6BPY+W2y3XAH0QEY9vj4SWCXrX
+Xh/2kjQbKJKtVaYzocVefwoK1ZoOIDpbgniuxU3YYi4oMdhxdPjK/0PubEZEU0XYSlllm/uS7NTI
+GGaGlfNHBvZoKKiZWWN/K/PjJRwkvbpNS3ZJ2gAiIYsRnITnmmUn7FuKX4YcFZlS4j7AXh5xc0b6
+7+ixaGglvSsmL7JTEGbA3gms3i5CMWkHKLXYXhFaL2uSt5wlq8m9k5n/i8+CWlLqH1bqdt0m9Duq
++hi/qSpQTL01aZ4m0dzFoohzhfPGMjLwbzJEww==
diff --git a/nss/cmd/bltest/tests/rsa_pss/ciphertext14 b/nss/cmd/bltest/tests/rsa_pss/ciphertext14
new file mode 100644
index 0000000..eaa167e
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/ciphertext14
@@ -0,0 +1,5 @@
+bj5Ne2sV0vtGATuJAKpbuzk5zywJVxeYcEICbuYsdMVM/9XX1X77v5UKD1xXT6CdP8HJ9ROwW0/1
+Ddjfft+iAQKFTDXlkhgBGacM5bCFGCqgLZ6iqpDR3wPy2q6IW6L10Fr9rJdHbwa5O1vJShqAqpEW
+xNYV8zOwmIkrJf+s4mb121paO8wQqCTtVarTW3J4NPuMB9oo/PQWpdmyIk8fi0QrNvkeRW/eotfP
+4zZyaN4DB6THTpJBWe0zOT1eBlVTHHcye4mCG97fiAFhx4zUGWtUGfesw/E+Xr8WG258ZyRxbKM7
+hcLiVkAZKsKFllHVC95+uXblHOyCi5i2VjuGuw==
diff --git a/nss/cmd/bltest/tests/rsa_pss/ciphertext15 b/nss/cmd/bltest/tests/rsa_pss/ciphertext15
new file mode 100644
index 0000000..a7bff41
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/ciphertext15
@@ -0,0 +1,5 @@
+NAR/+WxNwNyQstT/WaGjYaR1SyVdLuCvfYv4fJvJ593u3jOTTGPKHA49JiyxRe+TKh8sCpl6pqNP
+jq7nR32CzPCQlaa4rK041O7J+36retAtodEdjlTBgl5Vv1jCojI0uQK+Ek+ekDio9o+kXaty9m4J
+Rb8di6zJBExvBwmMn87FijqrEAyAUXgVXwMKEkxFDlrL2kfQ5PELgKI/gD53TQI7ABXCC5+bvnyR
+KWM41ey0ccr7AyAHtnpgvl9pUEqfAauzy0Z7Jg4rzoYL6Nlb+SwMjhSW7R5ShZOkq7bfRi3eiglo
+3/5GgxFoV6Iy9ev2yFviOHRa0POPdnpf2/SG+w==
diff --git a/nss/cmd/bltest/tests/rsa_pss/ciphertext16 b/nss/cmd/bltest/tests/rsa_pss/ciphertext16
new file mode 100644
index 0000000..79e7afb
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/ciphertext16
@@ -0,0 +1,5 @@
+fgk16hj01sHRfOgusrODbFWzhFic4Z3+dDNjrJlI0fNGt7/d/pLv14rbIfrvyJreQrEPN0AD/hIu
+Z0KaHLjL0fjZAUVkxE0SARb0mQ8abjh3TBlL0bghMoawd7BJnS57P0NKsSKJxVZoTe7XgTGTS7Pd
+ZTcjb3xvPcsJ1Ha+B3IeN+HO7Zsve0Boh71TFXMF4ci0+E1zO8Hhhv4GzFm27bj0vX/+/fT3upz7
+nVcGibWhpBCadGppCJPbN5klWgy5IV0tHNSQWQ6VLoyHhqoAESZSUkcMBB37w+7Hw8v3HCSGnRFc
+DLSpVvVtUwuAq1iaz+/GkHUd3zbo04P4PO3SzA==
diff --git a/nss/cmd/bltest/tests/rsa_pss/ciphertext17 b/nss/cmd/bltest/tests/rsa_pss/ciphertext17
new file mode 100644
index 0000000..86b2cfd
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/ciphertext17
@@ -0,0 +1,5 @@
+bTtbh/Z+plevIfdUQZd9IYD5GyxfaS3oKVVpamhnMNm5d42XB1jMsmBxwiCf+9YSW+LpbqgbZ8ub
+kwgjn9oX97K2Ts2glra5NWQKWhy0KpFVscnvemM6AsWfDW7lm4UsQ7NQKec8lA/wQQ6PEU7tRrvQ
++uFl5CviUopAHDso/YGO8yMtyp9NKg9RZuxZxCOW1sEdvBIVpW+hcWnblXU0PvNPneMqSc3DF0ki
+8inCPhjkXfk1MRnsQxnO3OehfGQIjB9vUr4pY0EAs5GdOPPR7ZTmiR5mpzuPuEn1h031lFnimMe7
+zi7ueCoZWqZv4tBzKyXllfV9PgYbH8PkBjv5jw==
diff --git a/nss/cmd/bltest/tests/rsa_pss/ciphertext2 b/nss/cmd/bltest/tests/rsa_pss/ciphertext2
new file mode 100644
index 0000000..47f9922
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/ciphertext2
@@ -0,0 +1,3 @@
+ZmAm+6cb0+fPExV8wsUajkqmhK+XePkYSfNDNdFBwAFUxBl2IfliSmdbWrwi7n1bqv+q4cm6yizD
+c7PzPnjmFDw5WpGqf6ymZOtzOv0U2IJyWdmadVD6ylAe8rBOM8I6pR9LnoKC79tyjMCrCUBakWB8
+Y2mWG8gnDS1POfzmErE=
diff --git a/nss/cmd/bltest/tests/rsa_pss/ciphertext3 b/nss/cmd/bltest/tests/rsa_pss/ciphertext3
new file mode 100644
index 0000000..28306f2
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/ciphertext3
@@ -0,0 +1,3 @@
+Rgl5OyPp0JNi3CG7R9oLTzp2ImSaR9RkAZua6v5TNZwXjJHNWLpry3i+A0anvGN/S4c9S6s47mYf
+GZY0xUehrYRC4D2gFbE25UP3qwfAwT5CJbjejM4l1PbrhAD4H34YM7fubjNNNwlkynn9uHK011Ij
+te6wgQFZH7Uy0VWm3oc=
diff --git a/nss/cmd/bltest/tests/rsa_pss/ciphertext4 b/nss/cmd/bltest/tests/rsa_pss/ciphertext4
new file mode 100644
index 0000000..a83e4f5
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/ciphertext4
@@ -0,0 +1,3 @@
+HSqtIhyk0x3fE1CSOQGTmOPRSzLcNNxa9K6uo8CVr3NHnPCkXlYpY1pToBg3dhWxbLmxOz4J1nHr
+ceOHuFRcWWDaWmR3bnaOgrLJNYO/EEw/2yNRK3tOifYz3QBjpTDbRSSwHD84TAkxDjFaedzT1oQC
+Kn8xyGWmZOMWl4t1n60=
diff --git a/nss/cmd/bltest/tests/rsa_pss/ciphertext5 b/nss/cmd/bltest/tests/rsa_pss/ciphertext5
new file mode 100644
index 0000000..b4a3e3c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/ciphertext5
@@ -0,0 +1,3 @@
+KjT2El4fawv5cehPvUHGMr6PLCrOfei2km4x/5Ppr5h/vAblHpvhT1GY+R8/lTvWfaYKnfWXZMPc
+D+COHL7wt1+GjRCtP7p0n+9Z+22sRqDW5QQ2kzFYb1jkYo85qieJglQ7wO61N9xhlYAZs5T7Jz8h
+WFigoBrE1lC5VcZ/TFg=
diff --git a/nss/cmd/bltest/tests/rsa_pss/ciphertext6 b/nss/cmd/bltest/tests/rsa_pss/ciphertext6
new file mode 100644
index 0000000..92a284c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/ciphertext6
@@ -0,0 +1,4 @@
+WGEHImw84BOnyPBNGmopWbtLjiBbpDontQ8SQRG8Ne9YmwOfWTIYfLaW19mjLAw4MApc3aSDS2LS
+6yQK8z950T378JW/WZ4NloaUjBlkdHtn6JyaulzYUBYjb1ZsxYAssT6tUbx8pr7zuU3L27HVcEaX
+cd8OALGooGd3Ry0jFiee2uhkdGaNTh7/+V8d5hxgINoyrpK78WUg/vPPTYj2ESHyS72f6RtZyvEj
+WyqT/4H8QDrd9OveqEk0qc2vjhqe
diff --git a/nss/cmd/bltest/tests/rsa_pss/ciphertext7 b/nss/cmd/bltest/tests/rsa_pss/ciphertext7
new file mode 100644
index 0000000..55bed19
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/ciphertext7
@@ -0,0 +1,4 @@
+gLbWQyVSCfCkVnY4l6ye0lnUWbScKIfliC7LRDTP1m3X4WmTdTgeUc1/VU8sJxcEs5nUK0viVAoO
+ymGVH1Umf3woeMEihC2tsosBvV+MAl9+IoQYpnPAPWvAxzbQopVGvWf3htnWkszqd41x2YwgY7en
+EJIYek01rxCBEdg+g+rkbEaqNCd+BgRFiZA3iPHV587iX7SF6SlJEYgU1vLD7jYUiQFvMn+1vFF+
+tQRwv/oa+l9M6aoM5bjuGb9VAblY
diff --git a/nss/cmd/bltest/tests/rsa_pss/ciphertext8 b/nss/cmd/bltest/tests/rsa_pss/ciphertext8
new file mode 100644
index 0000000..b6a3018
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/ciphertext8
@@ -0,0 +1,4 @@
+SEQI84mM1fU0g/gIGe+/JwjDTSeosqb66LMi+SQCN/mBgXrKGEbxCE2qbXwHlfblvxr1nDjhhYQ3
+zh9+xBm5jIc2rfbdmgCxgG0r060Kc3deBfUt/vOlmrSwgUPw3wXNGtnQS+zsptqkohKYA+IAy8d3
+h8r0wdBmOmxZh7YFlSAZeCyvLsFCbWj7lO0dS+gWp+0IG3fmqzMLP/wHOCD+zeNyf8vile5hoFCj
+Q2WGN8P9ZZz7Y3Nt4y2fkNPC9j7K
diff --git a/nss/cmd/bltest/tests/rsa_pss/ciphertext9 b/nss/cmd/bltest/tests/rsa_pss/ciphertext9
new file mode 100644
index 0000000..0da2bcb
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/ciphertext9
@@ -0,0 +1,4 @@
+hOvrSBvlmEW0ZGi6+0ccARLgKyNdhLXZEcvRkm7lB0rgQkSVyyDoIwi467ZfQZoD+0DnK3iYHYiq
+0UMFNoUXLJeynIt78K5ztbImPEA9oO0vgP90UK94KOuLhvACi9KosXak0ijMzqGDlPI4sJ/3WMwA
+vAQwEVI1V0LygrVOZjqRnnCdjaJK3lUAp7mqUCJuDKUpI+bC2GDsUP9ID6V0d+grBWX0N595x3LV
+wtqAr5+/Ml7Ob8ILAJYWFL7omhg+
diff --git a/nss/cmd/bltest/tests/rsa_pss/hash0 b/nss/cmd/bltest/tests/rsa_pss/hash0
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/hash0
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/hash1 b/nss/cmd/bltest/tests/rsa_pss/hash1
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/hash1
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/hash10 b/nss/cmd/bltest/tests/rsa_pss/hash10
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/hash10
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/hash11 b/nss/cmd/bltest/tests/rsa_pss/hash11
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/hash11
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/hash12 b/nss/cmd/bltest/tests/rsa_pss/hash12
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/hash12
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/hash13 b/nss/cmd/bltest/tests/rsa_pss/hash13
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/hash13
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/hash14 b/nss/cmd/bltest/tests/rsa_pss/hash14
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/hash14
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/hash15 b/nss/cmd/bltest/tests/rsa_pss/hash15
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/hash15
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/hash16 b/nss/cmd/bltest/tests/rsa_pss/hash16
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/hash16
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/hash17 b/nss/cmd/bltest/tests/rsa_pss/hash17
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/hash17
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/hash2 b/nss/cmd/bltest/tests/rsa_pss/hash2
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/hash2
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/hash3 b/nss/cmd/bltest/tests/rsa_pss/hash3
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/hash3
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/hash4 b/nss/cmd/bltest/tests/rsa_pss/hash4
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/hash4
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/hash5 b/nss/cmd/bltest/tests/rsa_pss/hash5
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/hash5
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/hash6 b/nss/cmd/bltest/tests/rsa_pss/hash6
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/hash6
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/hash7 b/nss/cmd/bltest/tests/rsa_pss/hash7
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/hash7
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/hash8 b/nss/cmd/bltest/tests/rsa_pss/hash8
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/hash8
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/hash9 b/nss/cmd/bltest/tests/rsa_pss/hash9
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/hash9
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/key0 b/nss/cmd/bltest/tests/rsa_pss/key0
new file mode 100644
index 0000000..4615480
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/key0
@@ -0,0 +1 @@
+AAAAAQAAAACApW5KDnAQF1iaUYfcfqhB0Vby7A42rVKkTf6x5h962ZHYxRBW/+2xYrTA8oOhKoijlN/1JqtykcuzB86r/OCx39XNlQgJbVsri2311nHvY3fAkhyyPCcKcOJZjm/4nRnxBazC0/DLNfKSgOE4a29kxO8i4eHyDQzoz/siSb2aITcAAAADAQABAAAAgDOlBCqQsn1PVFHKm7vQtEdxoQGviENArvmIXypLvpLolKckrDxWjI+XhTrQfAJmyMajygkp8ejxEjGIRCn8TZrlX+6JahDOcHw+1+c05Ecno5V0UBpTJoMQnCq6yrooPDG0vS9Tw+4341LO40+eUDvYDAYirXnG3O6INUfGo7MlAAAAQOfolCcgqHdRcnOjVgU+oqG8DJSqctVcboYpay38lnlIwKcsvMyn6ss1cG4Jod9VoVNb2bPMNBYLO23NPtqOZEMAAABAtp3KHPfU1+yB51uQ/MqHSrzeEj/ScAGAqpBHm25I3o1n7ST58Z2FuidYdPVCzSDccj5pYzZKH5QlRSsmmmeZ/QAAAEAo+hOThlW+H4oVnLrKWnLqGQwwCJ4ZzSdKVW82xPbhn1VLNMB3eQQnu92N0+3iRIMo84XYGzDo5Dsv/6Anhhl5AAAAQBqLOPOY+nEgSYmNf7ee4Kd2aHkSmc36Ce/A5Qessh7XQwHvW/1IvkVerrbhZ4JVgnWAqOTo4UFR0VEKgqPy5ykAAABAJxVqukEm0kqB86Uoy/sn9WiG+ECp9uhuF6RLlP6TGVhLjiL93h5aLjvYqluo2FhBlOshkKz4MrhH8To9JKefTQ==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_pss/key1 b/nss/cmd/bltest/tests/rsa_pss/key1
new file mode 100644
index 0000000..4615480
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/key1
@@ -0,0 +1 @@
+AAAAAQAAAACApW5KDnAQF1iaUYfcfqhB0Vby7A42rVKkTf6x5h962ZHYxRBW/+2xYrTA8oOhKoijlN/1JqtykcuzB86r/OCx39XNlQgJbVsri2311nHvY3fAkhyyPCcKcOJZjm/4nRnxBazC0/DLNfKSgOE4a29kxO8i4eHyDQzoz/siSb2aITcAAAADAQABAAAAgDOlBCqQsn1PVFHKm7vQtEdxoQGviENArvmIXypLvpLolKckrDxWjI+XhTrQfAJmyMajygkp8ejxEjGIRCn8TZrlX+6JahDOcHw+1+c05Ecno5V0UBpTJoMQnCq6yrooPDG0vS9Tw+4341LO40+eUDvYDAYirXnG3O6INUfGo7MlAAAAQOfolCcgqHdRcnOjVgU+oqG8DJSqctVcboYpay38lnlIwKcsvMyn6ss1cG4Jod9VoVNb2bPMNBYLO23NPtqOZEMAAABAtp3KHPfU1+yB51uQ/MqHSrzeEj/ScAGAqpBHm25I3o1n7ST58Z2FuidYdPVCzSDccj5pYzZKH5QlRSsmmmeZ/QAAAEAo+hOThlW+H4oVnLrKWnLqGQwwCJ4ZzSdKVW82xPbhn1VLNMB3eQQnu92N0+3iRIMo84XYGzDo5Dsv/6Anhhl5AAAAQBqLOPOY+nEgSYmNf7ee4Kd2aHkSmc36Ce/A5Qessh7XQwHvW/1IvkVerrbhZ4JVgnWAqOTo4UFR0VEKgqPy5ykAAABAJxVqukEm0kqB86Uoy/sn9WiG+ECp9uhuF6RLlP6TGVhLjiL93h5aLjvYqluo2FhBlOshkKz4MrhH8To9JKefTQ==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_pss/key10 b/nss/cmd/bltest/tests/rsa_pss/key10
new file mode 100644
index 0000000..ef62249
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/key10
@@ -0,0 +1 @@
+AAAAAQAAAADA5r1pKslmRXkEA/3Q9b64ub+S7RAAf8NlBGQZ3QbAXFtbL0js+YnkziaRCZecu0C0oK0k0iSD0e4xWtTMsVNCaDUmkcUk9t2ObCnSJM8kaXOuyGxb9rFAGoUNG5rRu4y87Eewbw+Mf0XT/I8xkpnFQz3bwrMFO0fe0uzUpMrv1hSDPci7Yi8xftB2uAV/6N4/hEgK1eg+SmGQSk8kj7OXAnNX4dMORjE5gVxv1P1axbgXKkUjDstjGKBPFFXYTlqLAAAAAwEAAQAAAMBqf9hPuF+tBzs0QG23T41hpqvBIZapYd15Vl6dpuUYe84tmAJQ9zWVdTWScNkVkLsOQnxxRgtV1RQQsZG88wn+oTGpLI5wJzj6cZ8eAEH1LkDpHyKfTZah5vFy4VWWtFEKba7CYQXyvrxTMWuHvfITEWZgcOjf7mnVLHGpdsqueccraNKFgNxobZ9RKdIl+Cs9YVUTqIKz25FBa0jOCIiCE+N+65r4ANgcqzKM5CBomQPADHtf0xt1UDptQZaE1ikAAABg+OuX6Y3xJmTu/bdhWWpp3c0Odtrs5u1L9aG1CsCG95KKTS+HJqd+UVt02kGYjyILHMh6ofyBDOmagvLRzoIe3O15TGlB9Cx6GguMTSjHXsYLZSJ59hVKdirtFl1H3uNnAAAAYO1NcdCm4kuTwuX2tLvgX1+wr6BC0gT+M3jTZcLyiLao2tfv5F0VPu9Aysx7gf+TQALRCJlLlKXkcozZyWM3WuSZZb2lXL8O/tjWVTtAJ/LYYgim5rSJwXYSgJLWKeSdPQAAAGArtovd+wxPVshVi/+viS2AQwN4Qef6gc+mGjjF45uQHI7nESKl2iInvWze60gUUsEq09YdXk93agq1Vlkb7+Plnlp/3bg0Xh8vNbn0zuV8MkFMCGrsmT6TU+SA2e7GKJ8AAABgT/iXcJ+tB5dGSUV45w/YVGEw7qtWJ8SbCA8F7krZ8+S3y6nWpd/xE6QcNAkzaDPxkIFtimvELpvsVrdWfQ88nGltthmyRdkB3YVtt8gJLnfpoczNVu5NukLF/bYa7CZpAAAAYHe50RN7UEBKmCcpMW76/H3+ZtNOWhgmANXzCgqFEgUcVg0IHU0KGDXsPSWmD05NaqlIsr89u1sSTLvDSJJVo6lINy9peElnRflD4dtPGDgs6qUF38ZXV7s/hXpY3OUhVg==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_pss/key11 b/nss/cmd/bltest/tests/rsa_pss/key11
new file mode 100644
index 0000000..ef62249
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/key11
@@ -0,0 +1 @@
+AAAAAQAAAADA5r1pKslmRXkEA/3Q9b64ub+S7RAAf8NlBGQZ3QbAXFtbL0js+YnkziaRCZecu0C0oK0k0iSD0e4xWtTMsVNCaDUmkcUk9t2ObCnSJM8kaXOuyGxb9rFAGoUNG5rRu4y87Eewbw+Mf0XT/I8xkpnFQz3bwrMFO0fe0uzUpMrv1hSDPci7Yi8xftB2uAV/6N4/hEgK1eg+SmGQSk8kj7OXAnNX4dMORjE5gVxv1P1axbgXKkUjDstjGKBPFFXYTlqLAAAAAwEAAQAAAMBqf9hPuF+tBzs0QG23T41hpqvBIZapYd15Vl6dpuUYe84tmAJQ9zWVdTWScNkVkLsOQnxxRgtV1RQQsZG88wn+oTGpLI5wJzj6cZ8eAEH1LkDpHyKfTZah5vFy4VWWtFEKba7CYQXyvrxTMWuHvfITEWZgcOjf7mnVLHGpdsqueccraNKFgNxobZ9RKdIl+Cs9YVUTqIKz25FBa0jOCIiCE+N+65r4ANgcqzKM5CBomQPADHtf0xt1UDptQZaE1ikAAABg+OuX6Y3xJmTu/bdhWWpp3c0Odtrs5u1L9aG1CsCG95KKTS+HJqd+UVt02kGYjyILHMh6ofyBDOmagvLRzoIe3O15TGlB9Cx6GguMTSjHXsYLZSJ59hVKdirtFl1H3uNnAAAAYO1NcdCm4kuTwuX2tLvgX1+wr6BC0gT+M3jTZcLyiLao2tfv5F0VPu9Aysx7gf+TQALRCJlLlKXkcozZyWM3WuSZZb2lXL8O/tjWVTtAJ/LYYgim5rSJwXYSgJLWKeSdPQAAAGArtovd+wxPVshVi/+viS2AQwN4Qef6gc+mGjjF45uQHI7nESKl2iInvWze60gUUsEq09YdXk93agq1Vlkb7+Plnlp/3bg0Xh8vNbn0zuV8MkFMCGrsmT6TU+SA2e7GKJ8AAABgT/iXcJ+tB5dGSUV45w/YVGEw7qtWJ8SbCA8F7krZ8+S3y6nWpd/xE6QcNAkzaDPxkIFtimvELpvsVrdWfQ88nGltthmyRdkB3YVtt8gJLnfpoczNVu5NukLF/bYa7CZpAAAAYHe50RN7UEBKmCcpMW76/H3+ZtNOWhgmANXzCgqFEgUcVg0IHU0KGDXsPSWmD05NaqlIsr89u1sSTLvDSJJVo6lINy9peElnRflD4dtPGDgs6qUF38ZXV7s/hXpY3OUhVg==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_pss/key12 b/nss/cmd/bltest/tests/rsa_pss/key12
new file mode 100644
index 0000000..9f74b31
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/key12
@@ -0,0 +1 @@
+AAAAAQAAAAEApd2GesTLAvkLlFfUjBSncO+ZHFbDnA7GX9Ea+ok3zqV7m+esc7RcABdhW4LWIuMYdTtgJ8D9FXvhL4CQ/uKnrc0O73WfiLpJl8ekLVjJqhLLma4AH+UhwTu1QxRFqNWuT15MfpSKwifTYEBx8g5XfpBfvrFd+vBtHeWuYlPWOmohILMaXaXavJVQYA4g8n03OeJieSX+o8xQnyHf8E5u6kVJxUDWgJ/5MH7t6R//WHM9g4WiN9bTcFoz45GQCZIHDfet8TV89+NwDONmfeg/F7jfF3jbOB3OCctK0FilEQAac4GY7ifPVaE7dUU5kGWC7IsXS9WNXR89dnxhNyGuBQAAAAMBAAEAAAEALS/1Z7P+dOBhkbf97W3hEikMZwaSQw1ZaRhAR9ojTJaT3u0Wc+1ClTnJadNywE1rR+D1uM7ghD5cIoNdvTsFoJl5hK5gWLEbxJB8v2fthPqa4lLfsNDNSeYY4139/lm8o93WbDPOu8d61EGqaV4T4yS1GPAcYPWoXJlK0XnyprX76TQCsRdnvgG/BzRE1rod0rylvQdNSl+uNTGtEwPYSzDYlzGMu7oE4DwuZt5tkfgvluodS7VKWq4QLVlGV/XJeJVTUSspbeop2AIxljV+PjpulY8548I0QDjqYEsx7cbw9/9ucYGlfJKCaiaPhnaOlvh4Vi/HHYXWnkSGEvcEjwAAAIDP1QKD/u65f28I1zy8ezg2+Cu81JlHn15vdv38uLOMT3Hcnoi9am92Nxr9ZdKvGGKzKvs0qV9xuLEyBD/+vjqVK691kkSBSMA/nGmx1o5M5c8yyGuvRv7TAcoatAMGmzL0VrkfcYmKsIHNjEJS71JxkVyXlLjylYUdp1EPmctz6wAAAIDMTpDSobOgZdOy0fWo/OMbVER1Zk6rVh0pcbmft774ROjsHzYLjCrINZaSlx6mo49yP8whH128sXeg/axRZKHU/3+7ToKZhjU8uYNlmhSM3UIMfTG6OCLqkKMr5GwDDowX4foK03hZ4GsKpvo7IW2cvmwOIjOXacCmFZE+XacZzwAAAIAcLR/DL2vEAE/YXf3g+7+aTDj5x8TkHeoaqII0ogHNkvO32lJlg6mK2FuzYPuYO3EeI0SdVh0XeNelFUhry/R7Rsnp4aOh93AA776wmor+R+W4V82pnLFtf/+bcS471gypbZx5c9YW1Gk0qcBQKBwAQ5nO/x233aeHZqipucsIcwAAAIDLOzwEyqWMYL59my3rs+OWQ/T1c5e+CCNqHp6vqnBlNuccOs/gHMZR8jyeBYWP7hO7aor8R99O3JpLowvOy3PQFXhSMn7niQFcLo3ue58FoPMayU62FzFkdAxclRR81fO1riy0qDeH8B2Ksx8nwtDuot2KEauQarogfEPG7hJTMQAAAIAS9rLPE3SnNvrQVhYFD5arS2HRF3x/nVJaKfPRgOd2Z+mdmavwUl0HWGYPN1JlWw8luN+EMdmo/3fBbBKgpRIqnwv3z9WiZqNcFZ+ZEgi5Axb/RE8+C2vQ6TuKeiRI6Vfj3abPzyJmsQYBOsRoCNOziHs7ADRLqslTC0znCPwytg==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_pss/key13 b/nss/cmd/bltest/tests/rsa_pss/key13
new file mode 100644
index 0000000..9f74b31
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/key13
@@ -0,0 +1 @@
+AAAAAQAAAAEApd2GesTLAvkLlFfUjBSncO+ZHFbDnA7GX9Ea+ok3zqV7m+esc7RcABdhW4LWIuMYdTtgJ8D9FXvhL4CQ/uKnrc0O73WfiLpJl8ekLVjJqhLLma4AH+UhwTu1QxRFqNWuT15MfpSKwifTYEBx8g5XfpBfvrFd+vBtHeWuYlPWOmohILMaXaXavJVQYA4g8n03OeJieSX+o8xQnyHf8E5u6kVJxUDWgJ/5MH7t6R//WHM9g4WiN9bTcFoz45GQCZIHDfet8TV89+NwDONmfeg/F7jfF3jbOB3OCctK0FilEQAac4GY7ifPVaE7dUU5kGWC7IsXS9WNXR89dnxhNyGuBQAAAAMBAAEAAAEALS/1Z7P+dOBhkbf97W3hEikMZwaSQw1ZaRhAR9ojTJaT3u0Wc+1ClTnJadNywE1rR+D1uM7ghD5cIoNdvTsFoJl5hK5gWLEbxJB8v2fthPqa4lLfsNDNSeYY4139/lm8o93WbDPOu8d61EGqaV4T4yS1GPAcYPWoXJlK0XnyprX76TQCsRdnvgG/BzRE1rod0rylvQdNSl+uNTGtEwPYSzDYlzGMu7oE4DwuZt5tkfgvluodS7VKWq4QLVlGV/XJeJVTUSspbeop2AIxljV+PjpulY8548I0QDjqYEsx7cbw9/9ucYGlfJKCaiaPhnaOlvh4Vi/HHYXWnkSGEvcEjwAAAIDP1QKD/u65f28I1zy8ezg2+Cu81JlHn15vdv38uLOMT3Hcnoi9am92Nxr9ZdKvGGKzKvs0qV9xuLEyBD/+vjqVK691kkSBSMA/nGmx1o5M5c8yyGuvRv7TAcoatAMGmzL0VrkfcYmKsIHNjEJS71JxkVyXlLjylYUdp1EPmctz6wAAAIDMTpDSobOgZdOy0fWo/OMbVER1Zk6rVh0pcbmft774ROjsHzYLjCrINZaSlx6mo49yP8whH128sXeg/axRZKHU/3+7ToKZhjU8uYNlmhSM3UIMfTG6OCLqkKMr5GwDDowX4foK03hZ4GsKpvo7IW2cvmwOIjOXacCmFZE+XacZzwAAAIAcLR/DL2vEAE/YXf3g+7+aTDj5x8TkHeoaqII0ogHNkvO32lJlg6mK2FuzYPuYO3EeI0SdVh0XeNelFUhry/R7Rsnp4aOh93AA776wmor+R+W4V82pnLFtf/+bcS471gypbZx5c9YW1Gk0qcBQKBwAQ5nO/x233aeHZqipucsIcwAAAIDLOzwEyqWMYL59my3rs+OWQ/T1c5e+CCNqHp6vqnBlNuccOs/gHMZR8jyeBYWP7hO7aor8R99O3JpLowvOy3PQFXhSMn7niQFcLo3ue58FoPMayU62FzFkdAxclRR81fO1riy0qDeH8B2Ksx8nwtDuot2KEauQarogfEPG7hJTMQAAAIAS9rLPE3SnNvrQVhYFD5arS2HRF3x/nVJaKfPRgOd2Z+mdmavwUl0HWGYPN1JlWw8luN+EMdmo/3fBbBKgpRIqnwv3z9WiZqNcFZ+ZEgi5Axb/RE8+C2vQ6TuKeiRI6Vfj3abPzyJmsQYBOsRoCNOziHs7ADRLqslTC0znCPwytg==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_pss/key14 b/nss/cmd/bltest/tests/rsa_pss/key14
new file mode 100644
index 0000000..9f74b31
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/key14
@@ -0,0 +1 @@
+AAAAAQAAAAEApd2GesTLAvkLlFfUjBSncO+ZHFbDnA7GX9Ea+ok3zqV7m+esc7RcABdhW4LWIuMYdTtgJ8D9FXvhL4CQ/uKnrc0O73WfiLpJl8ekLVjJqhLLma4AH+UhwTu1QxRFqNWuT15MfpSKwifTYEBx8g5XfpBfvrFd+vBtHeWuYlPWOmohILMaXaXavJVQYA4g8n03OeJieSX+o8xQnyHf8E5u6kVJxUDWgJ/5MH7t6R//WHM9g4WiN9bTcFoz45GQCZIHDfet8TV89+NwDONmfeg/F7jfF3jbOB3OCctK0FilEQAac4GY7ifPVaE7dUU5kGWC7IsXS9WNXR89dnxhNyGuBQAAAAMBAAEAAAEALS/1Z7P+dOBhkbf97W3hEikMZwaSQw1ZaRhAR9ojTJaT3u0Wc+1ClTnJadNywE1rR+D1uM7ghD5cIoNdvTsFoJl5hK5gWLEbxJB8v2fthPqa4lLfsNDNSeYY4139/lm8o93WbDPOu8d61EGqaV4T4yS1GPAcYPWoXJlK0XnyprX76TQCsRdnvgG/BzRE1rod0rylvQdNSl+uNTGtEwPYSzDYlzGMu7oE4DwuZt5tkfgvluodS7VKWq4QLVlGV/XJeJVTUSspbeop2AIxljV+PjpulY8548I0QDjqYEsx7cbw9/9ucYGlfJKCaiaPhnaOlvh4Vi/HHYXWnkSGEvcEjwAAAIDP1QKD/u65f28I1zy8ezg2+Cu81JlHn15vdv38uLOMT3Hcnoi9am92Nxr9ZdKvGGKzKvs0qV9xuLEyBD/+vjqVK691kkSBSMA/nGmx1o5M5c8yyGuvRv7TAcoatAMGmzL0VrkfcYmKsIHNjEJS71JxkVyXlLjylYUdp1EPmctz6wAAAIDMTpDSobOgZdOy0fWo/OMbVER1Zk6rVh0pcbmft774ROjsHzYLjCrINZaSlx6mo49yP8whH128sXeg/axRZKHU/3+7ToKZhjU8uYNlmhSM3UIMfTG6OCLqkKMr5GwDDowX4foK03hZ4GsKpvo7IW2cvmwOIjOXacCmFZE+XacZzwAAAIAcLR/DL2vEAE/YXf3g+7+aTDj5x8TkHeoaqII0ogHNkvO32lJlg6mK2FuzYPuYO3EeI0SdVh0XeNelFUhry/R7Rsnp4aOh93AA776wmor+R+W4V82pnLFtf/+bcS471gypbZx5c9YW1Gk0qcBQKBwAQ5nO/x233aeHZqipucsIcwAAAIDLOzwEyqWMYL59my3rs+OWQ/T1c5e+CCNqHp6vqnBlNuccOs/gHMZR8jyeBYWP7hO7aor8R99O3JpLowvOy3PQFXhSMn7niQFcLo3ue58FoPMayU62FzFkdAxclRR81fO1riy0qDeH8B2Ksx8nwtDuot2KEauQarogfEPG7hJTMQAAAIAS9rLPE3SnNvrQVhYFD5arS2HRF3x/nVJaKfPRgOd2Z+mdmavwUl0HWGYPN1JlWw8luN+EMdmo/3fBbBKgpRIqnwv3z9WiZqNcFZ+ZEgi5Axb/RE8+C2vQ6TuKeiRI6Vfj3abPzyJmsQYBOsRoCNOziHs7ADRLqslTC0znCPwytg==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_pss/key15 b/nss/cmd/bltest/tests/rsa_pss/key15
new file mode 100644
index 0000000..9f74b31
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/key15
@@ -0,0 +1 @@
+AAAAAQAAAAEApd2GesTLAvkLlFfUjBSncO+ZHFbDnA7GX9Ea+ok3zqV7m+esc7RcABdhW4LWIuMYdTtgJ8D9FXvhL4CQ/uKnrc0O73WfiLpJl8ekLVjJqhLLma4AH+UhwTu1QxRFqNWuT15MfpSKwifTYEBx8g5XfpBfvrFd+vBtHeWuYlPWOmohILMaXaXavJVQYA4g8n03OeJieSX+o8xQnyHf8E5u6kVJxUDWgJ/5MH7t6R//WHM9g4WiN9bTcFoz45GQCZIHDfet8TV89+NwDONmfeg/F7jfF3jbOB3OCctK0FilEQAac4GY7ifPVaE7dUU5kGWC7IsXS9WNXR89dnxhNyGuBQAAAAMBAAEAAAEALS/1Z7P+dOBhkbf97W3hEikMZwaSQw1ZaRhAR9ojTJaT3u0Wc+1ClTnJadNywE1rR+D1uM7ghD5cIoNdvTsFoJl5hK5gWLEbxJB8v2fthPqa4lLfsNDNSeYY4139/lm8o93WbDPOu8d61EGqaV4T4yS1GPAcYPWoXJlK0XnyprX76TQCsRdnvgG/BzRE1rod0rylvQdNSl+uNTGtEwPYSzDYlzGMu7oE4DwuZt5tkfgvluodS7VKWq4QLVlGV/XJeJVTUSspbeop2AIxljV+PjpulY8548I0QDjqYEsx7cbw9/9ucYGlfJKCaiaPhnaOlvh4Vi/HHYXWnkSGEvcEjwAAAIDP1QKD/u65f28I1zy8ezg2+Cu81JlHn15vdv38uLOMT3Hcnoi9am92Nxr9ZdKvGGKzKvs0qV9xuLEyBD/+vjqVK691kkSBSMA/nGmx1o5M5c8yyGuvRv7TAcoatAMGmzL0VrkfcYmKsIHNjEJS71JxkVyXlLjylYUdp1EPmctz6wAAAIDMTpDSobOgZdOy0fWo/OMbVER1Zk6rVh0pcbmft774ROjsHzYLjCrINZaSlx6mo49yP8whH128sXeg/axRZKHU/3+7ToKZhjU8uYNlmhSM3UIMfTG6OCLqkKMr5GwDDowX4foK03hZ4GsKpvo7IW2cvmwOIjOXacCmFZE+XacZzwAAAIAcLR/DL2vEAE/YXf3g+7+aTDj5x8TkHeoaqII0ogHNkvO32lJlg6mK2FuzYPuYO3EeI0SdVh0XeNelFUhry/R7Rsnp4aOh93AA776wmor+R+W4V82pnLFtf/+bcS471gypbZx5c9YW1Gk0qcBQKBwAQ5nO/x233aeHZqipucsIcwAAAIDLOzwEyqWMYL59my3rs+OWQ/T1c5e+CCNqHp6vqnBlNuccOs/gHMZR8jyeBYWP7hO7aor8R99O3JpLowvOy3PQFXhSMn7niQFcLo3ue58FoPMayU62FzFkdAxclRR81fO1riy0qDeH8B2Ksx8nwtDuot2KEauQarogfEPG7hJTMQAAAIAS9rLPE3SnNvrQVhYFD5arS2HRF3x/nVJaKfPRgOd2Z+mdmavwUl0HWGYPN1JlWw8luN+EMdmo/3fBbBKgpRIqnwv3z9WiZqNcFZ+ZEgi5Axb/RE8+C2vQ6TuKeiRI6Vfj3abPzyJmsQYBOsRoCNOziHs7ADRLqslTC0znCPwytg==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_pss/key16 b/nss/cmd/bltest/tests/rsa_pss/key16
new file mode 100644
index 0000000..9f74b31
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/key16
@@ -0,0 +1 @@
+AAAAAQAAAAEApd2GesTLAvkLlFfUjBSncO+ZHFbDnA7GX9Ea+ok3zqV7m+esc7RcABdhW4LWIuMYdTtgJ8D9FXvhL4CQ/uKnrc0O73WfiLpJl8ekLVjJqhLLma4AH+UhwTu1QxRFqNWuT15MfpSKwifTYEBx8g5XfpBfvrFd+vBtHeWuYlPWOmohILMaXaXavJVQYA4g8n03OeJieSX+o8xQnyHf8E5u6kVJxUDWgJ/5MH7t6R//WHM9g4WiN9bTcFoz45GQCZIHDfet8TV89+NwDONmfeg/F7jfF3jbOB3OCctK0FilEQAac4GY7ifPVaE7dUU5kGWC7IsXS9WNXR89dnxhNyGuBQAAAAMBAAEAAAEALS/1Z7P+dOBhkbf97W3hEikMZwaSQw1ZaRhAR9ojTJaT3u0Wc+1ClTnJadNywE1rR+D1uM7ghD5cIoNdvTsFoJl5hK5gWLEbxJB8v2fthPqa4lLfsNDNSeYY4139/lm8o93WbDPOu8d61EGqaV4T4yS1GPAcYPWoXJlK0XnyprX76TQCsRdnvgG/BzRE1rod0rylvQdNSl+uNTGtEwPYSzDYlzGMu7oE4DwuZt5tkfgvluodS7VKWq4QLVlGV/XJeJVTUSspbeop2AIxljV+PjpulY8548I0QDjqYEsx7cbw9/9ucYGlfJKCaiaPhnaOlvh4Vi/HHYXWnkSGEvcEjwAAAIDP1QKD/u65f28I1zy8ezg2+Cu81JlHn15vdv38uLOMT3Hcnoi9am92Nxr9ZdKvGGKzKvs0qV9xuLEyBD/+vjqVK691kkSBSMA/nGmx1o5M5c8yyGuvRv7TAcoatAMGmzL0VrkfcYmKsIHNjEJS71JxkVyXlLjylYUdp1EPmctz6wAAAIDMTpDSobOgZdOy0fWo/OMbVER1Zk6rVh0pcbmft774ROjsHzYLjCrINZaSlx6mo49yP8whH128sXeg/axRZKHU/3+7ToKZhjU8uYNlmhSM3UIMfTG6OCLqkKMr5GwDDowX4foK03hZ4GsKpvo7IW2cvmwOIjOXacCmFZE+XacZzwAAAIAcLR/DL2vEAE/YXf3g+7+aTDj5x8TkHeoaqII0ogHNkvO32lJlg6mK2FuzYPuYO3EeI0SdVh0XeNelFUhry/R7Rsnp4aOh93AA776wmor+R+W4V82pnLFtf/+bcS471gypbZx5c9YW1Gk0qcBQKBwAQ5nO/x233aeHZqipucsIcwAAAIDLOzwEyqWMYL59my3rs+OWQ/T1c5e+CCNqHp6vqnBlNuccOs/gHMZR8jyeBYWP7hO7aor8R99O3JpLowvOy3PQFXhSMn7niQFcLo3ue58FoPMayU62FzFkdAxclRR81fO1riy0qDeH8B2Ksx8nwtDuot2KEauQarogfEPG7hJTMQAAAIAS9rLPE3SnNvrQVhYFD5arS2HRF3x/nVJaKfPRgOd2Z+mdmavwUl0HWGYPN1JlWw8luN+EMdmo/3fBbBKgpRIqnwv3z9WiZqNcFZ+ZEgi5Axb/RE8+C2vQ6TuKeiRI6Vfj3abPzyJmsQYBOsRoCNOziHs7ADRLqslTC0znCPwytg==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_pss/key17 b/nss/cmd/bltest/tests/rsa_pss/key17
new file mode 100644
index 0000000..9f74b31
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/key17
@@ -0,0 +1 @@
+AAAAAQAAAAEApd2GesTLAvkLlFfUjBSncO+ZHFbDnA7GX9Ea+ok3zqV7m+esc7RcABdhW4LWIuMYdTtgJ8D9FXvhL4CQ/uKnrc0O73WfiLpJl8ekLVjJqhLLma4AH+UhwTu1QxRFqNWuT15MfpSKwifTYEBx8g5XfpBfvrFd+vBtHeWuYlPWOmohILMaXaXavJVQYA4g8n03OeJieSX+o8xQnyHf8E5u6kVJxUDWgJ/5MH7t6R//WHM9g4WiN9bTcFoz45GQCZIHDfet8TV89+NwDONmfeg/F7jfF3jbOB3OCctK0FilEQAac4GY7ifPVaE7dUU5kGWC7IsXS9WNXR89dnxhNyGuBQAAAAMBAAEAAAEALS/1Z7P+dOBhkbf97W3hEikMZwaSQw1ZaRhAR9ojTJaT3u0Wc+1ClTnJadNywE1rR+D1uM7ghD5cIoNdvTsFoJl5hK5gWLEbxJB8v2fthPqa4lLfsNDNSeYY4139/lm8o93WbDPOu8d61EGqaV4T4yS1GPAcYPWoXJlK0XnyprX76TQCsRdnvgG/BzRE1rod0rylvQdNSl+uNTGtEwPYSzDYlzGMu7oE4DwuZt5tkfgvluodS7VKWq4QLVlGV/XJeJVTUSspbeop2AIxljV+PjpulY8548I0QDjqYEsx7cbw9/9ucYGlfJKCaiaPhnaOlvh4Vi/HHYXWnkSGEvcEjwAAAIDP1QKD/u65f28I1zy8ezg2+Cu81JlHn15vdv38uLOMT3Hcnoi9am92Nxr9ZdKvGGKzKvs0qV9xuLEyBD/+vjqVK691kkSBSMA/nGmx1o5M5c8yyGuvRv7TAcoatAMGmzL0VrkfcYmKsIHNjEJS71JxkVyXlLjylYUdp1EPmctz6wAAAIDMTpDSobOgZdOy0fWo/OMbVER1Zk6rVh0pcbmft774ROjsHzYLjCrINZaSlx6mo49yP8whH128sXeg/axRZKHU/3+7ToKZhjU8uYNlmhSM3UIMfTG6OCLqkKMr5GwDDowX4foK03hZ4GsKpvo7IW2cvmwOIjOXacCmFZE+XacZzwAAAIAcLR/DL2vEAE/YXf3g+7+aTDj5x8TkHeoaqII0ogHNkvO32lJlg6mK2FuzYPuYO3EeI0SdVh0XeNelFUhry/R7Rsnp4aOh93AA776wmor+R+W4V82pnLFtf/+bcS471gypbZx5c9YW1Gk0qcBQKBwAQ5nO/x233aeHZqipucsIcwAAAIDLOzwEyqWMYL59my3rs+OWQ/T1c5e+CCNqHp6vqnBlNuccOs/gHMZR8jyeBYWP7hO7aor8R99O3JpLowvOy3PQFXhSMn7niQFcLo3ue58FoPMayU62FzFkdAxclRR81fO1riy0qDeH8B2Ksx8nwtDuot2KEauQarogfEPG7hJTMQAAAIAS9rLPE3SnNvrQVhYFD5arS2HRF3x/nVJaKfPRgOd2Z+mdmavwUl0HWGYPN1JlWw8luN+EMdmo/3fBbBKgpRIqnwv3z9WiZqNcFZ+ZEgi5Axb/RE8+C2vQ6TuKeiRI6Vfj3abPzyJmsQYBOsRoCNOziHs7ADRLqslTC0znCPwytg==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_pss/key2 b/nss/cmd/bltest/tests/rsa_pss/key2
new file mode 100644
index 0000000..4615480
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/key2
@@ -0,0 +1 @@
+AAAAAQAAAACApW5KDnAQF1iaUYfcfqhB0Vby7A42rVKkTf6x5h962ZHYxRBW/+2xYrTA8oOhKoijlN/1JqtykcuzB86r/OCx39XNlQgJbVsri2311nHvY3fAkhyyPCcKcOJZjm/4nRnxBazC0/DLNfKSgOE4a29kxO8i4eHyDQzoz/siSb2aITcAAAADAQABAAAAgDOlBCqQsn1PVFHKm7vQtEdxoQGviENArvmIXypLvpLolKckrDxWjI+XhTrQfAJmyMajygkp8ejxEjGIRCn8TZrlX+6JahDOcHw+1+c05Ecno5V0UBpTJoMQnCq6yrooPDG0vS9Tw+4341LO40+eUDvYDAYirXnG3O6INUfGo7MlAAAAQOfolCcgqHdRcnOjVgU+oqG8DJSqctVcboYpay38lnlIwKcsvMyn6ss1cG4Jod9VoVNb2bPMNBYLO23NPtqOZEMAAABAtp3KHPfU1+yB51uQ/MqHSrzeEj/ScAGAqpBHm25I3o1n7ST58Z2FuidYdPVCzSDccj5pYzZKH5QlRSsmmmeZ/QAAAEAo+hOThlW+H4oVnLrKWnLqGQwwCJ4ZzSdKVW82xPbhn1VLNMB3eQQnu92N0+3iRIMo84XYGzDo5Dsv/6Anhhl5AAAAQBqLOPOY+nEgSYmNf7ee4Kd2aHkSmc36Ce/A5Qessh7XQwHvW/1IvkVerrbhZ4JVgnWAqOTo4UFR0VEKgqPy5ykAAABAJxVqukEm0kqB86Uoy/sn9WiG+ECp9uhuF6RLlP6TGVhLjiL93h5aLjvYqluo2FhBlOshkKz4MrhH8To9JKefTQ==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_pss/key3 b/nss/cmd/bltest/tests/rsa_pss/key3
new file mode 100644
index 0000000..4615480
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/key3
@@ -0,0 +1 @@
+AAAAAQAAAACApW5KDnAQF1iaUYfcfqhB0Vby7A42rVKkTf6x5h962ZHYxRBW/+2xYrTA8oOhKoijlN/1JqtykcuzB86r/OCx39XNlQgJbVsri2311nHvY3fAkhyyPCcKcOJZjm/4nRnxBazC0/DLNfKSgOE4a29kxO8i4eHyDQzoz/siSb2aITcAAAADAQABAAAAgDOlBCqQsn1PVFHKm7vQtEdxoQGviENArvmIXypLvpLolKckrDxWjI+XhTrQfAJmyMajygkp8ejxEjGIRCn8TZrlX+6JahDOcHw+1+c05Ecno5V0UBpTJoMQnCq6yrooPDG0vS9Tw+4341LO40+eUDvYDAYirXnG3O6INUfGo7MlAAAAQOfolCcgqHdRcnOjVgU+oqG8DJSqctVcboYpay38lnlIwKcsvMyn6ss1cG4Jod9VoVNb2bPMNBYLO23NPtqOZEMAAABAtp3KHPfU1+yB51uQ/MqHSrzeEj/ScAGAqpBHm25I3o1n7ST58Z2FuidYdPVCzSDccj5pYzZKH5QlRSsmmmeZ/QAAAEAo+hOThlW+H4oVnLrKWnLqGQwwCJ4ZzSdKVW82xPbhn1VLNMB3eQQnu92N0+3iRIMo84XYGzDo5Dsv/6Anhhl5AAAAQBqLOPOY+nEgSYmNf7ee4Kd2aHkSmc36Ce/A5Qessh7XQwHvW/1IvkVerrbhZ4JVgnWAqOTo4UFR0VEKgqPy5ykAAABAJxVqukEm0kqB86Uoy/sn9WiG+ECp9uhuF6RLlP6TGVhLjiL93h5aLjvYqluo2FhBlOshkKz4MrhH8To9JKefTQ==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_pss/key4 b/nss/cmd/bltest/tests/rsa_pss/key4
new file mode 100644
index 0000000..4615480
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/key4
@@ -0,0 +1 @@
+AAAAAQAAAACApW5KDnAQF1iaUYfcfqhB0Vby7A42rVKkTf6x5h962ZHYxRBW/+2xYrTA8oOhKoijlN/1JqtykcuzB86r/OCx39XNlQgJbVsri2311nHvY3fAkhyyPCcKcOJZjm/4nRnxBazC0/DLNfKSgOE4a29kxO8i4eHyDQzoz/siSb2aITcAAAADAQABAAAAgDOlBCqQsn1PVFHKm7vQtEdxoQGviENArvmIXypLvpLolKckrDxWjI+XhTrQfAJmyMajygkp8ejxEjGIRCn8TZrlX+6JahDOcHw+1+c05Ecno5V0UBpTJoMQnCq6yrooPDG0vS9Tw+4341LO40+eUDvYDAYirXnG3O6INUfGo7MlAAAAQOfolCcgqHdRcnOjVgU+oqG8DJSqctVcboYpay38lnlIwKcsvMyn6ss1cG4Jod9VoVNb2bPMNBYLO23NPtqOZEMAAABAtp3KHPfU1+yB51uQ/MqHSrzeEj/ScAGAqpBHm25I3o1n7ST58Z2FuidYdPVCzSDccj5pYzZKH5QlRSsmmmeZ/QAAAEAo+hOThlW+H4oVnLrKWnLqGQwwCJ4ZzSdKVW82xPbhn1VLNMB3eQQnu92N0+3iRIMo84XYGzDo5Dsv/6Anhhl5AAAAQBqLOPOY+nEgSYmNf7ee4Kd2aHkSmc36Ce/A5Qessh7XQwHvW/1IvkVerrbhZ4JVgnWAqOTo4UFR0VEKgqPy5ykAAABAJxVqukEm0kqB86Uoy/sn9WiG+ECp9uhuF6RLlP6TGVhLjiL93h5aLjvYqluo2FhBlOshkKz4MrhH8To9JKefTQ==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_pss/key5 b/nss/cmd/bltest/tests/rsa_pss/key5
new file mode 100644
index 0000000..4615480
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/key5
@@ -0,0 +1 @@
+AAAAAQAAAACApW5KDnAQF1iaUYfcfqhB0Vby7A42rVKkTf6x5h962ZHYxRBW/+2xYrTA8oOhKoijlN/1JqtykcuzB86r/OCx39XNlQgJbVsri2311nHvY3fAkhyyPCcKcOJZjm/4nRnxBazC0/DLNfKSgOE4a29kxO8i4eHyDQzoz/siSb2aITcAAAADAQABAAAAgDOlBCqQsn1PVFHKm7vQtEdxoQGviENArvmIXypLvpLolKckrDxWjI+XhTrQfAJmyMajygkp8ejxEjGIRCn8TZrlX+6JahDOcHw+1+c05Ecno5V0UBpTJoMQnCq6yrooPDG0vS9Tw+4341LO40+eUDvYDAYirXnG3O6INUfGo7MlAAAAQOfolCcgqHdRcnOjVgU+oqG8DJSqctVcboYpay38lnlIwKcsvMyn6ss1cG4Jod9VoVNb2bPMNBYLO23NPtqOZEMAAABAtp3KHPfU1+yB51uQ/MqHSrzeEj/ScAGAqpBHm25I3o1n7ST58Z2FuidYdPVCzSDccj5pYzZKH5QlRSsmmmeZ/QAAAEAo+hOThlW+H4oVnLrKWnLqGQwwCJ4ZzSdKVW82xPbhn1VLNMB3eQQnu92N0+3iRIMo84XYGzDo5Dsv/6Anhhl5AAAAQBqLOPOY+nEgSYmNf7ee4Kd2aHkSmc36Ce/A5Qessh7XQwHvW/1IvkVerrbhZ4JVgnWAqOTo4UFR0VEKgqPy5ykAAABAJxVqukEm0kqB86Uoy/sn9WiG+ECp9uhuF6RLlP6TGVhLjiL93h5aLjvYqluo2FhBlOshkKz4MrhH8To9JKefTQ==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_pss/key6 b/nss/cmd/bltest/tests/rsa_pss/key6
new file mode 100644
index 0000000..ef62249
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/key6
@@ -0,0 +1 @@
+AAAAAQAAAADA5r1pKslmRXkEA/3Q9b64ub+S7RAAf8NlBGQZ3QbAXFtbL0js+YnkziaRCZecu0C0oK0k0iSD0e4xWtTMsVNCaDUmkcUk9t2ObCnSJM8kaXOuyGxb9rFAGoUNG5rRu4y87Eewbw+Mf0XT/I8xkpnFQz3bwrMFO0fe0uzUpMrv1hSDPci7Yi8xftB2uAV/6N4/hEgK1eg+SmGQSk8kj7OXAnNX4dMORjE5gVxv1P1axbgXKkUjDstjGKBPFFXYTlqLAAAAAwEAAQAAAMBqf9hPuF+tBzs0QG23T41hpqvBIZapYd15Vl6dpuUYe84tmAJQ9zWVdTWScNkVkLsOQnxxRgtV1RQQsZG88wn+oTGpLI5wJzj6cZ8eAEH1LkDpHyKfTZah5vFy4VWWtFEKba7CYQXyvrxTMWuHvfITEWZgcOjf7mnVLHGpdsqueccraNKFgNxobZ9RKdIl+Cs9YVUTqIKz25FBa0jOCIiCE+N+65r4ANgcqzKM5CBomQPADHtf0xt1UDptQZaE1ikAAABg+OuX6Y3xJmTu/bdhWWpp3c0Odtrs5u1L9aG1CsCG95KKTS+HJqd+UVt02kGYjyILHMh6ofyBDOmagvLRzoIe3O15TGlB9Cx6GguMTSjHXsYLZSJ59hVKdirtFl1H3uNnAAAAYO1NcdCm4kuTwuX2tLvgX1+wr6BC0gT+M3jTZcLyiLao2tfv5F0VPu9Aysx7gf+TQALRCJlLlKXkcozZyWM3WuSZZb2lXL8O/tjWVTtAJ/LYYgim5rSJwXYSgJLWKeSdPQAAAGArtovd+wxPVshVi/+viS2AQwN4Qef6gc+mGjjF45uQHI7nESKl2iInvWze60gUUsEq09YdXk93agq1Vlkb7+Plnlp/3bg0Xh8vNbn0zuV8MkFMCGrsmT6TU+SA2e7GKJ8AAABgT/iXcJ+tB5dGSUV45w/YVGEw7qtWJ8SbCA8F7krZ8+S3y6nWpd/xE6QcNAkzaDPxkIFtimvELpvsVrdWfQ88nGltthmyRdkB3YVtt8gJLnfpoczNVu5NukLF/bYa7CZpAAAAYHe50RN7UEBKmCcpMW76/H3+ZtNOWhgmANXzCgqFEgUcVg0IHU0KGDXsPSWmD05NaqlIsr89u1sSTLvDSJJVo6lINy9peElnRflD4dtPGDgs6qUF38ZXV7s/hXpY3OUhVg==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_pss/key7 b/nss/cmd/bltest/tests/rsa_pss/key7
new file mode 100644
index 0000000..ef62249
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/key7
@@ -0,0 +1 @@
+AAAAAQAAAADA5r1pKslmRXkEA/3Q9b64ub+S7RAAf8NlBGQZ3QbAXFtbL0js+YnkziaRCZecu0C0oK0k0iSD0e4xWtTMsVNCaDUmkcUk9t2ObCnSJM8kaXOuyGxb9rFAGoUNG5rRu4y87Eewbw+Mf0XT/I8xkpnFQz3bwrMFO0fe0uzUpMrv1hSDPci7Yi8xftB2uAV/6N4/hEgK1eg+SmGQSk8kj7OXAnNX4dMORjE5gVxv1P1axbgXKkUjDstjGKBPFFXYTlqLAAAAAwEAAQAAAMBqf9hPuF+tBzs0QG23T41hpqvBIZapYd15Vl6dpuUYe84tmAJQ9zWVdTWScNkVkLsOQnxxRgtV1RQQsZG88wn+oTGpLI5wJzj6cZ8eAEH1LkDpHyKfTZah5vFy4VWWtFEKba7CYQXyvrxTMWuHvfITEWZgcOjf7mnVLHGpdsqueccraNKFgNxobZ9RKdIl+Cs9YVUTqIKz25FBa0jOCIiCE+N+65r4ANgcqzKM5CBomQPADHtf0xt1UDptQZaE1ikAAABg+OuX6Y3xJmTu/bdhWWpp3c0Odtrs5u1L9aG1CsCG95KKTS+HJqd+UVt02kGYjyILHMh6ofyBDOmagvLRzoIe3O15TGlB9Cx6GguMTSjHXsYLZSJ59hVKdirtFl1H3uNnAAAAYO1NcdCm4kuTwuX2tLvgX1+wr6BC0gT+M3jTZcLyiLao2tfv5F0VPu9Aysx7gf+TQALRCJlLlKXkcozZyWM3WuSZZb2lXL8O/tjWVTtAJ/LYYgim5rSJwXYSgJLWKeSdPQAAAGArtovd+wxPVshVi/+viS2AQwN4Qef6gc+mGjjF45uQHI7nESKl2iInvWze60gUUsEq09YdXk93agq1Vlkb7+Plnlp/3bg0Xh8vNbn0zuV8MkFMCGrsmT6TU+SA2e7GKJ8AAABgT/iXcJ+tB5dGSUV45w/YVGEw7qtWJ8SbCA8F7krZ8+S3y6nWpd/xE6QcNAkzaDPxkIFtimvELpvsVrdWfQ88nGltthmyRdkB3YVtt8gJLnfpoczNVu5NukLF/bYa7CZpAAAAYHe50RN7UEBKmCcpMW76/H3+ZtNOWhgmANXzCgqFEgUcVg0IHU0KGDXsPSWmD05NaqlIsr89u1sSTLvDSJJVo6lINy9peElnRflD4dtPGDgs6qUF38ZXV7s/hXpY3OUhVg==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_pss/key8 b/nss/cmd/bltest/tests/rsa_pss/key8
new file mode 100644
index 0000000..ef62249
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/key8
@@ -0,0 +1 @@
+AAAAAQAAAADA5r1pKslmRXkEA/3Q9b64ub+S7RAAf8NlBGQZ3QbAXFtbL0js+YnkziaRCZecu0C0oK0k0iSD0e4xWtTMsVNCaDUmkcUk9t2ObCnSJM8kaXOuyGxb9rFAGoUNG5rRu4y87Eewbw+Mf0XT/I8xkpnFQz3bwrMFO0fe0uzUpMrv1hSDPci7Yi8xftB2uAV/6N4/hEgK1eg+SmGQSk8kj7OXAnNX4dMORjE5gVxv1P1axbgXKkUjDstjGKBPFFXYTlqLAAAAAwEAAQAAAMBqf9hPuF+tBzs0QG23T41hpqvBIZapYd15Vl6dpuUYe84tmAJQ9zWVdTWScNkVkLsOQnxxRgtV1RQQsZG88wn+oTGpLI5wJzj6cZ8eAEH1LkDpHyKfTZah5vFy4VWWtFEKba7CYQXyvrxTMWuHvfITEWZgcOjf7mnVLHGpdsqueccraNKFgNxobZ9RKdIl+Cs9YVUTqIKz25FBa0jOCIiCE+N+65r4ANgcqzKM5CBomQPADHtf0xt1UDptQZaE1ikAAABg+OuX6Y3xJmTu/bdhWWpp3c0Odtrs5u1L9aG1CsCG95KKTS+HJqd+UVt02kGYjyILHMh6ofyBDOmagvLRzoIe3O15TGlB9Cx6GguMTSjHXsYLZSJ59hVKdirtFl1H3uNnAAAAYO1NcdCm4kuTwuX2tLvgX1+wr6BC0gT+M3jTZcLyiLao2tfv5F0VPu9Aysx7gf+TQALRCJlLlKXkcozZyWM3WuSZZb2lXL8O/tjWVTtAJ/LYYgim5rSJwXYSgJLWKeSdPQAAAGArtovd+wxPVshVi/+viS2AQwN4Qef6gc+mGjjF45uQHI7nESKl2iInvWze60gUUsEq09YdXk93agq1Vlkb7+Plnlp/3bg0Xh8vNbn0zuV8MkFMCGrsmT6TU+SA2e7GKJ8AAABgT/iXcJ+tB5dGSUV45w/YVGEw7qtWJ8SbCA8F7krZ8+S3y6nWpd/xE6QcNAkzaDPxkIFtimvELpvsVrdWfQ88nGltthmyRdkB3YVtt8gJLnfpoczNVu5NukLF/bYa7CZpAAAAYHe50RN7UEBKmCcpMW76/H3+ZtNOWhgmANXzCgqFEgUcVg0IHU0KGDXsPSWmD05NaqlIsr89u1sSTLvDSJJVo6lINy9peElnRflD4dtPGDgs6qUF38ZXV7s/hXpY3OUhVg==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_pss/key9 b/nss/cmd/bltest/tests/rsa_pss/key9
new file mode 100644
index 0000000..ef62249
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/key9
@@ -0,0 +1 @@
+AAAAAQAAAADA5r1pKslmRXkEA/3Q9b64ub+S7RAAf8NlBGQZ3QbAXFtbL0js+YnkziaRCZecu0C0oK0k0iSD0e4xWtTMsVNCaDUmkcUk9t2ObCnSJM8kaXOuyGxb9rFAGoUNG5rRu4y87Eewbw+Mf0XT/I8xkpnFQz3bwrMFO0fe0uzUpMrv1hSDPci7Yi8xftB2uAV/6N4/hEgK1eg+SmGQSk8kj7OXAnNX4dMORjE5gVxv1P1axbgXKkUjDstjGKBPFFXYTlqLAAAAAwEAAQAAAMBqf9hPuF+tBzs0QG23T41hpqvBIZapYd15Vl6dpuUYe84tmAJQ9zWVdTWScNkVkLsOQnxxRgtV1RQQsZG88wn+oTGpLI5wJzj6cZ8eAEH1LkDpHyKfTZah5vFy4VWWtFEKba7CYQXyvrxTMWuHvfITEWZgcOjf7mnVLHGpdsqueccraNKFgNxobZ9RKdIl+Cs9YVUTqIKz25FBa0jOCIiCE+N+65r4ANgcqzKM5CBomQPADHtf0xt1UDptQZaE1ikAAABg+OuX6Y3xJmTu/bdhWWpp3c0Odtrs5u1L9aG1CsCG95KKTS+HJqd+UVt02kGYjyILHMh6ofyBDOmagvLRzoIe3O15TGlB9Cx6GguMTSjHXsYLZSJ59hVKdirtFl1H3uNnAAAAYO1NcdCm4kuTwuX2tLvgX1+wr6BC0gT+M3jTZcLyiLao2tfv5F0VPu9Aysx7gf+TQALRCJlLlKXkcozZyWM3WuSZZb2lXL8O/tjWVTtAJ/LYYgim5rSJwXYSgJLWKeSdPQAAAGArtovd+wxPVshVi/+viS2AQwN4Qef6gc+mGjjF45uQHI7nESKl2iInvWze60gUUsEq09YdXk93agq1Vlkb7+Plnlp/3bg0Xh8vNbn0zuV8MkFMCGrsmT6TU+SA2e7GKJ8AAABgT/iXcJ+tB5dGSUV45w/YVGEw7qtWJ8SbCA8F7krZ8+S3y6nWpd/xE6QcNAkzaDPxkIFtimvELpvsVrdWfQ88nGltthmyRdkB3YVtt8gJLnfpoczNVu5NukLF/bYa7CZpAAAAYHe50RN7UEBKmCcpMW76/H3+ZtNOWhgmANXzCgqFEgUcVg0IHU0KGDXsPSWmD05NaqlIsr89u1sSTLvDSJJVo6lINy9peElnRflD4dtPGDgs6qUF38ZXV7s/hXpY3OUhVg==
\ No newline at end of file
diff --git a/nss/cmd/bltest/tests/rsa_pss/maskhash0 b/nss/cmd/bltest/tests/rsa_pss/maskhash0
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/maskhash0
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/maskhash1 b/nss/cmd/bltest/tests/rsa_pss/maskhash1
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/maskhash1
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/maskhash10 b/nss/cmd/bltest/tests/rsa_pss/maskhash10
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/maskhash10
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/maskhash11 b/nss/cmd/bltest/tests/rsa_pss/maskhash11
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/maskhash11
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/maskhash12 b/nss/cmd/bltest/tests/rsa_pss/maskhash12
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/maskhash12
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/maskhash13 b/nss/cmd/bltest/tests/rsa_pss/maskhash13
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/maskhash13
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/maskhash14 b/nss/cmd/bltest/tests/rsa_pss/maskhash14
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/maskhash14
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/maskhash15 b/nss/cmd/bltest/tests/rsa_pss/maskhash15
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/maskhash15
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/maskhash16 b/nss/cmd/bltest/tests/rsa_pss/maskhash16
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/maskhash16
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/maskhash17 b/nss/cmd/bltest/tests/rsa_pss/maskhash17
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/maskhash17
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/maskhash2 b/nss/cmd/bltest/tests/rsa_pss/maskhash2
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/maskhash2
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/maskhash3 b/nss/cmd/bltest/tests/rsa_pss/maskhash3
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/maskhash3
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/maskhash4 b/nss/cmd/bltest/tests/rsa_pss/maskhash4
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/maskhash4
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/maskhash5 b/nss/cmd/bltest/tests/rsa_pss/maskhash5
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/maskhash5
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/maskhash6 b/nss/cmd/bltest/tests/rsa_pss/maskhash6
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/maskhash6
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/maskhash7 b/nss/cmd/bltest/tests/rsa_pss/maskhash7
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/maskhash7
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/maskhash8 b/nss/cmd/bltest/tests/rsa_pss/maskhash8
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/maskhash8
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/maskhash9 b/nss/cmd/bltest/tests/rsa_pss/maskhash9
new file mode 100644
index 0000000..fcdd09c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/maskhash9
@@ -0,0 +1 @@
+sha1
diff --git a/nss/cmd/bltest/tests/rsa_pss/numtests b/nss/cmd/bltest/tests/rsa_pss/numtests
new file mode 100644
index 0000000..3c03207
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/numtests
@@ -0,0 +1 @@
+18
diff --git a/nss/cmd/bltest/tests/rsa_pss/plaintext0 b/nss/cmd/bltest/tests/rsa_pss/plaintext0
new file mode 100644
index 0000000..6218384
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/plaintext0
@@ -0,0 +1 @@
+zYtlOMuOjeVmtovQZ1advx7icY4=
diff --git a/nss/cmd/bltest/tests/rsa_pss/plaintext1 b/nss/cmd/bltest/tests/rsa_pss/plaintext1
new file mode 100644
index 0000000..e8ce055
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/plaintext1
@@ -0,0 +1 @@
+41vvwXodFguc41+9jrFufuSR0/0=
diff --git a/nss/cmd/bltest/tests/rsa_pss/plaintext10 b/nss/cmd/bltest/tests/rsa_pss/plaintext10
new file mode 100644
index 0000000..e7c8e71
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/plaintext10
@@ -0,0 +1 @@
+altL5M02zJff3pmV77+PCXpKmRo=
diff --git a/nss/cmd/bltest/tests/rsa_pss/plaintext11 b/nss/cmd/bltest/tests/rsa_pss/plaintext11
new file mode 100644
index 0000000..6af26f1
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/plaintext11
@@ -0,0 +1 @@
+ud/R33akYcUeZXbGyO0Kkj0cUOc=
diff --git a/nss/cmd/bltest/tests/rsa_pss/plaintext12 b/nss/cmd/bltest/tests/rsa_pss/plaintext12
new file mode 100644
index 0000000..d94dd83
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/plaintext12
@@ -0,0 +1 @@
+lZa7Ywz2qNTqRgBCK566ixNnXdQ=
diff --git a/nss/cmd/bltest/tests/rsa_pss/plaintext13 b/nss/cmd/bltest/tests/rsa_pss/plaintext13
new file mode 100644
index 0000000..a7998a4
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/plaintext13
@@ -0,0 +1 @@
+tQMxk5knf9bByPEDPL8EGZ6iFxY=
diff --git a/nss/cmd/bltest/tests/rsa_pss/plaintext14 b/nss/cmd/bltest/tests/rsa_pss/plaintext14
new file mode 100644
index 0000000..b18920b
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/plaintext14
@@ -0,0 +1 @@
+UKrt6FNrLDByCLJ1pnri3xlsdig=
diff --git a/nss/cmd/bltest/tests/rsa_pss/plaintext15 b/nss/cmd/bltest/tests/rsa_pss/plaintext15
new file mode 100644
index 0000000..407ec5c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/plaintext15
@@ -0,0 +1 @@
+qgtyuLNx3dEMiuR0QlzMz4hCopQ=
diff --git a/nss/cmd/bltest/tests/rsa_pss/plaintext16 b/nss/cmd/bltest/tests/rsa_pss/plaintext16
new file mode 100644
index 0000000..c10bd8d
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/plaintext16
@@ -0,0 +1 @@
++tOQLJdQYiorxnJiLEgnDMV9Pqg=
diff --git a/nss/cmd/bltest/tests/rsa_pss/plaintext17 b/nss/cmd/bltest/tests/rsa_pss/plaintext17
new file mode 100644
index 0000000..cf9856c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/plaintext17
@@ -0,0 +1 @@
+EiGW3rXRIr2Mb8eB/2kk18aVqt4=
diff --git a/nss/cmd/bltest/tests/rsa_pss/plaintext2 b/nss/cmd/bltest/tests/rsa_pss/plaintext2
new file mode 100644
index 0000000..3b390ec
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/plaintext2
@@ -0,0 +1 @@
+BlLsZ7zuMPnSaZEiuRwZq9uon5E=
diff --git a/nss/cmd/bltest/tests/rsa_pss/plaintext3 b/nss/cmd/bltest/tests/rsa_pss/plaintext3
new file mode 100644
index 0000000..36da06a
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/plaintext3
@@ -0,0 +1 @@
+OcIcTM7anBrfg5x0ThISpkN1dew=
diff --git a/nss/cmd/bltest/tests/rsa_pss/plaintext4 b/nss/cmd/bltest/tests/rsa_pss/plaintext4
new file mode 100644
index 0000000..c8d7ff2
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/plaintext4
@@ -0,0 +1 @@
+NtrpE7d70XyubnsJRT0kVEzrszw=
diff --git a/nss/cmd/bltest/tests/rsa_pss/plaintext5 b/nss/cmd/bltest/tests/rsa_pss/plaintext5
new file mode 100644
index 0000000..fb0a775
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/plaintext5
@@ -0,0 +1 @@
+Re7xkfT3nDH+XS7eflCYmU6SnS0=
diff --git a/nss/cmd/bltest/tests/rsa_pss/plaintext6 b/nss/cmd/bltest/tests/rsa_pss/plaintext6
new file mode 100644
index 0000000..05de2c2
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/plaintext6
@@ -0,0 +1 @@
+JxWkm4sAEs167oTBFkRubf4/rsA=
diff --git a/nss/cmd/bltest/tests/rsa_pss/plaintext7 b/nss/cmd/bltest/tests/rsa_pss/plaintext7
new file mode 100644
index 0000000..b0b0660
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/plaintext7
@@ -0,0 +1 @@
+LayVbVOWR0isNk0GWVgnxrTxQ80=
diff --git a/nss/cmd/bltest/tests/rsa_pss/plaintext8 b/nss/cmd/bltest/tests/rsa_pss/plaintext8
new file mode 100644
index 0000000..dc97a9c
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/plaintext8
@@ -0,0 +1 @@
+KNmMRszK+9O8BOcvlnpUvT6hIpg=
diff --git a/nss/cmd/bltest/tests/rsa_pss/plaintext9 b/nss/cmd/bltest/tests/rsa_pss/plaintext9
new file mode 100644
index 0000000..cd9c072
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/plaintext9
@@ -0,0 +1 @@
+CGbS/1p58l72aM1vMbQt7kIeTA4=
diff --git a/nss/cmd/bltest/tests/rsa_pss/seed0 b/nss/cmd/bltest/tests/rsa_pss/seed0
new file mode 100644
index 0000000..2e26315
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/seed0
@@ -0,0 +1 @@
+3ulZx+BkETYUIP+AGF7Vfz5ndq8=
diff --git a/nss/cmd/bltest/tests/rsa_pss/seed1 b/nss/cmd/bltest/tests/rsa_pss/seed1
new file mode 100644
index 0000000..26e4788
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/seed1
@@ -0,0 +1 @@
+7yhp+kDDRssYPas9e//Jj9Vt9C0=
diff --git a/nss/cmd/bltest/tests/rsa_pss/seed10 b/nss/cmd/bltest/tests/rsa_pss/seed10
new file mode 100644
index 0000000..8418bb7
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/seed10
@@ -0,0 +1 @@
+1okleobv+mghLF4MYZ7KKV+5G2c=
diff --git a/nss/cmd/bltest/tests/rsa_pss/seed11 b/nss/cmd/bltest/tests/rsa_pss/seed11
new file mode 100644
index 0000000..f582586
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/seed11
@@ -0,0 +1 @@
+wl8Tv2fQgWcaBIGh8YINYTu6InY=
diff --git a/nss/cmd/bltest/tests/rsa_pss/seed12 b/nss/cmd/bltest/tests/rsa_pss/seed12
new file mode 100644
index 0000000..59469f9
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/seed12
@@ -0,0 +1 @@
+BOIV7m/5NLnacNdzDIc0q/zs3ok=
diff --git a/nss/cmd/bltest/tests/rsa_pss/seed13 b/nss/cmd/bltest/tests/rsa_pss/seed13
new file mode 100644
index 0000000..402552f
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/seed13
@@ -0,0 +1 @@
+iyvdS0D69UXHeN35vBpJy1f5txs=
diff --git a/nss/cmd/bltest/tests/rsa_pss/seed14 b/nss/cmd/bltest/tests/rsa_pss/seed14
new file mode 100644
index 0000000..d840fd5
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/seed14
@@ -0,0 +1 @@
+Tpb8GzmPkrRGcQEMDcPv1uIMLXM=
diff --git a/nss/cmd/bltest/tests/rsa_pss/seed15 b/nss/cmd/bltest/tests/rsa_pss/seed15
new file mode 100644
index 0000000..2edca8b
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/seed15
@@ -0,0 +1 @@
+x81pjYS2USjYg146ix6w4By1Qew=
diff --git a/nss/cmd/bltest/tests/rsa_pss/seed16 b/nss/cmd/bltest/tests/rsa_pss/seed16
new file mode 100644
index 0000000..80e23fb
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/seed16
@@ -0,0 +1 @@
+76i/+WISsvSj83GhDVdBUmVfXfs=
diff --git a/nss/cmd/bltest/tests/rsa_pss/seed17 b/nss/cmd/bltest/tests/rsa_pss/seed17
new file mode 100644
index 0000000..2e7a00d
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/seed17
@@ -0,0 +1 @@
+rYsVI3A2RiJLZgtVCIWRfKLR3yg=
diff --git a/nss/cmd/bltest/tests/rsa_pss/seed2 b/nss/cmd/bltest/tests/rsa_pss/seed2
new file mode 100644
index 0000000..4df6784
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/seed2
@@ -0,0 +1 @@
+cQucR0fYANTeh/Eq/c5t8YEHzHc=
diff --git a/nss/cmd/bltest/tests/rsa_pss/seed3 b/nss/cmd/bltest/tests/rsa_pss/seed3
new file mode 100644
index 0000000..d58108d
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/seed3
@@ -0,0 +1 @@
+BW8AmF3hTY71zqnoL4wnvvcgM14=
diff --git a/nss/cmd/bltest/tests/rsa_pss/seed4 b/nss/cmd/bltest/tests/rsa_pss/seed4
new file mode 100644
index 0000000..7d366c1
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/seed4
@@ -0,0 +1 @@
+gOcP+GoI3j7GCXKzm0+/3Opnro4=
diff --git a/nss/cmd/bltest/tests/rsa_pss/seed5 b/nss/cmd/bltest/tests/rsa_pss/seed5
new file mode 100644
index 0000000..a2da928
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/seed5
@@ -0,0 +1 @@
+qKtp3YAfAHTCofxgZJg2xhbZloE=
diff --git a/nss/cmd/bltest/tests/rsa_pss/seed6 b/nss/cmd/bltest/tests/rsa_pss/seed6
new file mode 100644
index 0000000..6dcd0e5
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/seed6
@@ -0,0 +1 @@
+wKQlMT3411ZL0kNNMRUj1SV+7YA=
diff --git a/nss/cmd/bltest/tests/rsa_pss/seed7 b/nss/cmd/bltest/tests/rsa_pss/seed7
new file mode 100644
index 0000000..0b6e3f3
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/seed7
@@ -0,0 +1 @@
+swfEO0hQqNrC8V8y43g574xcDpE=
diff --git a/nss/cmd/bltest/tests/rsa_pss/seed8 b/nss/cmd/bltest/tests/rsa_pss/seed8
new file mode 100644
index 0000000..b1b34b4
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/seed8
@@ -0,0 +1 @@
+misAfoCXi7sZLDVOt9qa7fx02/U=
diff --git a/nss/cmd/bltest/tests/rsa_pss/seed9 b/nss/cmd/bltest/tests/rsa_pss/seed9
new file mode 100644
index 0000000..d18d81a
--- /dev/null
+++ b/nss/cmd/bltest/tests/rsa_pss/seed9
@@ -0,0 +1 @@
+cPOCvd9NXS3YizvHtzCL5jK4QEU=
diff --git a/nss/cmd/bltest/tests/seed_cbc/ciphertext0 b/nss/cmd/bltest/tests/seed_cbc/ciphertext0
new file mode 100644
index 0000000..97e970e
--- /dev/null
+++ b/nss/cmd/bltest/tests/seed_cbc/ciphertext0
@@ -0,0 +1 @@
+JVdzim3if1YIcpGABasoCQ==
diff --git a/nss/cmd/bltest/tests/seed_cbc/iv0 b/nss/cmd/bltest/tests/seed_cbc/iv0
new file mode 100644
index 0000000..2b3b076
--- /dev/null
+++ b/nss/cmd/bltest/tests/seed_cbc/iv0
@@ -0,0 +1 @@
+1234567890123456
diff --git a/nss/cmd/bltest/tests/seed_cbc/key0 b/nss/cmd/bltest/tests/seed_cbc/key0
new file mode 100644
index 0000000..13911cc
--- /dev/null
+++ b/nss/cmd/bltest/tests/seed_cbc/key0
@@ -0,0 +1 @@
+fedcba9876543210
diff --git a/nss/cmd/bltest/tests/seed_cbc/numtests b/nss/cmd/bltest/tests/seed_cbc/numtests
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/nss/cmd/bltest/tests/seed_cbc/numtests
@@ -0,0 +1 @@
+1
diff --git a/nss/cmd/bltest/tests/seed_cbc/plaintext0 b/nss/cmd/bltest/tests/seed_cbc/plaintext0
new file mode 100644
index 0000000..8d6a8d5
--- /dev/null
+++ b/nss/cmd/bltest/tests/seed_cbc/plaintext0
@@ -0,0 +1 @@
+0123456789abcdef
diff --git a/nss/cmd/bltest/tests/seed_ecb/ciphertext0 b/nss/cmd/bltest/tests/seed_ecb/ciphertext0
new file mode 100644
index 0000000..314ffbd
--- /dev/null
+++ b/nss/cmd/bltest/tests/seed_ecb/ciphertext0
@@ -0,0 +1 @@
+GX8KY3uUhAQnL6XbQhXjEw==
diff --git a/nss/cmd/bltest/tests/seed_ecb/iv0 b/nss/cmd/bltest/tests/seed_ecb/iv0
new file mode 100644
index 0000000..2b3b076
--- /dev/null
+++ b/nss/cmd/bltest/tests/seed_ecb/iv0
@@ -0,0 +1 @@
+1234567890123456
diff --git a/nss/cmd/bltest/tests/seed_ecb/key0 b/nss/cmd/bltest/tests/seed_ecb/key0
new file mode 100644
index 0000000..13911cc
--- /dev/null
+++ b/nss/cmd/bltest/tests/seed_ecb/key0
@@ -0,0 +1 @@
+fedcba9876543210
diff --git a/nss/cmd/bltest/tests/seed_ecb/numtests b/nss/cmd/bltest/tests/seed_ecb/numtests
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/nss/cmd/bltest/tests/seed_ecb/numtests
@@ -0,0 +1 @@
+1
diff --git a/nss/cmd/bltest/tests/seed_ecb/plaintext0 b/nss/cmd/bltest/tests/seed_ecb/plaintext0
new file mode 100644
index 0000000..8d6a8d5
--- /dev/null
+++ b/nss/cmd/bltest/tests/seed_ecb/plaintext0
@@ -0,0 +1 @@
+0123456789abcdef
diff --git a/nss/cmd/bltest/tests/sha1/ciphertext0 b/nss/cmd/bltest/tests/sha1/ciphertext0
new file mode 100644
index 0000000..1fe4bd2
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha1/ciphertext0
@@ -0,0 +1 @@
+cDSMAygXMPIJZC5bntZ4ZhecQ9g=
diff --git a/nss/cmd/bltest/tests/sha1/numtests b/nss/cmd/bltest/tests/sha1/numtests
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha1/numtests
@@ -0,0 +1 @@
+1
diff --git a/nss/cmd/bltest/tests/sha1/plaintext0 b/nss/cmd/bltest/tests/sha1/plaintext0
new file mode 100644
index 0000000..863e79c
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha1/plaintext0
@@ -0,0 +1 @@
+A cage went in search of a bird.
diff --git a/nss/cmd/bltest/tests/sha224/ciphertext0 b/nss/cmd/bltest/tests/sha224/ciphertext0
new file mode 100644
index 0000000..dfc3d27
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha224/ciphertext0
@@ -0,0 +1,2 @@
+Iwl9IjQF2CKGQqR3vaJVsyqtvOS9oLP342ydpw==
+
diff --git a/nss/cmd/bltest/tests/sha224/ciphertext1 b/nss/cmd/bltest/tests/sha224/ciphertext1
new file mode 100644
index 0000000..bef4714
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha224/ciphertext1
@@ -0,0 +1,2 @@
+dTiLFlEndsxdul2h/YkBULDGRVy09YsZUlIlJQ==
+
diff --git a/nss/cmd/bltest/tests/sha224/numtests b/nss/cmd/bltest/tests/sha224/numtests
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha224/numtests
@@ -0,0 +1 @@
+2
diff --git a/nss/cmd/bltest/tests/sha224/plaintext0 b/nss/cmd/bltest/tests/sha224/plaintext0
new file mode 100644
index 0000000..8baef1b
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha224/plaintext0
@@ -0,0 +1 @@
+abc
diff --git a/nss/cmd/bltest/tests/sha224/plaintext1 b/nss/cmd/bltest/tests/sha224/plaintext1
new file mode 100644
index 0000000..afb5dce
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha224/plaintext1
@@ -0,0 +1 @@
+abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq
diff --git a/nss/cmd/bltest/tests/sha256/ciphertext0 b/nss/cmd/bltest/tests/sha256/ciphertext0
new file mode 100644
index 0000000..07e2ff1
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha256/ciphertext0
@@ -0,0 +1 @@
+ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0=
diff --git a/nss/cmd/bltest/tests/sha256/ciphertext1 b/nss/cmd/bltest/tests/sha256/ciphertext1
new file mode 100644
index 0000000..2ab6e1d
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha256/ciphertext1
@@ -0,0 +1 @@
+JI1qYdIGOLjlwCaTDD5gOaM85Flk/yFn9uzt1BnbBsE=
diff --git a/nss/cmd/bltest/tests/sha256/numtests b/nss/cmd/bltest/tests/sha256/numtests
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha256/numtests
@@ -0,0 +1 @@
+2
diff --git a/nss/cmd/bltest/tests/sha256/plaintext0 b/nss/cmd/bltest/tests/sha256/plaintext0
new file mode 100644
index 0000000..8baef1b
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha256/plaintext0
@@ -0,0 +1 @@
+abc
diff --git a/nss/cmd/bltest/tests/sha256/plaintext1 b/nss/cmd/bltest/tests/sha256/plaintext1
new file mode 100644
index 0000000..afb5dce
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha256/plaintext1
@@ -0,0 +1 @@
+abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq
diff --git a/nss/cmd/bltest/tests/sha384/ciphertext0 b/nss/cmd/bltest/tests/sha384/ciphertext0
new file mode 100644
index 0000000..c94f91e
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha384/ciphertext0
@@ -0,0 +1 @@
+ywB1P0WjXou1oD1pmsZQBycsMqsO3tFjGotgWkP/W+2AhgcroefMI1i67KE0yCWn
diff --git a/nss/cmd/bltest/tests/sha384/ciphertext1 b/nss/cmd/bltest/tests/sha384/ciphertext1
new file mode 100644
index 0000000..833f06d
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha384/ciphertext1
@@ -0,0 +1 @@
+CTMMM/cRR+g9GS/Hgs0bR1MRGxc7OwXSL6CAhuOw9xL8x8caVX4tuWbD6fqRdGA5
diff --git a/nss/cmd/bltest/tests/sha384/numtests b/nss/cmd/bltest/tests/sha384/numtests
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha384/numtests
@@ -0,0 +1 @@
+2
diff --git a/nss/cmd/bltest/tests/sha384/plaintext0 b/nss/cmd/bltest/tests/sha384/plaintext0
new file mode 100644
index 0000000..8baef1b
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha384/plaintext0
@@ -0,0 +1 @@
+abc
diff --git a/nss/cmd/bltest/tests/sha384/plaintext1 b/nss/cmd/bltest/tests/sha384/plaintext1
new file mode 100644
index 0000000..94fcc2b
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha384/plaintext1
@@ -0,0 +1 @@
+abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu
diff --git a/nss/cmd/bltest/tests/sha512/ciphertext0 b/nss/cmd/bltest/tests/sha512/ciphertext0
new file mode 100644
index 0000000..8b626e2
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha512/ciphertext0
@@ -0,0 +1,2 @@
+3a81oZNherrMQXNJriBBMRLm+k6JqX6iCp7u5ktV05ohkpkqJ0/BqDa6PCOj/uu9
+RU1EI2Q86A4qmslPpUyknw==
diff --git a/nss/cmd/bltest/tests/sha512/ciphertext1 b/nss/cmd/bltest/tests/sha512/ciphertext1
new file mode 100644
index 0000000..c02d175
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha512/ciphertext1
@@ -0,0 +1,2 @@
+jpWbddrjE9qM9PcoFPwUP493ecbrn3+hcpmurbaIkBhQHSieSQD35DMbmd7EtUM6
+x9Mp7rbdJlReluVbh0vpCQ==
diff --git a/nss/cmd/bltest/tests/sha512/numtests b/nss/cmd/bltest/tests/sha512/numtests
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha512/numtests
@@ -0,0 +1 @@
+2
diff --git a/nss/cmd/bltest/tests/sha512/plaintext0 b/nss/cmd/bltest/tests/sha512/plaintext0
new file mode 100644
index 0000000..8baef1b
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha512/plaintext0
@@ -0,0 +1 @@
+abc
diff --git a/nss/cmd/bltest/tests/sha512/plaintext1 b/nss/cmd/bltest/tests/sha512/plaintext1
new file mode 100644
index 0000000..94fcc2b
--- /dev/null
+++ b/nss/cmd/bltest/tests/sha512/plaintext1
@@ -0,0 +1 @@
+abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu
diff --git a/nss/cmd/btoa/Makefile b/nss/cmd/btoa/Makefile
new file mode 100644
index 0000000..f3b23fd
--- /dev/null
+++ b/nss/cmd/btoa/Makefile
@@ -0,0 +1,47 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include ../platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+
+include ../platrules.mk
+
diff --git a/nss/cmd/btoa/btoa.c b/nss/cmd/btoa/btoa.c
new file mode 100644
index 0000000..2a5e6d4
--- /dev/null
+++ b/nss/cmd/btoa/btoa.c
@@ -0,0 +1,203 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "plgetopt.h"
+#include "secutil.h"
+#include "nssb64.h"
+#include
+
+#if defined(XP_WIN) || (defined(__sun) && !defined(SVR4))
+#if !defined(WIN32)
+extern int fread(char *, size_t, size_t, FILE *);
+extern int fwrite(char *, size_t, size_t, FILE *);
+extern int fprintf(FILE *, char *, ...);
+#endif
+#endif
+
+#if defined(WIN32)
+#include "fcntl.h"
+#include "io.h"
+#endif
+
+static PRInt32
+output_ascii(void *arg, const char *obuf, PRInt32 size)
+{
+ FILE *outFile = arg;
+ int nb;
+
+ nb = fwrite(obuf, 1, size, outFile);
+ if (nb != size) {
+ PORT_SetError(SEC_ERROR_IO);
+ return -1;
+ }
+
+ return nb;
+}
+
+static SECStatus
+encode_file(FILE *outFile, FILE *inFile)
+{
+ NSSBase64Encoder *cx;
+ int nb;
+ SECStatus status = SECFailure;
+ unsigned char ibuf[4096];
+
+ cx = NSSBase64Encoder_Create(output_ascii, outFile);
+ if (!cx) {
+ return -1;
+ }
+
+ for (;;) {
+ if (feof(inFile))
+ break;
+ nb = fread(ibuf, 1, sizeof(ibuf), inFile);
+ if (nb != sizeof(ibuf)) {
+ if (nb == 0) {
+ if (ferror(inFile)) {
+ PORT_SetError(SEC_ERROR_IO);
+ goto loser;
+ }
+ /* eof */
+ break;
+ }
+ }
+
+ status = NSSBase64Encoder_Update(cx, ibuf, nb);
+ if (status != SECSuccess)
+ goto loser;
+ }
+
+ status = NSSBase64Encoder_Destroy(cx, PR_FALSE);
+ if (status != SECSuccess)
+ return status;
+
+ /*
+ * Add a trailing CRLF. Note this must be done *after* the call
+ * to Destroy above (because only then are we sure all data has
+ * been written out).
+ */
+ fwrite("\r\n", 1, 2, outFile);
+ return SECSuccess;
+
+loser:
+ (void)NSSBase64Encoder_Destroy(cx, PR_TRUE);
+ return status;
+}
+
+static void
+Usage(char *progName)
+{
+ fprintf(stderr,
+ "Usage: %s [-i input] [-o output]\n",
+ progName);
+ fprintf(stderr, "%-20s Define an input file to use (default is stdin)\n",
+ "-i input");
+ fprintf(stderr, "%-20s Define an output file to use (default is stdout)\n",
+ "-o output");
+ fprintf(stderr, "%-20s Wrap output in BEGIN/END lines and the given suffix\n",
+ "-w suffix");
+ fprintf(stderr, "%-20s (use \"c\" as a shortcut for suffix CERTIFICATE)\n",
+ "");
+ exit(-1);
+}
+
+int
+main(int argc, char **argv)
+{
+ char *progName;
+ SECStatus rv;
+ FILE *inFile, *outFile;
+ PLOptState *optstate;
+ PLOptStatus status;
+ char *suffix = NULL;
+
+ inFile = 0;
+ outFile = 0;
+ progName = strrchr(argv[0], '/');
+ if (!progName)
+ progName = strrchr(argv[0], '\\');
+ progName = progName ? progName + 1 : argv[0];
+
+ /* Parse command line arguments */
+ optstate = PL_CreateOptState(argc, argv, "i:o:w:");
+ while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
+ switch (optstate->option) {
+ default:
+ Usage(progName);
+ break;
+
+ case 'i':
+ inFile = fopen(optstate->value, "rb");
+ if (!inFile) {
+ fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
+ progName, optstate->value);
+ return -1;
+ }
+ break;
+
+ case 'o':
+ outFile = fopen(optstate->value, "wb");
+ if (!outFile) {
+ fprintf(stderr, "%s: unable to open \"%s\" for writing\n",
+ progName, optstate->value);
+ return -1;
+ }
+ break;
+
+ case 'w':
+ if (!strcmp(optstate->value, "c"))
+ suffix = strdup("CERTIFICATE");
+ else
+ suffix = strdup(optstate->value);
+ break;
+ }
+ }
+ if (status == PL_OPT_BAD)
+ Usage(progName);
+ if (!inFile) {
+#if defined(WIN32)
+ /* If we're going to read binary data from stdin, we must put stdin
+ ** into O_BINARY mode or else incoming \r\n's will become \n's.
+ */
+
+ int smrv = _setmode(_fileno(stdin), _O_BINARY);
+ if (smrv == -1) {
+ fprintf(stderr,
+ "%s: Cannot change stdin to binary mode. Use -i option instead.\n",
+ progName);
+ return smrv;
+ }
+#endif
+ inFile = stdin;
+ }
+ if (!outFile) {
+#if defined(WIN32)
+ /* We're going to write binary data to stdout. We must put stdout
+ ** into O_BINARY mode or else outgoing \r\n's will become \r\r\n's.
+ */
+
+ int smrv = _setmode(_fileno(stdout), _O_BINARY);
+ if (smrv == -1) {
+ fprintf(stderr,
+ "%s: Cannot change stdout to binary mode. Use -o option instead.\n",
+ progName);
+ return smrv;
+ }
+#endif
+ outFile = stdout;
+ }
+ if (suffix) {
+ fprintf(outFile, "-----BEGIN %s-----\n", suffix);
+ }
+ rv = encode_file(outFile, inFile);
+ if (rv != SECSuccess) {
+ fprintf(stderr, "%s: lossage: error=%d errno=%d\n",
+ progName, PORT_GetError(), errno);
+ return -1;
+ }
+ if (suffix) {
+ fprintf(outFile, "-----END %s-----\n", suffix);
+ }
+ return 0;
+}
diff --git a/nss/cmd/btoa/btoa.gyp b/nss/cmd/btoa/btoa.gyp
new file mode 100644
index 0000000..295d575
--- /dev/null
+++ b/nss/cmd/btoa/btoa.gyp
@@ -0,0 +1,30 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi',
+ '../../cmd/platlibs.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'btoa',
+ 'type': 'executable',
+ 'sources': [
+ 'btoa.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:dbm_exports',
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'target_defaults': {
+ 'defines': [
+ 'NSPR20'
+ ]
+ },
+ 'variables': {
+ 'module': 'nss'
+ }
+}
\ No newline at end of file
diff --git a/nss/cmd/btoa/manifest.mn b/nss/cmd/btoa/manifest.mn
new file mode 100644
index 0000000..52508a5
--- /dev/null
+++ b/nss/cmd/btoa/manifest.mn
@@ -0,0 +1,21 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+CORE_DEPTH = ../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+# This next line is used by .mk files
+# and gets translated into $LINCS in manifest.mnw
+# MODULE is implicitly REQUIRED, doesn't need to be listed below.
+REQUIRES = seccmd dbm
+
+DEFINES = -DNSPR20
+
+CSRCS = btoa.c
+
+PROGRAM = btoa
+
diff --git a/nss/cmd/certcgi/HOWTO.txt b/nss/cmd/certcgi/HOWTO.txt
new file mode 100644
index 0000000..54edf8e
--- /dev/null
+++ b/nss/cmd/certcgi/HOWTO.txt
@@ -0,0 +1,137 @@
+ How to setup your very own Cert-O-Matic Root CA server
+
+ This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+ How to setup your very own Cert-O-Matic Root CA server
+
+The program certcgi is part of a small test CA that is used inside
+Netscape by the NSS development team. That CA is affectionately known
+as "Cert-O-Matic" or "Cert-O-Matic II". It presently runs on a server
+named interzone.mcom.com inside Netscape's firewall.
+
+If you wish to setup your own Cert-O-Matic, here are directions.
+
+Disclaimer: This program does not follow good practices for root CAs.
+It should be used only for playing/testing and never for production use.
+Remember, you've been warned!
+
+Cert-O-Matic consists of some html files, shell scripts, one executable
+program that uses NSS and NSPR, the usual set of NSS .db files, and a file
+in which to remember the serial number of the last cert issued. The
+html files and the source to the executable program are in this directory.
+Sample shell scripts are shown below.
+
+The shell scripts and executable program run as CGI "scripts". The
+entire thing runs on an ordinary http web server. It would also run on
+an https web server. The shell scripts and html files must be
+customized for the server on which they run.
+
+The package assumes you have a "document root" directory $DOCROOT, and a
+"cgi-bin" directory $CGIBIN. In this example, the document root is
+assumed to be located in /var/www/htdocs, and the cgi-bin directory in
+/var/www/cgi-bin.
+
+The server is assumed to run all cgi scripts as the user "nobody".
+The names of the cgi scripts run directly by the server all end in .cgi
+because some servers like it that way.
+
+Instructions:
+
+- Create directory $DOCROOT/certomatic
+- Copy the following files from nss/cmd/certcgi to $DOCROOT/certomatic
+ ca.html index.html main.html nscp_ext_form.html stnd_ext_form.html
+- Edit the html files, substituting the name of your own server for the
+ server named in those files.
+- In some web page (e.g. your server's home page), provide an html link to
+ $DOCROOT/certomatic/index.html. This is where users start to get their
+ own certs from certomatic.
+- give these files and directories appropriate permissions.
+
+- Create directories $CGIBIN/certomatic and $CGIBIN/certomatic/bin
+ make sure that $CGIBIN/certomatic is writable by "nobody"
+
+- Create a new set of NSS db files there with the following command:
+
+ certutil -N -d $CGIBIN/certomatic
+
+- when certutil prompts you for the password, enter the word foo
+ because that is compiled into the certcgi program.
+
+- Create the new Root CA cert with this command
+
+ certutil -S -x -d $CGIBIN/certomatic -n "Cert-O-Matic II" \
+ -s "CN=Cert-O-Matic II, O=Cert-O-Matic II" -t TCu,cu,cu -k rsa \
+ -g 1024 -m 10001 -v 60
+
+ (adjust the -g, -m and -v parameters to taste. -s and -x must be as
+shown.)
+
+- dump out the new root CA cert in base64 encoding:
+
+ certutil -d $CGIBIN/certomatic -L -n "Cert-O-Matic II" -a > \
+ $CGIBIN/certomatic/root.cacert
+
+- In $CGIBIN/certomatic/bin add two shell scripts - one to download the
+ root CA cert on demand, and one to run the certcgi program.
+
+download.cgi, the script to install the root CA cert into a browser on
+demand, is this:
+
+#!/bin/sh
+echo "Content-type: application/x-x509-ca-cert"
+echo
+cat $CGIBIN/certomatic/root.cacert
+
+You'll have to put the real path into that cat command because CGIBIN
+won't be defined when this script is run by the server.
+
+certcgi.cgi, the script to run the certcgi program is similar to this:
+
+#!/bin/sh
+cd $CGIBIN/certomatic/bin
+LD_LIBRARY_PATH=$PLATFORM/lib
+export LD_LIBRARY_PATH
+$PLATFORM/bin/certcgi $* 2>&1
+
+Where $PLATFORM/lib is where the NSPR nad NSS DSOs are located, and
+$PLATFORM/bin is where certcgi is located. PLATFORM is not defined when
+the server runs this script, so you'll have to substitute the right value
+in your script. certcgi requires that the working directory be one level
+below the NSS DBs, that is, the DBs are accessed in the directory "..".
+
+You'll want to provide an html link somewhere to the script that downloads
+the root.cacert file. You'll probably want to put that next to the link
+that loads the index.html page. On interzone, this is done with the
+following html:
+
+Cert-O-Matic II Root CA server
+
+Download and trust Root CA
+certificate
+
+The index.html file in this directory invokes the certcgi.cgi script with
+the form post method, so if you change the name of the certcgi.cgi script,
+you'll also have to change the index.html file in $DOCROOT/certomatic
+
+The 4 files used by the certcgi program (the 3 NSS DBs, and the serial
+number file) are not required to live in $CGIBIN/certomatic, but they are
+required to live in $CWD/.. when certcgi starts.
+
+Known bugs:
+
+1. Because multiple of these CAs exist simultaneously, it would be best if
+they didn't all have to be called "Cert-O-Matic II", but that string is
+presently hard coded into certcgi.c.
+
+2. the html files in this directory contain numerous extraneous
+ Use a
+ CA long
+ automatically generated chain ending with the Cert-O-Matic Cert
+ (18 maximum)
+ Use a
+ CA long
+ user input chain ending in the Cert-O-Matic Cert.
+
diff --git a/nss/cmd/certcgi/ca_form.html b/nss/cmd/certcgi/ca_form.html
new file mode 100644
index 0000000..452996b
--- /dev/null
+++ b/nss/cmd/certcgi/ca_form.html
@@ -0,0 +1,357 @@
+
+
+
+
+
+ DN:
+
+ 1024 (High Grade)
+ 768 (Medium Grade)
+ 512 (Low Grade)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/nss/cmd/certcgi/certcgi.c b/nss/cmd/certcgi/certcgi.c
new file mode 100644
index 0000000..35409e2
--- /dev/null
+++ b/nss/cmd/certcgi/certcgi.c
@@ -0,0 +1,2246 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* Cert-O-Matic CGI */
+
+#include "nspr.h"
+#include "prtypes.h"
+#include "prtime.h"
+#include "prlong.h"
+
+#include "pk11func.h"
+#include "cert.h"
+#include "cryptohi.h"
+#include "secoid.h"
+#include "secder.h"
+#include "genname.h"
+#include "xconst.h"
+#include "secutil.h"
+#include "pk11pqg.h"
+#include "certxutl.h"
+#include "nss.h"
+
+/* #define TEST 1 */
+/* #define FILEOUT 1 */
+/* #define OFFLINE 1 */
+#define START_FIELDS 100
+#define PREFIX_LEN 6
+#define SERIAL_FILE "../serial"
+#define DB_DIRECTORY ".."
+
+static char *progName;
+
+typedef struct PairStr Pair;
+
+struct PairStr {
+ char *name;
+ char *data;
+};
+
+char prefix[PREFIX_LEN];
+
+const SEC_ASN1Template CERTIA5TypeTemplate[] = {
+ { SEC_ASN1_IA5_STRING }
+};
+
+SECKEYPrivateKey *privkeys[9] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL };
+
+#ifdef notdef
+const SEC_ASN1Template CERT_GeneralNameTemplate[] = {
+ { SEC_ASN1_SEQUENCE_OF, 0, SEC_AnyTemplate }
+};
+#endif
+
+static void
+error_out(char *error_string)
+{
+ printf("Content-type: text/plain\n\n");
+ printf("%s", error_string);
+ fflush(stderr);
+ fflush(stdout);
+ exit(1);
+}
+
+static void
+error_allocate(void)
+{
+ error_out("ERROR: Unable to allocate memory");
+}
+
+static char *
+make_copy_string(char *read_pos,
+ int length,
+ char sentinal_value)
+/* copys string from to a new string it creates and
+ returns a pointer to the new string */
+{
+ int remaining = length;
+ char *write_pos;
+ char *new;
+
+ new = write_pos = (char *)PORT_Alloc(length);
+ if (new == NULL) {
+ error_allocate();
+ }
+ while (*read_pos != sentinal_value) {
+ if (remaining == 1) {
+ remaining += length;
+ length = length * 2;
+ new = PORT_Realloc(new, length);
+ if (new == NULL) {
+ error_allocate();
+ }
+ write_pos = new + length - remaining;
+ }
+ *write_pos = *read_pos;
+ ++write_pos;
+ ++read_pos;
+ remaining = remaining - 1;
+ }
+ *write_pos = '\0';
+ return new;
+}
+
+static SECStatus
+clean_input(Pair *data)
+/* converts the non-alphanumeric characters in a form post
+ from hex codes back to characters */
+{
+ int length;
+ int hi_digit;
+ int low_digit;
+ char character;
+ char *begin_pos;
+ char *read_pos;
+ char *write_pos;
+ PRBool name = PR_TRUE;
+
+ begin_pos = data->name;
+ while (begin_pos != NULL) {
+ length = strlen(begin_pos);
+ read_pos = write_pos = begin_pos;
+ while ((read_pos - begin_pos) < length) {
+ if (*read_pos == '+') {
+ *read_pos = ' ';
+ }
+ if (*read_pos == '%') {
+ hi_digit = *(read_pos + 1);
+ low_digit = *(read_pos + 2);
+ read_pos += 3;
+ if (isdigit(hi_digit)) {
+ hi_digit = hi_digit - '0';
+ } else {
+ hi_digit = toupper(hi_digit);
+ if (isxdigit(hi_digit)) {
+ hi_digit = (hi_digit - 'A') + 10;
+ } else {
+ error_out("ERROR: Form data incorrectly formated");
+ }
+ }
+ if (isdigit(low_digit)) {
+ low_digit = low_digit - '0';
+ } else {
+ low_digit = toupper(low_digit);
+ if ((low_digit >= 'A') && (low_digit <= 'F')) {
+ low_digit = (low_digit - 'A') + 10;
+ } else {
+ error_out("ERROR: Form data incorrectly formated");
+ }
+ }
+ character = (hi_digit << 4) | low_digit;
+ if (character != 10) {
+ *write_pos = character;
+ ++write_pos;
+ }
+ } else {
+ *write_pos = *read_pos;
+ ++write_pos;
+ ++read_pos;
+ }
+ }
+ *write_pos = '\0';
+ if (name == PR_TRUE) {
+ begin_pos = data->data;
+ name = PR_FALSE;
+ } else {
+ data++;
+ begin_pos = data->name;
+ name = PR_TRUE;
+ }
+ }
+ return SECSuccess;
+}
+
+static char *
+make_name(char *new_data)
+/* gets the next field name in the input string and returns
+ a pointer to a string containing a copy of it */
+{
+ int length = 20;
+ char *name;
+
+ name = make_copy_string(new_data, length, '=');
+ return name;
+}
+
+static char *
+make_data(char *new_data)
+/* gets the data for the next field in the input string
+ and returns a pointer to a string containing it */
+{
+ int length = 100;
+ char *data;
+ char *read_pos;
+
+ read_pos = new_data;
+ while (*(read_pos - 1) != '=') {
+ ++read_pos;
+ }
+ data = make_copy_string(read_pos, length, '&');
+ return data;
+}
+
+static Pair
+make_pair(char *new_data)
+/* makes a pair name/data pair from the input string */
+{
+ Pair temp;
+
+ temp.name = make_name(new_data);
+ temp.data = make_data(new_data);
+ return temp;
+}
+
+static Pair *
+make_datastruct(char *data, int len)
+/* parses the input from the form post into a data
+ structure of field name/data pairs */
+{
+ Pair *datastruct;
+ Pair *current;
+ char *curr_pos;
+ int fields = START_FIELDS;
+ int remaining = START_FIELDS;
+
+ curr_pos = data;
+ datastruct = current = (Pair *)PORT_Alloc(fields * sizeof(Pair));
+ if (datastruct == NULL) {
+ error_allocate();
+ }
+ while (curr_pos - data < len) {
+ if (remaining == 1) {
+ remaining += fields;
+ fields = fields * 2;
+ datastruct = (Pair *)PORT_Realloc(datastruct, fields *
+ sizeof(Pair));
+ if (datastruct == NULL) {
+ error_allocate();
+ }
+ current = datastruct + (fields - remaining);
+ }
+ *current = make_pair(curr_pos);
+ while (*curr_pos != '&') {
+ ++curr_pos;
+ }
+ ++curr_pos;
+ ++current;
+ remaining = remaining - 1;
+ }
+ current->name = NULL;
+ return datastruct;
+}
+
+static char *
+return_name(Pair *data_struct,
+ int n)
+/* returns a pointer to the name of the nth
+ (starting from 0) item in the data structure */
+{
+ char *name;
+
+ if ((data_struct + n)->name != NULL) {
+ name = (data_struct + n)->name;
+ return name;
+ } else {
+ return NULL;
+ }
+}
+
+static char *
+return_data(Pair *data_struct, int n)
+/* returns a pointer to the data of the nth (starting from 0)
+ itme in the data structure */
+{
+ char *data;
+
+ data = (data_struct + n)->data;
+ return data;
+}
+
+static char *
+add_prefix(char *field_name)
+{
+ extern char prefix[PREFIX_LEN];
+ int i = 0;
+ char *rv;
+ char *write;
+
+ rv = write = PORT_Alloc(PORT_Strlen(prefix) + PORT_Strlen(field_name) + 1);
+ for (i = 0; i < PORT_Strlen(prefix); i++) {
+ *write = prefix[i];
+ write++;
+ }
+ *write = '\0';
+ rv = PORT_Strcat(rv, field_name);
+ return rv;
+}
+
+static char *
+find_field(Pair *data,
+ char *field_name,
+ PRBool add_pre)
+/* returns a pointer to the data of the first pair
+ thats name matches the string it is passed */
+{
+ int i = 0;
+ char *retrieved;
+ int found = 0;
+
+ if (add_pre) {
+ field_name = add_prefix(field_name);
+ }
+ while (return_name(data, i) != NULL) {
+ if (PORT_Strcmp(return_name(data, i), field_name) == 0) {
+ retrieved = return_data(data, i);
+ found = 1;
+ break;
+ }
+ i++;
+ }
+ if (!found) {
+ retrieved = NULL;
+ }
+ return retrieved;
+}
+
+static PRBool
+find_field_bool(Pair *data,
+ char *fieldname,
+ PRBool add_pre)
+{
+ char *rv;
+
+ rv = find_field(data, fieldname, add_pre);
+
+ if ((rv != NULL) && (PORT_Strcmp(rv, "true")) == 0) {
+ return PR_TRUE;
+ } else {
+ return PR_FALSE;
+ }
+}
+
+static CERTCertificateRequest *
+makeCertReq(Pair *form_data,
+ int which_priv_key)
+/* makes and encodes a certrequest */
+{
+
+ PK11SlotInfo *slot;
+ CERTCertificateRequest *certReq = NULL;
+ CERTSubjectPublicKeyInfo *spki;
+ SECKEYPrivateKey *privkey = NULL;
+ SECKEYPublicKey *pubkey = NULL;
+ CERTName *name;
+ char *key;
+ extern SECKEYPrivateKey *privkeys[9];
+ int keySizeInBits;
+ char *challenge = "foo";
+ SECStatus rv = SECSuccess;
+ PQGParams *pqgParams = NULL;
+ PQGVerify *pqgVfy = NULL;
+
+ name = CERT_AsciiToName(find_field(form_data, "subject", PR_TRUE));
+ if (name == NULL) {
+ error_out("ERROR: Unable to create Subject Name");
+ }
+ key = find_field(form_data, "key", PR_TRUE);
+ if (key == NULL) {
+ switch (*find_field(form_data, "keysize", PR_TRUE)) {
+ case '0':
+ keySizeInBits = 2048;
+ break;
+ case '1':
+ keySizeInBits = 1024;
+ break;
+ case '2':
+ keySizeInBits = 512;
+ break;
+ default:
+ error_out("ERROR: Unsupported Key length selected");
+ }
+ if (find_field_bool(form_data, "keyType-dsa", PR_TRUE)) {
+ rv = PK11_PQG_ParamGen(keySizeInBits, &pqgParams, &pqgVfy);
+ if (rv != SECSuccess) {
+ error_out("ERROR: Unable to generate PQG parameters");
+ }
+ slot = PK11_GetBestSlot(CKM_DSA_KEY_PAIR_GEN, NULL);
+ privkey = PK11_GenerateKeyPair(slot, CKM_DSA_KEY_PAIR_GEN,
+ pqgParams, &pubkey, PR_FALSE,
+ PR_TRUE, NULL);
+ } else {
+ privkey = SECKEY_CreateRSAPrivateKey(keySizeInBits, &pubkey, NULL);
+ }
+ privkeys[which_priv_key] = privkey;
+ spki = SECKEY_CreateSubjectPublicKeyInfo(pubkey);
+ } else {
+ spki = SECKEY_ConvertAndDecodePublicKeyAndChallenge(key, challenge,
+ NULL);
+ if (spki == NULL) {
+ error_out("ERROR: Unable to decode Public Key and Challenge String");
+ }
+ }
+ certReq = CERT_CreateCertificateRequest(name, spki, NULL);
+ if (certReq == NULL) {
+ error_out("ERROR: Unable to create Certificate Request");
+ }
+ if (pubkey != NULL) {
+ SECKEY_DestroyPublicKey(pubkey);
+ }
+ if (spki != NULL) {
+ SECKEY_DestroySubjectPublicKeyInfo(spki);
+ }
+ if (pqgParams != NULL) {
+ PK11_PQG_DestroyParams(pqgParams);
+ }
+ if (pqgVfy != NULL) {
+ PK11_PQG_DestroyVerify(pqgVfy);
+ }
+ return certReq;
+}
+
+static CERTCertificate *
+MakeV1Cert(CERTCertDBHandle *handle,
+ CERTCertificateRequest *req,
+ char *issuerNameStr,
+ PRBool selfsign,
+ int serialNumber,
+ int warpmonths,
+ Pair *data)
+{
+ CERTCertificate *issuerCert = NULL;
+ CERTValidity *validity;
+ CERTCertificate *cert = NULL;
+ PRExplodedTime printableTime;
+ PRTime now,
+ after;
+ if (!selfsign) {
+ issuerCert = CERT_FindCertByNameString(handle, issuerNameStr);
+ if (!issuerCert) {
+ error_out("ERROR: Could not find issuer's certificate");
+ return NULL;
+ }
+ }
+ if (find_field_bool(data, "manValidity", PR_TRUE)) {
+ (void)DER_AsciiToTime(&now, find_field(data, "notBefore", PR_TRUE));
+ } else {
+ now = PR_Now();
+ }
+ PR_ExplodeTime(now, PR_GMTParameters, &printableTime);
+ if (warpmonths) {
+ printableTime.tm_month += warpmonths;
+ now = PR_ImplodeTime(&printableTime);
+ PR_ExplodeTime(now, PR_GMTParameters, &printableTime);
+ }
+ if (find_field_bool(data, "manValidity", PR_TRUE)) {
+ (void)DER_AsciiToTime(&after, find_field(data, "notAfter", PR_TRUE));
+ PR_ExplodeTime(after, PR_GMTParameters, &printableTime);
+ } else {
+ printableTime.tm_month += 3;
+ after = PR_ImplodeTime(&printableTime);
+ }
+ /* note that the time is now in micro-second unit */
+ validity = CERT_CreateValidity(now, after);
+
+ if (selfsign) {
+ cert = CERT_CreateCertificate(serialNumber, &(req->subject), validity, req);
+ } else {
+ cert = CERT_CreateCertificate(serialNumber, &(issuerCert->subject), validity, req);
+ }
+
+ CERT_DestroyValidity(validity);
+ if (issuerCert) {
+ CERT_DestroyCertificate(issuerCert);
+ }
+ return (cert);
+}
+
+static int
+get_serial_number(Pair *data)
+{
+ int serial = 0;
+ int error;
+ char *filename = SERIAL_FILE;
+ char *SN;
+ FILE *serialFile;
+
+ if (find_field_bool(data, "serial-auto", PR_TRUE)) {
+ serialFile = fopen(filename, "r");
+ if (serialFile != NULL) {
+ size_t nread = fread(&serial, sizeof(int), 1, serialFile);
+ if (ferror(serialFile) != 0 || nread != 1) {
+ error_out("Error: Unable to read serial number file");
+ }
+ if (serial == -1) {
+ serial = 21;
+ }
+ fclose(serialFile);
+ ++serial;
+ serialFile = fopen(filename, "w");
+ if (serialFile == NULL) {
+ error_out("ERROR: Unable to open serial number file for writing");
+ }
+ fwrite(&serial, sizeof(int), 1, serialFile);
+ if (ferror(serialFile) != 0) {
+ error_out("Error: Unable to write to serial number file");
+ }
+ } else {
+ fclose(serialFile);
+ serialFile = fopen(filename, "w");
+ if (serialFile == NULL) {
+ error_out("ERROR: Unable to open serial number file");
+ }
+ serial = 21;
+ fwrite(&serial, sizeof(int), 1, serialFile);
+ if (ferror(serialFile) != 0) {
+ error_out("Error: Unable to write to serial number file");
+ }
+ error = ferror(serialFile);
+ if (error != 0) {
+ error_out("ERROR: Unable to write to serial file");
+ }
+ }
+ fclose(serialFile);
+ } else {
+ SN = find_field(data, "serial_value", PR_TRUE);
+ while (*SN != '\0') {
+ serial = serial * 16;
+ if ((*SN >= 'A') && (*SN <= 'F')) {
+ serial += *SN - 'A' + 10;
+ } else {
+ if ((*SN >= 'a') && (*SN <= 'f')) {
+ serial += *SN - 'a' + 10;
+ } else {
+ serial += *SN - '0';
+ }
+ }
+ ++SN;
+ }
+ }
+ return serial;
+}
+
+typedef SECStatus (*EXTEN_VALUE_ENCODER)(PLArenaPool *extHandle, void *value, SECItem *encodedValue);
+
+static SECStatus
+EncodeAndAddExtensionValue(
+ PLArenaPool *arena,
+ void *extHandle,
+ void *value,
+ PRBool criticality,
+ int extenType,
+ EXTEN_VALUE_ENCODER EncodeValueFn)
+{
+ SECItem encodedValue;
+ SECStatus rv;
+
+ encodedValue.data = NULL;
+ encodedValue.len = 0;
+ rv = (*EncodeValueFn)(arena, value, &encodedValue);
+ if (rv != SECSuccess) {
+ error_out("ERROR: Unable to encode extension value");
+ }
+ rv = CERT_AddExtension(extHandle, extenType, &encodedValue, criticality, PR_TRUE);
+ return (rv);
+}
+
+static SECStatus
+AddKeyUsage(void *extHandle,
+ Pair *data)
+{
+ SECItem bitStringValue;
+ unsigned char keyUsage = 0x0;
+
+ if (find_field_bool(data, "keyUsage-digitalSignature", PR_TRUE)) {
+ keyUsage |= (0x80 >> 0);
+ }
+ if (find_field_bool(data, "keyUsage-nonRepudiation", PR_TRUE)) {
+ keyUsage |= (0x80 >> 1);
+ }
+ if (find_field_bool(data, "keyUsage-keyEncipherment", PR_TRUE)) {
+ keyUsage |= (0x80 >> 2);
+ }
+ if (find_field_bool(data, "keyUsage-dataEncipherment", PR_TRUE)) {
+ keyUsage |= (0x80 >> 3);
+ }
+ if (find_field_bool(data, "keyUsage-keyAgreement", PR_TRUE)) {
+ keyUsage |= (0x80 >> 4);
+ }
+ if (find_field_bool(data, "keyUsage-keyCertSign", PR_TRUE)) {
+ keyUsage |= (0x80 >> 5);
+ }
+ if (find_field_bool(data, "keyUsage-cRLSign", PR_TRUE)) {
+ keyUsage |= (0x80 >> 6);
+ }
+
+ bitStringValue.data = &keyUsage;
+ bitStringValue.len = 1;
+
+ return (CERT_EncodeAndAddBitStrExtension(extHandle, SEC_OID_X509_KEY_USAGE, &bitStringValue,
+ (find_field_bool(data, "keyUsage-crit", PR_TRUE))));
+}
+
+static CERTOidSequence *
+CreateOidSequence(void)
+{
+ CERTOidSequence *rv = (CERTOidSequence *)NULL;
+ PLArenaPool *arena = (PLArenaPool *)NULL;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ((PLArenaPool *)NULL == arena) {
+ goto loser;
+ }
+
+ rv = (CERTOidSequence *)PORT_ArenaZAlloc(arena, sizeof(CERTOidSequence));
+ if ((CERTOidSequence *)NULL == rv) {
+ goto loser;
+ }
+
+ rv->oids = (SECItem **)PORT_ArenaZAlloc(arena, sizeof(SECItem *));
+ if ((SECItem **)NULL == rv->oids) {
+ goto loser;
+ }
+
+ rv->arena = arena;
+ return rv;
+
+loser:
+ if ((PLArenaPool *)NULL != arena) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return (CERTOidSequence *)NULL;
+}
+
+static SECStatus
+AddOidToSequence(CERTOidSequence *os, SECOidTag oidTag)
+{
+ SECItem **oids;
+ PRUint32 count = 0;
+ SECOidData *od;
+
+ od = SECOID_FindOIDByTag(oidTag);
+ if ((SECOidData *)NULL == od) {
+ return SECFailure;
+ }
+
+ for (oids = os->oids; (SECItem *)NULL != *oids; oids++) {
+ count++;
+ }
+
+ /* ArenaZRealloc */
+
+ {
+ PRUint32 i;
+
+ oids = (SECItem **)PORT_ArenaZAlloc(os->arena, sizeof(SECItem *) * (count + 2));
+ if ((SECItem **)NULL == oids) {
+ return SECFailure;
+ }
+
+ for (i = 0; i < count; i++) {
+ oids[i] = os->oids[i];
+ }
+
+ /* ArenaZFree(os->oids); */
+ }
+
+ os->oids = oids;
+ os->oids[count] = &od->oid;
+
+ return SECSuccess;
+}
+
+static SECItem *
+EncodeOidSequence(CERTOidSequence *os)
+{
+ SECItem *rv;
+ extern const SEC_ASN1Template CERT_OidSeqTemplate[];
+
+ rv = (SECItem *)PORT_ArenaZAlloc(os->arena, sizeof(SECItem));
+ if ((SECItem *)NULL == rv) {
+ goto loser;
+ }
+
+ if (!SEC_ASN1EncodeItem(os->arena, rv, os, CERT_OidSeqTemplate)) {
+ goto loser;
+ }
+
+ return rv;
+
+loser:
+ return (SECItem *)NULL;
+}
+
+static SECStatus
+AddExtKeyUsage(void *extHandle, Pair *data)
+{
+ SECStatus rv;
+ CERTOidSequence *os;
+ SECItem *value;
+ PRBool crit;
+
+ os = CreateOidSequence();
+ if ((CERTOidSequence *)NULL == os) {
+ return SECFailure;
+ }
+
+ if (find_field_bool(data, "extKeyUsage-serverAuth", PR_TRUE)) {
+ rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_SERVER_AUTH);
+ if (SECSuccess != rv)
+ goto loser;
+ }
+
+ if (find_field_bool(data, "extKeyUsage-msTrustListSign", PR_TRUE)) {
+ rv = AddOidToSequence(os, SEC_OID_MS_EXT_KEY_USAGE_CTL_SIGNING);
+ if (SECSuccess != rv)
+ goto loser;
+ }
+
+ if (find_field_bool(data, "extKeyUsage-clientAuth", PR_TRUE)) {
+ rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH);
+ if (SECSuccess != rv)
+ goto loser;
+ }
+
+ if (find_field_bool(data, "extKeyUsage-codeSign", PR_TRUE)) {
+ rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_CODE_SIGN);
+ if (SECSuccess != rv)
+ goto loser;
+ }
+
+ if (find_field_bool(data, "extKeyUsage-emailProtect", PR_TRUE)) {
+ rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT);
+ if (SECSuccess != rv)
+ goto loser;
+ }
+
+ if (find_field_bool(data, "extKeyUsage-timeStamp", PR_TRUE)) {
+ rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_TIME_STAMP);
+ if (SECSuccess != rv)
+ goto loser;
+ }
+
+ if (find_field_bool(data, "extKeyUsage-ocspResponder", PR_TRUE)) {
+ rv = AddOidToSequence(os, SEC_OID_OCSP_RESPONDER);
+ if (SECSuccess != rv)
+ goto loser;
+ }
+
+ if (find_field_bool(data, "extKeyUsage-NS-govtApproved", PR_TRUE)) {
+ rv = AddOidToSequence(os, SEC_OID_NS_KEY_USAGE_GOVT_APPROVED);
+ if (SECSuccess != rv)
+ goto loser;
+ }
+
+ value = EncodeOidSequence(os);
+
+ crit = find_field_bool(data, "extKeyUsage-crit", PR_TRUE);
+
+ rv = CERT_AddExtension(extHandle, SEC_OID_X509_EXT_KEY_USAGE, value,
+ crit, PR_TRUE);
+/*FALLTHROUGH*/
+loser:
+ CERT_DestroyOidSequence(os);
+ return rv;
+}
+
+static SECStatus
+AddSubKeyID(void *extHandle,
+ Pair *data,
+ CERTCertificate *subjectCert)
+{
+ SECItem encodedValue;
+ SECStatus rv;
+ char *read;
+ char *write;
+ char *first;
+ char character;
+ int high_digit = 0,
+ low_digit = 0;
+ int len;
+ PRBool odd = PR_FALSE;
+
+ encodedValue.data = NULL;
+ encodedValue.len = 0;
+ first = read = write = find_field(data, "subjectKeyIdentifier-text",
+ PR_TRUE);
+ len = PORT_Strlen(first);
+ odd = ((len % 2) != 0) ? PR_TRUE : PR_FALSE;
+ if (find_field_bool(data, "subjectKeyIdentifier-radio-hex", PR_TRUE)) {
+ if (odd) {
+ error_out("ERROR: Improperly formated subject key identifier, hex values must be expressed as an octet string");
+ }
+ while (*read != '\0') {
+ if (!isxdigit(*read)) {
+ error_out("ERROR: Improperly formated subject key identifier");
+ }
+ *read = toupper(*read);
+ if ((*read >= 'A') && (*read <= 'F')) {
+ high_digit = *read - 'A' + 10;
+ } else {
+ high_digit = *read - '0';
+ }
+ ++read;
+ if (!isxdigit(*read)) {
+ error_out("ERROR: Improperly formated subject key identifier");
+ }
+ *read = toupper(*read);
+ if ((*read >= 'A') && (*read <= 'F')) {
+ low_digit = *(read) - 'A' + 10;
+ } else {
+ low_digit = *(read) - '0';
+ }
+ character = (high_digit << 4) | low_digit;
+ *write = character;
+ ++write;
+ ++read;
+ }
+ *write = '\0';
+ len = write - first;
+ }
+ subjectCert->subjectKeyID.data = (unsigned char *)find_field(data, "subjectKeyIdentifier-text", PR_TRUE);
+ subjectCert->subjectKeyID.len = len;
+ rv = CERT_EncodeSubjectKeyID(NULL, &subjectCert->subjectKeyID, &encodedValue);
+ if (rv) {
+ return (rv);
+ }
+ return (CERT_AddExtension(extHandle, SEC_OID_X509_SUBJECT_KEY_ID,
+ &encodedValue, PR_FALSE, PR_TRUE));
+}
+
+static SECStatus
+AddAuthKeyID(void *extHandle,
+ Pair *data,
+ char *issuerNameStr,
+ CERTCertDBHandle *handle)
+{
+ CERTAuthKeyID *authKeyID = NULL;
+ PLArenaPool *arena = NULL;
+ SECStatus rv = SECSuccess;
+ CERTCertificate *issuerCert = NULL;
+ CERTGeneralName *genNames;
+ CERTName *directoryName = NULL;
+
+ issuerCert = CERT_FindCertByNameString(handle, issuerNameStr);
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ error_allocate();
+ }
+
+ authKeyID = PORT_ArenaZAlloc(arena, sizeof(CERTAuthKeyID));
+ if (authKeyID == NULL) {
+ error_allocate();
+ }
+ if (find_field_bool(data, "authorityKeyIdentifier-radio-keyIdentifier",
+ PR_TRUE)) {
+ authKeyID->keyID.data = PORT_ArenaAlloc(arena, PORT_Strlen((char *)issuerCert->subjectKeyID.data));
+ if (authKeyID->keyID.data == NULL) {
+ error_allocate();
+ }
+ PORT_Memcpy(authKeyID->keyID.data, issuerCert->subjectKeyID.data,
+ authKeyID->keyID.len =
+ PORT_Strlen((char *)issuerCert->subjectKeyID.data));
+ } else {
+
+ PORT_Assert(arena);
+ genNames = (CERTGeneralName *)PORT_ArenaZAlloc(arena, (sizeof(CERTGeneralName)));
+ if (genNames == NULL) {
+ error_allocate();
+ }
+ genNames->l.next = genNames->l.prev = &(genNames->l);
+ genNames->type = certDirectoryName;
+
+ directoryName = CERT_AsciiToName(issuerCert->subjectName);
+ if (!directoryName) {
+ error_out("ERROR: Unable to create Directory Name");
+ }
+ rv = CERT_CopyName(arena, &genNames->name.directoryName,
+ directoryName);
+ CERT_DestroyName(directoryName);
+ if (rv != SECSuccess) {
+ error_out("ERROR: Unable to copy Directory Name");
+ }
+ authKeyID->authCertIssuer = genNames;
+ if (authKeyID->authCertIssuer == NULL && SECFailure == PORT_GetError()) {
+ error_out("ERROR: Unable to get Issuer General Name for Authority Key ID Extension");
+ }
+ authKeyID->authCertSerialNumber = issuerCert->serialNumber;
+ }
+ rv = EncodeAndAddExtensionValue(arena, extHandle, authKeyID, PR_FALSE,
+ SEC_OID_X509_AUTH_KEY_ID,
+ (EXTEN_VALUE_ENCODER)
+ CERT_EncodeAuthKeyID);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+ return (rv);
+}
+
+static SECStatus
+AddPrivKeyUsagePeriod(void *extHandle,
+ Pair *data,
+ CERTCertificate *cert)
+{
+ char *notBeforeStr;
+ char *notAfterStr;
+ PLArenaPool *arena = NULL;
+ SECStatus rv = SECSuccess;
+ CERTPrivKeyUsagePeriod *pkup;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ error_allocate();
+ }
+ pkup = PORT_ArenaZNew(arena, CERTPrivKeyUsagePeriod);
+ if (pkup == NULL) {
+ error_allocate();
+ }
+ notBeforeStr = (char *)PORT_Alloc(16);
+ if (notBeforeStr == NULL) {
+ error_allocate();
+ }
+ notAfterStr = (char *)PORT_Alloc(16);
+ if (notAfterStr == NULL) {
+ error_allocate();
+ }
+ *notBeforeStr = '\0';
+ *notAfterStr = '\0';
+ pkup->arena = arena;
+ pkup->notBefore.len = 0;
+ pkup->notBefore.data = NULL;
+ pkup->notAfter.len = 0;
+ pkup->notAfter.data = NULL;
+ if (find_field_bool(data, "privKeyUsagePeriod-radio-notBefore", PR_TRUE) ||
+ find_field_bool(data, "privKeyUsagePeriod-radio-both", PR_TRUE)) {
+ pkup->notBefore.len = 15;
+ pkup->notBefore.data = (unsigned char *)notBeforeStr;
+ if (find_field_bool(data, "privKeyUsagePeriod-notBefore-radio-manual",
+ PR_TRUE)) {
+ PORT_Strcat(notBeforeStr, find_field(data,
+ "privKeyUsagePeriod-notBefore-year",
+ PR_TRUE));
+ PORT_Strcat(notBeforeStr, find_field(data,
+ "privKeyUsagePeriod-notBefore-month",
+ PR_TRUE));
+ PORT_Strcat(notBeforeStr, find_field(data,
+ "privKeyUsagePeriod-notBefore-day",
+ PR_TRUE));
+ PORT_Strcat(notBeforeStr, find_field(data,
+ "privKeyUsagePeriod-notBefore-hour",
+ PR_TRUE));
+ PORT_Strcat(notBeforeStr, find_field(data,
+ "privKeyUsagePeriod-notBefore-minute",
+ PR_TRUE));
+ PORT_Strcat(notBeforeStr, find_field(data,
+ "privKeyUsagePeriod-notBefore-second",
+ PR_TRUE));
+ if ((*(notBeforeStr + 14) != '\0') ||
+ (!isdigit(*(notBeforeStr + 13))) ||
+ (*(notBeforeStr + 12) >= '5' && *(notBeforeStr + 12) <= '0') ||
+ (!isdigit(*(notBeforeStr + 11))) ||
+ (*(notBeforeStr + 10) >= '5' && *(notBeforeStr + 10) <= '0') ||
+ (!isdigit(*(notBeforeStr + 9))) ||
+ (*(notBeforeStr + 8) >= '2' && *(notBeforeStr + 8) <= '0') ||
+ (!isdigit(*(notBeforeStr + 7))) ||
+ (*(notBeforeStr + 6) >= '3' && *(notBeforeStr + 6) <= '0') ||
+ (!isdigit(*(notBeforeStr + 5))) ||
+ (*(notBeforeStr + 4) >= '1' && *(notBeforeStr + 4) <= '0') ||
+ (!isdigit(*(notBeforeStr + 3))) ||
+ (!isdigit(*(notBeforeStr + 2))) ||
+ (!isdigit(*(notBeforeStr + 1))) ||
+ (!isdigit(*(notBeforeStr + 0))) ||
+ (*(notBeforeStr + 8) == '2' && *(notBeforeStr + 9) >= '4') ||
+ (*(notBeforeStr + 6) == '3' && *(notBeforeStr + 7) >= '1') ||
+ (*(notBeforeStr + 4) == '1' && *(notBeforeStr + 5) >= '2')) {
+ error_out("ERROR: Improperly formated private key usage period");
+ }
+ *(notBeforeStr + 14) = 'Z';
+ *(notBeforeStr + 15) = '\0';
+ } else {
+ if ((*(cert->validity.notBefore.data) > '5') ||
+ ((*(cert->validity.notBefore.data) == '5') &&
+ (*(cert->validity.notBefore.data + 1) != '0'))) {
+ PORT_Strcat(notBeforeStr, "19");
+ } else {
+ PORT_Strcat(notBeforeStr, "20");
+ }
+ PORT_Strcat(notBeforeStr, (char *)cert->validity.notBefore.data);
+ }
+ }
+ if (find_field_bool(data, "privKeyUsagePeriod-radio-notAfter", PR_TRUE) ||
+ find_field_bool(data, "privKeyUsagePeriod-radio-both", PR_TRUE)) {
+ pkup->notAfter.len = 15;
+ pkup->notAfter.data = (unsigned char *)notAfterStr;
+ PORT_Strcat(notAfterStr, find_field(data, "privKeyUsagePeriod-notAfter-year",
+ PR_TRUE));
+ PORT_Strcat(notAfterStr, find_field(data, "privKeyUsagePeriod-notAfter-month",
+ PR_TRUE));
+ PORT_Strcat(notAfterStr, find_field(data, "privKeyUsagePeriod-notAfter-day",
+ PR_TRUE));
+ PORT_Strcat(notAfterStr, find_field(data, "privKeyUsagePeriod-notAfter-hour",
+ PR_TRUE));
+ PORT_Strcat(notAfterStr, find_field(data, "privKeyUsagePeriod-notAfter-minute",
+ PR_TRUE));
+ PORT_Strcat(notAfterStr, find_field(data, "privKeyUsagePeriod-notAfter-second",
+ PR_TRUE));
+ if ((*(notAfterStr + 14) != '\0') ||
+ (!isdigit(*(notAfterStr + 13))) ||
+ (*(notAfterStr + 12) >= '5' && *(notAfterStr + 12) <= '0') ||
+ (!isdigit(*(notAfterStr + 11))) ||
+ (*(notAfterStr + 10) >= '5' && *(notAfterStr + 10) <= '0') ||
+ (!isdigit(*(notAfterStr + 9))) ||
+ (*(notAfterStr + 8) >= '2' && *(notAfterStr + 8) <= '0') ||
+ (!isdigit(*(notAfterStr + 7))) ||
+ (*(notAfterStr + 6) >= '3' && *(notAfterStr + 6) <= '0') ||
+ (!isdigit(*(notAfterStr + 5))) ||
+ (*(notAfterStr + 4) >= '1' && *(notAfterStr + 4) <= '0') ||
+ (!isdigit(*(notAfterStr + 3))) ||
+ (!isdigit(*(notAfterStr + 2))) ||
+ (!isdigit(*(notAfterStr + 1))) ||
+ (!isdigit(*(notAfterStr + 0))) ||
+ (*(notAfterStr + 8) == '2' && *(notAfterStr + 9) >= '4') ||
+ (*(notAfterStr + 6) == '3' && *(notAfterStr + 7) >= '1') ||
+ (*(notAfterStr + 4) == '1' && *(notAfterStr + 5) >= '2')) {
+ error_out("ERROR: Improperly formated private key usage period");
+ }
+ *(notAfterStr + 14) = 'Z';
+ *(notAfterStr + 15) = '\0';
+ }
+
+ PORT_Assert(arena);
+
+ rv = EncodeAndAddExtensionValue(arena, extHandle, pkup,
+ find_field_bool(data,
+ "privKeyUsagePeriod-crit",
+ PR_TRUE),
+ SEC_OID_X509_PRIVATE_KEY_USAGE_PERIOD,
+ (EXTEN_VALUE_ENCODER)
+ CERT_EncodePrivateKeyUsagePeriod);
+ PORT_FreeArena(arena, PR_FALSE);
+ PORT_Free(notBeforeStr);
+ PORT_Free(notAfterStr);
+ return (rv);
+}
+
+static SECStatus
+AddBasicConstraint(void *extHandle,
+ Pair *data)
+{
+ CERTBasicConstraints basicConstraint;
+ SECItem encodedValue;
+ SECStatus rv;
+
+ encodedValue.data = NULL;
+ encodedValue.len = 0;
+ basicConstraint.pathLenConstraint = CERT_UNLIMITED_PATH_CONSTRAINT;
+ basicConstraint.isCA = (find_field_bool(data, "basicConstraints-cA-radio-CA",
+ PR_TRUE));
+ if (find_field_bool(data, "basicConstraints-pathLengthConstraint", PR_TRUE)) {
+ basicConstraint.pathLenConstraint = atoi(find_field(data, "basicConstraints-pathLengthConstraint-text",
+ PR_TRUE));
+ }
+
+ rv = CERT_EncodeBasicConstraintValue(NULL, &basicConstraint,
+ &encodedValue);
+ if (rv)
+ return (rv);
+ rv = CERT_AddExtension(extHandle, SEC_OID_X509_BASIC_CONSTRAINTS,
+ &encodedValue,
+ (find_field_bool(data, "basicConstraints-crit",
+ PR_TRUE)),
+ PR_TRUE);
+
+ PORT_Free(encodedValue.data);
+ return (rv);
+}
+
+static SECStatus
+AddNscpCertType(void *extHandle,
+ Pair *data)
+{
+ SECItem bitStringValue;
+ unsigned char CertType = 0x0;
+
+ if (find_field_bool(data, "netscape-cert-type-ssl-client", PR_TRUE)) {
+ CertType |= (0x80 >> 0);
+ }
+ if (find_field_bool(data, "netscape-cert-type-ssl-server", PR_TRUE)) {
+ CertType |= (0x80 >> 1);
+ }
+ if (find_field_bool(data, "netscape-cert-type-smime", PR_TRUE)) {
+ CertType |= (0x80 >> 2);
+ }
+ if (find_field_bool(data, "netscape-cert-type-object-signing", PR_TRUE)) {
+ CertType |= (0x80 >> 3);
+ }
+ if (find_field_bool(data, "netscape-cert-type-reserved", PR_TRUE)) {
+ CertType |= (0x80 >> 4);
+ }
+ if (find_field_bool(data, "netscape-cert-type-ssl-ca", PR_TRUE)) {
+ CertType |= (0x80 >> 5);
+ }
+ if (find_field_bool(data, "netscape-cert-type-smime-ca", PR_TRUE)) {
+ CertType |= (0x80 >> 6);
+ }
+ if (find_field_bool(data, "netscape-cert-type-object-signing-ca", PR_TRUE)) {
+ CertType |= (0x80 >> 7);
+ }
+
+ bitStringValue.data = &CertType;
+ bitStringValue.len = 1;
+
+ return (CERT_EncodeAndAddBitStrExtension(extHandle, SEC_OID_NS_CERT_EXT_CERT_TYPE, &bitStringValue,
+ (find_field_bool(data, "netscape-cert-type-crit", PR_TRUE))));
+}
+
+static SECStatus
+add_IA5StringExtension(void *extHandle,
+ char *string,
+ PRBool crit,
+ int idtag)
+{
+ SECItem encodedValue;
+ SECStatus rv;
+
+ encodedValue.data = NULL;
+ encodedValue.len = 0;
+
+ rv = CERT_EncodeIA5TypeExtension(NULL, string, &encodedValue);
+ if (rv) {
+ return (rv);
+ }
+ return (CERT_AddExtension(extHandle, idtag, &encodedValue, crit, PR_TRUE));
+}
+
+static SECItem *
+string_to_oid(char *string)
+{
+ int i;
+ int length = 20;
+ int remaining;
+ int first_value;
+ int second_value;
+ int value;
+ int oidLength;
+ unsigned char *oidString;
+ unsigned char *write;
+ unsigned char *read;
+ unsigned char *temp;
+ SECItem *oid;
+
+ remaining = length;
+ i = 0;
+ while (*string == ' ') {
+ string++;
+ }
+ while (isdigit(*(string + i))) {
+ i++;
+ }
+ if (*(string + i) == '.') {
+ *(string + i) = '\0';
+ } else {
+ error_out("ERROR: Improperly formated OID");
+ }
+ first_value = atoi(string);
+ if (first_value < 0 || first_value > 2) {
+ error_out("ERROR: Improperly formated OID");
+ }
+ string += i + 1;
+ i = 0;
+ while (isdigit(*(string + i))) {
+ i++;
+ }
+ if (*(string + i) == '.') {
+ *(string + i) = '\0';
+ } else {
+ error_out("ERROR: Improperly formated OID");
+ }
+ second_value = atoi(string);
+ if (second_value < 0 || second_value > 39) {
+ error_out("ERROR: Improperly formated OID");
+ }
+ oidString = PORT_ZAlloc(2);
+ *oidString = (first_value * 40) + second_value;
+ *(oidString + 1) = '\0';
+ oidLength = 1;
+ string += i + 1;
+ i = 0;
+ temp = write = PORT_ZAlloc(length);
+ while (*string != '\0') {
+ value = 0;
+ while (isdigit(*(string + i))) {
+ i++;
+ }
+ if (*(string + i) == '\0') {
+ value = atoi(string);
+ string += i;
+ } else {
+ if (*(string + i) == '.') {
+ *(string + i) = '\0';
+ value = atoi(string);
+ string += i + 1;
+ } else {
+ *(string + i) = '\0';
+ i++;
+ value = atoi(string);
+ while (*(string + i) == ' ')
+ i++;
+ if (*(string + i) != '\0') {
+ error_out("ERROR: Improperly formated OID");
+ }
+ }
+ }
+ i = 0;
+ while (value != 0) {
+ if (remaining < 1) {
+ remaining += length;
+ length = length * 2;
+ temp = PORT_Realloc(temp, length);
+ write = temp + length - remaining;
+ }
+ *write = (value & 0x7f) | (0x80);
+ write++;
+ remaining--;
+ value = value >> 7;
+ }
+ *temp = *temp & (0x7f);
+ oidLength += write - temp;
+ oidString = PORT_Realloc(oidString, (oidLength + 1));
+ read = write - 1;
+ write = oidLength + oidString - 1;
+ for (i = 0; i < (length - remaining); i++) {
+ *write = *read;
+ write--;
+ read++;
+ }
+ write = temp;
+ remaining = length;
+ }
+ *(oidString + oidLength) = '\0';
+ oid = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
+ oid->data = oidString;
+ oid->len = oidLength;
+ PORT_Free(temp);
+ return oid;
+}
+
+static SECItem *
+string_to_ipaddress(char *string)
+{
+ int i = 0;
+ int value;
+ int j = 0;
+ SECItem *ipaddress;
+
+ while (*string == ' ') {
+ string++;
+ }
+ ipaddress = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
+ ipaddress->data = PORT_ZAlloc(9);
+ while (*string != '\0' && j < 8) {
+ while (isdigit(*(string + i))) {
+ i++;
+ }
+ if (*(string + i) == '.') {
+ *(string + i) = '\0';
+ value = atoi(string);
+ string = string + i + 1;
+ i = 0;
+ } else {
+ if (*(string + i) == '\0') {
+ value = atoi(string);
+ string = string + i;
+ i = 0;
+ } else {
+ *(string + i) = '\0';
+ while (*(string + i) == ' ') {
+ i++;
+ }
+ if (*(string + i) == '\0') {
+ value = atoi(string);
+ string = string + i;
+ i = 0;
+ } else {
+ error_out("ERROR: Improperly formated IP Address");
+ }
+ }
+ }
+ if (value >= 0 && value < 256) {
+ *(ipaddress->data + j) = value;
+ } else {
+ error_out("ERROR: Improperly formated IP Address");
+ }
+ j++;
+ }
+ *(ipaddress->data + j) = '\0';
+ if (j != 4 && j != 8) {
+ error_out("ERROR: Improperly formated IP Address");
+ }
+ ipaddress->len = j;
+ return ipaddress;
+}
+
+static int
+chr_to_hex(char c)
+{
+ if (isdigit(c)) {
+ return c - '0';
+ }
+ if (isxdigit(c)) {
+ return toupper(c) - 'A' + 10;
+ }
+ return -1;
+}
+
+static SECItem *
+string_to_binary(char *string)
+{
+ SECItem *rv;
+
+ rv = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
+ if (rv == NULL) {
+ error_allocate();
+ }
+ rv->data = (unsigned char *)PORT_ZAlloc((PORT_Strlen(string)) / 3 + 2);
+ rv->len = 0;
+ while (*string && !isxdigit(*string)) {
+ string++;
+ }
+ while (*string) {
+ int high, low;
+ high = chr_to_hex(*string++);
+ low = chr_to_hex(*string++);
+ if (high < 0 || low < 0) {
+ error_out("ERROR: Improperly formated binary encoding");
+ }
+ rv->data[(rv->len)++] = high << 4 | low;
+ if (*string != ':') {
+ break;
+ }
+ ++string;
+ }
+ while (*string == ' ') {
+ ++string;
+ }
+ if (*string) {
+ error_out("ERROR: Junk after binary encoding");
+ }
+
+ return rv;
+}
+
+static SECStatus
+MakeGeneralName(char *name,
+ CERTGeneralName *genName,
+ PLArenaPool *arena)
+{
+ SECItem *oid;
+ SECOidData *oidData;
+ SECItem *ipaddress;
+ SECItem *temp = NULL;
+ int i;
+ int nameType;
+ PRBool binary = PR_FALSE;
+ SECStatus rv = SECSuccess;
+ PRBool nickname = PR_FALSE;
+
+ PORT_Assert(genName);
+ PORT_Assert(arena);
+ nameType = *(name + PORT_Strlen(name) - 1) - '0';
+ if (nameType == 0 && *(name + PORT_Strlen(name) - 2) == '1') {
+ nickname = PR_TRUE;
+ nameType = certOtherName;
+ }
+ if (nameType < 1 || nameType > 9) {
+ error_out("ERROR: Unknown General Name Type");
+ }
+ *(name + PORT_Strlen(name) - 4) = '\0';
+ genName->type = nameType;
+
+ switch (genName->type) {
+ case certURI:
+ case certRFC822Name:
+ case certDNSName: {
+ genName->name.other.data = (unsigned char *)name;
+ genName->name.other.len = PORT_Strlen(name);
+ break;
+ }
+
+ case certIPAddress: {
+ ipaddress = string_to_ipaddress(name);
+ genName->name.other.data = ipaddress->data;
+ genName->name.other.len = ipaddress->len;
+ break;
+ }
+
+ case certRegisterID: {
+ oid = string_to_oid(name);
+ genName->name.other.data = oid->data;
+ genName->name.other.len = oid->len;
+ break;
+ }
+
+ case certEDIPartyName:
+ case certX400Address: {
+
+ genName->name.other.data = PORT_ArenaAlloc(arena,
+ PORT_Strlen(name) + 2);
+ if (genName->name.other.data == NULL) {
+ error_allocate();
+ }
+
+ PORT_Memcpy(genName->name.other.data + 2, name, PORT_Strlen(name));
+ /* This may not be accurate for all cases.
+ For now, use this tag type */
+ genName->name.other.data[0] = (char)(((genName->type - 1) &
+ 0x1f) |
+ 0x80);
+ genName->name.other.data[1] = (char)PORT_Strlen(name);
+ genName->name.other.len = PORT_Strlen(name) + 2;
+ break;
+ }
+
+ case certOtherName: {
+ i = 0;
+ if (!nickname) {
+ while (!isdigit(*(name + PORT_Strlen(name) - i))) {
+ i++;
+ }
+ if (*(name + PORT_Strlen(name) - i) == '1') {
+ binary = PR_TRUE;
+ } else {
+ binary = PR_FALSE;
+ }
+ while (*(name + PORT_Strlen(name) - i) != '-') {
+ i++;
+ }
+ *(name + PORT_Strlen(name) - i - 1) = '\0';
+ i = 0;
+ while (*(name + i) != '-') {
+ i++;
+ }
+ *(name + i - 1) = '\0';
+ oid = string_to_oid(name + i + 2);
+ } else {
+ oidData = SECOID_FindOIDByTag(SEC_OID_NETSCAPE_NICKNAME);
+ oid = &oidData->oid;
+ while (*(name + PORT_Strlen(name) - i) != '-') {
+ i++;
+ }
+ *(name + PORT_Strlen(name) - i) = '\0';
+ }
+ genName->name.OthName.oid.data = oid->data;
+ genName->name.OthName.oid.len = oid->len;
+ if (binary) {
+ temp = string_to_binary(name);
+ genName->name.OthName.name.data = temp->data;
+ genName->name.OthName.name.len = temp->len;
+ } else {
+ temp = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
+ if (temp == NULL) {
+ error_allocate();
+ }
+ temp->data = (unsigned char *)name;
+ temp->len = PORT_Strlen(name);
+ SEC_ASN1EncodeItem(arena, &(genName->name.OthName.name), temp,
+ CERTIA5TypeTemplate);
+ }
+ PORT_Free(temp);
+ break;
+ }
+
+ case certDirectoryName: {
+ CERTName *directoryName = NULL;
+
+ directoryName = CERT_AsciiToName(name);
+ if (!directoryName) {
+ error_out("ERROR: Improperly formated alternative name");
+ break;
+ }
+ rv = CERT_CopyName(arena, &genName->name.directoryName,
+ directoryName);
+ CERT_DestroyName(directoryName);
+
+ break;
+ }
+ }
+ genName->l.next = &(genName->l);
+ genName->l.prev = &(genName->l);
+ return rv;
+}
+
+static CERTGeneralName *
+MakeAltName(Pair *data,
+ char *which,
+ PLArenaPool *arena)
+{
+ CERTGeneralName *SubAltName;
+ CERTGeneralName *current;
+ CERTGeneralName *newname;
+ char *name = NULL;
+ SECStatus rv = SECSuccess;
+ int len;
+
+ len = PORT_Strlen(which);
+ name = find_field(data, which, PR_TRUE);
+ SubAltName = current = (CERTGeneralName *)PORT_ZAlloc(sizeof(CERTGeneralName));
+ if (current == NULL) {
+ error_allocate();
+ }
+ while (name != NULL) {
+
+ rv = MakeGeneralName(name, current, arena);
+
+ if (rv != SECSuccess) {
+ break;
+ }
+ if (*(which + len - 1) < '9') {
+ *(which + len - 1) = *(which + len - 1) + 1;
+ } else {
+ if (isdigit(*(which + len - 2))) {
+ *(which + len - 2) = *(which + len - 2) + 1;
+ *(which + len - 1) = '0';
+ } else {
+ *(which + len - 1) = '1';
+ *(which + len) = '0';
+ *(which + len + 1) = '\0';
+ len++;
+ }
+ }
+ len = PORT_Strlen(which);
+ name = find_field(data, which, PR_TRUE);
+ if (name != NULL) {
+ newname = (CERTGeneralName *)PORT_ZAlloc(sizeof(CERTGeneralName));
+ if (newname == NULL) {
+ error_allocate();
+ }
+ current->l.next = &(newname->l);
+ newname->l.prev = &(current->l);
+ current = newname;
+ newname = NULL;
+ } else {
+ current->l.next = &(SubAltName->l);
+ SubAltName->l.prev = &(current->l);
+ }
+ }
+ if (rv == SECFailure) {
+ return NULL;
+ }
+ return SubAltName;
+}
+
+static CERTNameConstraints *
+MakeNameConstraints(Pair *data,
+ PLArenaPool *arena)
+{
+ CERTNameConstraints *NameConstraints;
+ CERTNameConstraint *current = NULL;
+ CERTNameConstraint *last_permited = NULL;
+ CERTNameConstraint *last_excluded = NULL;
+ char *constraint = NULL;
+ char *which;
+ SECStatus rv = SECSuccess;
+ int len;
+ int i;
+ long max;
+ long min;
+ PRBool permited;
+
+ NameConstraints = (CERTNameConstraints *)PORT_ZAlloc(sizeof(CERTNameConstraints));
+ which = make_copy_string("NameConstraintSelect0", 25, '\0');
+ len = PORT_Strlen(which);
+ constraint = find_field(data, which, PR_TRUE);
+ NameConstraints->permited = NameConstraints->excluded = NULL;
+ while (constraint != NULL) {
+ current = (CERTNameConstraint *)PORT_ZAlloc(sizeof(CERTNameConstraint));
+ if (current == NULL) {
+ error_allocate();
+ }
+ i = 0;
+ while (*(constraint + PORT_Strlen(constraint) - i) != '-') {
+ i++;
+ }
+ *(constraint + PORT_Strlen(constraint) - i - 1) = '\0';
+ max = (long)atoi(constraint + PORT_Strlen(constraint) + 3);
+ if (max > 0) {
+ (void)SEC_ASN1EncodeInteger(arena, ¤t->max, max);
+ }
+ i = 0;
+ while (*(constraint + PORT_Strlen(constraint) - i) != '-') {
+ i++;
+ }
+ *(constraint + PORT_Strlen(constraint) - i - 1) = '\0';
+ min = (long)atoi(constraint + PORT_Strlen(constraint) + 3);
+ (void)SEC_ASN1EncodeInteger(arena, ¤t->min, min);
+ while (*(constraint + PORT_Strlen(constraint) - i) != '-') {
+ i++;
+ }
+ *(constraint + PORT_Strlen(constraint) - i - 1) = '\0';
+ if (*(constraint + PORT_Strlen(constraint) + 3) == 'p') {
+ permited = PR_TRUE;
+ } else {
+ permited = PR_FALSE;
+ }
+ rv = MakeGeneralName(constraint, &(current->name), arena);
+
+ if (rv != SECSuccess) {
+ break;
+ }
+ if (*(which + len - 1) < '9') {
+ *(which + len - 1) = *(which + len - 1) + 1;
+ } else {
+ if (isdigit(*(which + len - 2))) {
+ *(which + len - 2) = *(which + len - 2) + 1;
+ *(which + len - 1) = '0';
+ } else {
+ *(which + len - 1) = '1';
+ *(which + len) = '0';
+ *(which + len + 1) = '\0';
+ len++;
+ }
+ }
+ len = PORT_Strlen(which);
+ if (permited) {
+ if (NameConstraints->permited == NULL) {
+ NameConstraints->permited = last_permited = current;
+ }
+ last_permited->l.next = &(current->l);
+ current->l.prev = &(last_permited->l);
+ last_permited = current;
+ } else {
+ if (NameConstraints->excluded == NULL) {
+ NameConstraints->excluded = last_excluded = current;
+ }
+ last_excluded->l.next = &(current->l);
+ current->l.prev = &(last_excluded->l);
+ last_excluded = current;
+ }
+ constraint = find_field(data, which, PR_TRUE);
+ if (constraint != NULL) {
+ current = (CERTNameConstraint *)PORT_ZAlloc(sizeof(CERTNameConstraint));
+ if (current == NULL) {
+ error_allocate();
+ }
+ }
+ }
+ if (NameConstraints->permited != NULL) {
+ last_permited->l.next = &(NameConstraints->permited->l);
+ NameConstraints->permited->l.prev = &(last_permited->l);
+ }
+ if (NameConstraints->excluded != NULL) {
+ last_excluded->l.next = &(NameConstraints->excluded->l);
+ NameConstraints->excluded->l.prev = &(last_excluded->l);
+ }
+ if (which != NULL) {
+ PORT_Free(which);
+ }
+ if (rv == SECFailure) {
+ return NULL;
+ }
+ return NameConstraints;
+}
+
+static SECStatus
+AddAltName(void *extHandle,
+ Pair *data,
+ char *issuerNameStr,
+ CERTCertDBHandle *handle,
+ int type)
+{
+ PRBool autoIssuer = PR_FALSE;
+ PLArenaPool *arena = NULL;
+ CERTGeneralName *genName = NULL;
+ char *which = NULL;
+ char *name = NULL;
+ SECStatus rv = SECSuccess;
+ SECItem *issuersAltName = NULL;
+ CERTCertificate *issuerCert = NULL;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (arena == NULL) {
+ error_allocate();
+ }
+ if (type == 0) {
+ which = make_copy_string("SubAltNameSelect0", 20, '\0');
+ genName = MakeAltName(data, which, arena);
+ } else {
+ if (autoIssuer) {
+ autoIssuer = find_field_bool(data, "IssuerAltNameSourceRadio-auto",
+ PR_TRUE);
+ issuerCert = CERT_FindCertByNameString(handle, issuerNameStr);
+ rv = cert_FindExtension((*issuerCert).extensions,
+ SEC_OID_X509_SUBJECT_ALT_NAME,
+ issuersAltName);
+ if (issuersAltName == NULL) {
+ name = PORT_Alloc(PORT_Strlen((*issuerCert).subjectName) + 4);
+ PORT_Strcpy(name, (*issuerCert).subjectName);
+ PORT_Strcat(name, " - 5");
+ }
+ } else {
+ which = make_copy_string("IssuerAltNameSelect0", 20, '\0');
+ genName = MakeAltName(data, which, arena);
+ }
+ }
+ if (type == 0) {
+ EncodeAndAddExtensionValue(arena, extHandle, genName,
+ find_field_bool(data, "SubAltName-crit",
+ PR_TRUE),
+ SEC_OID_X509_SUBJECT_ALT_NAME,
+ (EXTEN_VALUE_ENCODER)
+ CERT_EncodeAltNameExtension);
+
+ } else {
+ if (autoIssuer && (name == NULL)) {
+ rv = CERT_AddExtension(extHandle, SEC_OID_X509_ISSUER_ALT_NAME, issuersAltName,
+ find_field_bool(data, "IssuerAltName-crit", PR_TRUE), PR_TRUE);
+ } else {
+ EncodeAndAddExtensionValue(arena, extHandle, genName,
+ find_field_bool(data,
+ "IssuerAltName-crit",
+ PR_TRUE),
+ SEC_OID_X509_ISSUER_ALT_NAME,
+ (EXTEN_VALUE_ENCODER)
+ CERT_EncodeAltNameExtension);
+ }
+ }
+ if (which != NULL) {
+ PORT_Free(which);
+ }
+ if (issuerCert != NULL) {
+ CERT_DestroyCertificate(issuerCert);
+ }
+ return rv;
+}
+
+static SECStatus
+AddNameConstraints(void *extHandle,
+ Pair *data)
+{
+ PLArenaPool *arena = NULL;
+ CERTNameConstraints *constraints = NULL;
+ SECStatus rv = SECSuccess;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (arena == NULL) {
+ error_allocate();
+ }
+ constraints = MakeNameConstraints(data, arena);
+ if (constraints != NULL) {
+ EncodeAndAddExtensionValue(arena, extHandle, constraints, PR_TRUE,
+ SEC_OID_X509_NAME_CONSTRAINTS,
+ (EXTEN_VALUE_ENCODER)
+ CERT_EncodeNameConstraintsExtension);
+ }
+ if (arena != NULL) {
+ PORT_ArenaRelease(arena, NULL);
+ }
+ return rv;
+}
+
+static SECStatus
+add_extensions(CERTCertificate *subjectCert,
+ Pair *data,
+ char *issuerNameStr,
+ CERTCertDBHandle *handle)
+{
+ void *extHandle;
+ SECStatus rv = SECSuccess;
+
+ extHandle = CERT_StartCertExtensions(subjectCert);
+ if (extHandle == NULL) {
+ error_out("ERROR: Unable to get certificates extension handle");
+ }
+ if (find_field_bool(data, "keyUsage", PR_TRUE)) {
+ rv = AddKeyUsage(extHandle, data);
+ if (rv != SECSuccess) {
+ error_out("ERROR: Unable to add Key Usage extension");
+ }
+ }
+
+ if (find_field_bool(data, "extKeyUsage", PR_TRUE)) {
+ rv = AddExtKeyUsage(extHandle, data);
+ if (SECSuccess != rv) {
+ error_out("ERROR: Unable to add Extended Key Usage extension");
+ }
+ }
+
+ if (find_field_bool(data, "basicConstraints", PR_TRUE)) {
+ rv = AddBasicConstraint(extHandle, data);
+ if (rv != SECSuccess) {
+ error_out("ERROR: Unable to add Basic Constraint extension");
+ }
+ }
+ if (find_field_bool(data, "subjectKeyIdentifier", PR_TRUE)) {
+ rv = AddSubKeyID(extHandle, data, subjectCert);
+ if (rv != SECSuccess) {
+ error_out("ERROR: Unable to add Subject Key Identifier Extension");
+ }
+ }
+ if (find_field_bool(data, "authorityKeyIdentifier", PR_TRUE)) {
+ rv = AddAuthKeyID(extHandle, data, issuerNameStr, handle);
+ if (rv != SECSuccess) {
+ error_out("ERROR: Unable to add Authority Key Identifier extension");
+ }
+ }
+ if (find_field_bool(data, "privKeyUsagePeriod", PR_TRUE)) {
+ rv = AddPrivKeyUsagePeriod(extHandle, data, subjectCert);
+ if (rv != SECSuccess) {
+ error_out("ERROR: Unable to add Private Key Usage Period extension");
+ }
+ }
+ if (find_field_bool(data, "SubAltName", PR_TRUE)) {
+ rv = AddAltName(extHandle, data, NULL, NULL, 0);
+ if (rv != SECSuccess) {
+ error_out("ERROR: Unable to add Subject Alternative Name extension");
+ }
+ }
+ if (find_field_bool(data, "IssuerAltName", PR_TRUE)) {
+ rv = AddAltName(extHandle, data, issuerNameStr, handle, 1);
+ if (rv != SECSuccess) {
+ error_out("ERROR: Unable to add Issuer Alternative Name Extension");
+ }
+ }
+ if (find_field_bool(data, "NameConstraints", PR_TRUE)) {
+ rv = AddNameConstraints(extHandle, data);
+ if (rv != SECSuccess) {
+ error_out("ERROR: Unable to add Name Constraints Extension");
+ }
+ }
+ if (find_field_bool(data, "netscape-cert-type", PR_TRUE)) {
+ rv = AddNscpCertType(extHandle, data);
+ if (rv != SECSuccess) {
+ error_out("ERROR: Unable to add Netscape Certificate Type Extension");
+ }
+ }
+ if (find_field_bool(data, "netscape-base-url", PR_TRUE)) {
+ rv = add_IA5StringExtension(extHandle,
+ find_field(data, "netscape-base-url-text",
+ PR_TRUE),
+ find_field_bool(data,
+ "netscape-base-url-crit",
+ PR_TRUE),
+ SEC_OID_NS_CERT_EXT_BASE_URL);
+ if (rv != SECSuccess) {
+ error_out("ERROR: Unable to add Netscape Base URL Extension");
+ }
+ }
+ if (find_field_bool(data, "netscape-revocation-url", PR_TRUE)) {
+ rv = add_IA5StringExtension(extHandle,
+ find_field(data,
+ "netscape-revocation-url-text",
+ PR_TRUE),
+ find_field_bool(data, "netscape-revocation-url-crit",
+ PR_TRUE),
+ SEC_OID_NS_CERT_EXT_REVOCATION_URL);
+ if (rv != SECSuccess) {
+ error_out("ERROR: Unable to add Netscape Revocation URL Extension");
+ }
+ }
+ if (find_field_bool(data, "netscape-ca-revocation-url", PR_TRUE)) {
+ rv = add_IA5StringExtension(extHandle,
+ find_field(data,
+ "netscape-ca-revocation-url-text",
+ PR_TRUE),
+ find_field_bool(data, "netscape-ca-revocation-url-crit", PR_TRUE),
+ SEC_OID_NS_CERT_EXT_CA_REVOCATION_URL);
+ if (rv != SECSuccess) {
+ error_out("ERROR: Unable to add Netscape CA Revocation URL Extension");
+ }
+ }
+ if (find_field_bool(data, "netscape-cert-renewal-url", PR_TRUE)) {
+ rv = add_IA5StringExtension(extHandle,
+ find_field(data,
+ "netscape-cert-renewal-url-text",
+ PR_TRUE),
+ find_field_bool(data, "netscape-cert-renewal-url-crit",
+ PR_TRUE),
+ SEC_OID_NS_CERT_EXT_CERT_RENEWAL_URL);
+ if (rv != SECSuccess) {
+ error_out("ERROR: Unable to add Netscape Certificate Renewal URL Extension");
+ }
+ }
+ if (find_field_bool(data, "netscape-ca-policy-url", PR_TRUE)) {
+ rv = add_IA5StringExtension(extHandle,
+ find_field(data,
+ "netscape-ca-policy-url-text",
+ PR_TRUE),
+ find_field_bool(data, "netscape-ca-policy-url-crit",
+ PR_TRUE),
+ SEC_OID_NS_CERT_EXT_CA_POLICY_URL);
+ if (rv != SECSuccess) {
+ error_out("ERROR: Unable to add Netscape CA Policy URL Extension");
+ }
+ }
+ if (find_field_bool(data, "netscape-ssl-server-name", PR_TRUE)) {
+ rv = add_IA5StringExtension(extHandle,
+ find_field(data,
+ "netscape-ssl-server-name-text",
+ PR_TRUE),
+ find_field_bool(data, "netscape-ssl-server-name-crit",
+ PR_TRUE),
+ SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME);
+ if (rv != SECSuccess) {
+ error_out("ERROR: Unable to add Netscape SSL Server Name Extension");
+ }
+ }
+ if (find_field_bool(data, "netscape-comment", PR_TRUE)) {
+ rv = add_IA5StringExtension(extHandle,
+ find_field(data, "netscape-comment-text",
+ PR_TRUE),
+ find_field_bool(data,
+ "netscape-comment-crit",
+ PR_TRUE),
+ SEC_OID_NS_CERT_EXT_COMMENT);
+ if (rv != SECSuccess) {
+ error_out("ERROR: Unable to add Netscape Comment Extension");
+ }
+ }
+ CERT_FinishExtensions(extHandle);
+ return (rv);
+}
+
+char *
+return_dbpasswd(PK11SlotInfo *slot, PRBool retry, void *data)
+{
+ char *rv;
+
+ /* don't clobber our poor smart card */
+ if (retry == PR_TRUE) {
+ return NULL;
+ }
+ rv = PORT_Alloc(4);
+ PORT_Strcpy(rv, "foo");
+ return rv;
+}
+
+SECKEYPrivateKey *
+FindPrivateKeyFromNameStr(char *name,
+ CERTCertDBHandle *certHandle)
+{
+ SECKEYPrivateKey *key;
+ CERTCertificate *cert;
+ CERTCertificate *p11Cert;
+
+ /* We don't presently have a PK11 function to find a cert by
+ ** subject name.
+ ** We do have a function to find a cert in the internal slot's
+ ** cert db by subject name, but it doesn't setup the slot info.
+ ** So, this HACK works, but should be replaced as soon as we
+ ** have a function to search for certs accross slots by subject name.
+ */
+ cert = CERT_FindCertByNameString(certHandle, name);
+ if (cert == NULL || cert->nickname == NULL) {
+ error_out("ERROR: Unable to retrieve issuers certificate");
+ }
+ p11Cert = PK11_FindCertFromNickname(cert->nickname, NULL);
+ if (p11Cert == NULL) {
+ error_out("ERROR: Unable to retrieve issuers certificate");
+ }
+ key = PK11_FindKeyByAnyCert(p11Cert, NULL);
+ return key;
+}
+
+static SECItem *
+SignCert(CERTCertificate *cert,
+ char *issuerNameStr,
+ Pair *data,
+ CERTCertDBHandle *handle,
+ int which_key)
+{
+ SECItem der;
+ SECKEYPrivateKey *caPrivateKey = NULL;
+ SECStatus rv;
+ PLArenaPool *arena;
+ SECOidTag algID;
+
+ if (which_key == 0) {
+ caPrivateKey = FindPrivateKeyFromNameStr(issuerNameStr, handle);
+ } else {
+ caPrivateKey = privkeys[which_key - 1];
+ }
+ if (caPrivateKey == NULL) {
+ error_out("ERROR: unable to retrieve issuers key");
+ }
+
+ arena = cert->arena;
+
+ algID = SEC_GetSignatureAlgorithmOidTag(caPrivateKey->keyType,
+ SEC_OID_UNKNOWN);
+ if (algID == SEC_OID_UNKNOWN) {
+ error_out("ERROR: Unknown key type for issuer.");
+ goto done;
+ }
+
+ rv = SECOID_SetAlgorithmID(arena, &cert->signature, algID, 0);
+ if (rv != SECSuccess) {
+ error_out("ERROR: Could not set signature algorithm id.");
+ }
+
+ if (find_field_bool(data, "ver-1", PR_TRUE)) {
+ *(cert->version.data) = 0;
+ cert->version.len = 1;
+ } else {
+ *(cert->version.data) = 2;
+ cert->version.len = 1;
+ }
+ der.data = NULL;
+ der.len = 0;
+ (void)SEC_ASN1EncodeItem(arena, &der, cert, CERT_CertificateTemplate);
+ if (der.data == NULL) {
+ error_out("ERROR: Could not encode certificate.\n");
+ }
+ rv = SEC_DerSignData(arena, &(cert->derCert), der.data, der.len, caPrivateKey,
+ algID);
+ if (rv != SECSuccess) {
+ error_out("ERROR: Could not sign encoded certificate data.\n");
+ }
+done:
+ SECKEY_DestroyPrivateKey(caPrivateKey);
+ return &(cert->derCert);
+}
+
+int
+main(int argc, char **argv)
+{
+ int length = 500;
+ int remaining = 500;
+ int n;
+ int i;
+ int serial;
+ int chainLen;
+ int which_key;
+ char *pos;
+#ifdef OFFLINE
+ char *form_output = "key=MIIBPTCBpzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA7"
+ "SLqjWBL9Wl11Vlg%0AaMqZCvcQOL%2FnvSqYPPRP0XZy9SoAeyWzQnBOiCm2t8H5mK7r2"
+ "jnKdAQOmfhjaJil%0A3hNVu3SekHOXF6Ze7bkWa6%2FSGVcY%2FojkydxFSgY43nd1iyd"
+ "zPQDp8WWLL%2BpVpt%2B%2B%0ATRhFtVXbF0fQI03j9h3BoTgP2lkCAwEAARYDZm9vMA0"
+ "GCSqGSIb3DQEBBAUAA4GB%0AAJ8UfRKJ0GtG%2B%2BufCC6tAfTzKrq3CTBHnom55EyXc"
+ "sAsv6WbDqI%2F0rLAPkn2Xo1r%0AnNhtMxIuj441blMt%2Fa3AGLOy5zmC7Qawt8IytvQ"
+ "ikQ1XTpTBCXevytrmLjCmlURr%0ANJryTM48WaMQHiMiJpbXCqVJC1d%2FpEWBtqvALzZ"
+ "aOOIy&subject=CN%3D%22test%22%26serial-auto%3Dtrue%26serial_value%3D%"
+ "26ver-1%3Dtrue%26ver-3%3Dfalse%26caChoiceradio-SignWithDefaultkey%3Dt"
+ "rue%26caChoiceradio-SignWithRandomChain%3Dfalse%26autoCAs%3D%26caChoi"
+ "ceradio-SignWithSpecifiedChain%3Dfalse%26manCAs%3D%26%24";
+#else
+ char *form_output;
+#endif
+ char *issuerNameStr;
+ char *certName;
+ char *DBdir = DB_DIRECTORY;
+ char *prefixs[10] = { "CA#1-", "CA#2-", "CA#3-",
+ "CA#4-", "CA#5-", "CA#6-",
+ "CA#7-", "CA#8-", "CA#9-", "" };
+ Pair *form_data;
+ CERTCertificate *cert;
+ CERTCertDBHandle *handle;
+ CERTCertificateRequest *certReq = NULL;
+ int warpmonths = 0;
+ SECItem *certDER;
+#ifdef FILEOUT
+ FILE *outfile;
+#endif
+ SECStatus status = SECSuccess;
+ extern char prefix[PREFIX_LEN];
+ SEC_PKCS7ContentInfo *certChain;
+ SECItem *encodedCertChain;
+ PRBool UChain = PR_FALSE;
+
+ progName = strrchr(argv[0], '/');
+ progName = progName ? progName + 1 : argv[0];
+
+#ifdef TEST
+ sleep(20);
+#endif
+ SECU_ConfigDirectory(DBdir);
+
+ PK11_SetPasswordFunc(return_dbpasswd);
+ status = NSS_InitReadWrite(DBdir);
+ if (status != SECSuccess) {
+ SECU_PrintPRandOSError(progName);
+ return -1;
+ }
+ handle = CERT_GetDefaultCertDB();
+
+ prefix[0] = '\0';
+#if !defined(OFFLINE)
+ form_output = (char *)PORT_Alloc(length);
+ if (form_output == NULL) {
+ error_allocate();
+ }
+ pos = form_output;
+ while (feof(stdin) == 0) {
+ if (remaining <= 1) {
+ remaining += length;
+ length = length * 2;
+ form_output = PORT_Realloc(form_output, (length));
+ if (form_output == NULL) {
+ error_allocate();
+ }
+ pos = form_output + length - remaining;
+ }
+ n = fread(pos, 1, (size_t)(remaining - 1), stdin);
+ pos += n;
+ remaining -= n;
+ }
+ *pos = '&';
+ pos++;
+ length = pos - form_output;
+#else
+ length = PORT_Strlen(form_output);
+#endif
+#ifdef FILEOUT
+ printf("Content-type: text/plain\n\n");
+ fwrite(form_output, 1, (size_t)length, stdout);
+ printf("\n");
+#endif
+#ifdef FILEOUT
+ fwrite(form_output, 1, (size_t)length, stdout);
+ printf("\n");
+ fflush(stdout);
+#endif
+ form_data = make_datastruct(form_output, length);
+ status = clean_input(form_data);
+#if !defined(OFFLINE)
+ PORT_Free(form_output);
+#endif
+#ifdef FILEOUT
+ i = 0;
+ while (return_name(form_data, i) != NULL) {
+ printf("%s", return_name(form_data, i));
+ printf("=\n");
+ printf("%s", return_data(form_data, i));
+ printf("\n");
+ i++;
+ }
+ printf("I got that done, woo hoo\n");
+ fflush(stdout);
+#endif
+ issuerNameStr = PORT_Alloc(200);
+ if (find_field_bool(form_data, "caChoiceradio-SignWithSpecifiedChain",
+ PR_FALSE)) {
+ UChain = PR_TRUE;
+ chainLen = atoi(find_field(form_data, "manCAs", PR_FALSE));
+ PORT_Strcpy(prefix, prefixs[0]);
+ issuerNameStr = PORT_Strcpy(issuerNameStr,
+ "CN=Cert-O-Matic II, O=Cert-O-Matic II");
+ if (chainLen == 0) {
+ UChain = PR_FALSE;
+ }
+ } else {
+ if (find_field_bool(form_data, "caChoiceradio-SignWithRandomChain",
+ PR_FALSE)) {
+ PORT_Strcpy(prefix, prefixs[9]);
+ chainLen = atoi(find_field(form_data, "autoCAs", PR_FALSE));
+ if (chainLen < 1 || chainLen > 18) {
+ issuerNameStr = PORT_Strcpy(issuerNameStr,
+ "CN=CA18, O=Cert-O-Matic II");
+ }
+ issuerNameStr = PORT_Strcpy(issuerNameStr, "CN=CA");
+ issuerNameStr = PORT_Strcat(issuerNameStr,
+ find_field(form_data, "autoCAs", PR_FALSE));
+ issuerNameStr = PORT_Strcat(issuerNameStr, ", O=Cert-O-Matic II");
+ } else {
+ issuerNameStr = PORT_Strcpy(issuerNameStr,
+ "CN=Cert-O-Matic II, O=Cert-O-Matic II");
+ }
+ chainLen = 0;
+ }
+
+ i = -1;
+ which_key = 0;
+ do {
+ extern SECStatus cert_GetKeyID(CERTCertificate * cert);
+ i++;
+ if (i != 0 && UChain) {
+ PORT_Strcpy(prefix, prefixs[i]);
+ }
+ /* find_field(form_data,"subject", PR_TRUE); */
+ certReq = makeCertReq(form_data, which_key);
+#ifdef OFFLINE
+ serial = 900;
+#else
+ serial = get_serial_number(form_data);
+#endif
+ cert = MakeV1Cert(handle, certReq, issuerNameStr, PR_FALSE,
+ serial, warpmonths, form_data);
+ if (certReq != NULL) {
+ CERT_DestroyCertificateRequest(certReq);
+ }
+ if (find_field_bool(form_data, "ver-3", PR_TRUE)) {
+ status = add_extensions(cert, form_data, issuerNameStr, handle);
+ if (status != SECSuccess) {
+ error_out("ERROR: Unable to add extensions");
+ }
+ }
+ status = cert_GetKeyID(cert);
+ if (status == SECFailure) {
+ error_out("ERROR: Unable to get Key ID.");
+ }
+ certDER = SignCert(cert, issuerNameStr, form_data, handle, which_key);
+ CERT_NewTempCertificate(handle, certDER, NULL, PR_FALSE, PR_TRUE);
+ issuerNameStr = find_field(form_data, "subject", PR_TRUE);
+ /* SECITEM_FreeItem(certDER, PR_TRUE); */
+ CERT_DestroyCertificate(cert);
+ if (i == (chainLen - 1)) {
+ i = 8;
+ }
+ ++which_key;
+ } while (i < 9 && UChain);
+
+#ifdef FILEOUT
+ outfile = fopen("../certout", "wb");
+#endif
+ certName = find_field(form_data, "subject", PR_FALSE);
+ cert = CERT_FindCertByNameString(handle, certName);
+ certChain = SEC_PKCS7CreateCertsOnly(cert, PR_TRUE, handle);
+ if (certChain == NULL) {
+ error_out("ERROR: No certificates in cert chain");
+ }
+ encodedCertChain = SEC_PKCS7EncodeItem(NULL, NULL, certChain, NULL, NULL,
+ NULL);
+ if (encodedCertChain) {
+#if !defined(FILEOUT)
+ printf("Content-type: application/x-x509-user-cert\r\n");
+ printf("Content-length: %d\r\n\r\n", encodedCertChain->len);
+ fwrite(encodedCertChain->data, 1, encodedCertChain->len, stdout);
+#else
+ fwrite(encodedCertChain->data, 1, encodedCertChain->len, outfile);
+#endif
+
+ } else {
+ error_out("Error: Unable to DER encode certificate");
+ }
+#ifdef FILEOUT
+ printf("\nI got here!\n");
+ fflush(outfile);
+ fclose(outfile);
+#endif
+ fflush(stdout);
+ if (NSS_Shutdown() != SECSuccess) {
+ exit(1);
+ }
+ return 0;
+}
diff --git a/nss/cmd/certcgi/certcgi.gyp b/nss/cmd/certcgi/certcgi.gyp
new file mode 100644
index 0000000..5ad2893
--- /dev/null
+++ b/nss/cmd/certcgi/certcgi.gyp
@@ -0,0 +1,33 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi',
+ '../../cmd/platlibs.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'certcgi',
+ 'type': 'executable',
+ 'sources': [
+ 'certcgi.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:dbm_exports',
+ '<(DEPTH)/exports.gyp:nss_exports',
+ '<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3'
+ ]
+ }
+ ],
+ 'target_defaults': {
+ 'defines': [
+ 'NSPR20',
+ 'NSS_USE_STATIC_LIBS'
+ ]
+ },
+ 'variables': {
+ 'module': 'nss',
+ 'use_static_libs': 1
+ }
+}
\ No newline at end of file
diff --git a/nss/cmd/certcgi/index.html b/nss/cmd/certcgi/index.html
new file mode 100644
index 0000000..3ae6a10
--- /dev/null
+++ b/nss/cmd/certcgi/index.html
@@ -0,0 +1,789 @@
+
+
+
+
+
+
+
+Cert-O-Matic
+
+
+
+
+
diff --git a/nss/cmd/certcgi/main.html b/nss/cmd/certcgi/main.html
new file mode 100644
index 0000000..05dd9da
--- /dev/null
+++ b/nss/cmd/certcgi/main.html
@@ -0,0 +1,76 @@
+
+
+
+ Main Layer for CertOMatic
+
+
+
+
+ DN:
+
+
diff --git a/nss/cmd/certcgi/manifest.mn b/nss/cmd/certcgi/manifest.mn
new file mode 100644
index 0000000..9e17cef
--- /dev/null
+++ b/nss/cmd/certcgi/manifest.mn
@@ -0,0 +1,22 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+CORE_DEPTH = ../..
+
+# MODULE public and private header directories are implicitly REQUIREd.
+MODULE = nss
+
+# This next line is used by .mk files
+# and gets translated into $LINCS in manifest.mnw
+REQUIRES = seccmd dbm
+
+DEFINES = -DNSPR20
+
+CSRCS = certcgi.c
+
+PROGRAM = certcgi
+
+USE_STATIC_LIBS = 1
+
diff --git a/nss/cmd/certcgi/nscp_ext_form.html b/nss/cmd/certcgi/nscp_ext_form.html
new file mode 100644
index 0000000..f2a4a20
--- /dev/null
+++ b/nss/cmd/certcgi/nscp_ext_form.html
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
diff --git a/nss/cmd/certcgi/stnd_ext_form.html b/nss/cmd/certcgi/stnd_ext_form.html
new file mode 100644
index 0000000..60d4d86
--- /dev/null
+++ b/nss/cmd/certcgi/stnd_ext_form.html
@@ -0,0 +1,219 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/nss/cmd/certutil/Makefile b/nss/cmd/certutil/Makefile
new file mode 100644
index 0000000..74ae200
--- /dev/null
+++ b/nss/cmd/certutil/Makefile
@@ -0,0 +1,48 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include ../platlibs.mk
+
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+
+include ../platrules.mk
+
diff --git a/nss/cmd/certutil/certext.c b/nss/cmd/certutil/certext.c
new file mode 100644
index 0000000..b080f06
--- /dev/null
+++ b/nss/cmd/certutil/certext.c
@@ -0,0 +1,2218 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+** certext.c
+**
+** part of certutil for managing certificates extensions
+**
+*/
+#include
+#include
+#include
+
+#if defined(WIN32)
+#include "fcntl.h"
+#include "io.h"
+#endif
+
+#include "secutil.h"
+
+#if defined(XP_UNIX)
+#include
+#endif
+
+#include "cert.h"
+#include "xconst.h"
+#include "prprf.h"
+#include "certutil.h"
+#include "genname.h"
+#include "prnetdb.h"
+
+#define GEN_BREAK(e) \
+ rv = e; \
+ break;
+
+static char *
+Gets_s(char *buff, size_t size)
+{
+ char *str;
+
+ if (buff == NULL || size < 1) {
+ PORT_Assert(0);
+ return NULL;
+ }
+ if ((str = fgets(buff, size, stdin)) != NULL) {
+ int len = PORT_Strlen(str);
+ /*
+ * fgets() automatically converts native text file
+ * line endings to '\n'. As defensive programming
+ * (just in case fgets has a bug or we put stdin in
+ * binary mode by mistake), we handle three native
+ * text file line endings here:
+ * '\n' Unix (including Linux and Mac OS X)
+ * '\r''\n' DOS/Windows & OS/2
+ * '\r' Mac OS Classic
+ * len can not be less then 1, since in case with
+ * empty string it has at least '\n' in the buffer
+ */
+ if (buff[len - 1] == '\n' || buff[len - 1] == '\r') {
+ buff[len - 1] = '\0';
+ if (len > 1 && buff[len - 2] == '\r')
+ buff[len - 2] = '\0';
+ }
+ } else {
+ buff[0] = '\0';
+ }
+ return str;
+}
+
+static SECStatus
+PrintChoicesAndGetAnswer(char *str, char *rBuff, int rSize)
+{
+ fputs(str, stdout);
+ fputs(" > ", stdout);
+ fflush(stdout);
+ if (Gets_s(rBuff, rSize) == NULL) {
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+static CERTGeneralName *
+GetGeneralName(PLArenaPool *arena, CERTGeneralName *useExistingName, PRBool onlyOne)
+{
+ CERTGeneralName *namesList = NULL;
+ CERTGeneralName *current;
+ CERTGeneralName *tail = NULL;
+ SECStatus rv = SECSuccess;
+ int intValue;
+ char buffer[512];
+ void *mark;
+
+ PORT_Assert(arena);
+ mark = PORT_ArenaMark(arena);
+ do {
+ if (PrintChoicesAndGetAnswer(
+ "\nSelect one of the following general name type: \n"
+ "\t2 - rfc822Name\n"
+ "\t3 - dnsName\n"
+ "\t5 - directoryName\n"
+ "\t7 - uniformResourceidentifier\n"
+ "\t8 - ipAddress\n"
+ "\t9 - registerID\n"
+ "\tAny other number to finish\n"
+ "\t\tChoice:",
+ buffer, sizeof(buffer)) == SECFailure) {
+ GEN_BREAK(SECFailure);
+ }
+ intValue = PORT_Atoi(buffer);
+ /*
+ * Should use ZAlloc instead of Alloc to avoid problem with garbage
+ * initialized pointers in CERT_CopyName
+ */
+ switch (intValue) {
+ case certRFC822Name:
+ case certDNSName:
+ case certDirectoryName:
+ case certURI:
+ case certIPAddress:
+ case certRegisterID:
+ break;
+ default:
+ intValue = 0; /* force a break for anything else */
+ }
+
+ if (intValue == 0)
+ break;
+
+ if (namesList == NULL) {
+ if (useExistingName) {
+ namesList = current = tail = useExistingName;
+ } else {
+ namesList = current = tail =
+ PORT_ArenaZNew(arena, CERTGeneralName);
+ }
+ } else {
+ current = PORT_ArenaZNew(arena, CERTGeneralName);
+ }
+ if (current == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+
+ current->type = intValue;
+ puts("\nEnter data:");
+ fflush(stdout);
+ if (Gets_s(buffer, sizeof(buffer)) == NULL) {
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ GEN_BREAK(SECFailure);
+ }
+ switch (current->type) {
+ case certURI:
+ case certDNSName:
+ case certRFC822Name:
+ current->name.other.data =
+ PORT_ArenaAlloc(arena, strlen(buffer));
+ if (current->name.other.data == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+ PORT_Memcpy(current->name.other.data, buffer,
+ current->name.other.len = strlen(buffer));
+ break;
+
+ case certEDIPartyName:
+ case certIPAddress:
+ case certOtherName:
+ case certRegisterID:
+ case certX400Address: {
+
+ current->name.other.data =
+ PORT_ArenaAlloc(arena, strlen(buffer) + 2);
+ if (current->name.other.data == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+
+ PORT_Memcpy(current->name.other.data + 2, buffer,
+ strlen(buffer));
+ /* This may not be accurate for all cases. For now,
+ * use this tag type */
+ current->name.other.data[0] =
+ (char)(((current->type - 1) & 0x1f) | 0x80);
+ current->name.other.data[1] = (char)strlen(buffer);
+ current->name.other.len = strlen(buffer) + 2;
+ break;
+ }
+
+ case certDirectoryName: {
+ CERTName *directoryName = NULL;
+
+ directoryName = CERT_AsciiToName(buffer);
+ if (!directoryName) {
+ fprintf(stderr, "certutil: improperly formatted name: "
+ "\"%s\"\n",
+ buffer);
+ break;
+ }
+
+ rv = CERT_CopyName(arena, ¤t->name.directoryName,
+ directoryName);
+ CERT_DestroyName(directoryName);
+
+ break;
+ }
+ }
+ if (rv != SECSuccess)
+ break;
+ current->l.next = &(namesList->l);
+ current->l.prev = &(tail->l);
+ tail->l.next = &(current->l);
+ tail = current;
+
+ } while (!onlyOne);
+
+ if (rv != SECSuccess) {
+ PORT_ArenaRelease(arena, mark);
+ namesList = NULL;
+ }
+ return (namesList);
+}
+
+static CERTGeneralName *
+CreateGeneralName(PLArenaPool *arena)
+{
+ return GetGeneralName(arena, NULL, PR_FALSE);
+}
+
+static SECStatus
+GetString(PLArenaPool *arena, char *prompt, SECItem *value)
+{
+ char buffer[251];
+ char *buffPrt;
+
+ buffer[0] = '\0';
+ value->data = NULL;
+ value->len = 0;
+
+ puts(prompt);
+ buffPrt = Gets_s(buffer, sizeof(buffer));
+ /* returned NULL here treated the same way as empty string */
+ if (buffPrt && strlen(buffer) > 0) {
+ value->data = PORT_ArenaAlloc(arena, strlen(buffer));
+ if (value->data == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return (SECFailure);
+ }
+ PORT_Memcpy(value->data, buffer, value->len = strlen(buffer));
+ }
+ return (SECSuccess);
+}
+
+static PRBool
+GetYesNo(char *prompt)
+{
+ char buf[3];
+ char *buffPrt;
+
+ buf[0] = 'n';
+ puts(prompt);
+ buffPrt = Gets_s(buf, sizeof(buf));
+ return (buffPrt && (buf[0] == 'y' || buf[0] == 'Y')) ? PR_TRUE : PR_FALSE;
+}
+
+/* Parses comma separated values out of the string pointed by nextPos.
+ * Parsed value is compared to an array of possible values(valueArray).
+ * If match is found, a value index is returned, otherwise returns SECFailue.
+ * nextPos is set to the token after found comma separator or to NULL.
+ * NULL in nextPos should be used as indication of the last parsed token.
+ * A special value "critical" can be parsed out from the supplied sting.*/
+
+static SECStatus
+parseNextCmdInput(const char *const *valueArray, int *value, char **nextPos,
+ PRBool *critical)
+{
+ char *thisPos;
+ int keyLen = 0;
+ int arrIndex = 0;
+
+ if (!valueArray || !value || !nextPos || !critical) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ thisPos = *nextPos;
+ while (1) {
+ if ((*nextPos = strchr(thisPos, ',')) == NULL) {
+ keyLen = strlen(thisPos);
+ } else {
+ keyLen = *nextPos - thisPos;
+ *nextPos += 1;
+ }
+ /* if critical keyword is found, go for another loop,
+ * but check, if it is the last keyword of
+ * the string.*/
+ if (!strncmp("critical", thisPos, keyLen)) {
+ *critical = PR_TRUE;
+ if (*nextPos == NULL) {
+ return SECSuccess;
+ }
+ thisPos = *nextPos;
+ continue;
+ }
+ break;
+ }
+ for (arrIndex = 0; valueArray[arrIndex]; arrIndex++) {
+ if (!strncmp(valueArray[arrIndex], thisPos, keyLen)) {
+ *value = arrIndex;
+ return SECSuccess;
+ }
+ }
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+}
+
+static const char *const
+ keyUsageKeyWordArray[] = { "digitalSignature",
+ "nonRepudiation",
+ "keyEncipherment",
+ "dataEncipherment",
+ "keyAgreement",
+ "certSigning",
+ "crlSigning",
+ NULL };
+
+static SECStatus
+AddKeyUsage(void *extHandle, const char *userSuppliedValue)
+{
+ SECItem bitStringValue;
+ unsigned char keyUsage = 0x0;
+ char buffer[5];
+ int value;
+ char *nextPos = (char *)userSuppliedValue;
+ PRBool isCriticalExt = PR_FALSE;
+
+ if (!userSuppliedValue) {
+ while (1) {
+ if (PrintChoicesAndGetAnswer(
+ "\t\t0 - Digital Signature\n"
+ "\t\t1 - Non-repudiation\n"
+ "\t\t2 - Key encipherment\n"
+ "\t\t3 - Data encipherment\n"
+ "\t\t4 - Key agreement\n"
+ "\t\t5 - Cert signing key\n"
+ "\t\t6 - CRL signing key\n"
+ "\t\tOther to finish\n",
+ buffer, sizeof(buffer)) == SECFailure) {
+ return SECFailure;
+ }
+ value = PORT_Atoi(buffer);
+ if (value < 0 || value > 6)
+ break;
+ if (value == 0) {
+ /* Checking that zero value of variable 'value'
+ * corresponds to '0' input made by user */
+ char *chPtr = strchr(buffer, '0');
+ if (chPtr == NULL) {
+ continue;
+ }
+ }
+ keyUsage |= (0x80 >> value);
+ }
+ isCriticalExt = GetYesNo("Is this a critical extension [y/N]?");
+ } else {
+ while (1) {
+ if (parseNextCmdInput(keyUsageKeyWordArray, &value, &nextPos,
+ &isCriticalExt) == SECFailure) {
+ return SECFailure;
+ }
+ keyUsage |= (0x80 >> value);
+ if (!nextPos)
+ break;
+ }
+ }
+
+ bitStringValue.data = &keyUsage;
+ bitStringValue.len = 1;
+
+ return (CERT_EncodeAndAddBitStrExtension(extHandle, SEC_OID_X509_KEY_USAGE, &bitStringValue,
+ isCriticalExt));
+}
+
+static CERTOidSequence *
+CreateOidSequence(void)
+{
+ CERTOidSequence *rv = (CERTOidSequence *)NULL;
+ PLArenaPool *arena = (PLArenaPool *)NULL;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ((PLArenaPool *)NULL == arena) {
+ goto loser;
+ }
+
+ rv = (CERTOidSequence *)PORT_ArenaZNew(arena, CERTOidSequence);
+ if ((CERTOidSequence *)NULL == rv) {
+ goto loser;
+ }
+
+ rv->oids = (SECItem **)PORT_ArenaZNew(arena, SECItem *);
+ if ((SECItem **)NULL == rv->oids) {
+ goto loser;
+ }
+
+ rv->arena = arena;
+ return rv;
+
+loser:
+ if ((PLArenaPool *)NULL != arena) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return (CERTOidSequence *)NULL;
+}
+
+static void
+DestroyOidSequence(CERTOidSequence *os)
+{
+ if (os->arena) {
+ PORT_FreeArena(os->arena, PR_FALSE);
+ }
+}
+
+static SECStatus
+AddOidToSequence(CERTOidSequence *os, SECOidTag oidTag)
+{
+ SECItem **oids;
+ PRUint32 count = 0;
+ SECOidData *od;
+
+ od = SECOID_FindOIDByTag(oidTag);
+ if ((SECOidData *)NULL == od) {
+ return SECFailure;
+ }
+
+ for (oids = os->oids; (SECItem *)NULL != *oids; oids++) {
+ if (*oids == &od->oid) {
+ /* We already have this oid */
+ return SECSuccess;
+ }
+ count++;
+ }
+
+ /* ArenaZRealloc */
+
+ {
+ PRUint32 i;
+
+ oids = (SECItem **)PORT_ArenaZNewArray(os->arena, SECItem *, count + 2);
+ if ((SECItem **)NULL == oids) {
+ return SECFailure;
+ }
+
+ for (i = 0; i < count; i++) {
+ oids[i] = os->oids[i];
+ }
+
+ /* ArenaZFree(os->oids); */
+ }
+
+ os->oids = oids;
+ os->oids[count] = &od->oid;
+
+ return SECSuccess;
+}
+
+SEC_ASN1_MKSUB(SEC_ObjectIDTemplate)
+
+const SEC_ASN1Template CERT_OidSeqTemplate[] = {
+ { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, offsetof(CERTOidSequence, oids),
+ SEC_ASN1_SUB(SEC_ObjectIDTemplate) }
+};
+
+static SECItem *
+EncodeOidSequence(CERTOidSequence *os)
+{
+ SECItem *rv;
+
+ rv = (SECItem *)PORT_ArenaZNew(os->arena, SECItem);
+ if ((SECItem *)NULL == rv) {
+ goto loser;
+ }
+
+ if (!SEC_ASN1EncodeItem(os->arena, rv, os, CERT_OidSeqTemplate)) {
+ goto loser;
+ }
+
+ return rv;
+
+loser:
+ return (SECItem *)NULL;
+}
+
+static const char *const
+ extKeyUsageKeyWordArray[] = { "serverAuth",
+ "clientAuth",
+ "codeSigning",
+ "emailProtection",
+ "timeStamp",
+ "ocspResponder",
+ "stepUp",
+ "msTrustListSigning",
+ NULL };
+
+static SECStatus
+AddExtKeyUsage(void *extHandle, const char *userSuppliedValue)
+{
+ char buffer[5];
+ int value;
+ CERTOidSequence *os;
+ SECStatus rv;
+ SECItem *item;
+ PRBool isCriticalExt = PR_FALSE;
+ char *nextPos = (char *)userSuppliedValue;
+
+ os = CreateOidSequence();
+ if ((CERTOidSequence *)NULL == os) {
+ return SECFailure;
+ }
+
+ while (1) {
+ if (!userSuppliedValue) {
+ if (PrintChoicesAndGetAnswer(
+ "\t\t0 - Server Auth\n"
+ "\t\t1 - Client Auth\n"
+ "\t\t2 - Code Signing\n"
+ "\t\t3 - Email Protection\n"
+ "\t\t4 - Timestamp\n"
+ "\t\t5 - OCSP Responder\n"
+ "\t\t6 - Step-up\n"
+ "\t\t7 - Microsoft Trust List Signing\n"
+ "\t\tOther to finish\n",
+ buffer, sizeof(buffer)) == SECFailure) {
+ GEN_BREAK(SECFailure);
+ }
+ value = PORT_Atoi(buffer);
+
+ if (value == 0) {
+ /* Checking that zero value of variable 'value'
+ * corresponds to '0' input made by user */
+ char *chPtr = strchr(buffer, '0');
+ if (chPtr == NULL) {
+ continue;
+ }
+ }
+ } else {
+ if (parseNextCmdInput(extKeyUsageKeyWordArray, &value, &nextPos,
+ &isCriticalExt) == SECFailure) {
+ return SECFailure;
+ }
+ }
+
+ switch (value) {
+ case 0:
+ rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_SERVER_AUTH);
+ break;
+ case 1:
+ rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH);
+ break;
+ case 2:
+ rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_CODE_SIGN);
+ break;
+ case 3:
+ rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT);
+ break;
+ case 4:
+ rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_TIME_STAMP);
+ break;
+ case 5:
+ rv = AddOidToSequence(os, SEC_OID_OCSP_RESPONDER);
+ break;
+ case 6:
+ rv = AddOidToSequence(os, SEC_OID_NS_KEY_USAGE_GOVT_APPROVED);
+ break;
+ case 7:
+ rv = AddOidToSequence(os, SEC_OID_MS_EXT_KEY_USAGE_CTL_SIGNING);
+ break;
+ default:
+ goto endloop;
+ }
+
+ if (userSuppliedValue && !nextPos)
+ break;
+ if (SECSuccess != rv)
+ goto loser;
+ }
+
+endloop:
+ item = EncodeOidSequence(os);
+
+ if (!userSuppliedValue) {
+ isCriticalExt = GetYesNo("Is this a critical extension [y/N]?");
+ }
+
+ rv = CERT_AddExtension(extHandle, SEC_OID_X509_EXT_KEY_USAGE, item,
+ isCriticalExt, PR_TRUE);
+/*FALLTHROUGH*/
+loser:
+ DestroyOidSequence(os);
+ return rv;
+}
+
+static const char *const
+ nsCertTypeKeyWordArray[] = { "sslClient",
+ "sslServer",
+ "smime",
+ "objectSigning",
+ "Not!Used",
+ "sslCA",
+ "smimeCA",
+ "objectSigningCA",
+ NULL };
+
+static SECStatus
+AddNscpCertType(void *extHandle, const char *userSuppliedValue)
+{
+ SECItem bitStringValue;
+ unsigned char keyUsage = 0x0;
+ char buffer[5];
+ int value;
+ char *nextPos = (char *)userSuppliedValue;
+ PRBool isCriticalExt = PR_FALSE;
+
+ if (!userSuppliedValue) {
+ while (1) {
+ if (PrintChoicesAndGetAnswer(
+ "\t\t0 - SSL Client\n"
+ "\t\t1 - SSL Server\n"
+ "\t\t2 - S/MIME\n"
+ "\t\t3 - Object Signing\n"
+ "\t\t4 - Reserved for future use\n"
+ "\t\t5 - SSL CA\n"
+ "\t\t6 - S/MIME CA\n"
+ "\t\t7 - Object Signing CA\n"
+ "\t\tOther to finish\n",
+ buffer, sizeof(buffer)) == SECFailure) {
+ return SECFailure;
+ }
+ value = PORT_Atoi(buffer);
+ if (value < 0 || value > 7)
+ break;
+ if (value == 0) {
+ /* Checking that zero value of variable 'value'
+ * corresponds to '0' input made by user */
+ char *chPtr = strchr(buffer, '0');
+ if (chPtr == NULL) {
+ continue;
+ }
+ }
+ keyUsage |= (0x80 >> value);
+ }
+ isCriticalExt = GetYesNo("Is this a critical extension [y/N]?");
+ } else {
+ while (1) {
+ if (parseNextCmdInput(nsCertTypeKeyWordArray, &value, &nextPos,
+ &isCriticalExt) == SECFailure) {
+ return SECFailure;
+ }
+ keyUsage |= (0x80 >> value);
+ if (!nextPos)
+ break;
+ }
+ }
+
+ bitStringValue.data = &keyUsage;
+ bitStringValue.len = 1;
+
+ return (CERT_EncodeAndAddBitStrExtension(extHandle, SEC_OID_NS_CERT_EXT_CERT_TYPE, &bitStringValue,
+ isCriticalExt));
+}
+
+SECStatus
+GetOidFromString(PLArenaPool *arena, SECItem *to,
+ const char *from, size_t fromLen)
+{
+ SECStatus rv;
+ SECOidTag tag;
+ SECOidData *coid;
+
+ /* try dotted form first */
+ rv = SEC_StringToOID(arena, to, from, fromLen);
+ if (rv == SECSuccess) {
+ return rv;
+ }
+
+ /* Check to see if it matches a name in our oid table.
+ * SECOID_FindOIDByTag returns NULL if tag is out of bounds.
+ */
+ tag = SEC_OID_UNKNOWN;
+ coid = SECOID_FindOIDByTag(tag);
+ for (; coid; coid = SECOID_FindOIDByTag(++tag)) {
+ if (PORT_Strncasecmp(from, coid->desc, fromLen) == 0) {
+ break;
+ }
+ }
+ if (coid == NULL) {
+ /* none found */
+ return SECFailure;
+ }
+ return SECITEM_CopyItem(arena, to, &coid->oid);
+}
+
+static SECStatus
+AddSubjectAltNames(PLArenaPool *arena, CERTGeneralName **existingListp,
+ const char *constNames, CERTGeneralNameType type)
+{
+ CERTGeneralName *nameList = NULL;
+ CERTGeneralName *current = NULL;
+ PRCList *prev = NULL;
+ char *cp, *nextName = NULL;
+ SECStatus rv = SECSuccess;
+ PRBool readTypeFromName = (PRBool)(type == 0);
+ char *names = NULL;
+
+ if (constNames)
+ names = PORT_Strdup(constNames);
+
+ if (names == NULL) {
+ return SECFailure;
+ }
+
+ /*
+ * walk down the comma separated list of names. NOTE: there is
+ * no sanity checks to see if the email address look like
+ * email addresses.
+ *
+ * Each name may optionally be prefixed with a type: string.
+ * If it isn't, the type from the previous name will be used.
+ * If there wasn't a previous name yet, the type given
+ * as a parameter to this function will be used.
+ * If the type value is zero (undefined), we'll fail.
+ */
+ for (cp = names; cp; cp = nextName) {
+ int len;
+ char *oidString;
+ char *nextComma;
+ CERTName *name;
+ PRStatus status;
+ unsigned char *data;
+ PRNetAddr addr;
+
+ nextName = NULL;
+ if (*cp == ',') {
+ cp++;
+ }
+ nextComma = PORT_Strchr(cp, ',');
+ if (nextComma) {
+ *nextComma = 0;
+ nextName = nextComma + 1;
+ }
+ if ((*cp) == 0) {
+ continue;
+ }
+ if (readTypeFromName) {
+ char *save = cp;
+ /* Because we already replaced nextComma with end-of-string,
+ * a found colon belongs to the current name */
+ cp = PORT_Strchr(cp, ':');
+ if (cp) {
+ *cp = 0;
+ cp++;
+ type = CERT_GetGeneralNameTypeFromString(save);
+ if (*cp == 0) {
+ continue;
+ }
+ } else {
+ if (type == 0) {
+ /* no type known yet */
+ rv = SECFailure;
+ break;
+ }
+ cp = save;
+ }
+ }
+
+ current = PORT_ArenaZNew(arena, CERTGeneralName);
+ if (!current) {
+ rv = SECFailure;
+ break;
+ }
+
+ current->type = type;
+ switch (type) {
+ /* string types */
+ case certRFC822Name:
+ case certDNSName:
+ case certURI:
+ current->name.other.data =
+ (unsigned char *)PORT_ArenaStrdup(arena, cp);
+ current->name.other.len = PORT_Strlen(cp);
+ break;
+ /* unformated data types */
+ case certX400Address:
+ case certEDIPartyName:
+ /* turn a string into a data and len */
+ rv = SECFailure; /* punt on these for now */
+ fprintf(stderr, "EDI Party Name and X.400 Address not supported\n");
+ break;
+ case certDirectoryName:
+ /* certDirectoryName */
+ name = CERT_AsciiToName(cp);
+ if (name == NULL) {
+ rv = SECFailure;
+ fprintf(stderr, "Invalid Directory Name (\"%s\")\n", cp);
+ break;
+ }
+ rv = CERT_CopyName(arena, ¤t->name.directoryName, name);
+ CERT_DestroyName(name);
+ break;
+ /* types that require more processing */
+ case certIPAddress:
+ /* convert the string to an ip address */
+ status = PR_StringToNetAddr(cp, &addr);
+ if (status != PR_SUCCESS) {
+ rv = SECFailure;
+ fprintf(stderr, "Invalid IP Address (\"%s\")\n", cp);
+ break;
+ }
+
+ if (PR_NetAddrFamily(&addr) == PR_AF_INET) {
+ len = sizeof(addr.inet.ip);
+ data = (unsigned char *)&addr.inet.ip;
+ } else if (PR_NetAddrFamily(&addr) == PR_AF_INET6) {
+ len = sizeof(addr.ipv6.ip);
+ data = (unsigned char *)&addr.ipv6.ip;
+ } else {
+ fprintf(stderr, "Invalid IP Family\n");
+ rv = SECFailure;
+ break;
+ }
+ current->name.other.data = PORT_ArenaAlloc(arena, len);
+ if (current->name.other.data == NULL) {
+ rv = SECFailure;
+ break;
+ }
+ current->name.other.len = len;
+ PORT_Memcpy(current->name.other.data, data, len);
+ break;
+ case certRegisterID:
+ rv = GetOidFromString(arena, ¤t->name.other, cp, strlen(cp));
+ break;
+ case certOtherName:
+ oidString = cp;
+ cp = PORT_Strchr(cp, ';');
+ if (cp == NULL) {
+ rv = SECFailure;
+ fprintf(stderr, "missing name in other name\n");
+ break;
+ }
+ *cp++ = 0;
+ current->name.OthName.name.data =
+ (unsigned char *)PORT_ArenaStrdup(arena, cp);
+ if (current->name.OthName.name.data == NULL) {
+ rv = SECFailure;
+ break;
+ }
+ current->name.OthName.name.len = PORT_Strlen(cp);
+ rv = GetOidFromString(arena, ¤t->name.OthName.oid,
+ oidString, strlen(oidString));
+ break;
+ default:
+ rv = SECFailure;
+ fprintf(stderr, "Missing or invalid Subject Alternate Name type\n");
+ break;
+ }
+ if (rv == SECFailure) {
+ break;
+ }
+
+ if (prev) {
+ current->l.prev = prev;
+ prev->next = &(current->l);
+ } else {
+ nameList = current;
+ }
+ prev = &(current->l);
+ }
+ PORT_Free(names);
+ /* at this point nameList points to the head of a doubly linked,
+ * but not yet circular, list and current points to its tail. */
+ if (rv == SECSuccess && nameList) {
+ if (*existingListp != NULL) {
+ PRCList *existingprev;
+ /* add nameList to the end of the existing list */
+ existingprev = (*existingListp)->l.prev;
+ (*existingListp)->l.prev = &(current->l);
+ nameList->l.prev = existingprev;
+ existingprev->next = &(nameList->l);
+ current->l.next = &((*existingListp)->l);
+ } else {
+ /* make nameList circular and set it as the new existingList */
+ nameList->l.prev = prev;
+ current->l.next = &(nameList->l);
+ *existingListp = nameList;
+ }
+ }
+ return rv;
+}
+
+static SECStatus
+AddEmailSubjectAlt(PLArenaPool *arena, CERTGeneralName **existingListp,
+ const char *emailAddrs)
+{
+ return AddSubjectAltNames(arena, existingListp, emailAddrs,
+ certRFC822Name);
+}
+
+static SECStatus
+AddDNSSubjectAlt(PLArenaPool *arena, CERTGeneralName **existingListp,
+ const char *dnsNames)
+{
+ return AddSubjectAltNames(arena, existingListp, dnsNames, certDNSName);
+}
+
+static SECStatus
+AddGeneralSubjectAlt(PLArenaPool *arena, CERTGeneralName **existingListp,
+ const char *altNames)
+{
+ return AddSubjectAltNames(arena, existingListp, altNames, 0);
+}
+
+static SECStatus
+AddBasicConstraint(PLArenaPool *arena, void *extHandle)
+{
+ CERTBasicConstraints basicConstraint;
+ SECStatus rv;
+ char buffer[10];
+ PRBool yesNoAns;
+
+ do {
+ basicConstraint.pathLenConstraint = CERT_UNLIMITED_PATH_CONSTRAINT;
+ basicConstraint.isCA = GetYesNo("Is this a CA certificate [y/N]?");
+
+ buffer[0] = '\0';
+ if (PrintChoicesAndGetAnswer("Enter the path length constraint, "
+ "enter to skip [<0 for unlimited path]:",
+ buffer, sizeof(buffer)) == SECFailure) {
+ GEN_BREAK(SECFailure);
+ }
+ if (PORT_Strlen(buffer) > 0)
+ basicConstraint.pathLenConstraint = PORT_Atoi(buffer);
+
+ yesNoAns = GetYesNo("Is this a critical extension [y/N]?");
+
+ rv = SECU_EncodeAndAddExtensionValue(arena, extHandle,
+ &basicConstraint, yesNoAns, SEC_OID_X509_BASIC_CONSTRAINTS,
+ (EXTEN_EXT_VALUE_ENCODER)CERT_EncodeBasicConstraintValue);
+ } while (0);
+
+ return (rv);
+}
+
+static SECStatus
+AddNameConstraints(void *extHandle)
+{
+ PLArenaPool *arena = NULL;
+ CERTNameConstraints *constraints = NULL;
+
+ CERTNameConstraint *current = NULL;
+ CERTNameConstraint *last_permited = NULL;
+ CERTNameConstraint *last_excluded = NULL;
+ SECStatus rv = SECSuccess;
+
+ char buffer[512];
+ int intValue = 0;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (arena) {
+ constraints = PORT_ArenaZNew(arena, CERTNameConstraints);
+ }
+
+ if (!arena || !constraints) {
+ SECU_PrintError(progName, "out of memory");
+ PORT_FreeArena(arena, PR_FALSE);
+ return SECFailure;
+ }
+
+ constraints->permited = constraints->excluded = NULL;
+
+ do {
+ current = PORT_ArenaZNew(arena, CERTNameConstraint);
+ if (!current) {
+ GEN_BREAK(SECFailure);
+ }
+
+ (void)SEC_ASN1EncodeInteger(arena, ¤t->min, 0);
+
+ if (!GetGeneralName(arena, ¤t->name, PR_TRUE)) {
+ GEN_BREAK(SECFailure);
+ }
+
+ if (PrintChoicesAndGetAnswer("Type of Name Constraint?\n"
+ "\t1 - permitted\n\t2 - excluded\n\tAny"
+ "other number to finish\n\tChoice",
+ buffer, sizeof(buffer)) !=
+ SECSuccess) {
+ GEN_BREAK(SECFailure);
+ }
+
+ intValue = PORT_Atoi(buffer);
+ switch (intValue) {
+ case 1:
+ if (constraints->permited == NULL) {
+ constraints->permited = last_permited = current;
+ }
+ last_permited->l.next = &(current->l);
+ current->l.prev = &(last_permited->l);
+ last_permited = current;
+ break;
+ case 2:
+ if (constraints->excluded == NULL) {
+ constraints->excluded = last_excluded = current;
+ }
+ last_excluded->l.next = &(current->l);
+ current->l.prev = &(last_excluded->l);
+ last_excluded = current;
+ break;
+ }
+
+ PR_snprintf(buffer, sizeof(buffer), "Add another entry to the"
+ " Name Constraint Extension [y/N]");
+
+ if (GetYesNo(buffer) == 0) {
+ break;
+ }
+
+ } while (1);
+
+ if (rv == SECSuccess) {
+ int oidIdent = SEC_OID_X509_NAME_CONSTRAINTS;
+
+ PRBool yesNoAns = GetYesNo("Is this a critical extension [y/N]?");
+
+ if (constraints->permited != NULL) {
+ last_permited->l.next = &(constraints->permited->l);
+ constraints->permited->l.prev = &(last_permited->l);
+ }
+ if (constraints->excluded != NULL) {
+ last_excluded->l.next = &(constraints->excluded->l);
+ constraints->excluded->l.prev = &(last_excluded->l);
+ }
+
+ rv = SECU_EncodeAndAddExtensionValue(arena, extHandle, constraints,
+ yesNoAns, oidIdent,
+ (EXTEN_EXT_VALUE_ENCODER)CERT_EncodeNameConstraintsExtension);
+ }
+ if (arena)
+ PORT_FreeArena(arena, PR_FALSE);
+ return (rv);
+}
+
+static SECStatus
+AddAuthKeyID(void *extHandle)
+{
+ CERTAuthKeyID *authKeyID = NULL;
+ PLArenaPool *arena = NULL;
+ SECStatus rv = SECSuccess;
+ PRBool yesNoAns;
+
+ do {
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ SECU_PrintError(progName, "out of memory");
+ GEN_BREAK(SECFailure);
+ }
+
+ if (GetYesNo("Enter value for the authKeyID extension [y/N]?") == 0)
+ break;
+
+ authKeyID = PORT_ArenaZNew(arena, CERTAuthKeyID);
+ if (authKeyID == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+
+ rv = GetString(arena, "Enter value for the key identifier fields,"
+ "enter to omit:",
+ &authKeyID->keyID);
+ if (rv != SECSuccess)
+ break;
+
+ SECU_SECItemHexStringToBinary(&authKeyID->keyID);
+
+ authKeyID->authCertIssuer = CreateGeneralName(arena);
+ if (authKeyID->authCertIssuer == NULL &&
+ SECFailure == PORT_GetError())
+ break;
+
+ rv = GetString(arena, "Enter value for the authCertSerial field, "
+ "enter to omit:",
+ &authKeyID->authCertSerialNumber);
+
+ yesNoAns = GetYesNo("Is this a critical extension [y/N]?");
+
+ rv = SECU_EncodeAndAddExtensionValue(arena, extHandle,
+ authKeyID, yesNoAns, SEC_OID_X509_AUTH_KEY_ID,
+ (EXTEN_EXT_VALUE_ENCODER)CERT_EncodeAuthKeyID);
+ if (rv)
+ break;
+
+ } while (0);
+ if (arena)
+ PORT_FreeArena(arena, PR_FALSE);
+ return (rv);
+}
+
+static SECStatus
+AddSubjKeyID(void *extHandle)
+{
+ SECItem keyID;
+ PLArenaPool *arena = NULL;
+ SECStatus rv = SECSuccess;
+ PRBool yesNoAns;
+
+ do {
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ SECU_PrintError(progName, "out of memory");
+ GEN_BREAK(SECFailure);
+ }
+ printf("Adding Subject Key ID extension.\n");
+
+ rv = GetString(arena, "Enter value for the key identifier fields,"
+ "enter to omit:",
+ &keyID);
+ if (rv != SECSuccess)
+ break;
+
+ SECU_SECItemHexStringToBinary(&keyID);
+
+ yesNoAns = GetYesNo("Is this a critical extension [y/N]?");
+
+ rv = SECU_EncodeAndAddExtensionValue(arena, extHandle,
+ &keyID, yesNoAns, SEC_OID_X509_SUBJECT_KEY_ID,
+ (EXTEN_EXT_VALUE_ENCODER)CERT_EncodeSubjectKeyID);
+ if (rv)
+ break;
+
+ } while (0);
+ if (arena)
+ PORT_FreeArena(arena, PR_FALSE);
+ return (rv);
+}
+
+static SECStatus
+AddCrlDistPoint(void *extHandle)
+{
+ PLArenaPool *arena = NULL;
+ CERTCrlDistributionPoints *crlDistPoints = NULL;
+ CRLDistributionPoint *current;
+ SECStatus rv = SECSuccess;
+ int count = 0, intValue;
+ char buffer[512];
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena)
+ return (SECFailure);
+
+ do {
+ current = NULL;
+
+ current = PORT_ArenaZNew(arena, CRLDistributionPoint);
+ if (current == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+
+ /* Get the distributionPointName fields - this field is optional */
+ if (PrintChoicesAndGetAnswer(
+ "Enter the type of the distribution point name:\n"
+ "\t1 - Full Name\n\t2 - Relative Name\n\tAny other "
+ "number to finish\n\t\tChoice: ",
+ buffer, sizeof(buffer)) == SECFailure) {
+ GEN_BREAK(SECFailure);
+ }
+ intValue = PORT_Atoi(buffer);
+ switch (intValue) {
+ case generalName:
+ current->distPointType = intValue;
+ current->distPoint.fullName = CreateGeneralName(arena);
+ rv = PORT_GetError();
+ break;
+
+ case relativeDistinguishedName: {
+ CERTName *name;
+
+ current->distPointType = intValue;
+ puts("Enter the relative name: ");
+ fflush(stdout);
+ if (Gets_s(buffer, sizeof(buffer)) == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+ /* For simplicity, use CERT_AsciiToName to converse from a string
+ to NAME, but we only interest in the first RDN */
+ name = CERT_AsciiToName(buffer);
+ if (!name) {
+ GEN_BREAK(SECFailure);
+ }
+ rv = CERT_CopyRDN(arena, ¤t->distPoint.relativeName,
+ name->rdns[0]);
+ CERT_DestroyName(name);
+ break;
+ }
+ }
+ if (rv != SECSuccess)
+ break;
+
+ /* Get the reason flags */
+ if (PrintChoicesAndGetAnswer(
+ "\nSelect one of the following for the reason flags\n"
+ "\t0 - unused\n\t1 - keyCompromise\n"
+ "\t2 - caCompromise\n\t3 - affiliationChanged\n"
+ "\t4 - superseded\n\t5 - cessationOfOperation\n"
+ "\t6 - certificateHold\n"
+ "\tAny other number to finish\t\tChoice: ",
+ buffer, sizeof(buffer)) == SECFailure) {
+ GEN_BREAK(SECFailure);
+ }
+ intValue = PORT_Atoi(buffer);
+ if (intValue == 0) {
+ /* Checking that zero value of variable 'value'
+ * corresponds to '0' input made by user */
+ char *chPtr = strchr(buffer, '0');
+ if (chPtr == NULL) {
+ intValue = -1;
+ }
+ }
+ if (intValue >= 0 && intValue < 8) {
+ current->reasons.data = PORT_ArenaAlloc(arena, sizeof(char));
+ if (current->reasons.data == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+ *current->reasons.data = (char)(0x80 >> intValue);
+ current->reasons.len = 1;
+ }
+ puts("Enter value for the CRL Issuer name:\n");
+ current->crlIssuer = CreateGeneralName(arena);
+ if (current->crlIssuer == NULL && (rv = PORT_GetError()) == SECFailure)
+ break;
+
+ if (crlDistPoints == NULL) {
+ crlDistPoints = PORT_ArenaZNew(arena, CERTCrlDistributionPoints);
+ if (crlDistPoints == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+ }
+
+ if (crlDistPoints->distPoints) {
+ crlDistPoints->distPoints =
+ PORT_ArenaGrow(arena, crlDistPoints->distPoints,
+ sizeof(*crlDistPoints->distPoints) * count,
+ sizeof(*crlDistPoints->distPoints) * (count + 1));
+ } else {
+ crlDistPoints->distPoints =
+ PORT_ArenaZAlloc(arena, sizeof(*crlDistPoints->distPoints) * (count + 1));
+ }
+ if (crlDistPoints->distPoints == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+
+ crlDistPoints->distPoints[count] = current;
+ ++count;
+ if (GetYesNo("Enter another value for the CRLDistributionPoint "
+ "extension [y/N]?") == 0) {
+ /* Add null to the end to mark end of data */
+ crlDistPoints->distPoints =
+ PORT_ArenaGrow(arena, crlDistPoints->distPoints,
+ sizeof(*crlDistPoints->distPoints) * count,
+ sizeof(*crlDistPoints->distPoints) * (count + 1));
+ crlDistPoints->distPoints[count] = NULL;
+ break;
+ }
+
+ } while (1);
+
+ if (rv == SECSuccess) {
+ PRBool yesNoAns = GetYesNo("Is this a critical extension [y/N]?");
+
+ rv = SECU_EncodeAndAddExtensionValue(arena, extHandle,
+ crlDistPoints, yesNoAns, SEC_OID_X509_CRL_DIST_POINTS,
+ (EXTEN_EXT_VALUE_ENCODER)CERT_EncodeCRLDistributionPoints);
+ }
+ if (arena)
+ PORT_FreeArena(arena, PR_FALSE);
+ return (rv);
+}
+
+static SECStatus
+AddPolicyConstraints(void *extHandle)
+{
+ CERTCertificatePolicyConstraints *policyConstr;
+ PLArenaPool *arena = NULL;
+ SECStatus rv = SECSuccess;
+ SECItem *item, *dummy;
+ char buffer[512];
+ int value;
+ PRBool yesNoAns;
+ PRBool skipExt = PR_TRUE;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ SECU_PrintError(progName, "out of memory");
+ return SECFailure;
+ }
+
+ policyConstr = PORT_ArenaZNew(arena, CERTCertificatePolicyConstraints);
+ if (policyConstr == NULL) {
+ SECU_PrintError(progName, "out of memory");
+ goto loser;
+ }
+
+ if (PrintChoicesAndGetAnswer("for requireExplicitPolicy enter the number "
+ "of certs in path\nbefore explicit policy is required\n"
+ "(press Enter to omit)",
+ buffer, sizeof(buffer)) == SECFailure) {
+ goto loser;
+ }
+
+ if (PORT_Strlen(buffer)) {
+ value = PORT_Atoi(buffer);
+ if (value < 0) {
+ goto loser;
+ }
+ item = &policyConstr->explicitPolicySkipCerts;
+ dummy = SEC_ASN1EncodeInteger(arena, item, value);
+ if (!dummy) {
+ goto loser;
+ }
+ skipExt = PR_FALSE;
+ }
+
+ if (PrintChoicesAndGetAnswer("for inihibitPolicyMapping enter "
+ "the number of certs in path\n"
+ "after which policy mapping is not allowed\n"
+ "(press Enter to omit)",
+ buffer, sizeof(buffer)) == SECFailure) {
+ goto loser;
+ }
+
+ if (PORT_Strlen(buffer)) {
+ value = PORT_Atoi(buffer);
+ if (value < 0) {
+ goto loser;
+ }
+ item = &policyConstr->inhibitMappingSkipCerts;
+ dummy = SEC_ASN1EncodeInteger(arena, item, value);
+ if (!dummy) {
+ goto loser;
+ }
+ skipExt = PR_FALSE;
+ }
+
+ if (!skipExt) {
+ yesNoAns = GetYesNo("Is this a critical extension [y/N]?");
+
+ rv = SECU_EncodeAndAddExtensionValue(arena, extHandle, policyConstr,
+ yesNoAns, SEC_OID_X509_POLICY_CONSTRAINTS,
+ (EXTEN_EXT_VALUE_ENCODER)CERT_EncodePolicyConstraintsExtension);
+ } else {
+ fprintf(stdout, "Policy Constraint extensions must contain "
+ "at least one policy field\n");
+ rv = SECFailure;
+ }
+
+loser:
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+ return (rv);
+}
+
+static SECStatus
+AddInhibitAnyPolicy(void *extHandle)
+{
+ CERTCertificateInhibitAny certInhibitAny;
+ PLArenaPool *arena = NULL;
+ SECStatus rv = SECSuccess;
+ SECItem *item, *dummy;
+ char buffer[10];
+ int value;
+ PRBool yesNoAns;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ SECU_PrintError(progName, "out of memory");
+ return SECFailure;
+ }
+
+ if (PrintChoicesAndGetAnswer("Enter the number of certs in the path "
+ "permitted to use anyPolicy.\n"
+ "(press Enter for 0)",
+ buffer, sizeof(buffer)) == SECFailure) {
+ goto loser;
+ }
+
+ item = &certInhibitAny.inhibitAnySkipCerts;
+ value = PORT_Atoi(buffer);
+ if (value < 0) {
+ goto loser;
+ }
+ dummy = SEC_ASN1EncodeInteger(arena, item, value);
+ if (!dummy) {
+ goto loser;
+ }
+
+ yesNoAns = GetYesNo("Is this a critical extension [y/N]?");
+
+ rv = SECU_EncodeAndAddExtensionValue(arena, extHandle, &certInhibitAny,
+ yesNoAns, SEC_OID_X509_INHIBIT_ANY_POLICY,
+ (EXTEN_EXT_VALUE_ENCODER)CERT_EncodeInhibitAnyExtension);
+loser:
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+ return (rv);
+}
+
+static SECStatus
+AddPolicyMappings(void *extHandle)
+{
+ CERTPolicyMap **policyMapArr = NULL;
+ CERTPolicyMap *current;
+ PLArenaPool *arena = NULL;
+ SECStatus rv = SECSuccess;
+ int count = 0;
+ char buffer[512];
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ SECU_PrintError(progName, "out of memory");
+ return SECFailure;
+ }
+
+ do {
+ if (PrintChoicesAndGetAnswer("Enter an Object Identifier (dotted "
+ "decimal format) for Issuer Domain Policy",
+ buffer, sizeof(buffer)) == SECFailure) {
+ GEN_BREAK(SECFailure);
+ }
+
+ current = PORT_ArenaZNew(arena, CERTPolicyMap);
+ if (current == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+
+ rv = SEC_StringToOID(arena, ¤t->issuerDomainPolicy, buffer, 0);
+ if (rv == SECFailure) {
+ GEN_BREAK(SECFailure);
+ }
+
+ if (PrintChoicesAndGetAnswer("Enter an Object Identifier for "
+ "Subject Domain Policy",
+ buffer, sizeof(buffer)) == SECFailure) {
+ GEN_BREAK(SECFailure);
+ }
+
+ rv = SEC_StringToOID(arena, ¤t->subjectDomainPolicy, buffer, 0);
+ if (rv == SECFailure) {
+ GEN_BREAK(SECFailure);
+ }
+
+ if (policyMapArr == NULL) {
+ policyMapArr = PORT_ArenaZNew(arena, CERTPolicyMap *);
+ if (policyMapArr == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+ }
+
+ policyMapArr = PORT_ArenaGrow(arena, policyMapArr,
+ sizeof(current) * count,
+ sizeof(current) * (count + 1));
+ if (policyMapArr == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+
+ policyMapArr[count] = current;
+ ++count;
+
+ if (!GetYesNo("Enter another Policy Mapping [y/N]")) {
+ /* Add null to the end to mark end of data */
+ policyMapArr = PORT_ArenaGrow(arena, policyMapArr,
+ sizeof(current) * count,
+ sizeof(current) * (count + 1));
+ if (policyMapArr == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+ policyMapArr[count] = NULL;
+ break;
+ }
+
+ } while (1);
+
+ if (rv == SECSuccess) {
+ CERTCertificatePolicyMappings mappings;
+ PRBool yesNoAns = GetYesNo("Is this a critical extension [y/N]?");
+
+ mappings.arena = arena;
+ mappings.policyMaps = policyMapArr;
+ rv = SECU_EncodeAndAddExtensionValue(arena, extHandle, &mappings,
+ yesNoAns, SEC_OID_X509_POLICY_MAPPINGS,
+ (EXTEN_EXT_VALUE_ENCODER)CERT_EncodePolicyMappingExtension);
+ }
+ if (arena)
+ PORT_FreeArena(arena, PR_FALSE);
+ return (rv);
+}
+
+enum PoliciQualifierEnum {
+ cpsPointer = 1,
+ userNotice = 2
+};
+
+static CERTPolicyQualifier **
+RequestPolicyQualifiers(PLArenaPool *arena, SECItem *policyID)
+{
+ CERTPolicyQualifier **policyQualifArr = NULL;
+ CERTPolicyQualifier *current;
+ SECStatus rv = SECSuccess;
+ int count = 0;
+ char buffer[512];
+ void *mark;
+ SECOidData *oid = NULL;
+ int intValue = 0;
+ int inCount = 0;
+
+ PORT_Assert(arena);
+ mark = PORT_ArenaMark(arena);
+ do {
+ current = PORT_ArenaZNew(arena, CERTPolicyQualifier);
+ if (current == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+
+ /* Get the accessMethod fields */
+ SECU_PrintObjectID(stdout, policyID,
+ "Choose the type of qualifier for policy", 0);
+
+ if (PrintChoicesAndGetAnswer(
+ "\t1 - CPS Pointer qualifier\n"
+ "\t2 - User notice qualifier\n"
+ "\tAny other number to finish\n"
+ "\t\tChoice: ",
+ buffer, sizeof(buffer)) == SECFailure) {
+ GEN_BREAK(SECFailure);
+ }
+ intValue = PORT_Atoi(buffer);
+ switch (intValue) {
+ case cpsPointer: {
+ SECItem input;
+
+ oid = SECOID_FindOIDByTag(SEC_OID_PKIX_CPS_POINTER_QUALIFIER);
+ if (PrintChoicesAndGetAnswer("Enter CPS pointer URI: ",
+ buffer, sizeof(buffer)) == SECFailure) {
+ GEN_BREAK(SECFailure);
+ }
+ input.len = PORT_Strlen(buffer);
+ input.data = (void *)PORT_ArenaStrdup(arena, buffer);
+ if (input.data == NULL ||
+ SEC_ASN1EncodeItem(arena, ¤t->qualifierValue, &input,
+ SEC_ASN1_GET(SEC_IA5StringTemplate)) == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+ break;
+ }
+ case userNotice: {
+ SECItem **noticeNumArr;
+ CERTUserNotice *notice = PORT_ArenaZNew(arena, CERTUserNotice);
+ if (!notice) {
+ GEN_BREAK(SECFailure);
+ }
+
+ oid = SECOID_FindOIDByTag(SEC_OID_PKIX_USER_NOTICE_QUALIFIER);
+
+ if (GetYesNo("\t add a User Notice reference? [y/N]")) {
+
+ if (PrintChoicesAndGetAnswer("Enter user organization string: ",
+ buffer, sizeof(buffer)) ==
+ SECFailure) {
+ GEN_BREAK(SECFailure);
+ }
+
+ notice->noticeReference.organization.type = siAsciiString;
+ notice->noticeReference.organization.len =
+ PORT_Strlen(buffer);
+ notice->noticeReference.organization.data =
+ (void *)PORT_ArenaStrdup(arena, buffer);
+
+ noticeNumArr = PORT_ArenaZNewArray(arena, SECItem *, 2);
+ if (!noticeNumArr) {
+ GEN_BREAK(SECFailure);
+ }
+
+ do {
+ SECItem *noticeNum;
+
+ noticeNum = PORT_ArenaZNew(arena, SECItem);
+
+ if (PrintChoicesAndGetAnswer(
+ "Enter User Notice reference number "
+ "(or -1 to quit): ",
+ buffer, sizeof(buffer)) == SECFailure) {
+ GEN_BREAK(SECFailure);
+ }
+
+ intValue = PORT_Atoi(buffer);
+ if (noticeNum == NULL) {
+ if (intValue < 0) {
+ fprintf(stdout, "a noticeReference must have at "
+ "least one reference number\n");
+ GEN_BREAK(SECFailure);
+ }
+ } else {
+ if (intValue >= 0) {
+ noticeNumArr = PORT_ArenaGrow(arena, noticeNumArr,
+ sizeof(current) *
+ inCount,
+ sizeof(current) *
+ (inCount + 1));
+ if (noticeNumArr == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+ } else {
+ break;
+ }
+ }
+ if (!SEC_ASN1EncodeInteger(arena, noticeNum, intValue)) {
+ GEN_BREAK(SECFailure);
+ }
+ noticeNumArr[inCount++] = noticeNum;
+ noticeNumArr[inCount] = NULL;
+
+ } while (1);
+ if (rv == SECFailure) {
+ GEN_BREAK(SECFailure);
+ }
+ notice->noticeReference.noticeNumbers = noticeNumArr;
+ rv = CERT_EncodeNoticeReference(arena, ¬ice->noticeReference,
+ ¬ice->derNoticeReference);
+ if (rv == SECFailure) {
+ GEN_BREAK(SECFailure);
+ }
+ }
+ if (GetYesNo("\t EnterUser Notice explicit text? [y/N]")) {
+ /* Getting only 200 bytes - RFC limitation */
+ if (PrintChoicesAndGetAnswer(
+ "\t", buffer, 200) == SECFailure) {
+ GEN_BREAK(SECFailure);
+ }
+ notice->displayText.type = siAsciiString;
+ notice->displayText.len = PORT_Strlen(buffer);
+ notice->displayText.data =
+ (void *)PORT_ArenaStrdup(arena, buffer);
+ if (notice->displayText.data == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+ }
+
+ rv = CERT_EncodeUserNotice(arena, notice, ¤t->qualifierValue);
+ if (rv == SECFailure) {
+ GEN_BREAK(SECFailure);
+ }
+
+ break;
+ }
+ }
+ if (rv == SECFailure || oid == NULL ||
+ SECITEM_CopyItem(arena, ¤t->qualifierID, &oid->oid) ==
+ SECFailure) {
+ GEN_BREAK(SECFailure);
+ }
+
+ if (!policyQualifArr) {
+ policyQualifArr = PORT_ArenaZNew(arena, CERTPolicyQualifier *);
+ } else {
+ policyQualifArr = PORT_ArenaGrow(arena, policyQualifArr,
+ sizeof(current) * count,
+ sizeof(current) * (count + 1));
+ }
+ if (policyQualifArr == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+
+ policyQualifArr[count] = current;
+ ++count;
+
+ if (!GetYesNo("Enter another policy qualifier [y/N]")) {
+ /* Add null to the end to mark end of data */
+ policyQualifArr = PORT_ArenaGrow(arena, policyQualifArr,
+ sizeof(current) * count,
+ sizeof(current) * (count + 1));
+ if (policyQualifArr == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+ policyQualifArr[count] = NULL;
+ break;
+ }
+
+ } while (1);
+
+ if (rv != SECSuccess) {
+ PORT_ArenaRelease(arena, mark);
+ policyQualifArr = NULL;
+ }
+ return (policyQualifArr);
+}
+
+static SECStatus
+AddCertPolicies(void *extHandle)
+{
+ CERTPolicyInfo **certPoliciesArr = NULL;
+ CERTPolicyInfo *current;
+ PLArenaPool *arena = NULL;
+ SECStatus rv = SECSuccess;
+ int count = 0;
+ char buffer[512];
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ SECU_PrintError(progName, "out of memory");
+ return SECFailure;
+ }
+
+ do {
+ current = PORT_ArenaZNew(arena, CERTPolicyInfo);
+ if (current == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+
+ if (PrintChoicesAndGetAnswer("Enter a CertPolicy Object Identifier "
+ "(dotted decimal format)\n"
+ "or \"any\" for AnyPolicy:",
+ buffer, sizeof(buffer)) == SECFailure) {
+ GEN_BREAK(SECFailure);
+ }
+
+ if (strncmp(buffer, "any", 3) == 0) {
+ /* use string version of X509_CERTIFICATE_POLICIES.anyPolicy */
+ strcpy(buffer, "OID.2.5.29.32.0");
+ }
+ rv = SEC_StringToOID(arena, ¤t->policyID, buffer, 0);
+
+ if (rv == SECFailure) {
+ GEN_BREAK(SECFailure);
+ }
+
+ current->policyQualifiers =
+ RequestPolicyQualifiers(arena, ¤t->policyID);
+
+ if (!certPoliciesArr) {
+ certPoliciesArr = PORT_ArenaZNew(arena, CERTPolicyInfo *);
+ } else {
+ certPoliciesArr = PORT_ArenaGrow(arena, certPoliciesArr,
+ sizeof(current) * count,
+ sizeof(current) * (count + 1));
+ }
+ if (certPoliciesArr == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+
+ certPoliciesArr[count] = current;
+ ++count;
+
+ if (!GetYesNo("Enter another PolicyInformation field [y/N]?")) {
+ /* Add null to the end to mark end of data */
+ certPoliciesArr = PORT_ArenaGrow(arena, certPoliciesArr,
+ sizeof(current) * count,
+ sizeof(current) * (count + 1));
+ if (certPoliciesArr == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+ certPoliciesArr[count] = NULL;
+ break;
+ }
+
+ } while (1);
+
+ if (rv == SECSuccess) {
+ CERTCertificatePolicies policies;
+ PRBool yesNoAns = GetYesNo("Is this a critical extension [y/N]?");
+
+ policies.arena = arena;
+ policies.policyInfos = certPoliciesArr;
+
+ rv = SECU_EncodeAndAddExtensionValue(arena, extHandle, &policies,
+ yesNoAns, SEC_OID_X509_CERTIFICATE_POLICIES,
+ (EXTEN_EXT_VALUE_ENCODER)CERT_EncodeCertPoliciesExtension);
+ }
+ if (arena)
+ PORT_FreeArena(arena, PR_FALSE);
+ return (rv);
+}
+
+enum AuthInfoAccessTypesEnum {
+ caIssuers = 1,
+ ocsp = 2
+};
+
+enum SubjInfoAccessTypesEnum {
+ caRepository = 1,
+ timeStamping = 2
+};
+
+/* Encode and add an AIA or SIA extension */
+static SECStatus
+AddInfoAccess(void *extHandle, PRBool addSIAExt, PRBool isCACert)
+{
+ CERTAuthInfoAccess **infoAccArr = NULL;
+ CERTAuthInfoAccess *current;
+ PLArenaPool *arena = NULL;
+ SECStatus rv = SECSuccess;
+ int count = 0;
+ char buffer[512];
+ SECOidData *oid = NULL;
+ int intValue = 0;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ SECU_PrintError(progName, "out of memory");
+ return SECFailure;
+ }
+
+ do {
+ current = NULL;
+ current = PORT_ArenaZNew(arena, CERTAuthInfoAccess);
+ if (current == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+
+ /* Get the accessMethod fields */
+ if (addSIAExt) {
+ if (isCACert) {
+ puts("Adding \"CA Repository\" access method type for "
+ "Subject Information Access extension:\n");
+ intValue = caRepository;
+ } else {
+ puts("Adding \"Time Stamping Services\" access method type for "
+ "Subject Information Access extension:\n");
+ intValue = timeStamping;
+ }
+ } else {
+ if (PrintChoicesAndGetAnswer("Enter access method type "
+ "for Authority Information Access extension:\n"
+ "\t1 - CA Issuers\n\t2 - OCSP\n\tAny"
+ "other number to finish\n\tChoice",
+ buffer, sizeof(buffer)) !=
+ SECSuccess) {
+ GEN_BREAK(SECFailure);
+ }
+ intValue = PORT_Atoi(buffer);
+ }
+ if (addSIAExt) {
+ switch (intValue) {
+ case caRepository:
+ oid = SECOID_FindOIDByTag(SEC_OID_PKIX_CA_REPOSITORY);
+ break;
+
+ case timeStamping:
+ oid = SECOID_FindOIDByTag(SEC_OID_PKIX_TIMESTAMPING);
+ break;
+ }
+ } else {
+ switch (intValue) {
+ case caIssuers:
+ oid = SECOID_FindOIDByTag(SEC_OID_PKIX_CA_ISSUERS);
+ break;
+
+ case ocsp:
+ oid = SECOID_FindOIDByTag(SEC_OID_PKIX_OCSP);
+ break;
+ }
+ }
+ if (oid == NULL ||
+ SECITEM_CopyItem(arena, ¤t->method, &oid->oid) ==
+ SECFailure) {
+ GEN_BREAK(SECFailure);
+ }
+
+ current->location = CreateGeneralName(arena);
+ if (!current->location) {
+ GEN_BREAK(SECFailure);
+ }
+
+ if (infoAccArr == NULL) {
+ infoAccArr = PORT_ArenaZNew(arena, CERTAuthInfoAccess *);
+ } else {
+ infoAccArr = PORT_ArenaGrow(arena, infoAccArr,
+ sizeof(current) * count,
+ sizeof(current) * (count + 1));
+ }
+ if (infoAccArr == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+
+ infoAccArr[count] = current;
+ ++count;
+
+ PR_snprintf(buffer, sizeof(buffer), "Add another location to the %s"
+ " Information Access extension [y/N]",
+ (addSIAExt) ? "Subject" : "Authority");
+
+ if (GetYesNo(buffer) == 0) {
+ /* Add null to the end to mark end of data */
+ infoAccArr = PORT_ArenaGrow(arena, infoAccArr,
+ sizeof(current) * count,
+ sizeof(current) * (count + 1));
+ if (infoAccArr == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+ infoAccArr[count] = NULL;
+ break;
+ }
+
+ } while (1);
+
+ if (rv == SECSuccess) {
+ int oidIdent = SEC_OID_X509_AUTH_INFO_ACCESS;
+
+ PRBool yesNoAns = GetYesNo("Is this a critical extension [y/N]?");
+
+ if (addSIAExt) {
+ oidIdent = SEC_OID_X509_SUBJECT_INFO_ACCESS;
+ }
+ rv = SECU_EncodeAndAddExtensionValue(arena, extHandle, infoAccArr,
+ yesNoAns, oidIdent,
+ (EXTEN_EXT_VALUE_ENCODER)CERT_EncodeInfoAccessExtension);
+ }
+ if (arena)
+ PORT_FreeArena(arena, PR_FALSE);
+ return (rv);
+}
+
+/* Example of valid input:
+ * 1.2.3.4:critical:/tmp/abc,5.6.7.8:not-critical:/tmp/xyz
+ */
+static SECStatus
+parseNextGenericExt(const char *nextExtension, const char **oid, int *oidLen,
+ const char **crit, int *critLen,
+ const char **filename, int *filenameLen,
+ const char **next)
+{
+ const char *nextColon;
+ const char *nextComma;
+ const char *iter = nextExtension;
+
+ if (!iter || !*iter)
+ return SECFailure;
+
+ /* Require colons at earlier positions than nextComma (or end of string ) */
+ nextComma = strchr(iter, ',');
+
+ *oid = iter;
+ nextColon = strchr(iter, ':');
+ if (!nextColon || (nextComma && nextColon > nextComma))
+ return SECFailure;
+ *oidLen = (nextColon - *oid);
+
+ if (!*oidLen)
+ return SECFailure;
+
+ iter = nextColon;
+ ++iter;
+
+ *crit = iter;
+ nextColon = strchr(iter, ':');
+ if (!nextColon || (nextComma && nextColon > nextComma))
+ return SECFailure;
+ *critLen = (nextColon - *crit);
+
+ if (!*critLen)
+ return SECFailure;
+
+ iter = nextColon;
+ ++iter;
+
+ *filename = iter;
+ if (nextComma) {
+ *filenameLen = (nextComma - *filename);
+ iter = nextComma;
+ ++iter;
+ *next = iter;
+ } else {
+ *filenameLen = strlen(*filename);
+ *next = NULL;
+ }
+
+ if (!*filenameLen)
+ return SECFailure;
+
+ return SECSuccess;
+}
+
+SECStatus
+AddExtensions(void *extHandle, const char *emailAddrs, const char *dnsNames,
+ certutilExtnList extList, const char *extGeneric)
+{
+ PLArenaPool *arena;
+ SECStatus rv = SECSuccess;
+ char *errstring = NULL;
+ const char *nextExtension = NULL;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (arena == NULL) {
+ return SECFailure;
+ }
+
+ do {
+ /* Add key usage extension */
+ if (extList[ext_keyUsage].activated) {
+ rv = AddKeyUsage(extHandle, extList[ext_keyUsage].arg);
+ if (rv) {
+ errstring = "KeyUsage";
+ break;
+ }
+ }
+
+ /* Add extended key usage extension */
+ if (extList[ext_extKeyUsage].activated) {
+ rv = AddExtKeyUsage(extHandle, extList[ext_extKeyUsage].arg);
+ if (rv) {
+ errstring = "ExtendedKeyUsage";
+ break;
+ }
+ }
+
+ /* Add basic constraint extension */
+ if (extList[ext_basicConstraint].activated) {
+ rv = AddBasicConstraint(arena, extHandle);
+ if (rv) {
+ errstring = "BasicConstraint";
+ break;
+ }
+ }
+
+ /* Add name constraints extension */
+ if (extList[ext_nameConstraints].activated) {
+ rv = AddNameConstraints(extHandle);
+ if (rv) {
+ errstring = "NameConstraints";
+ break;
+ }
+ }
+
+ if (extList[ext_authorityKeyID].activated) {
+ rv = AddAuthKeyID(extHandle);
+ if (rv) {
+ errstring = "AuthorityKeyID";
+ break;
+ }
+ }
+
+ if (extList[ext_subjectKeyID].activated) {
+ rv = AddSubjKeyID(extHandle);
+ if (rv) {
+ errstring = "SubjectKeyID";
+ break;
+ }
+ }
+
+ if (extList[ext_CRLDistPts].activated) {
+ rv = AddCrlDistPoint(extHandle);
+ if (rv) {
+ errstring = "CRLDistPoints";
+ break;
+ }
+ }
+
+ if (extList[ext_NSCertType].activated) {
+ rv = AddNscpCertType(extHandle, extList[ext_NSCertType].arg);
+ if (rv) {
+ errstring = "NSCertType";
+ break;
+ }
+ }
+
+ if (extList[ext_authInfoAcc].activated ||
+ extList[ext_subjInfoAcc].activated) {
+ rv = AddInfoAccess(extHandle, extList[ext_subjInfoAcc].activated,
+ extList[ext_basicConstraint].activated);
+ if (rv) {
+ errstring = "InformationAccess";
+ break;
+ }
+ }
+
+ if (extList[ext_certPolicies].activated) {
+ rv = AddCertPolicies(extHandle);
+ if (rv) {
+ errstring = "Policies";
+ break;
+ }
+ }
+
+ if (extList[ext_policyMappings].activated) {
+ rv = AddPolicyMappings(extHandle);
+ if (rv) {
+ errstring = "PolicyMappings";
+ break;
+ }
+ }
+
+ if (extList[ext_policyConstr].activated) {
+ rv = AddPolicyConstraints(extHandle);
+ if (rv) {
+ errstring = "PolicyConstraints";
+ break;
+ }
+ }
+
+ if (extList[ext_inhibitAnyPolicy].activated) {
+ rv = AddInhibitAnyPolicy(extHandle);
+ if (rv) {
+ errstring = "InhibitAnyPolicy";
+ break;
+ }
+ }
+
+ if (emailAddrs || dnsNames || extList[ext_subjectAltName].activated) {
+ CERTGeneralName *namelist = NULL;
+ SECItem item = { 0, NULL, 0 };
+
+ rv = SECSuccess;
+
+ if (emailAddrs) {
+ rv |= AddEmailSubjectAlt(arena, &namelist, emailAddrs);
+ }
+
+ if (dnsNames) {
+ rv |= AddDNSSubjectAlt(arena, &namelist, dnsNames);
+ }
+
+ if (extList[ext_subjectAltName].activated) {
+ rv |= AddGeneralSubjectAlt(arena, &namelist,
+ extList[ext_subjectAltName].arg);
+ }
+
+ if (rv == SECSuccess) {
+ rv = CERT_EncodeAltNameExtension(arena, namelist, &item);
+ if (rv == SECSuccess) {
+ rv = CERT_AddExtension(extHandle,
+ SEC_OID_X509_SUBJECT_ALT_NAME,
+ &item, PR_FALSE, PR_TRUE);
+ }
+ }
+ if (rv) {
+ errstring = "SubjectAltName";
+ break;
+ }
+ }
+ } while (0);
+
+ PORT_FreeArena(arena, PR_FALSE);
+
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "Problem creating %s extension", errstring);
+ }
+
+ nextExtension = extGeneric;
+ while (nextExtension && *nextExtension) {
+ SECItem oid_item, value;
+ PRBool isCritical;
+ const char *oid, *crit, *filename, *next;
+ int oidLen, critLen, filenameLen;
+ PRFileDesc *inFile = NULL;
+ char *zeroTerminatedFilename = NULL;
+
+ rv = parseNextGenericExt(nextExtension, &oid, &oidLen, &crit, &critLen,
+ &filename, &filenameLen, &next);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName,
+ "error parsing generic extension parameter %s",
+ nextExtension);
+ break;
+ }
+ oid_item.data = NULL;
+ oid_item.len = 0;
+ rv = GetOidFromString(NULL, &oid_item, oid, oidLen);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "malformed extension OID %s", nextExtension);
+ break;
+ }
+ if (!strncmp("critical", crit, critLen)) {
+ isCritical = PR_TRUE;
+ } else if (!strncmp("not-critical", crit, critLen)) {
+ isCritical = PR_FALSE;
+ } else {
+ rv = SECFailure;
+ SECU_PrintError(progName, "expected 'critical' or 'not-critical'");
+ break;
+ }
+ zeroTerminatedFilename = PL_strndup(filename, filenameLen);
+ if (!zeroTerminatedFilename) {
+ rv = SECFailure;
+ SECU_PrintError(progName, "out of memory");
+ break;
+ }
+ rv = SECFailure;
+ inFile = PR_Open(zeroTerminatedFilename, PR_RDONLY, 0);
+ if (inFile) {
+ rv = SECU_ReadDERFromFile(&value, inFile, PR_FALSE, PR_FALSE);
+ PR_Close(inFile);
+ inFile = NULL;
+ }
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "unable to read file %s",
+ zeroTerminatedFilename);
+ }
+ PL_strfree(zeroTerminatedFilename);
+ if (rv != SECSuccess) {
+ break;
+ }
+ rv = CERT_AddExtensionByOID(extHandle, &oid_item, &value, isCritical,
+ PR_TRUE /*copyData*/);
+ SECITEM_FreeItem(&value, PR_FALSE);
+ SECITEM_FreeItem(&oid_item, PR_FALSE);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "failed to add extension %s", nextExtension);
+ break;
+ }
+ nextExtension = next;
+ }
+
+ return rv;
+}
diff --git a/nss/cmd/certutil/certutil.c b/nss/cmd/certutil/certutil.c
new file mode 100644
index 0000000..24acdbc
--- /dev/null
+++ b/nss/cmd/certutil/certutil.c
@@ -0,0 +1,3707 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+** certutil.c
+**
+** utility for managing certificates and the cert database
+**
+*/
+#include
+#include
+#include
+
+#if defined(WIN32)
+#include "fcntl.h"
+#include "io.h"
+#endif
+
+#include "secutil.h"
+
+#if defined(XP_UNIX)
+#include
+#endif
+
+#include "nspr.h"
+#include "prtypes.h"
+#include "prtime.h"
+#include "prlong.h"
+
+#include "pk11func.h"
+#include "secasn1.h"
+#include "cert.h"
+#include "cryptohi.h"
+#include "secoid.h"
+#include "certdb.h"
+#include "nss.h"
+#include "certutil.h"
+
+#define MIN_KEY_BITS 512
+/* MAX_KEY_BITS should agree with MAX_RSA_MODULUS in freebl */
+#define MAX_KEY_BITS 8192
+#define DEFAULT_KEY_BITS 2048
+
+#define GEN_BREAK(e) \
+ rv = e; \
+ break;
+
+char *progName;
+
+static CERTCertificateRequest *
+GetCertRequest(const SECItem *reqDER, void *pwarg)
+{
+ CERTCertificateRequest *certReq = NULL;
+ CERTSignedData signedData;
+ PLArenaPool *arena = NULL;
+ SECStatus rv;
+
+ do {
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (arena == NULL) {
+ GEN_BREAK(SECFailure);
+ }
+
+ certReq = (CERTCertificateRequest *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificateRequest));
+ if (!certReq) {
+ GEN_BREAK(SECFailure);
+ }
+ certReq->arena = arena;
+
+ /* Since cert request is a signed data, must decode to get the inner
+ data
+ */
+ PORT_Memset(&signedData, 0, sizeof(signedData));
+ rv = SEC_ASN1DecodeItem(arena, &signedData,
+ SEC_ASN1_GET(CERT_SignedDataTemplate), reqDER);
+ if (rv) {
+ break;
+ }
+ rv = SEC_ASN1DecodeItem(arena, certReq,
+ SEC_ASN1_GET(CERT_CertificateRequestTemplate), &signedData.data);
+ if (rv) {
+ break;
+ }
+ rv = CERT_VerifySignedDataWithPublicKeyInfo(&signedData,
+ &certReq->subjectPublicKeyInfo, pwarg);
+ } while (0);
+
+ if (rv) {
+ SECU_PrintError(progName, "bad certificate request\n");
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+ certReq = NULL;
+ }
+
+ return certReq;
+}
+
+static SECStatus
+AddCert(PK11SlotInfo *slot, CERTCertDBHandle *handle, char *name, char *trusts,
+ const SECItem *certDER, PRBool emailcert, void *pwdata)
+{
+ CERTCertTrust *trust = NULL;
+ CERTCertificate *cert = NULL;
+ SECStatus rv;
+
+ do {
+ /* Read in an ASCII cert and return a CERTCertificate */
+ cert = CERT_DecodeCertFromPackage((char *)certDER->data, certDER->len);
+ if (!cert) {
+ SECU_PrintError(progName, "could not decode certificate");
+ GEN_BREAK(SECFailure);
+ }
+
+ /* Create a cert trust */
+ trust = (CERTCertTrust *)PORT_ZAlloc(sizeof(CERTCertTrust));
+ if (!trust) {
+ SECU_PrintError(progName, "unable to allocate cert trust");
+ GEN_BREAK(SECFailure);
+ }
+
+ rv = CERT_DecodeTrustString(trust, trusts);
+ if (rv) {
+ SECU_PrintError(progName, "unable to decode trust string");
+ GEN_BREAK(SECFailure);
+ }
+
+ rv = PK11_ImportCert(slot, cert, CK_INVALID_HANDLE, name, PR_FALSE);
+ if (rv != SECSuccess) {
+ /* sigh, PK11_Import Cert and CERT_ChangeCertTrust should have
+ * been coded to take a password arg. */
+ if (PORT_GetError() == SEC_ERROR_TOKEN_NOT_LOGGED_IN) {
+ rv = PK11_Authenticate(slot, PR_TRUE, pwdata);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName,
+ "could not authenticate to token %s.",
+ PK11_GetTokenName(slot));
+ GEN_BREAK(SECFailure);
+ }
+ rv = PK11_ImportCert(slot, cert, CK_INVALID_HANDLE,
+ name, PR_FALSE);
+ }
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName,
+ "could not add certificate to token or database");
+ GEN_BREAK(SECFailure);
+ }
+ }
+
+ rv = CERT_ChangeCertTrust(handle, cert, trust);
+ if (rv != SECSuccess) {
+ if (PORT_GetError() == SEC_ERROR_TOKEN_NOT_LOGGED_IN) {
+ rv = PK11_Authenticate(slot, PR_TRUE, pwdata);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName,
+ "could not authenticate to token %s.",
+ PK11_GetTokenName(slot));
+ GEN_BREAK(SECFailure);
+ }
+ rv = CERT_ChangeCertTrust(handle, cert, trust);
+ }
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName,
+ "could not change trust on certificate");
+ GEN_BREAK(SECFailure);
+ }
+ }
+
+ if (emailcert) {
+ CERT_SaveSMimeProfile(cert, NULL, pwdata);
+ }
+
+ } while (0);
+
+ CERT_DestroyCertificate(cert);
+ PORT_Free(trust);
+
+ return rv;
+}
+
+static SECStatus
+CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType,
+ SECOidTag hashAlgTag, CERTName *subject, const char *phone, int ascii,
+ const char *emailAddrs, const char *dnsNames,
+ certutilExtnList extnList, const char *extGeneric,
+ PRBool pssCertificate, /*out*/ SECItem *result)
+{
+ CERTSubjectPublicKeyInfo *spki;
+ CERTCertificateRequest *cr;
+ SECItem *encoding;
+ SECOidTag signAlgTag;
+ SECStatus rv;
+ PLArenaPool *arena;
+ void *extHandle;
+ SECItem signedReq = { siBuffer, NULL, 0 };
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ SECU_PrintError(progName, "out of memory");
+ return SECFailure;
+ }
+
+ /* Create info about public key */
+ spki = SECKEY_CreateSubjectPublicKeyInfo(pubk);
+ if (!spki) {
+ PORT_FreeArena(arena, PR_FALSE);
+ SECU_PrintError(progName, "unable to create subject public key");
+ return SECFailure;
+ }
+
+ /* Change cert type to RSA-PSS, if desired. */
+ if (pssCertificate) {
+ spki->algorithm.parameters.data = NULL;
+ rv = SECOID_SetAlgorithmID(arena, &spki->algorithm,
+ SEC_OID_PKCS1_RSA_PSS_SIGNATURE, 0);
+ if (rv != SECSuccess) {
+ PORT_FreeArena(arena, PR_FALSE);
+ SECU_PrintError(progName, "unable to set algorithm ID");
+ return SECFailure;
+ }
+ }
+
+ /* Generate certificate request */
+ cr = CERT_CreateCertificateRequest(subject, spki, NULL);
+ SECKEY_DestroySubjectPublicKeyInfo(spki);
+ if (!cr) {
+ PORT_FreeArena(arena, PR_FALSE);
+ SECU_PrintError(progName, "unable to make certificate request");
+ return SECFailure;
+ }
+
+ extHandle = CERT_StartCertificateRequestAttributes(cr);
+ if (extHandle == NULL) {
+ PORT_FreeArena(arena, PR_FALSE);
+ CERT_DestroyCertificateRequest(cr);
+ return SECFailure;
+ }
+ if (AddExtensions(extHandle, emailAddrs, dnsNames, extnList, extGeneric) !=
+ SECSuccess) {
+ PORT_FreeArena(arena, PR_FALSE);
+ CERT_FinishExtensions(extHandle);
+ CERT_DestroyCertificateRequest(cr);
+ return SECFailure;
+ }
+ CERT_FinishExtensions(extHandle);
+ CERT_FinishCertificateRequestAttributes(cr);
+
+ /* Der encode the request */
+ encoding = SEC_ASN1EncodeItem(arena, NULL, cr,
+ SEC_ASN1_GET(CERT_CertificateRequestTemplate));
+ CERT_DestroyCertificateRequest(cr);
+ if (encoding == NULL) {
+ PORT_FreeArena(arena, PR_FALSE);
+ SECU_PrintError(progName, "der encoding of request failed");
+ return SECFailure;
+ }
+
+ /* Sign the request */
+ signAlgTag = SEC_GetSignatureAlgorithmOidTag(keyType, hashAlgTag);
+ if (signAlgTag == SEC_OID_UNKNOWN) {
+ PORT_FreeArena(arena, PR_FALSE);
+ SECU_PrintError(progName, "unknown Key or Hash type");
+ return SECFailure;
+ }
+
+ rv = SEC_DerSignData(arena, &signedReq, encoding->data, encoding->len,
+ privk, signAlgTag);
+ if (rv) {
+ PORT_FreeArena(arena, PR_FALSE);
+ SECU_PrintError(progName, "signing of data failed");
+ return SECFailure;
+ }
+
+ /* Encode request in specified format */
+ if (ascii) {
+ char *obuf;
+ char *header, *name, *email, *org, *state, *country;
+
+ obuf = BTOA_ConvertItemToAscii(&signedReq);
+ if (!obuf) {
+ goto oom;
+ }
+
+ name = CERT_GetCommonName(subject);
+ if (!name) {
+ name = PORT_Strdup("(not specified)");
+ }
+
+ if (!phone)
+ phone = "(not specified)";
+
+ email = CERT_GetCertEmailAddress(subject);
+ if (!email)
+ email = PORT_Strdup("(not specified)");
+
+ org = CERT_GetOrgName(subject);
+ if (!org)
+ org = PORT_Strdup("(not specified)");
+
+ state = CERT_GetStateName(subject);
+ if (!state)
+ state = PORT_Strdup("(not specified)");
+
+ country = CERT_GetCountryName(subject);
+ if (!country)
+ country = PORT_Strdup("(not specified)");
+
+ header = PR_smprintf(
+ "\nCertificate request generated by Netscape certutil\n"
+ "Phone: %s\n\n"
+ "Common Name: %s\n"
+ "Email: %s\n"
+ "Organization: %s\n"
+ "State: %s\n"
+ "Country: %s\n\n"
+ "%s\n",
+ phone, name, email, org, state, country, NS_CERTREQ_HEADER);
+
+ PORT_Free(name);
+ PORT_Free(email);
+ PORT_Free(org);
+ PORT_Free(state);
+ PORT_Free(country);
+
+ if (header) {
+ char *trailer = PR_smprintf("\n%s\n", NS_CERTREQ_TRAILER);
+ if (trailer) {
+ PRUint32 headerLen = PL_strlen(header);
+ PRUint32 obufLen = PL_strlen(obuf);
+ PRUint32 trailerLen = PL_strlen(trailer);
+ SECITEM_AllocItem(NULL, result,
+ headerLen + obufLen + trailerLen);
+ if (result->data) {
+ PORT_Memcpy(result->data, header, headerLen);
+ PORT_Memcpy(result->data + headerLen, obuf, obufLen);
+ PORT_Memcpy(result->data + headerLen + obufLen,
+ trailer, trailerLen);
+ }
+ PR_smprintf_free(trailer);
+ }
+ PR_smprintf_free(header);
+ }
+ PORT_Free(obuf);
+ } else {
+ (void)SECITEM_CopyItem(NULL, result, &signedReq);
+ }
+
+ if (!result->data) {
+ oom:
+ SECU_PrintError(progName, "out of memory");
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ rv = SECFailure;
+ }
+
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+static SECStatus
+ChangeTrustAttributes(CERTCertDBHandle *handle, PK11SlotInfo *slot,
+ char *name, char *trusts, void *pwdata)
+{
+ SECStatus rv;
+ CERTCertificate *cert;
+ CERTCertTrust *trust;
+
+ cert = CERT_FindCertByNicknameOrEmailAddr(handle, name);
+ if (!cert) {
+ SECU_PrintError(progName, "could not find certificate named \"%s\"",
+ name);
+ return SECFailure;
+ }
+
+ trust = (CERTCertTrust *)PORT_ZAlloc(sizeof(CERTCertTrust));
+ if (!trust) {
+ SECU_PrintError(progName, "unable to allocate cert trust");
+ return SECFailure;
+ }
+
+ /* This function only decodes these characters: pPwcTCu, */
+ rv = CERT_DecodeTrustString(trust, trusts);
+ if (rv) {
+ SECU_PrintError(progName, "unable to decode trust string");
+ return SECFailure;
+ }
+
+ /* CERT_ChangeCertTrust API does not have a way to pass in
+ * a context, so NSS can't prompt for the password if it needs to.
+ * check to see if the failure was token not logged in and
+ * log in if need be. */
+ rv = CERT_ChangeCertTrust(handle, cert, trust);
+ if (rv != SECSuccess) {
+ if (PORT_GetError() == SEC_ERROR_TOKEN_NOT_LOGGED_IN) {
+ rv = PK11_Authenticate(slot, PR_TRUE, pwdata);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "could not authenticate to token %s.",
+ PK11_GetTokenName(slot));
+ return SECFailure;
+ }
+ rv = CERT_ChangeCertTrust(handle, cert, trust);
+ }
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "unable to modify trust attributes");
+ return SECFailure;
+ }
+ }
+ CERT_DestroyCertificate(cert);
+ PORT_Free(trust);
+
+ return SECSuccess;
+}
+
+static SECStatus
+DumpChain(CERTCertDBHandle *handle, char *name, PRBool ascii)
+{
+ CERTCertificate *the_cert;
+ CERTCertificateList *chain;
+ int i, j;
+ the_cert = SECU_FindCertByNicknameOrFilename(handle, name,
+ ascii, NULL);
+ if (!the_cert) {
+ SECU_PrintError(progName, "Could not find: %s\n", name);
+ return SECFailure;
+ }
+ chain = CERT_CertChainFromCert(the_cert, 0, PR_TRUE);
+ CERT_DestroyCertificate(the_cert);
+ if (!chain) {
+ SECU_PrintError(progName, "Could not obtain chain for: %s\n", name);
+ return SECFailure;
+ }
+ for (i = chain->len - 1; i >= 0; i--) {
+ CERTCertificate *c;
+ c = CERT_FindCertByDERCert(handle, &chain->certs[i]);
+ for (j = i; j < chain->len - 1; j++) {
+ printf(" ");
+ }
+ if (c) {
+ printf("\"%s\" [%s]\n\n", c->nickname, c->subjectName);
+ CERT_DestroyCertificate(c);
+ } else {
+ printf("(null)\n\n");
+ }
+ }
+ CERT_DestroyCertificateList(chain);
+ return SECSuccess;
+}
+
+static SECStatus
+outputCertOrExtension(CERTCertificate *the_cert, PRBool raw, PRBool ascii,
+ SECItem *extensionOID, PRFileDesc *outfile)
+{
+ SECItem data;
+ PRInt32 numBytes;
+ SECStatus rv = SECFailure;
+ if (extensionOID) {
+ int i;
+ PRBool found = PR_FALSE;
+ for (i = 0; the_cert->extensions[i] != NULL; i++) {
+ CERTCertExtension *extension = the_cert->extensions[i];
+ if (SECITEM_CompareItem(&extension->id, extensionOID) == SECEqual) {
+ found = PR_TRUE;
+ numBytes = PR_Write(outfile, extension->value.data,
+ extension->value.len);
+ rv = SECSuccess;
+ if (numBytes != (PRInt32)extension->value.len) {
+ SECU_PrintSystemError(progName, "error writing extension");
+ rv = SECFailure;
+ }
+ break;
+ }
+ }
+ if (!found) {
+ SECU_PrintSystemError(progName, "extension not found");
+ rv = SECFailure;
+ }
+ } else {
+ data.data = the_cert->derCert.data;
+ data.len = the_cert->derCert.len;
+ if (ascii) {
+ PR_fprintf(outfile, "%s\n%s\n%s\n", NS_CERT_HEADER,
+ BTOA_DataToAscii(data.data, data.len), NS_CERT_TRAILER);
+ rv = SECSuccess;
+ } else if (raw) {
+ numBytes = PR_Write(outfile, data.data, data.len);
+ rv = SECSuccess;
+ if (numBytes != (PRInt32)data.len) {
+ SECU_PrintSystemError(progName, "error writing raw cert");
+ rv = SECFailure;
+ }
+ } else {
+ rv = SEC_PrintCertificateAndTrust(the_cert, "Certificate", NULL);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "problem printing certificate");
+ }
+ }
+ }
+ return rv;
+}
+
+static SECStatus
+listCerts(CERTCertDBHandle *handle, char *name, char *email,
+ PK11SlotInfo *slot, PRBool raw, PRBool ascii,
+ SECItem *extensionOID,
+ PRFileDesc *outfile, void *pwarg)
+{
+ SECStatus rv = SECFailure;
+ CERTCertList *certs;
+ CERTCertListNode *node;
+
+ /* List certs on a non-internal slot. */
+ if (!PK11_IsFriendly(slot) && PK11_NeedLogin(slot)) {
+ SECStatus newrv = PK11_Authenticate(slot, PR_TRUE, pwarg);
+ if (newrv != SECSuccess) {
+ SECU_PrintError(progName, "could not authenticate to token %s.",
+ PK11_GetTokenName(slot));
+ return SECFailure;
+ }
+ }
+ if (name) {
+ CERTCertificate *the_cert =
+ SECU_FindCertByNicknameOrFilename(handle, name, ascii, NULL);
+ if (!the_cert) {
+ SECU_PrintError(progName, "Could not find cert: %s\n", name);
+ return SECFailure;
+ }
+ /* Here, we have one cert with the desired nickname or email
+ * address. Now, we will attempt to get a list of ALL certs
+ * with the same subject name as the cert we have. That list
+ * should contain, at a minimum, the one cert we have already found.
+ * If the list of certs is empty (NULL), the libraries have failed.
+ */
+ certs = CERT_CreateSubjectCertList(NULL, handle, &the_cert->derSubject,
+ PR_Now(), PR_FALSE);
+ CERT_DestroyCertificate(the_cert);
+ if (!certs) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ SECU_PrintError(progName, "problem printing certificates");
+ return SECFailure;
+ }
+ for (node = CERT_LIST_HEAD(certs); !CERT_LIST_END(node, certs);
+ node = CERT_LIST_NEXT(node)) {
+ rv = outputCertOrExtension(node->cert, raw, ascii, extensionOID,
+ outfile);
+ if (rv != SECSuccess) {
+ break;
+ }
+ }
+ } else if (email) {
+ certs = PK11_FindCertsFromEmailAddress(email, NULL);
+ if (!certs) {
+ SECU_PrintError(progName,
+ "Could not find certificates for email address: %s\n",
+ email);
+ return SECFailure;
+ }
+ for (node = CERT_LIST_HEAD(certs); !CERT_LIST_END(node, certs);
+ node = CERT_LIST_NEXT(node)) {
+ rv = outputCertOrExtension(node->cert, raw, ascii, extensionOID,
+ outfile);
+ if (rv != SECSuccess) {
+ break;
+ }
+ }
+ } else {
+ certs = PK11_ListCertsInSlot(slot);
+ if (certs) {
+ for (node = CERT_LIST_HEAD(certs); !CERT_LIST_END(node, certs);
+ node = CERT_LIST_NEXT(node)) {
+ SECU_PrintCertNickname(node, stdout);
+ }
+ rv = SECSuccess;
+ }
+ }
+ if (certs) {
+ CERT_DestroyCertList(certs);
+ }
+ if (rv) {
+ SECU_PrintError(progName, "problem printing certificate nicknames");
+ return SECFailure;
+ }
+
+ return SECSuccess; /* not rv ?? */
+}
+
+static SECStatus
+ListCerts(CERTCertDBHandle *handle, char *nickname, char *email,
+ PK11SlotInfo *slot, PRBool raw, PRBool ascii,
+ SECItem *extensionOID,
+ PRFileDesc *outfile, secuPWData *pwdata)
+{
+ SECStatus rv;
+
+ if (!ascii && !raw && !nickname && !email) {
+ PR_fprintf(outfile, "\n%-60s %-5s\n%-60s %-5s\n\n",
+ "Certificate Nickname", "Trust Attributes", "",
+ "SSL,S/MIME,JAR/XPI");
+ }
+ if (slot == NULL) {
+ CERTCertList *list;
+ CERTCertListNode *node;
+
+ list = PK11_ListCerts(PK11CertListAll, pwdata);
+ for (node = CERT_LIST_HEAD(list); !CERT_LIST_END(node, list);
+ node = CERT_LIST_NEXT(node)) {
+ SECU_PrintCertNickname(node, stdout);
+ }
+ CERT_DestroyCertList(list);
+ return SECSuccess;
+ }
+ rv = listCerts(handle, nickname, email, slot, raw, ascii,
+ extensionOID, outfile, pwdata);
+ return rv;
+}
+
+static SECStatus
+DeleteCert(CERTCertDBHandle *handle, char *name)
+{
+ SECStatus rv;
+ CERTCertificate *cert;
+
+ cert = CERT_FindCertByNicknameOrEmailAddr(handle, name);
+ if (!cert) {
+ SECU_PrintError(progName, "could not find certificate named \"%s\"",
+ name);
+ return SECFailure;
+ }
+
+ rv = SEC_DeletePermCertificate(cert);
+ CERT_DestroyCertificate(cert);
+ if (rv) {
+ SECU_PrintError(progName, "unable to delete certificate");
+ }
+ return rv;
+}
+
+static SECStatus
+RenameCert(CERTCertDBHandle *handle, char *name, char *newName)
+{
+ SECStatus rv;
+ CERTCertificate *cert;
+
+ cert = CERT_FindCertByNicknameOrEmailAddr(handle, name);
+ if (!cert) {
+ SECU_PrintError(progName, "could not find certificate named \"%s\"",
+ name);
+ return SECFailure;
+ }
+
+ rv = __PK11_SetCertificateNickname(cert, newName);
+ CERT_DestroyCertificate(cert);
+ if (rv) {
+ SECU_PrintError(progName, "unable to rename certificate");
+ }
+ return rv;
+}
+
+static SECStatus
+ValidateCert(CERTCertDBHandle *handle, char *name, char *date,
+ char *certUsage, PRBool checkSig, PRBool logit,
+ PRBool ascii, secuPWData *pwdata)
+{
+ SECStatus rv;
+ CERTCertificate *cert = NULL;
+ PRTime timeBoundary;
+ SECCertificateUsage usage;
+ CERTVerifyLog reallog;
+ CERTVerifyLog *log = NULL;
+
+ if (!certUsage) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return (SECFailure);
+ }
+
+ switch (*certUsage) {
+ case 'O':
+ usage = certificateUsageStatusResponder;
+ break;
+ case 'L':
+ usage = certificateUsageSSLCA;
+ break;
+ case 'A':
+ usage = certificateUsageAnyCA;
+ break;
+ case 'Y':
+ usage = certificateUsageVerifyCA;
+ break;
+ case 'C':
+ usage = certificateUsageSSLClient;
+ break;
+ case 'V':
+ usage = certificateUsageSSLServer;
+ break;
+ case 'S':
+ usage = certificateUsageEmailSigner;
+ break;
+ case 'R':
+ usage = certificateUsageEmailRecipient;
+ break;
+ case 'J':
+ usage = certificateUsageObjectSigner;
+ break;
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return (SECFailure);
+ }
+ do {
+ cert = SECU_FindCertByNicknameOrFilename(handle, name, ascii,
+ NULL);
+ if (!cert) {
+ SECU_PrintError(progName, "could not find certificate named \"%s\"",
+ name);
+ GEN_BREAK(SECFailure)
+ }
+
+ if (date != NULL) {
+ rv = DER_AsciiToTime(&timeBoundary, date);
+ if (rv) {
+ SECU_PrintError(progName, "invalid input date");
+ GEN_BREAK(SECFailure)
+ }
+ } else {
+ timeBoundary = PR_Now();
+ }
+
+ if (logit) {
+ log = &reallog;
+
+ log->count = 0;
+ log->head = NULL;
+ log->tail = NULL;
+ log->arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (log->arena == NULL) {
+ SECU_PrintError(progName, "out of memory");
+ GEN_BREAK(SECFailure)
+ }
+ }
+
+ rv = CERT_VerifyCertificate(handle, cert, checkSig, usage,
+ timeBoundary, pwdata, log, &usage);
+ if (log) {
+ if (log->head == NULL) {
+ fprintf(stdout, "%s: certificate is valid\n", progName);
+ GEN_BREAK(SECSuccess)
+ } else {
+ char *name;
+ CERTVerifyLogNode *node;
+
+ node = log->head;
+ while (node) {
+ if (node->cert->nickname != NULL) {
+ name = node->cert->nickname;
+ } else {
+ name = node->cert->subjectName;
+ }
+ fprintf(stderr, "%s : %s\n", name,
+ SECU_Strerror(node->error));
+ CERT_DestroyCertificate(node->cert);
+ node = node->next;
+ }
+ }
+ } else {
+ if (rv != SECSuccess) {
+ PRErrorCode perr = PORT_GetError();
+ fprintf(stdout, "%s: certificate is invalid: %s\n",
+ progName, SECU_Strerror(perr));
+ GEN_BREAK(SECFailure)
+ }
+ fprintf(stdout, "%s: certificate is valid\n", progName);
+ GEN_BREAK(SECSuccess)
+ }
+ } while (0);
+
+ if (cert) {
+ CERT_DestroyCertificate(cert);
+ }
+
+ return (rv);
+}
+
+static PRBool
+ItemIsPrintableASCII(const SECItem *item)
+{
+ unsigned char *src = item->data;
+ unsigned int len = item->len;
+ while (len-- > 0) {
+ unsigned char uc = *src++;
+ if (uc < 0x20 || uc > 0x7e)
+ return PR_FALSE;
+ }
+ return PR_TRUE;
+}
+
+/* Caller ensures that dst is at least item->len*2+1 bytes long */
+static void
+SECItemToHex(const SECItem *item, char *dst)
+{
+ if (dst && item && item->data) {
+ unsigned char *src = item->data;
+ unsigned int len = item->len;
+ for (; len > 0; --len, dst += 2) {
+ sprintf(dst, "%02x", *src++);
+ }
+ *dst = '\0';
+ }
+}
+
+static const char *const keyTypeName[] = {
+ "null", "rsa", "dsa", "fortezza", "dh", "kea", "ec"
+};
+
+#define MAX_CKA_ID_BIN_LEN 20
+#define MAX_CKA_ID_STR_LEN 40
+
+/* print key number, key ID (in hex or ASCII), key label (nickname) */
+static SECStatus
+PrintKey(PRFileDesc *out, const char *nickName, int count,
+ SECKEYPrivateKey *key, void *pwarg)
+{
+ SECItem *ckaID;
+ char ckaIDbuf[MAX_CKA_ID_STR_LEN + 4];
+
+ pwarg = NULL;
+ ckaID = PK11_GetLowLevelKeyIDForPrivateKey(key);
+ if (!ckaID) {
+ strcpy(ckaIDbuf, "(no CKA_ID)");
+ } else if (ItemIsPrintableASCII(ckaID)) {
+ int len = PR_MIN(MAX_CKA_ID_STR_LEN, ckaID->len);
+ ckaIDbuf[0] = '"';
+ memcpy(ckaIDbuf + 1, ckaID->data, len);
+ ckaIDbuf[1 + len] = '"';
+ ckaIDbuf[2 + len] = '\0';
+ } else {
+ /* print ckaid in hex */
+ SECItem idItem = *ckaID;
+ if (idItem.len > MAX_CKA_ID_BIN_LEN)
+ idItem.len = MAX_CKA_ID_BIN_LEN;
+ SECItemToHex(&idItem, ckaIDbuf);
+ }
+
+ PR_fprintf(out, "<%2d> %-8.8s %-42.42s %s\n", count,
+ keyTypeName[key->keyType], ckaIDbuf, nickName);
+ SECITEM_ZfreeItem(ckaID, PR_TRUE);
+
+ return SECSuccess;
+}
+
+/* returns SECSuccess if ANY keys are found, SECFailure otherwise. */
+static SECStatus
+ListKeysInSlot(PK11SlotInfo *slot, const char *nickName, KeyType keyType,
+ void *pwarg)
+{
+ SECKEYPrivateKeyList *list;
+ SECKEYPrivateKeyListNode *node;
+ int count = 0;
+
+ if (PK11_NeedLogin(slot)) {
+ SECStatus rv = PK11_Authenticate(slot, PR_TRUE, pwarg);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "could not authenticate to token %s.",
+ PK11_GetTokenName(slot));
+ return SECFailure;
+ }
+ }
+
+ if (nickName && nickName[0])
+ list = PK11_ListPrivKeysInSlot(slot, (char *)nickName, pwarg);
+ else
+ list = PK11_ListPrivateKeysInSlot(slot);
+ if (list == NULL) {
+ SECU_PrintError(progName, "problem listing keys");
+ return SECFailure;
+ }
+ for (node = PRIVKEY_LIST_HEAD(list);
+ !PRIVKEY_LIST_END(node, list);
+ node = PRIVKEY_LIST_NEXT(node)) {
+ char *keyName;
+ static const char orphan[] = { "(orphan)" };
+
+ if (keyType != nullKey && keyType != node->key->keyType)
+ continue;
+ keyName = PK11_GetPrivateKeyNickname(node->key);
+ if (!keyName || !keyName[0]) {
+ /* Try extra hard to find nicknames for keys that lack them. */
+ CERTCertificate *cert;
+ PORT_Free((void *)keyName);
+ keyName = NULL;
+ cert = PK11_GetCertFromPrivateKey(node->key);
+ if (cert) {
+ if (cert->nickname && cert->nickname[0]) {
+ keyName = PORT_Strdup(cert->nickname);
+ } else if (cert->emailAddr && cert->emailAddr[0]) {
+ keyName = PORT_Strdup(cert->emailAddr);
+ }
+ CERT_DestroyCertificate(cert);
+ }
+ }
+ if (nickName) {
+ if (!keyName || PL_strcmp(keyName, nickName)) {
+ /* PKCS#11 module returned unwanted keys */
+ PORT_Free((void *)keyName);
+ continue;
+ }
+ }
+ if (!keyName)
+ keyName = (char *)orphan;
+
+ PrintKey(PR_STDOUT, keyName, count, node->key, pwarg);
+
+ if (keyName != (char *)orphan)
+ PORT_Free((void *)keyName);
+ count++;
+ }
+ SECKEY_DestroyPrivateKeyList(list);
+
+ if (count == 0) {
+ PR_fprintf(PR_STDOUT, "%s: no keys found\n", progName);
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+/* returns SECSuccess if ANY keys are found, SECFailure otherwise. */
+static SECStatus
+ListKeys(PK11SlotInfo *slot, const char *nickName, int index,
+ KeyType keyType, PRBool dopriv, secuPWData *pwdata)
+{
+ SECStatus rv = SECFailure;
+ static const char fmt[] =
+ "%s: Checking token \"%.33s\" in slot \"%.65s\"\n";
+
+ if (slot == NULL) {
+ PK11SlotList *list;
+ PK11SlotListElement *le;
+
+ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, pwdata);
+ if (list) {
+ for (le = list->head; le; le = le->next) {
+ PR_fprintf(PR_STDOUT, fmt, progName,
+ PK11_GetTokenName(le->slot),
+ PK11_GetSlotName(le->slot));
+ rv &= ListKeysInSlot(le->slot, nickName, keyType, pwdata);
+ }
+ PK11_FreeSlotList(list);
+ }
+ } else {
+ PR_fprintf(PR_STDOUT, fmt, progName, PK11_GetTokenName(slot),
+ PK11_GetSlotName(slot));
+ rv = ListKeysInSlot(slot, nickName, keyType, pwdata);
+ }
+ return rv;
+}
+
+static SECStatus
+DeleteKey(char *nickname, secuPWData *pwdata)
+{
+ SECStatus rv;
+ CERTCertificate *cert;
+ PK11SlotInfo *slot;
+
+ slot = PK11_GetInternalKeySlot();
+ if (PK11_NeedLogin(slot)) {
+ SECStatus rv = PK11_Authenticate(slot, PR_TRUE, pwdata);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "could not authenticate to token %s.",
+ PK11_GetTokenName(slot));
+ return SECFailure;
+ }
+ }
+ cert = PK11_FindCertFromNickname(nickname, pwdata);
+ if (!cert) {
+ PK11_FreeSlot(slot);
+ return SECFailure;
+ }
+ rv = PK11_DeleteTokenCertAndKey(cert, pwdata);
+ if (rv != SECSuccess) {
+ SECU_PrintError("problem deleting private key \"%s\"\n", nickname);
+ }
+ CERT_DestroyCertificate(cert);
+ PK11_FreeSlot(slot);
+ return rv;
+}
+
+/*
+ * L i s t M o d u l e s
+ *
+ * Print a list of the PKCS11 modules that are
+ * available. This is useful for smartcard people to
+ * make sure they have the drivers loaded.
+ *
+ */
+static SECStatus
+ListModules(void)
+{
+ PK11SlotList *list;
+ PK11SlotListElement *le;
+
+ /* get them all! */
+ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, NULL);
+ if (list == NULL)
+ return SECFailure;
+
+ /* look at each slot*/
+ for (le = list->head; le; le = le->next) {
+ printf("\n");
+ printf(" slot: %s\n", PK11_GetSlotName(le->slot));
+ printf(" token: %s\n", PK11_GetTokenName(le->slot));
+ }
+ PK11_FreeSlotList(list);
+
+ return SECSuccess;
+}
+
+static void
+PrintSyntax(char *progName)
+{
+#define FPS fprintf(stderr,
+ FPS "Type %s -H for more detailed descriptions\n", progName);
+ FPS "Usage: %s -N [-d certdir] [-P dbprefix] [-f pwfile] [--empty-password]\n", progName);
+ FPS "Usage: %s -T [-d certdir] [-P dbprefix] [-h token-name]\n"
+ "\t\t [-f pwfile] [-0 SSO-password]\n", progName);
+ FPS "\t%s -A -n cert-name -t trustargs [-d certdir] [-P dbprefix] [-a] [-i input]\n",
+ progName);
+ FPS "\t%s -B -i batch-file\n", progName);
+ FPS "\t%s -C [-c issuer-name | -x] -i cert-request-file -o cert-file\n"
+ "\t\t [-m serial-number] [-w warp-months] [-v months-valid]\n"
+ "\t\t [-f pwfile] [-d certdir] [-P dbprefix] [-Z hashAlg]\n"
+ "\t\t [-1 | --keyUsage [keyUsageKeyword,..]] [-2] [-3] [-4]\n"
+ "\t\t [-5 | --nsCertType [nsCertTypeKeyword,...]]\n"
+ "\t\t [-6 | --extKeyUsage [extKeyUsageKeyword,...]] [-7 emailAddrs]\n"
+ "\t\t [-8 dns-names] [-a]\n",
+ progName);
+ FPS "\t%s -D -n cert-name [-d certdir] [-P dbprefix]\n", progName);
+ FPS "\t%s --rename -n cert-name --new-n new-cert-name\n"
+ "\t\t [-d certdir] [-P dbprefix]\n", progName);
+ FPS "\t%s -E -n cert-name -t trustargs [-d certdir] [-P dbprefix] [-a] [-i input]\n",
+ progName);
+ FPS "\t%s -F -n nickname [-d certdir] [-P dbprefix]\n",
+ progName);
+ FPS "\t%s -G -n key-name [-h token-name] [-k rsa] [-g key-size] [-y exp]\n"
+ "\t\t [-f pwfile] [-z noisefile] [-d certdir] [-P dbprefix]\n", progName);
+ FPS "\t%s -G [-h token-name] -k dsa [-q pqgfile -g key-size] [-f pwfile]\n"
+ "\t\t [-z noisefile] [-d certdir] [-P dbprefix]\n", progName);
+#ifndef NSS_DISABLE_ECC
+ FPS "\t%s -G [-h token-name] -k ec -q curve [-f pwfile]\n"
+ "\t\t [-z noisefile] [-d certdir] [-P dbprefix]\n", progName);
+ FPS "\t%s -K [-n key-name] [-h token-name] [-k dsa|ec|rsa|all]\n",
+ progName);
+#else
+ FPS "\t%s -K [-n key-name] [-h token-name] [-k dsa|rsa|all]\n",
+ progName);
+#endif /* NSS_DISABLE_ECC */
+ FPS "\t\t [-f pwfile] [-X] [-d certdir] [-P dbprefix]\n");
+ FPS "\t%s --upgrade-merge --source-dir upgradeDir --upgrade-id uniqueID\n",
+ progName);
+ FPS "\t\t [--upgrade-token-name tokenName] [-d targetDBDir]\n");
+ FPS "\t\t [-P targetDBPrefix] [--source-prefix upgradeDBPrefix]\n");
+ FPS "\t\t [-f targetPWfile] [-@ upgradePWFile]\n");
+ FPS "\t%s --merge --source-dir sourceDBDir [-d targetDBdir]\n",
+ progName);
+ FPS "\t\t [-P targetDBPrefix] [--source-prefix sourceDBPrefix]\n");
+ FPS "\t\t [-f targetPWfile] [-@ sourcePWFile]\n");
+ FPS "\t%s -L [-n cert-name] [-h token-name] [--email email-address]\n",
+ progName);
+ FPS "\t\t [-X] [-r] [-a] [--dump-ext-val OID] [-d certdir] [-P dbprefix]\n");
+ FPS "\t%s -M -n cert-name -t trustargs [-d certdir] [-P dbprefix]\n",
+ progName);
+ FPS "\t%s -O -n cert-name [-X] [-d certdir] [-a] [-P dbprefix]\n", progName);
+ FPS "\t%s -R -s subj -o cert-request-file [-d certdir] [-P dbprefix] [-p phone] [-a]\n"
+ "\t\t [-7 emailAddrs] [-k key-type-or-id] [-h token-name] [-f pwfile]\n"
+ "\t\t [-g key-size] [-Z hashAlg]\n",
+ progName);
+ FPS "\t%s -V -n cert-name -u usage [-b time] [-e] [-a]\n"
+ "\t\t[-X] [-d certdir] [-P dbprefix]\n",
+ progName);
+ FPS "Usage: %s -W [-d certdir] [-f pwfile] [-@newpwfile]\n",
+ progName);
+ FPS "\t%s -S -n cert-name -s subj [-c issuer-name | -x] -t trustargs\n"
+ "\t\t [-k key-type-or-id] [-q key-params] [-h token-name] [-g key-size]\n"
+ "\t\t [-m serial-number] [-w warp-months] [-v months-valid]\n"
+ "\t\t [-f pwfile] [-d certdir] [-P dbprefix] [-Z hashAlg]\n"
+ "\t\t [-p phone] [-1] [-2] [-3] [-4] [-5] [-6] [-7 emailAddrs]\n"
+ "\t\t [-8 DNS-names]\n"
+ "\t\t [--extAIA] [--extSIA] [--extCP] [--extPM] [--extPC] [--extIA]\n"
+ "\t\t [--extSKID] [--extNC] [--extSAN type:name[,type:name]...]\n"
+ "\t\t [--extGeneric OID:critical-flag:filename[,OID:critical-flag:filename]...]\n", progName);
+ FPS "\t%s -U [-X] [-d certdir] [-P dbprefix]\n", progName);
+ exit(1);
+}
+
+enum usage_level {
+ usage_all = 0,
+ usage_selected = 1
+};
+
+static void luCommonDetailsAE();
+
+static void
+luA(enum usage_level ul, const char *command)
+{
+ int is_my_command = (command && 0 == strcmp(command, "A"));
+ if (ul == usage_all || !command || is_my_command)
+ FPS "%-15s Add a certificate to the database (create if needed)\n",
+ "-A");
+ if (ul == usage_selected && !is_my_command)
+ return;
+ if (ul == usage_all) {
+ FPS "%-20s\n", " All options under -E apply");
+ } else {
+ luCommonDetailsAE();
+ }
+}
+
+static void
+luB(enum usage_level ul, const char *command)
+{
+ int is_my_command = (command && 0 == strcmp(command, "B"));
+ if (ul == usage_all || !command || is_my_command)
+ FPS "%-15s Run a series of certutil commands from a batch file\n", "-B");
+ if (ul == usage_selected && !is_my_command)
+ return;
+ FPS "%-20s Specify the batch file\n", " -i batch-file");
+}
+
+static void
+luE(enum usage_level ul, const char *command)
+{
+ int is_my_command = (command && 0 == strcmp(command, "E"));
+ if (ul == usage_all || !command || is_my_command)
+ FPS "%-15s Add an Email certificate to the database (create if needed)\n",
+ "-E");
+ if (ul == usage_selected && !is_my_command)
+ return;
+ luCommonDetailsAE();
+}
+
+static void
+luCommonDetailsAE()
+{
+ FPS "%-20s Specify the nickname of the certificate to add\n",
+ " -n cert-name");
+ FPS "%-20s Set the certificate trust attributes:\n",
+ " -t trustargs");
+ FPS "%-25s trustargs is of the form x,y,z where x is for SSL, y is for S/MIME,\n", "");
+ FPS "%-25s and z is for code signing. Use ,, for no explicit trust.\n", "");
+ FPS "%-25s p \t prohibited (explicitly distrusted)\n", "");
+ FPS "%-25s P \t trusted peer\n", "");
+ FPS "%-25s c \t valid CA\n", "");
+ FPS "%-25s T \t trusted CA to issue client certs (implies c)\n", "");
+ FPS "%-25s C \t trusted CA to issue server certs (implies c)\n", "");
+ FPS "%-25s u \t user cert\n", "");
+ FPS "%-25s w \t send warning\n", "");
+ FPS "%-25s g \t make step-up cert\n", "");
+ FPS "%-20s Specify the password file\n",
+ " -f pwfile");
+ FPS "%-20s Cert database directory (default is ~/.netscape)\n",
+ " -d certdir");
+ FPS "%-20s Cert & Key database prefix\n",
+ " -P dbprefix");
+ FPS "%-20s The input certificate is encoded in ASCII (RFC1113)\n",
+ " -a");
+ FPS "%-20s Specify the certificate file (default is stdin)\n",
+ " -i input");
+ FPS "\n");
+}
+
+static void
+luC(enum usage_level ul, const char *command)
+{
+ int is_my_command = (command && 0 == strcmp(command, "C"));
+ if (ul == usage_all || !command || is_my_command)
+ FPS "%-15s Create a new binary certificate from a BINARY cert request\n",
+ "-C");
+ if (ul == usage_selected && !is_my_command)
+ return;
+ FPS "%-20s The nickname of the issuer cert\n",
+ " -c issuer-name");
+ FPS "%-20s The BINARY certificate request file\n",
+ " -i cert-request ");
+ FPS "%-20s Output binary cert to this file (default is stdout)\n",
+ " -o output-cert");
+ FPS "%-20s Self sign\n",
+ " -x");
+ FPS "%-20s Cert serial number\n",
+ " -m serial-number");
+ FPS "%-20s Time Warp\n",
+ " -w warp-months");
+ FPS "%-20s Months valid (default is 3)\n",
+ " -v months-valid");
+ FPS "%-20s Specify the password file\n",
+ " -f pwfile");
+ FPS "%-20s Cert database directory (default is ~/.netscape)\n",
+ " -d certdir");
+ FPS "%-20s Cert & Key database prefix\n",
+ " -P dbprefix");
+ FPS "%-20s \n"
+ "%-20s Specify the hash algorithm to use. Possible keywords:\n"
+ "%-20s \"MD2\", \"MD4\", \"MD5\", \"SHA1\", \"SHA224\",\n"
+ "%-20s \"SHA256\", \"SHA384\", \"SHA512\"\n",
+ " -Z hashAlg", "", "", "");
+ FPS "%-20s \n"
+ "%-20s Create key usage extension. Possible keywords:\n"
+ "%-20s \"digitalSignature\", \"nonRepudiation\", \"keyEncipherment\",\n"
+ "%-20s \"dataEncipherment\", \"keyAgreement\", \"certSigning\",\n"
+ "%-20s \"crlSigning\", \"critical\"\n",
+ " -1 | --keyUsage keyword,keyword,...", "", "", "", "");
+ FPS "%-20s Create basic constraint extension\n",
+ " -2 ");
+ FPS "%-20s Create authority key ID extension\n",
+ " -3 ");
+ FPS "%-20s Create crl distribution point extension\n",
+ " -4 ");
+ FPS "%-20s \n"
+ "%-20s Create netscape cert type extension. Possible keywords:\n"
+ "%-20s \"sslClient\", \"sslServer\", \"smime\", \"objectSigning\",\n"
+ "%-20s \"sslCA\", \"smimeCA\", \"objectSigningCA\", \"critical\".\n",
+ " -5 | --nsCertType keyword,keyword,... ", "", "", "");
+ FPS "%-20s \n"
+ "%-20s Create extended key usage extension. Possible keywords:\n"
+ "%-20s \"serverAuth\", \"clientAuth\",\"codeSigning\",\n"
+ "%-20s \"emailProtection\", \"timeStamp\",\"ocspResponder\",\n"
+ "%-20s \"stepUp\", \"msTrustListSign\", \"critical\"\n",
+ " -6 | --extKeyUsage keyword,keyword,...", "", "", "", "");
+ FPS "%-20s Create an email subject alt name extension\n",
+ " -7 emailAddrs");
+ FPS "%-20s Create an dns subject alt name extension\n",
+ " -8 dnsNames");
+ FPS "%-20s The input certificate request is encoded in ASCII (RFC1113)\n",
+ " -a");
+ FPS "\n");
+}
+
+static void
+luG(enum usage_level ul, const char *command)
+{
+ int is_my_command = (command && 0 == strcmp(command, "G"));
+ if (ul == usage_all || !command || is_my_command)
+ FPS "%-15s Generate a new key pair\n",
+ "-G");
+ if (ul == usage_selected && !is_my_command)
+ return;
+ FPS "%-20s Name of token in which to generate key (default is internal)\n",
+ " -h token-name");
+#ifndef NSS_DISABLE_ECC
+ FPS "%-20s Type of key pair to generate (\"dsa\", \"ec\", \"rsa\" (default))\n",
+ " -k key-type");
+ FPS "%-20s Key size in bits, (min %d, max %d, default %d) (not for ec)\n",
+ " -g key-size", MIN_KEY_BITS, MAX_KEY_BITS, DEFAULT_KEY_BITS);
+#else
+ FPS "%-20s Type of key pair to generate (\"dsa\", \"rsa\" (default))\n",
+ " -k key-type");
+ FPS "%-20s Key size in bits, (min %d, max %d, default %d)\n",
+ " -g key-size", MIN_KEY_BITS, MAX_KEY_BITS, DEFAULT_KEY_BITS);
+#endif /* NSS_DISABLE_ECC */
+ FPS "%-20s Set the public exponent value (3, 17, 65537) (rsa only)\n",
+ " -y exp");
+ FPS "%-20s Specify the password file\n",
+ " -f password-file");
+ FPS "%-20s Specify the noise file to be used\n",
+ " -z noisefile");
+ FPS "%-20s read PQG value from pqgfile (dsa only)\n",
+ " -q pqgfile");
+#ifndef NSS_DISABLE_ECC
+ FPS "%-20s Elliptic curve name (ec only)\n",
+ " -q curve-name");
+ FPS "%-20s One of nistp256, nistp384, nistp521, curve25519.\n", "");
+ FPS "%-20s If a custom token is present, the following curves are also supported:\n", "");
+ FPS "%-20s sect163k1, nistk163, sect163r1, sect163r2,\n", "");
+ FPS "%-20s nistb163, sect193r1, sect193r2, sect233k1, nistk233,\n", "");
+ FPS "%-20s sect233r1, nistb233, sect239k1, sect283k1, nistk283,\n", "");
+ FPS "%-20s sect283r1, nistb283, sect409k1, nistk409, sect409r1,\n", "");
+ FPS "%-20s nistb409, sect571k1, nistk571, sect571r1, nistb571,\n", "");
+ FPS "%-20s secp160k1, secp160r1, secp160r2, secp192k1, secp192r1,\n", "");
+ FPS "%-20s nistp192, secp224k1, secp224r1, nistp224, secp256k1,\n", "");
+ FPS "%-20s secp256r1, secp384r1, secp521r1,\n", "");
+ FPS "%-20s prime192v1, prime192v2, prime192v3, \n", "");
+ FPS "%-20s prime239v1, prime239v2, prime239v3, c2pnb163v1, \n", "");
+ FPS "%-20s c2pnb163v2, c2pnb163v3, c2pnb176v1, c2tnb191v1, \n", "");
+ FPS "%-20s c2tnb191v2, c2tnb191v3, \n", "");
+ FPS "%-20s c2pnb208w1, c2tnb239v1, c2tnb239v2, c2tnb239v3, \n", "");
+ FPS "%-20s c2pnb272w1, c2pnb304w1, \n", "");
+ FPS "%-20s c2tnb359w1, c2pnb368w1, c2tnb431r1, secp112r1, \n", "");
+ FPS "%-20s secp112r2, secp128r1, secp128r2, sect113r1, sect113r2\n", "");
+ FPS "%-20s sect131r1, sect131r2\n", "");
+#endif
+ FPS "%-20s Key database directory (default is ~/.netscape)\n",
+ " -d keydir");
+ FPS "%-20s Cert & Key database prefix\n",
+ " -P dbprefix");
+ FPS "%-20s\n"
+ "%-20s PKCS #11 key Attributes.\n",
+ " --keyAttrFlags attrflags", "");
+ FPS "%-20s Comma separated list of key attribute attribute flags,\n", "");
+ FPS "%-20s selected from the following list of choices:\n", "");
+ FPS "%-20s {token | session} {public | private} {sensitive | insensitive}\n", "");
+ FPS "%-20s {modifiable | unmodifiable} {extractable | unextractable}\n", "");
+ FPS "%-20s\n",
+ " --keyOpFlagsOn opflags");
+ FPS "%-20s\n"
+ "%-20s PKCS #11 key Operation Flags.\n",
+ " --keyOpFlagsOff opflags", "");
+ FPS "%-20s Comma separated list of one or more of the following:\n", "");
+ FPS "%-20s encrypt, decrypt, sign, sign_recover, verify,\n", "");
+ FPS "%-20s verify_recover, wrap, unwrap, derive\n", "");
+ FPS "\n");
+}
+
+static void
+luD(enum usage_level ul, const char *command)
+{
+ int is_my_command = (command && 0 == strcmp(command, "D"));
+ if (ul == usage_all || !command || is_my_command)
+ FPS "%-15s Delete a certificate from the database\n",
+ "-D");
+ if (ul == usage_selected && !is_my_command)
+ return;
+ FPS "%-20s The nickname of the cert to delete\n",
+ " -n cert-name");
+ FPS "%-20s Cert database directory (default is ~/.netscape)\n",
+ " -d certdir");
+ FPS "%-20s Cert & Key database prefix\n",
+ " -P dbprefix");
+ FPS "\n");
+}
+
+static void
+luF(enum usage_level ul, const char *command)
+{
+ int is_my_command = (command && 0 == strcmp(command, "F"));
+ if (ul == usage_all || !command || is_my_command)
+ FPS "%-15s Delete a key from the database\n",
+ "-F");
+ if (ul == usage_selected && !is_my_command)
+ return;
+ FPS "%-20s The nickname of the key to delete\n",
+ " -n cert-name");
+ FPS "%-20s Cert database directory (default is ~/.netscape)\n",
+ " -d certdir");
+ FPS "%-20s Cert & Key database prefix\n",
+ " -P dbprefix");
+ FPS "\n");
+}
+
+static void
+luU(enum usage_level ul, const char *command)
+{
+ int is_my_command = (command && 0 == strcmp(command, "U"));
+ if (ul == usage_all || !command || is_my_command)
+ FPS "%-15s List all modules\n", /*, or print out a single named module\n",*/
+ "-U");
+ if (ul == usage_selected && !is_my_command)
+ return;
+ FPS "%-20s Module database directory (default is '~/.netscape')\n",
+ " -d moddir");
+ FPS "%-20s Cert & Key database prefix\n",
+ " -P dbprefix");
+ FPS "%-20s force the database to open R/W\n",
+ " -X");
+ FPS "\n");
+}
+
+static void
+luK(enum usage_level ul, const char *command)
+{
+ int is_my_command = (command && 0 == strcmp(command, "K"));
+ if (ul == usage_all || !command || is_my_command)
+ FPS "%-15s List all private keys\n",
+ "-K");
+ if (ul == usage_selected && !is_my_command)
+ return;
+ FPS "%-20s Name of token to search (\"all\" for all tokens)\n",
+ " -h token-name ");
+
+ FPS "%-20s Key type (\"all\" (default), \"dsa\","
+#ifndef NSS_DISABLE_ECC
+ " \"ec\","
+#endif
+ " \"rsa\")\n",
+ " -k key-type");
+ FPS "%-20s The nickname of the key or associated certificate\n",
+ " -n name");
+ FPS "%-20s Specify the password file\n",
+ " -f password-file");
+ FPS "%-20s Key database directory (default is ~/.netscape)\n",
+ " -d keydir");
+ FPS "%-20s Cert & Key database prefix\n",
+ " -P dbprefix");
+ FPS "%-20s force the database to open R/W\n",
+ " -X");
+ FPS "\n");
+}
+
+static void
+luL(enum usage_level ul, const char *command)
+{
+ int is_my_command = (command && 0 == strcmp(command, "L"));
+ if (ul == usage_all || !command || is_my_command)
+ FPS "%-15s List all certs, or print out a single named cert (or a subset)\n",
+ "-L");
+ if (ul == usage_selected && !is_my_command)
+ return;
+ FPS "%-20s Name of token to search (\"all\" for all tokens)\n",
+ " -h token-name ");
+ FPS "%-20s Pretty print named cert (list all if unspecified)\n",
+ " -n cert-name");
+ FPS "%-20s \n"
+ "%-20s Pretty print cert with email address (list all if unspecified)\n",
+ " --email email-address", "");
+ FPS "%-20s Cert database directory (default is ~/.netscape)\n",
+ " -d certdir");
+ FPS "%-20s Cert & Key database prefix\n",
+ " -P dbprefix");
+ FPS "%-20s force the database to open R/W\n",
+ " -X");
+ FPS "%-20s For single cert, print binary DER encoding\n",
+ " -r");
+ FPS "%-20s For single cert, print ASCII encoding (RFC1113)\n",
+ " -a");
+ FPS "%-20s \n"
+ "%-20s For single cert, print binary DER encoding of extension OID\n",
+ " --dump-ext-val OID", "");
+ FPS "\n");
+}
+
+static void
+luM(enum usage_level ul, const char *command)
+{
+ int is_my_command = (command && 0 == strcmp(command, "M"));
+ if (ul == usage_all || !command || is_my_command)
+ FPS "%-15s Modify trust attributes of certificate\n",
+ "-M");
+ if (ul == usage_selected && !is_my_command)
+ return;
+ FPS "%-20s The nickname of the cert to modify\n",
+ " -n cert-name");
+ FPS "%-20s Set the certificate trust attributes (see -A above)\n",
+ " -t trustargs");
+ FPS "%-20s Cert database directory (default is ~/.netscape)\n",
+ " -d certdir");
+ FPS "%-20s Cert & Key database prefix\n",
+ " -P dbprefix");
+ FPS "\n");
+}
+
+static void
+luN(enum usage_level ul, const char *command)
+{
+ int is_my_command = (command && 0 == strcmp(command, "N"));
+ if (ul == usage_all || !command || is_my_command)
+ FPS "%-15s Create a new certificate database\n",
+ "-N");
+ if (ul == usage_selected && !is_my_command)
+ return;
+ FPS "%-20s Cert database directory (default is ~/.netscape)\n",
+ " -d certdir");
+ FPS "%-20s Cert & Key database prefix\n",
+ " -P dbprefix");
+ FPS "%-20s Specify the password file\n",
+ " -f password-file");
+ FPS "%-20s use empty password when creating a new database\n",
+ " --empty-password");
+ FPS "\n");
+}
+
+static void
+luT(enum usage_level ul, const char *command)
+{
+ int is_my_command = (command && 0 == strcmp(command, "T"));
+ if (ul == usage_all || !command || is_my_command)
+ FPS "%-15s Reset the Key database or token\n",
+ "-T");
+ if (ul == usage_selected && !is_my_command)
+ return;
+ FPS "%-20s Cert database directory (default is ~/.netscape)\n",
+ " -d certdir");
+ FPS "%-20s Cert & Key database prefix\n",
+ " -P dbprefix");
+ FPS "%-20s Token to reset (default is internal)\n",
+ " -h token-name");
+ FPS "%-20s Set token's Site Security Officer password\n",
+ " -0 SSO-password");
+ FPS "\n");
+}
+
+static void
+luO(enum usage_level ul, const char *command)
+{
+ int is_my_command = (command && 0 == strcmp(command, "O"));
+ if (ul == usage_all || !command || is_my_command)
+ FPS "%-15s Print the chain of a certificate\n",
+ "-O");
+ if (ul == usage_selected && !is_my_command)
+ return;
+ FPS "%-20s The nickname of the cert to modify\n",
+ " -n cert-name");
+ FPS "%-20s Cert database directory (default is ~/.netscape)\n",
+ " -d certdir");
+ FPS "%-20s Input the certificate in ASCII (RFC1113); default is binary\n",
+ " -a");
+ FPS "%-20s Cert & Key database prefix\n",
+ " -P dbprefix");
+ FPS "%-20s force the database to open R/W\n",
+ " -X");
+ FPS "\n");
+}
+
+static void
+luR(enum usage_level ul, const char *command)
+{
+ int is_my_command = (command && 0 == strcmp(command, "R"));
+ if (ul == usage_all || !command || is_my_command)
+ FPS "%-15s Generate a certificate request (stdout)\n",
+ "-R");
+ if (ul == usage_selected && !is_my_command)
+ return;
+ FPS "%-20s Specify the subject name (using RFC1485)\n",
+ " -s subject");
+ FPS "%-20s Output the cert request to this file\n",
+ " -o output-req");
+#ifndef NSS_DISABLE_ECC
+ FPS "%-20s Type of key pair to generate (\"dsa\", \"ec\", \"rsa\" (default))\n",
+#else
+ FPS "%-20s Type of key pair to generate (\"dsa\", \"rsa\" (default))\n",
+#endif /* NSS_DISABLE_ECC */
+ " -k key-type-or-id");
+ FPS "%-20s or nickname of the cert key to use \n",
+ "");
+ FPS "%-20s Name of token in which to generate key (default is internal)\n",
+ " -h token-name");
+ FPS "%-20s Key size in bits, RSA keys only (min %d, max %d, default %d)\n",
+ " -g key-size", MIN_KEY_BITS, MAX_KEY_BITS, DEFAULT_KEY_BITS);
+ FPS "%-20s Name of file containing PQG parameters (dsa only)\n",
+ " -q pqgfile");
+#ifndef NSS_DISABLE_ECC
+ FPS "%-20s Elliptic curve name (ec only)\n",
+ " -q curve-name");
+ FPS "%-20s See the \"-G\" option for a full list of supported names.\n",
+ "");
+#endif /* NSS_DISABLE_ECC */
+ FPS "%-20s Specify the password file\n",
+ " -f pwfile");
+ FPS "%-20s Key database directory (default is ~/.netscape)\n",
+ " -d keydir");
+ FPS "%-20s Cert & Key database prefix\n",
+ " -P dbprefix");
+ FPS "%-20s Specify the contact phone number (\"123-456-7890\")\n",
+ " -p phone");
+ FPS "%-20s \n"
+ "%-20s Specify the hash algorithm to use. Possible keywords:\n"
+ "%-20s \"MD2\", \"MD4\", \"MD5\", \"SHA1\", \"SHA224\",\n"
+ "%-20s \"SHA256\", \"SHA384\", \"SHA512\"\n",
+ " -Z hashAlg", "", "", "");
+ FPS "%-20s Output the cert request in ASCII (RFC1113); default is binary\n",
+ " -a");
+ FPS "%-20s \n",
+ " See -S for available extension options");
+ FPS "%-20s \n",
+ " See -G for available key flag options");
+ FPS "\n");
+}
+
+static void
+luV(enum usage_level ul, const char *command)
+{
+ int is_my_command = (command && 0 == strcmp(command, "V"));
+ if (ul == usage_all || !command || is_my_command)
+ FPS "%-15s Validate a certificate\n",
+ "-V");
+ if (ul == usage_selected && !is_my_command)
+ return;
+ FPS "%-20s The nickname of the cert to Validate\n",
+ " -n cert-name");
+ FPS "%-20s validity time (\"YYMMDDHHMMSS[+HHMM|-HHMM|Z]\")\n",
+ " -b time");
+ FPS "%-20s Check certificate signature \n",
+ " -e ");
+ FPS "%-20s Specify certificate usage:\n", " -u certusage");
+ FPS "%-25s C \t SSL Client\n", "");
+ FPS "%-25s V \t SSL Server\n", "");
+ FPS "%-25s L \t SSL CA\n", "");
+ FPS "%-25s A \t Any CA\n", "");
+ FPS "%-25s Y \t Verify CA\n", "");
+ FPS "%-25s S \t Email signer\n", "");
+ FPS "%-25s R \t Email Recipient\n", "");
+ FPS "%-25s O \t OCSP status responder\n", "");
+ FPS "%-25s J \t Object signer\n", "");
+ FPS "%-20s Cert database directory (default is ~/.netscape)\n",
+ " -d certdir");
+ FPS "%-20s Input the certificate in ASCII (RFC1113); default is binary\n",
+ " -a");
+ FPS "%-20s Cert & Key database prefix\n",
+ " -P dbprefix");
+ FPS "%-20s force the database to open R/W\n",
+ " -X");
+ FPS "\n");
+}
+
+static void
+luW(enum usage_level ul, const char *command)
+{
+ int is_my_command = (command && 0 == strcmp(command, "W"));
+ if (ul == usage_all || !command || is_my_command)
+ FPS "%-15s Change the key database password\n",
+ "-W");
+ if (ul == usage_selected && !is_my_command)
+ return;
+ FPS "%-20s cert and key database directory\n",
+ " -d certdir");
+ FPS "%-20s Specify a file with the current password\n",
+ " -f pwfile");
+ FPS "%-20s Specify a file with the new password in two lines\n",
+ " -@ newpwfile");
+ FPS "\n");
+}
+
+static void
+luRename(enum usage_level ul, const char *command)
+{
+ int is_my_command = (command && 0 == strcmp(command, "rename"));
+ if (ul == usage_all || !command || is_my_command)
+ FPS "%-15s Change the database nickname of a certificate\n",
+ "--rename");
+ if (ul == usage_selected && !is_my_command)
+ return;
+ FPS "%-20s The old nickname of the cert to rename\n",
+ " -n cert-name");
+ FPS "%-20s The new nickname of the cert to rename\n",
+ " --new-n new-name");
+ FPS "%-20s Cert database directory (default is ~/.netscape)\n",
+ " -d certdir");
+ FPS "%-20s Cert & Key database prefix\n",
+ " -P dbprefix");
+ FPS "\n");
+}
+
+static void
+luUpgradeMerge(enum usage_level ul, const char *command)
+{
+ int is_my_command = (command && 0 == strcmp(command, "upgrade-merge"));
+ if (ul == usage_all || !command || is_my_command)
+ FPS "%-15s Upgrade an old database and merge it into a new one\n",
+ "--upgrade-merge");
+ if (ul == usage_selected && !is_my_command)
+ return;
+ FPS "%-20s Cert database directory to merge into (default is ~/.netscape)\n",
+ " -d certdir");
+ FPS "%-20s Cert & Key database prefix of the target database\n",
+ " -P dbprefix");
+ FPS "%-20s Specify the password file for the target database\n",
+ " -f pwfile");
+ FPS "%-20s \n%-20s Cert database directory to upgrade from\n",
+ " --source-dir certdir", "");
+ FPS "%-20s \n%-20s Cert & Key database prefix of the upgrade database\n",
+ " --source-prefix dbprefix", "");
+ FPS "%-20s \n%-20s Unique identifier for the upgrade database\n",
+ " --upgrade-id uniqueID", "");
+ FPS "%-20s \n%-20s Name of the token while it is in upgrade state\n",
+ " --upgrade-token-name name", "");
+ FPS "%-20s Specify the password file for the upgrade database\n",
+ " -@ pwfile");
+ FPS "\n");
+}
+
+static void
+luMerge(enum usage_level ul, const char *command)
+{
+ int is_my_command = (command && 0 == strcmp(command, "merge"));
+ if (ul == usage_all || !command || is_my_command)
+ FPS "%-15s Merge source database into the target database\n",
+ "--merge");
+ if (ul == usage_selected && !is_my_command)
+ return;
+ FPS "%-20s Cert database directory of target (default is ~/.netscape)\n",
+ " -d certdir");
+ FPS "%-20s Cert & Key database prefix of the target database\n",
+ " -P dbprefix");
+ FPS "%-20s Specify the password file for the target database\n",
+ " -f pwfile");
+ FPS "%-20s \n%-20s Cert database directory of the source database\n",
+ " --source-dir certdir", "");
+ FPS "%-20s \n%-20s Cert & Key database prefix of the source database\n",
+ " --source-prefix dbprefix", "");
+ FPS "%-20s Specify the password file for the source database\n",
+ " -@ pwfile");
+ FPS "\n");
+}
+
+static void
+luS(enum usage_level ul, const char *command)
+{
+ int is_my_command = (command && 0 == strcmp(command, "S"));
+ if (ul == usage_all || !command || is_my_command)
+ FPS "%-15s Make a certificate and add to database\n",
+ "-S");
+ if (ul == usage_selected && !is_my_command)
+ return;
+ FPS "%-20s Specify the nickname of the cert\n",
+ " -n key-name");
+ FPS "%-20s Specify the subject name (using RFC1485)\n",
+ " -s subject");
+ FPS "%-20s The nickname of the issuer cert\n",
+ " -c issuer-name");
+ FPS "%-20s Set the certificate trust attributes (see -A above)\n",
+ " -t trustargs");
+#ifndef NSS_DISABLE_ECC
+ FPS "%-20s Type of key pair to generate (\"dsa\", \"ec\", \"rsa\" (default))\n",
+#else
+ FPS "%-20s Type of key pair to generate (\"dsa\", \"rsa\" (default))\n",
+#endif /* NSS_DISABLE_ECC */
+ " -k key-type-or-id");
+ FPS "%-20s Name of token in which to generate key (default is internal)\n",
+ " -h token-name");
+ FPS "%-20s Key size in bits, RSA keys only (min %d, max %d, default %d)\n",
+ " -g key-size", MIN_KEY_BITS, MAX_KEY_BITS, DEFAULT_KEY_BITS);
+ FPS "%-20s Name of file containing PQG parameters (dsa only)\n",
+ " -q pqgfile");
+#ifndef NSS_DISABLE_ECC
+ FPS "%-20s Elliptic curve name (ec only)\n",
+ " -q curve-name");
+ FPS "%-20s See the \"-G\" option for a full list of supported names.\n",
+ "");
+#endif /* NSS_DISABLE_ECC */
+ FPS "%-20s Self sign\n",
+ " -x");
+ FPS "%-20s Cert serial number\n",
+ " -m serial-number");
+ FPS "%-20s Time Warp\n",
+ " -w warp-months");
+ FPS "%-20s Months valid (default is 3)\n",
+ " -v months-valid");
+ FPS "%-20s Specify the password file\n",
+ " -f pwfile");
+ FPS "%-20s Cert database directory (default is ~/.netscape)\n",
+ " -d certdir");
+ FPS "%-20s Cert & Key database prefix\n",
+ " -P dbprefix");
+ FPS "%-20s Specify the contact phone number (\"123-456-7890\")\n",
+ " -p phone");
+ FPS "%-20s \n"
+ "%-20s Specify the hash algorithm to use. Possible keywords:\n"
+ "%-20s \"MD2\", \"MD4\", \"MD5\", \"SHA1\", \"SHA224\",\n"
+ "%-20s \"SHA256\", \"SHA384\", \"SHA512\"\n",
+ " -Z hashAlg", "", "", "");
+ FPS "%-20s Create key usage extension\n",
+ " -1 ");
+ FPS "%-20s Create basic constraint extension\n",
+ " -2 ");
+ FPS "%-20s Create authority key ID extension\n",
+ " -3 ");
+ FPS "%-20s Create crl distribution point extension\n",
+ " -4 ");
+ FPS "%-20s Create netscape cert type extension\n",
+ " -5 ");
+ FPS "%-20s Create extended key usage extension\n",
+ " -6 ");
+ FPS "%-20s Create an email subject alt name extension\n",
+ " -7 emailAddrs ");
+ FPS "%-20s Create a DNS subject alt name extension\n",
+ " -8 DNS-names");
+ FPS "%-20s Create an Authority Information Access extension\n",
+ " --extAIA ");
+ FPS "%-20s Create a Subject Information Access extension\n",
+ " --extSIA ");
+ FPS "%-20s Create a Certificate Policies extension\n",
+ " --extCP ");
+ FPS "%-20s Create a Policy Mappings extension\n",
+ " --extPM ");
+ FPS "%-20s Create a Policy Constraints extension\n",
+ " --extPC ");
+ FPS "%-20s Create an Inhibit Any Policy extension\n",
+ " --extIA ");
+ FPS "%-20s Create a subject key ID extension\n",
+ " --extSKID ");
+ FPS "%-20s \n",
+ " See -G for available key flag options");
+ FPS "%-20s Create a name constraints extension\n",
+ " --extNC ");
+ FPS "%-20s \n"
+ "%-20s Create a Subject Alt Name extension with one or multiple names\n",
+ " --extSAN type:name[,type:name]...", "");
+ FPS "%-20s - type: directory, dn, dns, edi, ediparty, email, ip, ipaddr,\n", "");
+ FPS "%-20s other, registerid, rfc822, uri, x400, x400addr\n", "");
+ FPS "%-20s \n"
+ "%-20s Add one or multiple extensions that certutil cannot encode yet,\n"
+ "%-20s by loading their encodings from external files.\n",
+ " --extGeneric OID:critical-flag:filename[,OID:critical-flag:filename]...", "", "");
+ FPS "%-20s - OID (example): 1.2.3.4\n", "");
+ FPS "%-20s - critical-flag: critical or not-critical\n", "");
+ FPS "%-20s - filename: full path to a file containing an encoded extension\n", "");
+ FPS "\n");
+}
+
+static void
+LongUsage(char *progName, enum usage_level ul, const char *command)
+{
+ luA(ul, command);
+ luB(ul, command);
+ luE(ul, command);
+ luC(ul, command);
+ luG(ul, command);
+ luD(ul, command);
+ luRename(ul, command);
+ luF(ul, command);
+ luU(ul, command);
+ luK(ul, command);
+ luL(ul, command);
+ luM(ul, command);
+ luN(ul, command);
+ luT(ul, command);
+ luO(ul, command);
+ luR(ul, command);
+ luV(ul, command);
+ luW(ul, command);
+ luUpgradeMerge(ul, command);
+ luMerge(ul, command);
+ luS(ul, command);
+#undef FPS
+}
+
+static void
+Usage(char *progName)
+{
+ PR_fprintf(PR_STDERR,
+ "%s - Utility to manipulate NSS certificate databases\n\n"
+ "Usage: %s -d \n\n"
+ "Valid commands:\n",
+ progName, progName);
+ LongUsage(progName, usage_selected, NULL);
+ PR_fprintf(PR_STDERR, "\n"
+ "%s -H : Print available options for the given command\n"
+ "%s -H : Print complete help output of all commands and options\n"
+ "%s --syntax : Print a short summary of all commands and options\n",
+ progName, progName, progName);
+ exit(1);
+}
+
+static CERTCertificate *
+MakeV1Cert(CERTCertDBHandle *handle,
+ CERTCertificateRequest *req,
+ char *issuerNickName,
+ PRBool selfsign,
+ unsigned int serialNumber,
+ int warpmonths,
+ int validityMonths)
+{
+ CERTCertificate *issuerCert = NULL;
+ CERTValidity *validity;
+ CERTCertificate *cert = NULL;
+ PRExplodedTime printableTime;
+ PRTime now, after;
+
+ if (!selfsign) {
+ issuerCert = CERT_FindCertByNicknameOrEmailAddr(handle, issuerNickName);
+ if (!issuerCert) {
+ SECU_PrintError(progName, "could not find certificate named \"%s\"",
+ issuerNickName);
+ return NULL;
+ }
+ }
+
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_GMTParameters, &printableTime);
+ if (warpmonths) {
+ printableTime.tm_month += warpmonths;
+ now = PR_ImplodeTime(&printableTime);
+ PR_ExplodeTime(now, PR_GMTParameters, &printableTime);
+ }
+ printableTime.tm_month += validityMonths;
+ after = PR_ImplodeTime(&printableTime);
+
+ /* note that the time is now in micro-second unit */
+ validity = CERT_CreateValidity(now, after);
+ if (validity) {
+ cert = CERT_CreateCertificate(serialNumber,
+ (selfsign ? &req->subject
+ : &issuerCert->subject),
+ validity, req);
+
+ CERT_DestroyValidity(validity);
+ }
+ if (issuerCert) {
+ CERT_DestroyCertificate(issuerCert);
+ }
+
+ return (cert);
+}
+
+static SECStatus
+SignCert(CERTCertDBHandle *handle, CERTCertificate *cert, PRBool selfsign,
+ SECOidTag hashAlgTag,
+ SECKEYPrivateKey *privKey, char *issuerNickName,
+ int certVersion, void *pwarg)
+{
+ SECItem der;
+ SECKEYPrivateKey *caPrivateKey = NULL;
+ SECStatus rv;
+ PLArenaPool *arena;
+ SECOidTag algID;
+ void *dummy;
+
+ if (!selfsign) {
+ CERTCertificate *issuer = PK11_FindCertFromNickname(issuerNickName, pwarg);
+ if ((CERTCertificate *)NULL == issuer) {
+ SECU_PrintError(progName, "unable to find issuer with nickname %s",
+ issuerNickName);
+ return SECFailure;
+ }
+
+ privKey = caPrivateKey = PK11_FindKeyByAnyCert(issuer, pwarg);
+ CERT_DestroyCertificate(issuer);
+ if (caPrivateKey == NULL) {
+ SECU_PrintError(progName, "unable to retrieve key %s", issuerNickName);
+ return SECFailure;
+ }
+ }
+
+ arena = cert->arena;
+
+ algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, hashAlgTag);
+ if (algID == SEC_OID_UNKNOWN) {
+ fprintf(stderr, "Unknown key or hash type for issuer.");
+ rv = SECFailure;
+ goto done;
+ }
+
+ rv = SECOID_SetAlgorithmID(arena, &cert->signature, algID, 0);
+ if (rv != SECSuccess) {
+ fprintf(stderr, "Could not set signature algorithm id.");
+ goto done;
+ }
+
+ switch (certVersion) {
+ case (SEC_CERTIFICATE_VERSION_1):
+ /* The initial version for x509 certificates is version one
+ * and this default value must be an implicit DER encoding. */
+ cert->version.data = NULL;
+ cert->version.len = 0;
+ break;
+ case (SEC_CERTIFICATE_VERSION_2):
+ case (SEC_CERTIFICATE_VERSION_3):
+ case 3: /* unspecified format (would be version 4 certificate). */
+ *(cert->version.data) = certVersion;
+ cert->version.len = 1;
+ break;
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ der.len = 0;
+ der.data = NULL;
+ dummy = SEC_ASN1EncodeItem(arena, &der, cert,
+ SEC_ASN1_GET(CERT_CertificateTemplate));
+ if (!dummy) {
+ fprintf(stderr, "Could not encode certificate.\n");
+ rv = SECFailure;
+ goto done;
+ }
+
+ rv = SEC_DerSignData(arena, &cert->derCert, der.data, der.len, privKey, algID);
+ if (rv != SECSuccess) {
+ fprintf(stderr, "Could not sign encoded certificate data.\n");
+ /* result allocated out of the arena, it will be freed
+ * when the arena is freed */
+ goto done;
+ }
+done:
+ if (caPrivateKey) {
+ SECKEY_DestroyPrivateKey(caPrivateKey);
+ }
+ return rv;
+}
+
+static SECStatus
+CreateCert(
+ CERTCertDBHandle *handle,
+ PK11SlotInfo *slot,
+ char *issuerNickName,
+ const SECItem *certReqDER,
+ SECKEYPrivateKey **selfsignprivkey,
+ void *pwarg,
+ SECOidTag hashAlgTag,
+ unsigned int serialNumber,
+ int warpmonths,
+ int validityMonths,
+ const char *emailAddrs,
+ const char *dnsNames,
+ PRBool ascii,
+ PRBool selfsign,
+ certutilExtnList extnList,
+ const char *extGeneric,
+ int certVersion,
+ SECItem *certDER)
+{
+ void *extHandle = NULL;
+ CERTCertificate *subjectCert = NULL;
+ CERTCertificateRequest *certReq = NULL;
+ SECStatus rv = SECSuccess;
+ CERTCertExtension **CRexts;
+
+ do {
+ /* Create a certrequest object from the input cert request der */
+ certReq = GetCertRequest(certReqDER, pwarg);
+ if (certReq == NULL) {
+ GEN_BREAK(SECFailure)
+ }
+
+ subjectCert = MakeV1Cert(handle, certReq, issuerNickName, selfsign,
+ serialNumber, warpmonths, validityMonths);
+ if (subjectCert == NULL) {
+ GEN_BREAK(SECFailure)
+ }
+
+ extHandle = CERT_StartCertExtensions(subjectCert);
+ if (extHandle == NULL) {
+ GEN_BREAK(SECFailure)
+ }
+
+ rv = AddExtensions(extHandle, emailAddrs, dnsNames, extnList, extGeneric);
+ if (rv != SECSuccess) {
+ GEN_BREAK(SECFailure)
+ }
+
+ if (certReq->attributes != NULL &&
+ certReq->attributes[0] != NULL &&
+ certReq->attributes[0]->attrType.data != NULL &&
+ certReq->attributes[0]->attrType.len > 0 &&
+ SECOID_FindOIDTag(&certReq->attributes[0]->attrType) ==
+ SEC_OID_PKCS9_EXTENSION_REQUEST) {
+ rv = CERT_GetCertificateRequestExtensions(certReq, &CRexts);
+ if (rv != SECSuccess)
+ break;
+ rv = CERT_MergeExtensions(extHandle, CRexts);
+ if (rv != SECSuccess)
+ break;
+ }
+
+ CERT_FinishExtensions(extHandle);
+ extHandle = NULL;
+
+ /* self-signing a cert request, find the private key */
+ if (selfsign && *selfsignprivkey == NULL) {
+ *selfsignprivkey = PK11_FindKeyByDERCert(slot, subjectCert, pwarg);
+ if (!*selfsignprivkey) {
+ fprintf(stderr, "Failed to locate private key.\n");
+ rv = SECFailure;
+ break;
+ }
+ }
+
+ rv = SignCert(handle, subjectCert, selfsign, hashAlgTag,
+ *selfsignprivkey, issuerNickName,
+ certVersion, pwarg);
+ if (rv != SECSuccess)
+ break;
+
+ rv = SECFailure;
+ if (ascii) {
+ char *asciiDER = BTOA_DataToAscii(subjectCert->derCert.data,
+ subjectCert->derCert.len);
+ if (asciiDER) {
+ char *wrapped = PR_smprintf("%s\n%s\n%s\n",
+ NS_CERT_HEADER,
+ asciiDER,
+ NS_CERT_TRAILER);
+ if (wrapped) {
+ PRUint32 wrappedLen = PL_strlen(wrapped);
+ if (SECITEM_AllocItem(NULL, certDER, wrappedLen)) {
+ PORT_Memcpy(certDER->data, wrapped, wrappedLen);
+ rv = SECSuccess;
+ }
+ PR_smprintf_free(wrapped);
+ }
+ PORT_Free(asciiDER);
+ }
+ } else {
+ rv = SECITEM_CopyItem(NULL, certDER, &subjectCert->derCert);
+ }
+ } while (0);
+ if (extHandle) {
+ CERT_FinishExtensions(extHandle);
+ }
+ CERT_DestroyCertificateRequest(certReq);
+ CERT_DestroyCertificate(subjectCert);
+ if (rv != SECSuccess) {
+ PRErrorCode perr = PR_GetError();
+ fprintf(stderr, "%s: unable to create cert (%s)\n", progName,
+ SECU_Strerror(perr));
+ }
+ return (rv);
+}
+
+/*
+ * map a class to a user presentable string
+ */
+static const char *objClassArray[] = {
+ "Data",
+ "Certificate",
+ "Public Key",
+ "Private Key",
+ "Secret Key",
+ "Hardware Feature",
+ "Domain Parameters",
+ "Mechanism"
+};
+
+static const char *objNSSClassArray[] = {
+ "CKO_NSS",
+ "Crl",
+ "SMIME Record",
+ "Trust",
+ "Builtin Root List"
+};
+
+const char *
+getObjectClass(CK_ULONG classType)
+{
+ static char buf[sizeof(CK_ULONG) * 2 + 3];
+
+ if (classType <= CKO_MECHANISM) {
+ return objClassArray[classType];
+ }
+ if (classType >= CKO_NSS && classType <= CKO_NSS_BUILTIN_ROOT_LIST) {
+ return objNSSClassArray[classType - CKO_NSS];
+ }
+ sprintf(buf, "0x%lx", classType);
+ return buf;
+}
+
+typedef struct {
+ char *name;
+ int nameSize;
+ CK_ULONG value;
+} flagArray;
+
+#define NAME_SIZE(x) #x, sizeof(#x) - 1
+
+flagArray opFlagsArray[] =
+ {
+ { NAME_SIZE(encrypt), CKF_ENCRYPT },
+ { NAME_SIZE(decrypt), CKF_DECRYPT },
+ { NAME_SIZE(sign), CKF_SIGN },
+ { NAME_SIZE(sign_recover), CKF_SIGN_RECOVER },
+ { NAME_SIZE(verify), CKF_VERIFY },
+ { NAME_SIZE(verify_recover), CKF_VERIFY_RECOVER },
+ { NAME_SIZE(wrap), CKF_WRAP },
+ { NAME_SIZE(unwrap), CKF_UNWRAP },
+ { NAME_SIZE(derive), CKF_DERIVE },
+ };
+
+int opFlagsCount = sizeof(opFlagsArray) / sizeof(flagArray);
+
+flagArray attrFlagsArray[] =
+ {
+ { NAME_SIZE(token), PK11_ATTR_TOKEN },
+ { NAME_SIZE(session), PK11_ATTR_SESSION },
+ { NAME_SIZE(private), PK11_ATTR_PRIVATE },
+ { NAME_SIZE(public), PK11_ATTR_PUBLIC },
+ { NAME_SIZE(modifiable), PK11_ATTR_MODIFIABLE },
+ { NAME_SIZE(unmodifiable), PK11_ATTR_UNMODIFIABLE },
+ { NAME_SIZE(sensitive), PK11_ATTR_SENSITIVE },
+ { NAME_SIZE(insensitive), PK11_ATTR_INSENSITIVE },
+ { NAME_SIZE(extractable), PK11_ATTR_EXTRACTABLE },
+ { NAME_SIZE(unextractable), PK11_ATTR_UNEXTRACTABLE }
+
+ };
+
+int attrFlagsCount = sizeof(attrFlagsArray) / sizeof(flagArray);
+
+#define MAX_STRING 30
+CK_ULONG
+GetFlags(char *flagsString, flagArray *flagArray, int count)
+{
+ CK_ULONG flagsValue = strtol(flagsString, NULL, 0);
+ int i;
+
+ if ((flagsValue != 0) || (*flagsString == 0)) {
+ return flagsValue;
+ }
+ while (*flagsString) {
+ for (i = 0; i < count; i++) {
+ if (strncmp(flagsString, flagArray[i].name, flagArray[i].nameSize) ==
+ 0) {
+ flagsValue |= flagArray[i].value;
+ flagsString += flagArray[i].nameSize;
+ if (*flagsString != 0) {
+ flagsString++;
+ }
+ break;
+ }
+ }
+ if (i == count) {
+ char name[MAX_STRING];
+ char *tok;
+
+ strncpy(name, flagsString, MAX_STRING);
+ name[MAX_STRING - 1] = 0;
+ tok = strchr(name, ',');
+ if (tok) {
+ *tok = 0;
+ }
+ fprintf(stderr, "Unknown flag (%s)\n", name);
+ tok = strchr(flagsString, ',');
+ if (tok == NULL) {
+ break;
+ }
+ flagsString = tok + 1;
+ }
+ }
+ return flagsValue;
+}
+
+CK_FLAGS
+GetOpFlags(char *flags)
+{
+ return GetFlags(flags, opFlagsArray, opFlagsCount);
+}
+
+PK11AttrFlags
+GetAttrFlags(char *flags)
+{
+ return GetFlags(flags, attrFlagsArray, attrFlagsCount);
+}
+
+char *
+mkNickname(unsigned char *data, int len)
+{
+ char *nick = PORT_Alloc(len + 1);
+ if (!nick) {
+ return nick;
+ }
+ PORT_Memcpy(nick, data, len);
+ nick[len] = 0;
+ return nick;
+}
+
+/*
+ * dump a PK11_MergeTokens error log to the console
+ */
+void
+DumpMergeLog(const char *progname, PK11MergeLog *log)
+{
+ PK11MergeLogNode *node;
+
+ for (node = log->head; node; node = node->next) {
+ SECItem attrItem;
+ char *nickname = NULL;
+ const char *objectClass = NULL;
+ SECStatus rv;
+
+ attrItem.data = NULL;
+ rv = PK11_ReadRawAttribute(PK11_TypeGeneric, node->object,
+ CKA_LABEL, &attrItem);
+ if (rv == SECSuccess) {
+ nickname = mkNickname(attrItem.data, attrItem.len);
+ PORT_Free(attrItem.data);
+ }
+ attrItem.data = NULL;
+ rv = PK11_ReadRawAttribute(PK11_TypeGeneric, node->object,
+ CKA_CLASS, &attrItem);
+ if (rv == SECSuccess) {
+ if (attrItem.len == sizeof(CK_ULONG)) {
+ objectClass = getObjectClass(*(CK_ULONG *)attrItem.data);
+ }
+ PORT_Free(attrItem.data);
+ }
+
+ fprintf(stderr, "%s: Could not merge object %s (type %s): %s\n",
+ progName,
+ nickname ? nickname : "unnamed",
+ objectClass ? objectClass : "unknown",
+ SECU_Strerror(node->error));
+
+ if (nickname) {
+ PORT_Free(nickname);
+ }
+ }
+}
+
+/* Certutil commands */
+enum {
+ cmd_AddCert = 0,
+ cmd_CreateNewCert,
+ cmd_DeleteCert,
+ cmd_AddEmailCert,
+ cmd_DeleteKey,
+ cmd_GenKeyPair,
+ cmd_PrintHelp,
+ cmd_PrintSyntax,
+ cmd_ListKeys,
+ cmd_ListCerts,
+ cmd_ModifyCertTrust,
+ cmd_NewDBs,
+ cmd_DumpChain,
+ cmd_CertReq,
+ cmd_CreateAndAddCert,
+ cmd_TokenReset,
+ cmd_ListModules,
+ cmd_CheckCertValidity,
+ cmd_ChangePassword,
+ cmd_Version,
+ cmd_Batch,
+ cmd_Merge,
+ cmd_UpgradeMerge, /* test only */
+ cmd_Rename,
+ max_cmd
+};
+
+/* Certutil options */
+enum certutilOpts {
+ opt_SSOPass = 0,
+ opt_AddKeyUsageExt,
+ opt_AddBasicConstraintExt,
+ opt_AddAuthorityKeyIDExt,
+ opt_AddCRLDistPtsExt,
+ opt_AddNSCertTypeExt,
+ opt_AddExtKeyUsageExt,
+ opt_ExtendedEmailAddrs,
+ opt_ExtendedDNSNames,
+ opt_ASCIIForIO,
+ opt_ValidityTime,
+ opt_IssuerName,
+ opt_CertDir,
+ opt_VerifySig,
+ opt_PasswordFile,
+ opt_KeySize,
+ opt_TokenName,
+ opt_InputFile,
+ opt_Emailaddress,
+ opt_KeyIndex,
+ opt_KeyType,
+ opt_DetailedInfo,
+ opt_SerialNumber,
+ opt_Nickname,
+ opt_OutputFile,
+ opt_PhoneNumber,
+ opt_DBPrefix,
+ opt_PQGFile,
+ opt_BinaryDER,
+ opt_Subject,
+ opt_Trust,
+ opt_Usage,
+ opt_Validity,
+ opt_OffsetMonths,
+ opt_SelfSign,
+ opt_RW,
+ opt_Exponent,
+ opt_NoiseFile,
+ opt_Hash,
+ opt_NewPasswordFile,
+ opt_AddAuthInfoAccExt,
+ opt_AddSubjInfoAccExt,
+ opt_AddCertPoliciesExt,
+ opt_AddPolicyMapExt,
+ opt_AddPolicyConstrExt,
+ opt_AddInhibAnyExt,
+ opt_AddNameConstraintsExt,
+ opt_AddSubjectKeyIDExt,
+ opt_AddCmdKeyUsageExt,
+ opt_AddCmdNSCertTypeExt,
+ opt_AddCmdExtKeyUsageExt,
+ opt_SourceDir,
+ opt_SourcePrefix,
+ opt_UpgradeID,
+ opt_UpgradeTokenName,
+ opt_KeyOpFlagsOn,
+ opt_KeyOpFlagsOff,
+ opt_KeyAttrFlags,
+ opt_EmptyPassword,
+ opt_CertVersion,
+ opt_AddSubjectAltNameExt,
+ opt_DumpExtensionValue,
+ opt_GenericExtensions,
+ opt_NewNickname,
+ opt_Pss,
+ opt_Help
+};
+
+static const secuCommandFlag commands_init[] =
+ {
+ { /* cmd_AddCert */ 'A', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_CreateNewCert */ 'C', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_DeleteCert */ 'D', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_AddEmailCert */ 'E', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_DeleteKey */ 'F', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_GenKeyPair */ 'G', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_PrintHelp */ 'H', PR_FALSE, 0, PR_FALSE, "help" },
+ { /* cmd_PrintSyntax */ 0, PR_FALSE, 0, PR_FALSE,
+ "syntax" },
+ { /* cmd_ListKeys */ 'K', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_ListCerts */ 'L', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_ModifyCertTrust */ 'M', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_NewDBs */ 'N', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_DumpChain */ 'O', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_CertReq */ 'R', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_CreateAndAddCert */ 'S', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_TokenReset */ 'T', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_ListModules */ 'U', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_CheckCertValidity */ 'V', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_ChangePassword */ 'W', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_Version */ 'Y', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_Batch */ 'B', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_Merge */ 0, PR_FALSE, 0, PR_FALSE, "merge" },
+ { /* cmd_UpgradeMerge */ 0, PR_FALSE, 0, PR_FALSE,
+ "upgrade-merge" },
+ { /* cmd_Rename */ 0, PR_FALSE, 0, PR_FALSE,
+ "rename" }
+ };
+#define NUM_COMMANDS ((sizeof commands_init) / (sizeof commands_init[0]))
+
+static const secuCommandFlag options_init[] =
+ {
+ { /* opt_SSOPass */ '0', PR_TRUE, 0, PR_FALSE },
+ { /* opt_AddKeyUsageExt */ '1', PR_FALSE, 0, PR_FALSE },
+ { /* opt_AddBasicConstraintExt*/ '2', PR_FALSE, 0, PR_FALSE },
+ { /* opt_AddAuthorityKeyIDExt*/ '3', PR_FALSE, 0, PR_FALSE },
+ { /* opt_AddCRLDistPtsExt */ '4', PR_FALSE, 0, PR_FALSE },
+ { /* opt_AddNSCertTypeExt */ '5', PR_FALSE, 0, PR_FALSE },
+ { /* opt_AddExtKeyUsageExt */ '6', PR_FALSE, 0, PR_FALSE },
+ { /* opt_ExtendedEmailAddrs */ '7', PR_TRUE, 0, PR_FALSE },
+ { /* opt_ExtendedDNSNames */ '8', PR_TRUE, 0, PR_FALSE },
+ { /* opt_ASCIIForIO */ 'a', PR_FALSE, 0, PR_FALSE },
+ { /* opt_ValidityTime */ 'b', PR_TRUE, 0, PR_FALSE },
+ { /* opt_IssuerName */ 'c', PR_TRUE, 0, PR_FALSE },
+ { /* opt_CertDir */ 'd', PR_TRUE, 0, PR_FALSE },
+ { /* opt_VerifySig */ 'e', PR_FALSE, 0, PR_FALSE },
+ { /* opt_PasswordFile */ 'f', PR_TRUE, 0, PR_FALSE },
+ { /* opt_KeySize */ 'g', PR_TRUE, 0, PR_FALSE },
+ { /* opt_TokenName */ 'h', PR_TRUE, 0, PR_FALSE },
+ { /* opt_InputFile */ 'i', PR_TRUE, 0, PR_FALSE },
+ { /* opt_Emailaddress */ 0, PR_TRUE, 0, PR_FALSE, "email" },
+ { /* opt_KeyIndex */ 'j', PR_TRUE, 0, PR_FALSE },
+ { /* opt_KeyType */ 'k', PR_TRUE, 0, PR_FALSE },
+ { /* opt_DetailedInfo */ 'l', PR_FALSE, 0, PR_FALSE },
+ { /* opt_SerialNumber */ 'm', PR_TRUE, 0, PR_FALSE },
+ { /* opt_Nickname */ 'n', PR_TRUE, 0, PR_FALSE },
+ { /* opt_OutputFile */ 'o', PR_TRUE, 0, PR_FALSE },
+ { /* opt_PhoneNumber */ 'p', PR_TRUE, 0, PR_FALSE },
+ { /* opt_DBPrefix */ 'P', PR_TRUE, 0, PR_FALSE },
+ { /* opt_PQGFile */ 'q', PR_TRUE, 0, PR_FALSE },
+ { /* opt_BinaryDER */ 'r', PR_FALSE, 0, PR_FALSE },
+ { /* opt_Subject */ 's', PR_TRUE, 0, PR_FALSE },
+ { /* opt_Trust */ 't', PR_TRUE, 0, PR_FALSE },
+ { /* opt_Usage */ 'u', PR_TRUE, 0, PR_FALSE },
+ { /* opt_Validity */ 'v', PR_TRUE, 0, PR_FALSE },
+ { /* opt_OffsetMonths */ 'w', PR_TRUE, 0, PR_FALSE },
+ { /* opt_SelfSign */ 'x', PR_FALSE, 0, PR_FALSE },
+ { /* opt_RW */ 'X', PR_FALSE, 0, PR_FALSE },
+ { /* opt_Exponent */ 'y', PR_TRUE, 0, PR_FALSE },
+ { /* opt_NoiseFile */ 'z', PR_TRUE, 0, PR_FALSE },
+ { /* opt_Hash */ 'Z', PR_TRUE, 0, PR_FALSE },
+ { /* opt_NewPasswordFile */ '@', PR_TRUE, 0, PR_FALSE },
+ { /* opt_AddAuthInfoAccExt */ 0, PR_FALSE, 0, PR_FALSE, "extAIA" },
+ { /* opt_AddSubjInfoAccExt */ 0, PR_FALSE, 0, PR_FALSE, "extSIA" },
+ { /* opt_AddCertPoliciesExt */ 0, PR_FALSE, 0, PR_FALSE, "extCP" },
+ { /* opt_AddPolicyMapExt */ 0, PR_FALSE, 0, PR_FALSE, "extPM" },
+ { /* opt_AddPolicyConstrExt */ 0, PR_FALSE, 0, PR_FALSE, "extPC" },
+ { /* opt_AddInhibAnyExt */ 0, PR_FALSE, 0, PR_FALSE, "extIA" },
+ { /* opt_AddNameConstraintsExt*/ 0, PR_FALSE, 0, PR_FALSE, "extNC" },
+ { /* opt_AddSubjectKeyIDExt */ 0, PR_FALSE, 0, PR_FALSE,
+ "extSKID" },
+ { /* opt_AddCmdKeyUsageExt */ 0, PR_TRUE, 0, PR_FALSE,
+ "keyUsage" },
+ { /* opt_AddCmdNSCertTypeExt */ 0, PR_TRUE, 0, PR_FALSE,
+ "nsCertType" },
+ { /* opt_AddCmdExtKeyUsageExt*/ 0, PR_TRUE, 0, PR_FALSE,
+ "extKeyUsage" },
+
+ { /* opt_SourceDir */ 0, PR_TRUE, 0, PR_FALSE,
+ "source-dir" },
+ { /* opt_SourcePrefix */ 0, PR_TRUE, 0, PR_FALSE,
+ "source-prefix" },
+ { /* opt_UpgradeID */ 0, PR_TRUE, 0, PR_FALSE,
+ "upgrade-id" },
+ { /* opt_UpgradeTokenName */ 0, PR_TRUE, 0, PR_FALSE,
+ "upgrade-token-name" },
+ { /* opt_KeyOpFlagsOn */ 0, PR_TRUE, 0, PR_FALSE,
+ "keyOpFlagsOn" },
+ { /* opt_KeyOpFlagsOff */ 0, PR_TRUE, 0, PR_FALSE,
+ "keyOpFlagsOff" },
+ { /* opt_KeyAttrFlags */ 0, PR_TRUE, 0, PR_FALSE,
+ "keyAttrFlags" },
+ { /* opt_EmptyPassword */ 0, PR_FALSE, 0, PR_FALSE,
+ "empty-password" },
+ { /* opt_CertVersion */ 0, PR_TRUE, 0, PR_FALSE,
+ "certVersion" },
+ { /* opt_AddSubjectAltExt */ 0, PR_TRUE, 0, PR_FALSE, "extSAN" },
+ { /* opt_DumpExtensionValue */ 0, PR_TRUE, 0, PR_FALSE,
+ "dump-ext-val" },
+ { /* opt_GenericExtensions */ 0, PR_TRUE, 0, PR_FALSE,
+ "extGeneric" },
+ { /* opt_NewNickname */ 0, PR_TRUE, 0, PR_FALSE,
+ "new-n" },
+ { /* opt_Pss */ 0, PR_FALSE, 0, PR_FALSE,
+ "pss" },
+ };
+#define NUM_OPTIONS ((sizeof options_init) / (sizeof options_init[0]))
+
+static secuCommandFlag certutil_commands[NUM_COMMANDS];
+static secuCommandFlag certutil_options[NUM_OPTIONS];
+
+static const secuCommand certutil = {
+ NUM_COMMANDS,
+ NUM_OPTIONS,
+ certutil_commands,
+ certutil_options
+};
+
+static certutilExtnList certutil_extns;
+
+static int
+certutil_main(int argc, char **argv, PRBool initialize)
+{
+ CERTCertDBHandle *certHandle;
+ PK11SlotInfo *slot = NULL;
+ CERTName *subject = 0;
+ PRFileDesc *inFile = PR_STDIN;
+ PRFileDesc *outFile = PR_STDOUT;
+ SECItem certReqDER = { siBuffer, NULL, 0 };
+ SECItem certDER = { siBuffer, NULL, 0 };
+ const char *slotname = "internal";
+ const char *certPrefix = "";
+ char *sourceDir = "";
+ const char *srcCertPrefix = "";
+ char *upgradeID = "";
+ char *upgradeTokenName = "";
+ KeyType keytype = rsaKey;
+ char *name = NULL;
+ char *newName = NULL;
+ char *email = NULL;
+ char *keysource = NULL;
+ SECOidTag hashAlgTag = SEC_OID_UNKNOWN;
+ int keysize = DEFAULT_KEY_BITS;
+ int publicExponent = 0x010001;
+ int certVersion = SEC_CERTIFICATE_VERSION_3;
+ unsigned int serialNumber = 0;
+ int warpmonths = 0;
+ int validityMonths = 3;
+ int commandsEntered = 0;
+ char commandToRun = '\0';
+ secuPWData pwdata = { PW_NONE, 0 };
+ secuPWData pwdata2 = { PW_NONE, 0 };
+ PRBool readOnly = PR_FALSE;
+ PRBool initialized = PR_FALSE;
+ CK_FLAGS keyOpFlagsOn = 0;
+ CK_FLAGS keyOpFlagsOff = 0;
+ PK11AttrFlags keyAttrFlags =
+ PK11_ATTR_TOKEN | PK11_ATTR_SENSITIVE | PK11_ATTR_PRIVATE;
+
+ SECKEYPrivateKey *privkey = NULL;
+ SECKEYPublicKey *pubkey = NULL;
+
+ int i;
+ SECStatus rv;
+
+ progName = PORT_Strrchr(argv[0], '/');
+ progName = progName ? progName + 1 : argv[0];
+ memcpy(certutil_commands, commands_init, sizeof commands_init);
+ memcpy(certutil_options, options_init, sizeof options_init);
+
+ rv = SECU_ParseCommandLine(argc, argv, progName, &certutil);
+
+ if (rv != SECSuccess)
+ Usage(progName);
+
+ if (certutil.commands[cmd_PrintSyntax].activated) {
+ PrintSyntax(progName);
+ }
+
+ if (certutil.commands[cmd_PrintHelp].activated) {
+ int i;
+ char buf[2];
+ const char *command = NULL;
+ for (i = 0; i < max_cmd; i++) {
+ if (i == cmd_PrintHelp)
+ continue;
+ if (certutil.commands[i].activated) {
+ if (certutil.commands[i].flag) {
+ buf[0] = certutil.commands[i].flag;
+ buf[1] = 0;
+ command = buf;
+ } else {
+ command = certutil.commands[i].longform;
+ }
+ break;
+ }
+ }
+ LongUsage(progName, (command ? usage_selected : usage_all), command);
+ exit(1);
+ }
+
+ if (certutil.options[opt_PasswordFile].arg) {
+ pwdata.source = PW_FROMFILE;
+ pwdata.data = certutil.options[opt_PasswordFile].arg;
+ }
+ if (certutil.options[opt_NewPasswordFile].arg) {
+ pwdata2.source = PW_FROMFILE;
+ pwdata2.data = certutil.options[opt_NewPasswordFile].arg;
+ }
+
+ if (certutil.options[opt_CertDir].activated)
+ SECU_ConfigDirectory(certutil.options[opt_CertDir].arg);
+
+ if (certutil.options[opt_SourceDir].activated)
+ sourceDir = certutil.options[opt_SourceDir].arg;
+
+ if (certutil.options[opt_UpgradeID].activated)
+ upgradeID = certutil.options[opt_UpgradeID].arg;
+
+ if (certutil.options[opt_UpgradeTokenName].activated)
+ upgradeTokenName = certutil.options[opt_UpgradeTokenName].arg;
+
+ if (certutil.options[opt_KeySize].activated) {
+ keysize = PORT_Atoi(certutil.options[opt_KeySize].arg);
+ if ((keysize < MIN_KEY_BITS) || (keysize > MAX_KEY_BITS)) {
+ PR_fprintf(PR_STDERR,
+ "%s -g: Keysize must be between %d and %d.\n",
+ progName, MIN_KEY_BITS, MAX_KEY_BITS);
+ return 255;
+ }
+#ifndef NSS_DISABLE_ECC
+ if (keytype == ecKey) {
+ PR_fprintf(PR_STDERR, "%s -g: Not for ec keys.\n", progName);
+ return 255;
+ }
+#endif /* NSS_DISABLE_ECC */
+ }
+
+ /* -h specify token name */
+ if (certutil.options[opt_TokenName].activated) {
+ if (PL_strcmp(certutil.options[opt_TokenName].arg, "all") == 0)
+ slotname = NULL;
+ else
+ slotname = certutil.options[opt_TokenName].arg;
+ }
+
+ /* -Z hash type */
+ if (certutil.options[opt_Hash].activated) {
+ char *arg = certutil.options[opt_Hash].arg;
+ hashAlgTag = SECU_StringToSignatureAlgTag(arg);
+ if (hashAlgTag == SEC_OID_UNKNOWN) {
+ PR_fprintf(PR_STDERR, "%s -Z: %s is not a recognized type.\n",
+ progName, arg);
+ return 255;
+ }
+ }
+
+ /* -k key type */
+ if (certutil.options[opt_KeyType].activated) {
+ char *arg = certutil.options[opt_KeyType].arg;
+ if (PL_strcmp(arg, "rsa") == 0) {
+ keytype = rsaKey;
+ } else if (PL_strcmp(arg, "dsa") == 0) {
+ keytype = dsaKey;
+#ifndef NSS_DISABLE_ECC
+ } else if (PL_strcmp(arg, "ec") == 0) {
+ keytype = ecKey;
+#endif /* NSS_DISABLE_ECC */
+ } else if (PL_strcmp(arg, "all") == 0) {
+ keytype = nullKey;
+ } else {
+ /* use an existing private/public key pair */
+ keysource = arg;
+ }
+ } else if (certutil.commands[cmd_ListKeys].activated) {
+ keytype = nullKey;
+ }
+
+ if (certutil.options[opt_KeyOpFlagsOn].activated) {
+ keyOpFlagsOn = GetOpFlags(certutil.options[opt_KeyOpFlagsOn].arg);
+ }
+ if (certutil.options[opt_KeyOpFlagsOff].activated) {
+ keyOpFlagsOff = GetOpFlags(certutil.options[opt_KeyOpFlagsOff].arg);
+ keyOpFlagsOn &= ~keyOpFlagsOff; /* make off override on */
+ }
+ if (certutil.options[opt_KeyAttrFlags].activated) {
+ keyAttrFlags = GetAttrFlags(certutil.options[opt_KeyAttrFlags].arg);
+ }
+
+ /* -m serial number */
+ if (certutil.options[opt_SerialNumber].activated) {
+ int sn = PORT_Atoi(certutil.options[opt_SerialNumber].arg);
+ if (sn < 0) {
+ PR_fprintf(PR_STDERR, "%s -m: %s is not a valid serial number.\n",
+ progName, certutil.options[opt_SerialNumber].arg);
+ return 255;
+ }
+ serialNumber = sn;
+ }
+
+ /* -P certdb name prefix */
+ if (certutil.options[opt_DBPrefix].activated) {
+ if (certutil.options[opt_DBPrefix].arg) {
+ certPrefix = certutil.options[opt_DBPrefix].arg;
+ } else {
+ Usage(progName);
+ }
+ }
+
+ /* --source-prefix certdb name prefix */
+ if (certutil.options[opt_SourcePrefix].activated) {
+ if (certutil.options[opt_SourcePrefix].arg) {
+ srcCertPrefix = certutil.options[opt_SourcePrefix].arg;
+ } else {
+ Usage(progName);
+ }
+ }
+
+ /* -q PQG file or curve name */
+ if (certutil.options[opt_PQGFile].activated) {
+#ifndef NSS_DISABLE_ECC
+ if ((keytype != dsaKey) && (keytype != ecKey)) {
+ PR_fprintf(PR_STDERR, "%s -q: specifies a PQG file for DSA keys"
+ " (-k dsa) or a named curve for EC keys (-k ec)\n)",
+ progName);
+#else /* } */
+ if (keytype != dsaKey) {
+ PR_fprintf(PR_STDERR, "%s -q: PQG file is for DSA key (-k dsa).\n)",
+ progName);
+#endif /* NSS_DISABLE_ECC */
+ return 255;
+ }
+ }
+
+ /* -s subject name */
+ if (certutil.options[opt_Subject].activated) {
+ subject = CERT_AsciiToName(certutil.options[opt_Subject].arg);
+ if (!subject) {
+ PR_fprintf(PR_STDERR, "%s -s: improperly formatted name: \"%s\"\n",
+ progName, certutil.options[opt_Subject].arg);
+ return 255;
+ }
+ }
+
+ /* -v validity period */
+ if (certutil.options[opt_Validity].activated) {
+ validityMonths = PORT_Atoi(certutil.options[opt_Validity].arg);
+ if (validityMonths < 0) {
+ PR_fprintf(PR_STDERR, "%s -v: incorrect validity period: \"%s\"\n",
+ progName, certutil.options[opt_Validity].arg);
+ return 255;
+ }
+ }
+
+ /* -w warp months */
+ if (certutil.options[opt_OffsetMonths].activated)
+ warpmonths = PORT_Atoi(certutil.options[opt_OffsetMonths].arg);
+
+ /* -y public exponent (for RSA) */
+ if (certutil.options[opt_Exponent].activated) {
+ publicExponent = PORT_Atoi(certutil.options[opt_Exponent].arg);
+ if ((publicExponent != 3) &&
+ (publicExponent != 17) &&
+ (publicExponent != 65537)) {
+ PR_fprintf(PR_STDERR, "%s -y: incorrect public exponent %d.",
+ progName, publicExponent);
+ PR_fprintf(PR_STDERR, "Must be 3, 17, or 65537.\n");
+ return 255;
+ }
+ }
+
+ /* --certVersion */
+ if (certutil.options[opt_CertVersion].activated) {
+ certVersion = PORT_Atoi(certutil.options[opt_CertVersion].arg);
+ if (certVersion < 1 || certVersion > 4) {
+ PR_fprintf(PR_STDERR, "%s -certVersion: incorrect certificate version %d.",
+ progName, certVersion);
+ PR_fprintf(PR_STDERR, "Must be 1, 2, 3 or 4.\n");
+ return 255;
+ }
+ certVersion = certVersion - 1;
+ }
+
+ /* Check number of commands entered. */
+ commandsEntered = 0;
+ for (i = 0; i < certutil.numCommands; i++) {
+ if (certutil.commands[i].activated) {
+ commandToRun = certutil.commands[i].flag;
+ commandsEntered++;
+ }
+ if (commandsEntered > 1)
+ break;
+ }
+ if (commandsEntered > 1) {
+ PR_fprintf(PR_STDERR, "%s: only one command at a time!\n", progName);
+ PR_fprintf(PR_STDERR, "You entered: ");
+ for (i = 0; i < certutil.numCommands; i++) {
+ if (certutil.commands[i].activated)
+ PR_fprintf(PR_STDERR, " -%c", certutil.commands[i].flag);
+ }
+ PR_fprintf(PR_STDERR, "\n");
+ return 255;
+ }
+ if (commandsEntered == 0) {
+ Usage(progName);
+ }
+
+ if (certutil.commands[cmd_ListCerts].activated ||
+ certutil.commands[cmd_PrintHelp].activated ||
+ certutil.commands[cmd_ListKeys].activated ||
+ certutil.commands[cmd_ListModules].activated ||
+ certutil.commands[cmd_CheckCertValidity].activated ||
+ certutil.commands[cmd_Version].activated) {
+ readOnly = !certutil.options[opt_RW].activated;
+ }
+
+ /* -A, -D, -F, -M, -S, -V, and all require -n */
+ if ((certutil.commands[cmd_AddCert].activated ||
+ certutil.commands[cmd_DeleteCert].activated ||
+ certutil.commands[cmd_DeleteKey].activated ||
+ certutil.commands[cmd_DumpChain].activated ||
+ certutil.commands[cmd_ModifyCertTrust].activated ||
+ certutil.commands[cmd_CreateAndAddCert].activated ||
+ certutil.commands[cmd_CheckCertValidity].activated) &&
+ !certutil.options[opt_Nickname].activated) {
+ PR_fprintf(PR_STDERR,
+ "%s -%c: nickname is required for this command (-n).\n",
+ progName, commandToRun);
+ return 255;
+ }
+
+ /* -A, -E, -M, -S require trust */
+ if ((certutil.commands[cmd_AddCert].activated ||
+ certutil.commands[cmd_AddEmailCert].activated ||
+ certutil.commands[cmd_ModifyCertTrust].activated ||
+ certutil.commands[cmd_CreateAndAddCert].activated) &&
+ !certutil.options[opt_Trust].activated) {
+ PR_fprintf(PR_STDERR,
+ "%s -%c: trust is required for this command (-t).\n",
+ progName, commandToRun);
+ return 255;
+ }
+
+ /* if -L is given raw, ascii or dump mode, it must be for only one cert. */
+ if (certutil.commands[cmd_ListCerts].activated &&
+ (certutil.options[opt_ASCIIForIO].activated ||
+ certutil.options[opt_DumpExtensionValue].activated ||
+ certutil.options[opt_BinaryDER].activated) &&
+ !certutil.options[opt_Nickname].activated) {
+ PR_fprintf(PR_STDERR,
+ "%s: nickname is required to dump cert in raw or ascii mode.\n",
+ progName);
+ return 255;
+ }
+
+ /* -L can only be in (raw || ascii). */
+ if (certutil.commands[cmd_ListCerts].activated &&
+ certutil.options[opt_ASCIIForIO].activated &&
+ certutil.options[opt_BinaryDER].activated) {
+ PR_fprintf(PR_STDERR,
+ "%s: cannot specify both -r and -a when dumping cert.\n",
+ progName);
+ return 255;
+ }
+
+ /* If making a cert request, need a subject. */
+ if ((certutil.commands[cmd_CertReq].activated ||
+ certutil.commands[cmd_CreateAndAddCert].activated) &&
+ !(certutil.options[opt_Subject].activated || keysource)) {
+ PR_fprintf(PR_STDERR,
+ "%s -%c: subject is required to create a cert request.\n",
+ progName, commandToRun);
+ return 255;
+ }
+
+ /* If making a cert, need a serial number. */
+ if ((certutil.commands[cmd_CreateNewCert].activated ||
+ certutil.commands[cmd_CreateAndAddCert].activated) &&
+ !certutil.options[opt_SerialNumber].activated) {
+ /* Make a default serial number from the current time. */
+ PRTime now = PR_Now();
+ LL_USHR(now, now, 19);
+ LL_L2UI(serialNumber, now);
+ }
+
+ /* Validation needs the usage to validate for. */
+ if (certutil.commands[cmd_CheckCertValidity].activated &&
+ !certutil.options[opt_Usage].activated) {
+ PR_fprintf(PR_STDERR,
+ "%s -V: specify a usage to validate the cert for (-u).\n",
+ progName);
+ return 255;
+ }
+
+ /* Rename needs an old and a new nickname */
+ if (certutil.commands[cmd_Rename].activated &&
+ !(certutil.options[opt_Nickname].activated &&
+ certutil.options[opt_NewNickname].activated)) {
+
+ PR_fprintf(PR_STDERR,
+ "%s --rename: specify an old nickname (-n) and\n"
+ " a new nickname (--new-n).\n",
+ progName);
+ return 255;
+ }
+
+ /* Upgrade/Merge needs a source database and a upgrade id. */
+ if (certutil.commands[cmd_UpgradeMerge].activated &&
+ !(certutil.options[opt_SourceDir].activated &&
+ certutil.options[opt_UpgradeID].activated)) {
+
+ PR_fprintf(PR_STDERR,
+ "%s --upgrade-merge: specify an upgrade database directory "
+ "(--source-dir) and\n"
+ " an upgrade ID (--upgrade-id).\n",
+ progName);
+ return 255;
+ }
+
+ /* Merge needs a source database */
+ if (certutil.commands[cmd_Merge].activated &&
+ !certutil.options[opt_SourceDir].activated) {
+
+ PR_fprintf(PR_STDERR,
+ "%s --merge: specify an source database directory "
+ "(--source-dir)\n",
+ progName);
+ return 255;
+ }
+
+ /* To make a cert, need either a issuer or to self-sign it. */
+ if (certutil.commands[cmd_CreateAndAddCert].activated &&
+ !(certutil.options[opt_IssuerName].activated ||
+ certutil.options[opt_SelfSign].activated)) {
+ PR_fprintf(PR_STDERR,
+ "%s -S: must specify issuer (-c) or self-sign (-x).\n",
+ progName);
+ return 255;
+ }
+
+ /* Using slotname == NULL for listing keys and certs on all slots,
+ * but only that. */
+ if (!(certutil.commands[cmd_ListKeys].activated ||
+ certutil.commands[cmd_DumpChain].activated ||
+ certutil.commands[cmd_ListCerts].activated) &&
+ slotname == NULL) {
+ PR_fprintf(PR_STDERR,
+ "%s -%c: cannot use \"-h all\" for this command.\n",
+ progName, commandToRun);
+ return 255;
+ }
+
+ /* Using keytype == nullKey for list all key types, but only that. */
+ if (!certutil.commands[cmd_ListKeys].activated && keytype == nullKey) {
+ PR_fprintf(PR_STDERR,
+ "%s -%c: cannot use \"-k all\" for this command.\n",
+ progName, commandToRun);
+ return 255;
+ }
+
+ /* Open the input file. */
+ if (certutil.options[opt_InputFile].activated) {
+ inFile = PR_Open(certutil.options[opt_InputFile].arg, PR_RDONLY, 0);
+ if (!inFile) {
+ PR_fprintf(PR_STDERR,
+ "%s: unable to open \"%s\" for reading (%ld, %ld).\n",
+ progName, certutil.options[opt_InputFile].arg,
+ PR_GetError(), PR_GetOSError());
+ return 255;
+ }
+ }
+
+ /* Open the output file. */
+ if (certutil.options[opt_OutputFile].activated) {
+ outFile = PR_Open(certutil.options[opt_OutputFile].arg,
+ PR_CREATE_FILE | PR_RDWR | PR_TRUNCATE, 00660);
+ if (!outFile) {
+ PR_fprintf(PR_STDERR,
+ "%s: unable to open \"%s\" for writing (%ld, %ld).\n",
+ progName, certutil.options[opt_OutputFile].arg,
+ PR_GetError(), PR_GetOSError());
+ return 255;
+ }
+ }
+
+ name = SECU_GetOptionArg(&certutil, opt_Nickname);
+ newName = SECU_GetOptionArg(&certutil, opt_NewNickname);
+ email = SECU_GetOptionArg(&certutil, opt_Emailaddress);
+
+ PK11_SetPasswordFunc(SECU_GetModulePassword);
+
+ if (PR_TRUE == initialize) {
+ /* Initialize NSPR and NSS. */
+ PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
+ if (!certutil.commands[cmd_UpgradeMerge].activated) {
+ rv = NSS_Initialize(SECU_ConfigDirectory(NULL),
+ certPrefix, certPrefix,
+ "secmod.db", readOnly ? NSS_INIT_READONLY : 0);
+ } else {
+ rv = NSS_InitWithMerge(SECU_ConfigDirectory(NULL),
+ certPrefix, certPrefix, "secmod.db",
+ sourceDir, srcCertPrefix, srcCertPrefix,
+ upgradeID, upgradeTokenName,
+ readOnly ? NSS_INIT_READONLY : 0);
+ }
+ if (rv != SECSuccess) {
+ SECU_PrintPRandOSError(progName);
+ rv = SECFailure;
+ goto shutdown;
+ }
+ initialized = PR_TRUE;
+ SECU_RegisterDynamicOids();
+ }
+ certHandle = CERT_GetDefaultCertDB();
+
+ if (certutil.commands[cmd_Version].activated) {
+ printf("Certificate database content version: command not implemented.\n");
+ }
+
+ if (PL_strcmp(slotname, "internal") == 0)
+ slot = PK11_GetInternalKeySlot();
+ else if (slotname != NULL)
+ slot = PK11_FindSlotByName(slotname);
+
+ if (!slot && (certutil.commands[cmd_NewDBs].activated ||
+ certutil.commands[cmd_ModifyCertTrust].activated ||
+ certutil.commands[cmd_ChangePassword].activated ||
+ certutil.commands[cmd_TokenReset].activated ||
+ certutil.commands[cmd_CreateAndAddCert].activated ||
+ certutil.commands[cmd_AddCert].activated ||
+ certutil.commands[cmd_Merge].activated ||
+ certutil.commands[cmd_UpgradeMerge].activated ||
+ certutil.commands[cmd_AddEmailCert].activated)) {
+
+ SECU_PrintError(progName, "could not find the slot %s", slotname);
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+ /* If creating new database, initialize the password. */
+ if (certutil.commands[cmd_NewDBs].activated) {
+ if (certutil.options[opt_EmptyPassword].activated && (PK11_NeedUserInit(slot)))
+ PK11_InitPin(slot, (char *)NULL, "");
+ else
+ SECU_ChangePW2(slot, 0, 0, certutil.options[opt_PasswordFile].arg,
+ certutil.options[opt_NewPasswordFile].arg);
+ }
+
+ /* walk through the upgrade merge if necessary.
+ * This option is more to test what some applications will want to do
+ * to do an automatic upgrade. The --merge command is more useful for
+ * the general case where 2 database need to be merged together.
+ */
+ if (certutil.commands[cmd_UpgradeMerge].activated) {
+ if (*upgradeTokenName == 0) {
+ upgradeTokenName = upgradeID;
+ }
+ if (!PK11_IsInternal(slot)) {
+ fprintf(stderr, "Only internal DB's can be upgraded\n");
+ rv = SECSuccess;
+ goto shutdown;
+ }
+ if (!PK11_IsRemovable(slot)) {
+ printf("database already upgraded.\n");
+ rv = SECSuccess;
+ goto shutdown;
+ }
+ if (!PK11_NeedLogin(slot)) {
+ printf("upgrade complete!\n");
+ rv = SECSuccess;
+ goto shutdown;
+ }
+ /* authenticate to the old DB if necessary */
+ if (PORT_Strcmp(PK11_GetTokenName(slot), upgradeTokenName) == 0) {
+ /* if we need a password, supply it. This will be the password
+ * for the old database */
+ rv = PK11_Authenticate(slot, PR_FALSE, &pwdata2);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "Could not get password for %s",
+ upgradeTokenName);
+ goto shutdown;
+ }
+ /*
+ * if we succeeded above, but still aren't logged in, that means
+ * we just supplied the password for the old database. We may
+ * need the password for the new database. NSS will automatically
+ * change the token names at this point
+ */
+ if (PK11_IsLoggedIn(slot, &pwdata)) {
+ printf("upgrade complete!\n");
+ rv = SECSuccess;
+ goto shutdown;
+ }
+ }
+
+ /* call PK11_IsPresent to update our cached token information */
+ if (!PK11_IsPresent(slot)) {
+ /* this shouldn't happen. We call isPresent to force a token
+ * info update */
+ fprintf(stderr, "upgrade/merge internal error\n");
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+ /* the token is now set to the state of the source database,
+ * if we need a password for it, PK11_Authenticate will
+ * automatically prompt us */
+ rv = PK11_Authenticate(slot, PR_FALSE, &pwdata);
+ if (rv == SECSuccess) {
+ printf("upgrade complete!\n");
+ } else {
+ SECU_PrintError(progName, "Could not get password for %s",
+ PK11_GetTokenName(slot));
+ }
+ goto shutdown;
+ }
+
+ /*
+ * merge 2 databases.
+ */
+ if (certutil.commands[cmd_Merge].activated) {
+ PK11SlotInfo *sourceSlot = NULL;
+ PK11MergeLog *log;
+ char *modspec = PR_smprintf(
+ "configDir='%s' certPrefix='%s' tokenDescription='%s'",
+ sourceDir, srcCertPrefix,
+ *upgradeTokenName ? upgradeTokenName : "Source Database");
+
+ if (!modspec) {
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+ sourceSlot = SECMOD_OpenUserDB(modspec);
+ PR_smprintf_free(modspec);
+ if (!sourceSlot) {
+ SECU_PrintError(progName, "couldn't open source database");
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+ rv = PK11_Authenticate(slot, PR_FALSE, &pwdata);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "Couldn't get password for %s",
+ PK11_GetTokenName(slot));
+ goto merge_fail;
+ }
+
+ rv = PK11_Authenticate(sourceSlot, PR_FALSE, &pwdata2);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "Couldn't get password for %s",
+ PK11_GetTokenName(sourceSlot));
+ goto merge_fail;
+ }
+
+ log = PK11_CreateMergeLog();
+ if (!log) {
+ rv = SECFailure;
+ SECU_PrintError(progName, "couldn't create error log");
+ goto merge_fail;
+ }
+
+ rv = PK11_MergeTokens(slot, sourceSlot, log, &pwdata, &pwdata2);
+ if (rv != SECSuccess) {
+ DumpMergeLog(progName, log);
+ }
+ PK11_DestroyMergeLog(log);
+
+ merge_fail:
+ SECMOD_CloseUserDB(sourceSlot);
+ PK11_FreeSlot(sourceSlot);
+ goto shutdown;
+ }
+
+ /* The following 8 options are mutually exclusive with all others. */
+
+ /* List certs (-L) */
+ if (certutil.commands[cmd_ListCerts].activated) {
+ if (certutil.options[opt_DumpExtensionValue].activated) {
+ const char *oid_str;
+ SECItem oid_item;
+ SECStatus srv;
+ oid_item.data = NULL;
+ oid_item.len = 0;
+ oid_str = certutil.options[opt_DumpExtensionValue].arg;
+ srv = GetOidFromString(NULL, &oid_item, oid_str, strlen(oid_str));
+ if (srv != SECSuccess) {
+ SECU_PrintError(progName, "malformed extension OID %s",
+ oid_str);
+ goto shutdown;
+ }
+ rv = ListCerts(certHandle, name, email, slot,
+ PR_TRUE /*binary*/, PR_FALSE /*ascii*/,
+ &oid_item,
+ outFile, &pwdata);
+ SECITEM_FreeItem(&oid_item, PR_FALSE);
+ } else {
+ rv = ListCerts(certHandle, name, email, slot,
+ certutil.options[opt_BinaryDER].activated,
+ certutil.options[opt_ASCIIForIO].activated,
+ NULL, outFile, &pwdata);
+ }
+ goto shutdown;
+ }
+ if (certutil.commands[cmd_DumpChain].activated) {
+ rv = DumpChain(certHandle, name,
+ certutil.options[opt_ASCIIForIO].activated);
+ goto shutdown;
+ }
+ /* XXX needs work */
+ /* List keys (-K) */
+ if (certutil.commands[cmd_ListKeys].activated) {
+ rv = ListKeys(slot, name, 0 /*keyindex*/, keytype, PR_FALSE /*dopriv*/,
+ &pwdata);
+ goto shutdown;
+ }
+ /* List modules (-U) */
+ if (certutil.commands[cmd_ListModules].activated) {
+ rv = ListModules();
+ goto shutdown;
+ }
+ /* Delete cert (-D) */
+ if (certutil.commands[cmd_DeleteCert].activated) {
+ rv = DeleteCert(certHandle, name);
+ goto shutdown;
+ }
+ /* Rename cert (--rename) */
+ if (certutil.commands[cmd_Rename].activated) {
+ rv = RenameCert(certHandle, name, newName);
+ goto shutdown;
+ }
+ /* Delete key (-F) */
+ if (certutil.commands[cmd_DeleteKey].activated) {
+ rv = DeleteKey(name, &pwdata);
+ goto shutdown;
+ }
+ /* Modify trust attribute for cert (-M) */
+ if (certutil.commands[cmd_ModifyCertTrust].activated) {
+ rv = ChangeTrustAttributes(certHandle, slot, name,
+ certutil.options[opt_Trust].arg, &pwdata);
+ goto shutdown;
+ }
+ /* Change key db password (-W) (future - change pw to slot?) */
+ if (certutil.commands[cmd_ChangePassword].activated) {
+ rv = SECU_ChangePW2(slot, 0, 0, certutil.options[opt_PasswordFile].arg,
+ certutil.options[opt_NewPasswordFile].arg);
+ goto shutdown;
+ }
+ /* Reset the a token */
+ if (certutil.commands[cmd_TokenReset].activated) {
+ char *sso_pass = "";
+
+ if (certutil.options[opt_SSOPass].activated) {
+ sso_pass = certutil.options[opt_SSOPass].arg;
+ }
+ rv = PK11_ResetToken(slot, sso_pass);
+
+ goto shutdown;
+ }
+ /* Check cert validity against current time (-V) */
+ if (certutil.commands[cmd_CheckCertValidity].activated) {
+ /* XXX temporary hack for fips - must log in to get priv key */
+ if (certutil.options[opt_VerifySig].activated) {
+ if (slot && PK11_NeedLogin(slot)) {
+ SECStatus newrv = PK11_Authenticate(slot, PR_TRUE, &pwdata);
+ if (newrv != SECSuccess) {
+ SECU_PrintError(progName, "could not authenticate to token %s.",
+ PK11_GetTokenName(slot));
+ goto shutdown;
+ }
+ }
+ }
+ rv = ValidateCert(certHandle, name,
+ certutil.options[opt_ValidityTime].arg,
+ certutil.options[opt_Usage].arg,
+ certutil.options[opt_VerifySig].activated,
+ certutil.options[opt_DetailedInfo].activated,
+ certutil.options[opt_ASCIIForIO].activated,
+ &pwdata);
+ if (rv != SECSuccess && PR_GetError() == SEC_ERROR_INVALID_ARGS)
+ SECU_PrintError(progName, "validation failed");
+ goto shutdown;
+ }
+
+ /*
+ * Key generation
+ */
+
+ /* These commands may require keygen. */
+ if (certutil.commands[cmd_CertReq].activated ||
+ certutil.commands[cmd_CreateAndAddCert].activated ||
+ certutil.commands[cmd_GenKeyPair].activated) {
+ if (keysource) {
+ CERTCertificate *keycert;
+ keycert = CERT_FindCertByNicknameOrEmailAddr(certHandle, keysource);
+ if (!keycert) {
+ keycert = PK11_FindCertFromNickname(keysource, NULL);
+ if (!keycert) {
+ SECU_PrintError(progName,
+ "%s is neither a key-type nor a nickname", keysource);
+ return SECFailure;
+ }
+ }
+ privkey = PK11_FindKeyByDERCert(slot, keycert, &pwdata);
+ if (privkey)
+ pubkey = CERT_ExtractPublicKey(keycert);
+ if (!pubkey) {
+ SECU_PrintError(progName,
+ "Could not get keys from cert %s", keysource);
+ rv = SECFailure;
+ CERT_DestroyCertificate(keycert);
+ goto shutdown;
+ }
+ keytype = privkey->keyType;
+ /* On CertReq for renewal if no subject has been
+ * specified obtain it from the certificate.
+ */
+ if (certutil.commands[cmd_CertReq].activated && !subject) {
+ subject = CERT_AsciiToName(keycert->subjectName);
+ if (!subject) {
+ SECU_PrintError(progName,
+ "Could not get subject from certificate %s", keysource);
+ CERT_DestroyCertificate(keycert);
+ rv = SECFailure;
+ goto shutdown;
+ }
+ }
+ CERT_DestroyCertificate(keycert);
+ } else {
+ privkey =
+ CERTUTIL_GeneratePrivateKey(keytype, slot, keysize,
+ publicExponent,
+ certutil.options[opt_NoiseFile].arg,
+ &pubkey,
+ certutil.options[opt_PQGFile].arg,
+ keyAttrFlags,
+ keyOpFlagsOn,
+ keyOpFlagsOff,
+ &pwdata);
+ if (privkey == NULL) {
+ SECU_PrintError(progName, "unable to generate key(s)\n");
+ rv = SECFailure;
+ goto shutdown;
+ }
+ }
+ privkey->wincx = &pwdata;
+ PORT_Assert(pubkey != NULL);
+
+ /* If all that was needed was keygen, exit. */
+ if (certutil.commands[cmd_GenKeyPair].activated) {
+ rv = SECSuccess;
+ goto shutdown;
+ }
+ }
+
+ if (certutil.options[opt_Pss].activated) {
+ if (!certutil.commands[cmd_CertReq].activated &&
+ !certutil.commands[cmd_CreateAndAddCert].activated) {
+ PR_fprintf(PR_STDERR,
+ "%s -%c: --pss only works with -R or -S.\n",
+ progName, commandToRun);
+ return 255;
+ }
+ if (keytype != rsaKey) {
+ PR_fprintf(PR_STDERR,
+ "%s -%c: --pss only works with RSA keys.\n",
+ progName, commandToRun);
+ return 255;
+ }
+ }
+
+ /* If we need a list of extensions convert the flags into list format */
+ if (certutil.commands[cmd_CertReq].activated ||
+ certutil.commands[cmd_CreateAndAddCert].activated ||
+ certutil.commands[cmd_CreateNewCert].activated) {
+ certutil_extns[ext_keyUsage].activated =
+ certutil.options[opt_AddCmdKeyUsageExt].activated;
+ if (!certutil_extns[ext_keyUsage].activated) {
+ certutil_extns[ext_keyUsage].activated =
+ certutil.options[opt_AddKeyUsageExt].activated;
+ } else {
+ certutil_extns[ext_keyUsage].arg =
+ certutil.options[opt_AddCmdKeyUsageExt].arg;
+ }
+ certutil_extns[ext_basicConstraint].activated =
+ certutil.options[opt_AddBasicConstraintExt].activated;
+ certutil_extns[ext_nameConstraints].activated =
+ certutil.options[opt_AddNameConstraintsExt].activated;
+ certutil_extns[ext_authorityKeyID].activated =
+ certutil.options[opt_AddAuthorityKeyIDExt].activated;
+ certutil_extns[ext_subjectKeyID].activated =
+ certutil.options[opt_AddSubjectKeyIDExt].activated;
+ certutil_extns[ext_CRLDistPts].activated =
+ certutil.options[opt_AddCRLDistPtsExt].activated;
+ certutil_extns[ext_NSCertType].activated =
+ certutil.options[opt_AddCmdNSCertTypeExt].activated;
+ if (!certutil_extns[ext_NSCertType].activated) {
+ certutil_extns[ext_NSCertType].activated =
+ certutil.options[opt_AddNSCertTypeExt].activated;
+ } else {
+ certutil_extns[ext_NSCertType].arg =
+ certutil.options[opt_AddCmdNSCertTypeExt].arg;
+ }
+
+ certutil_extns[ext_extKeyUsage].activated =
+ certutil.options[opt_AddCmdExtKeyUsageExt].activated;
+ if (!certutil_extns[ext_extKeyUsage].activated) {
+ certutil_extns[ext_extKeyUsage].activated =
+ certutil.options[opt_AddExtKeyUsageExt].activated;
+ } else {
+ certutil_extns[ext_extKeyUsage].arg =
+ certutil.options[opt_AddCmdExtKeyUsageExt].arg;
+ }
+ certutil_extns[ext_subjectAltName].activated =
+ certutil.options[opt_AddSubjectAltNameExt].activated;
+ if (certutil_extns[ext_subjectAltName].activated) {
+ certutil_extns[ext_subjectAltName].arg =
+ certutil.options[opt_AddSubjectAltNameExt].arg;
+ }
+
+ certutil_extns[ext_authInfoAcc].activated =
+ certutil.options[opt_AddAuthInfoAccExt].activated;
+ certutil_extns[ext_subjInfoAcc].activated =
+ certutil.options[opt_AddSubjInfoAccExt].activated;
+ certutil_extns[ext_certPolicies].activated =
+ certutil.options[opt_AddCertPoliciesExt].activated;
+ certutil_extns[ext_policyMappings].activated =
+ certutil.options[opt_AddPolicyMapExt].activated;
+ certutil_extns[ext_policyConstr].activated =
+ certutil.options[opt_AddPolicyConstrExt].activated;
+ certutil_extns[ext_inhibitAnyPolicy].activated =
+ certutil.options[opt_AddInhibAnyExt].activated;
+ }
+
+ /* -A -C or -E Read inFile */
+ if (certutil.commands[cmd_CreateNewCert].activated ||
+ certutil.commands[cmd_AddCert].activated ||
+ certutil.commands[cmd_AddEmailCert].activated) {
+ PRBool isCreate = certutil.commands[cmd_CreateNewCert].activated;
+ rv = SECU_ReadDERFromFile(isCreate ? &certReqDER : &certDER, inFile,
+ certutil.options[opt_ASCIIForIO].activated,
+ PR_TRUE);
+ if (rv)
+ goto shutdown;
+ }
+
+ /*
+ * Certificate request
+ */
+
+ /* Make a cert request (-R). */
+ if (certutil.commands[cmd_CertReq].activated) {
+ rv = CertReq(privkey, pubkey, keytype, hashAlgTag, subject,
+ certutil.options[opt_PhoneNumber].arg,
+ certutil.options[opt_ASCIIForIO].activated,
+ certutil.options[opt_ExtendedEmailAddrs].arg,
+ certutil.options[opt_ExtendedDNSNames].arg,
+ certutil_extns,
+ (certutil.options[opt_GenericExtensions].activated ? certutil.options[opt_GenericExtensions].arg
+ : NULL),
+ certutil.options[opt_Pss].activated,
+ &certReqDER);
+ if (rv)
+ goto shutdown;
+ privkey->wincx = &pwdata;
+ }
+
+ /*
+ * Certificate creation
+ */
+
+ /* If making and adding a cert, create a cert request file first without
+ * any extensions, then load it with the command line extensions
+ * and output the cert to another file.
+ */
+ if (certutil.commands[cmd_CreateAndAddCert].activated) {
+ static certutilExtnList nullextnlist = { { PR_FALSE, NULL } };
+ rv = CertReq(privkey, pubkey, keytype, hashAlgTag, subject,
+ certutil.options[opt_PhoneNumber].arg,
+ PR_FALSE, /* do not BASE64-encode regardless of -a option */
+ NULL,
+ NULL,
+ nullextnlist,
+ (certutil.options[opt_GenericExtensions].activated ? certutil.options[opt_GenericExtensions].arg
+ : NULL),
+ certutil.options[opt_Pss].activated,
+ &certReqDER);
+ if (rv)
+ goto shutdown;
+ privkey->wincx = &pwdata;
+ }
+
+ /* Create a certificate (-C or -S). */
+ if (certutil.commands[cmd_CreateAndAddCert].activated ||
+ certutil.commands[cmd_CreateNewCert].activated) {
+ rv = CreateCert(certHandle, slot,
+ certutil.options[opt_IssuerName].arg,
+ &certReqDER, &privkey, &pwdata, hashAlgTag,
+ serialNumber, warpmonths, validityMonths,
+ certutil.options[opt_ExtendedEmailAddrs].arg,
+ certutil.options[opt_ExtendedDNSNames].arg,
+ certutil.options[opt_ASCIIForIO].activated &&
+ certutil.commands[cmd_CreateNewCert].activated,
+ certutil.options[opt_SelfSign].activated,
+ certutil_extns,
+ (certutil.options[opt_GenericExtensions].activated ? certutil.options[opt_GenericExtensions].arg
+ : NULL),
+ certVersion,
+ &certDER);
+ if (rv)
+ goto shutdown;
+ }
+
+ /*
+ * Adding a cert to the database (or slot)
+ */
+
+ /* -A -E or -S Add the cert to the DB */
+ if (certutil.commands[cmd_CreateAndAddCert].activated ||
+ certutil.commands[cmd_AddCert].activated ||
+ certutil.commands[cmd_AddEmailCert].activated) {
+ if (strstr(certutil.options[opt_Trust].arg, "u")) {
+ fprintf(stderr, "Notice: Trust flag u is set automatically if the "
+ "private key is present.\n");
+ }
+ rv = AddCert(slot, certHandle, name,
+ certutil.options[opt_Trust].arg,
+ &certDER,
+ certutil.commands[cmd_AddEmailCert].activated, &pwdata);
+ if (rv)
+ goto shutdown;
+ }
+
+ if (certutil.commands[cmd_CertReq].activated ||
+ certutil.commands[cmd_CreateNewCert].activated) {
+ SECItem *item = certutil.commands[cmd_CertReq].activated ? &certReqDER
+ : &certDER;
+ PRInt32 written = PR_Write(outFile, item->data, item->len);
+ if (written < 0 || (PRUint32)written != item->len) {
+ rv = SECFailure;
+ }
+ }
+
+shutdown:
+ if (slot) {
+ PK11_FreeSlot(slot);
+ }
+ if (privkey) {
+ SECKEY_DestroyPrivateKey(privkey);
+ }
+ if (pubkey) {
+ SECKEY_DestroyPublicKey(pubkey);
+ }
+ if (subject) {
+ CERT_DestroyName(subject);
+ }
+ if (name) {
+ PL_strfree(name);
+ }
+ if (newName) {
+ PL_strfree(newName);
+ }
+ if (inFile && inFile != PR_STDIN) {
+ PR_Close(inFile);
+ }
+ if (outFile && outFile != PR_STDOUT) {
+ PR_Close(outFile);
+ }
+ SECITEM_FreeItem(&certReqDER, PR_FALSE);
+ SECITEM_FreeItem(&certDER, PR_FALSE);
+ if (pwdata.data && pwdata.source == PW_PLAINTEXT) {
+ /* Allocated by a PL_strdup call in SECU_GetModulePassword. */
+ PL_strfree(pwdata.data);
+ }
+ if (email) {
+ PL_strfree(email);
+ }
+
+ /* Open the batch command file.
+ *
+ * - If -B option is specified, the contents in the
+ * command file will be interpreted as subsequent certutil
+ * commands to be executed in the current certutil process
+ * context after the current certutil command has been executed.
+ * - Each line in the command file consists of the command
+ * line arguments for certutil.
+ * - The -d option will be ignored if specified in the
+ * command file.
+ * - Quoting with double quote characters ("...") is supported
+ * to allow white space in a command line argument. The
+ * double quote character cannot be escaped and quoting cannot
+ * be nested in this version.
+ * - each line in the batch file is limited to 512 characters
+ */
+
+ if ((SECSuccess == rv) && certutil.commands[cmd_Batch].activated) {
+ FILE *batchFile = NULL;
+ char *nextcommand = NULL;
+ PRInt32 cmd_len = 0, buf_size = 0;
+ static const int increment = 512;
+
+ if (!certutil.options[opt_InputFile].activated ||
+ !certutil.options[opt_InputFile].arg) {
+ PR_fprintf(PR_STDERR,
+ "%s: no batch input file specified.\n",
+ progName);
+ return 255;
+ }
+ batchFile = fopen(certutil.options[opt_InputFile].arg, "r");
+ if (!batchFile) {
+ PR_fprintf(PR_STDERR,
+ "%s: unable to open \"%s\" for reading (%ld, %ld).\n",
+ progName, certutil.options[opt_InputFile].arg,
+ PR_GetError(), PR_GetOSError());
+ return 255;
+ }
+ /* read and execute command-lines in a loop */
+ while (SECSuccess == rv) {
+ PRBool invalid = PR_FALSE;
+ int newargc = 2;
+ char *space = NULL;
+ char *nextarg = NULL;
+ char **newargv = NULL;
+ char *crlf;
+
+ if (cmd_len + increment > buf_size) {
+ char *new_buf;
+ buf_size += increment;
+ new_buf = PORT_Realloc(nextcommand, buf_size);
+ if (!new_buf) {
+ PR_fprintf(PR_STDERR, "%s: PORT_Realloc(%ld) failed\n",
+ progName, buf_size);
+ break;
+ }
+ nextcommand = new_buf;
+ nextcommand[cmd_len] = '\0';
+ }
+ if (!fgets(nextcommand + cmd_len, buf_size - cmd_len, batchFile)) {
+ break;
+ }
+ crlf = PORT_Strrchr(nextcommand, '\n');
+ if (crlf) {
+ *crlf = '\0';
+ }
+ cmd_len = strlen(nextcommand);
+ if (cmd_len && nextcommand[cmd_len - 1] == '\\') {
+ nextcommand[--cmd_len] = '\0';
+ continue;
+ }
+
+ /* we now need to split the command into argc / argv format */
+
+ newargv = PORT_Alloc(sizeof(char *) * (newargc + 1));
+ newargv[0] = progName;
+ newargv[1] = nextcommand;
+ nextarg = nextcommand;
+ while ((space = PORT_Strpbrk(nextarg, " \f\n\r\t\v"))) {
+ while (isspace(*space)) {
+ *space = '\0';
+ space++;
+ }
+ if (*space == '\0') {
+ break;
+ } else if (*space != '\"') {
+ nextarg = space;
+ } else {
+ char *closingquote = strchr(space + 1, '\"');
+ if (closingquote) {
+ *closingquote = '\0';
+ space++;
+ nextarg = closingquote + 1;
+ } else {
+ invalid = PR_TRUE;
+ nextarg = space;
+ }
+ }
+ newargc++;
+ newargv = PORT_Realloc(newargv, sizeof(char *) * (newargc + 1));
+ newargv[newargc - 1] = space;
+ }
+ newargv[newargc] = NULL;
+
+ /* invoke next command */
+ if (PR_TRUE == invalid) {
+ PR_fprintf(PR_STDERR, "Missing closing quote in batch command :\n%s\nNot executed.\n",
+ nextcommand);
+ rv = SECFailure;
+ } else {
+ if (0 != certutil_main(newargc, newargv, PR_FALSE))
+ rv = SECFailure;
+ }
+ PORT_Free(newargv);
+ cmd_len = 0;
+ nextcommand[0] = '\0';
+ }
+ PORT_Free(nextcommand);
+ fclose(batchFile);
+ }
+
+ if ((initialized == PR_TRUE) && NSS_Shutdown() != SECSuccess) {
+ exit(1);
+ }
+ if (rv == SECSuccess) {
+ return 0;
+ } else {
+ return 255;
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ int rv = certutil_main(argc, argv, PR_TRUE);
+ PL_ArenaFinish();
+ PR_Cleanup();
+ return rv;
+}
diff --git a/nss/cmd/certutil/certutil.gyp b/nss/cmd/certutil/certutil.gyp
new file mode 100644
index 0000000..d8f1b5d
--- /dev/null
+++ b/nss/cmd/certutil/certutil.gyp
@@ -0,0 +1,32 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi',
+ '../../cmd/platlibs.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'certutil',
+ 'type': 'executable',
+ 'sources': [
+ 'certext.c',
+ 'certutil.c',
+ 'keystuff.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:dbm_exports',
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'target_defaults': {
+ 'defines': [
+ 'NSPR20'
+ ]
+ },
+ 'variables': {
+ 'module': 'nss'
+ }
+}
\ No newline at end of file
diff --git a/nss/cmd/certutil/certutil.h b/nss/cmd/certutil/certutil.h
new file mode 100644
index 0000000..5655872
--- /dev/null
+++ b/nss/cmd/certutil/certutil.h
@@ -0,0 +1,57 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef _CERTUTIL_H
+#define _CERTUTIL_H
+
+extern SECKEYPrivateKey *
+CERTUTIL_GeneratePrivateKey(KeyType keytype,
+ PK11SlotInfo *slot,
+ int rsasize,
+ int publicExponent,
+ char *noise,
+ SECKEYPublicKey **pubkeyp,
+ char *pqgFile,
+ PK11AttrFlags attrFlags,
+ CK_FLAGS opFlagsOn,
+ CK_FLAGS opFlagsOff,
+ secuPWData *pwdata);
+
+extern char *progName;
+
+enum certutilExtns {
+ ext_keyUsage = 0,
+ ext_basicConstraint,
+ ext_authorityKeyID,
+ ext_CRLDistPts,
+ ext_NSCertType,
+ ext_extKeyUsage,
+ ext_authInfoAcc,
+ ext_subjInfoAcc,
+ ext_certPolicies,
+ ext_policyMappings,
+ ext_policyConstr,
+ ext_inhibitAnyPolicy,
+ ext_subjectKeyID,
+ ext_nameConstraints,
+ ext_subjectAltName,
+ ext_End
+};
+
+typedef struct ExtensionEntryStr {
+ PRBool activated;
+ const char *arg;
+} ExtensionEntry;
+
+typedef ExtensionEntry certutilExtnList[ext_End];
+
+extern SECStatus
+AddExtensions(void *extHandle, const char *emailAddrs, const char *dnsNames,
+ certutilExtnList extList, const char *extGeneric);
+
+extern SECStatus
+GetOidFromString(PLArenaPool *arena, SECItem *to,
+ const char *from, size_t fromLen);
+
+#endif /* _CERTUTIL_H */
diff --git a/nss/cmd/certutil/keystuff.c b/nss/cmd/certutil/keystuff.c
new file mode 100644
index 0000000..1569313
--- /dev/null
+++ b/nss/cmd/certutil/keystuff.c
@@ -0,0 +1,609 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include
+#include
+#include "secutil.h"
+
+#if defined(XP_UNIX)
+#include
+#include
+#include
+#endif
+
+#if defined(XP_WIN) || defined(XP_PC)
+#include
+#include
+#endif
+
+#if defined(__sun) && !defined(SVR4)
+extern int fclose(FILE *);
+extern int fprintf(FILE *, char *, ...);
+extern int isatty(int);
+extern char *sys_errlist[];
+#define strerror(errno) sys_errlist[errno]
+#endif
+
+#include "nspr.h"
+#include "prtypes.h"
+#include "prtime.h"
+#include "prlong.h"
+
+#include "pk11func.h"
+
+#define NUM_KEYSTROKES 120
+#define RAND_BUF_SIZE 60
+
+#define ERROR_BREAK \
+ rv = SECFailure; \
+ break;
+
+const SEC_ASN1Template SECKEY_PQGParamsTemplate[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPQGParams) },
+ { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams, prime) },
+ { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams, subPrime) },
+ { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams, base) },
+ { 0 }
+};
+
+/* returns 0 for success, -1 for failure (EOF encountered) */
+static int
+UpdateRNG(void)
+{
+ char randbuf[RAND_BUF_SIZE];
+ int fd;
+ int c;
+ int rv = 0;
+ size_t count;
+#ifdef XP_UNIX
+ cc_t orig_cc_min;
+ cc_t orig_cc_time;
+ tcflag_t orig_lflag;
+ struct termios tio;
+#endif
+ char meter[] = {
+ "\r| |"
+ };
+
+#define FPS fprintf(stderr,
+ FPS "\n");
+ FPS "A random seed must be generated that will be used in the\n");
+ FPS "creation of your key. One of the easiest ways to create a\n");
+ FPS "random seed is to use the timing of keystrokes on a keyboard.\n");
+ FPS "\n");
+ FPS "To begin, type keys on the keyboard until this progress meter\n");
+ FPS "is full. DO NOT USE THE AUTOREPEAT FUNCTION ON YOUR KEYBOARD!\n");
+ FPS "\n");
+ FPS "\n");
+ FPS "Continue typing until the progress meter is full:\n\n");
+ FPS "%s", meter);
+ FPS "\r|");
+
+ /* turn off echo on stdin & return on 1 char instead of NL */
+ fd = fileno(stdin);
+
+#if defined(XP_UNIX)
+ tcgetattr(fd, &tio);
+ orig_lflag = tio.c_lflag;
+ orig_cc_min = tio.c_cc[VMIN];
+ orig_cc_time = tio.c_cc[VTIME];
+ tio.c_lflag &= ~ECHO;
+ tio.c_lflag &= ~ICANON;
+ tio.c_cc[VMIN] = 1;
+ tio.c_cc[VTIME] = 0;
+ tcsetattr(fd, TCSAFLUSH, &tio);
+#endif
+
+ /* Get random noise from keyboard strokes */
+ count = 0;
+ while (count < sizeof randbuf) {
+#if defined(XP_UNIX)
+ c = getc(stdin);
+#else
+ c = getch();
+#endif
+ if (c == EOF) {
+ rv = -1;
+ break;
+ }
+ randbuf[count] = c;
+ if (count == 0 || c != randbuf[count - 1]) {
+ count++;
+ FPS "*");
+ }
+ }
+ PK11_RandomUpdate(randbuf, sizeof randbuf);
+ memset(randbuf, 0, sizeof randbuf);
+
+ FPS "\n\n");
+ FPS "Finished. Press enter to continue: ");
+ while ((c = getc(stdin)) != '\n' && c != EOF)
+ ;
+ if (c == EOF)
+ rv = -1;
+ FPS "\n");
+
+#undef FPS
+
+#if defined(XP_UNIX)
+ /* set back termio the way it was */
+ tio.c_lflag = orig_lflag;
+ tio.c_cc[VMIN] = orig_cc_min;
+ tio.c_cc[VTIME] = orig_cc_time;
+ tcsetattr(fd, TCSAFLUSH, &tio);
+#endif
+ return rv;
+}
+
+static const unsigned char P[] = { 0,
+ 0xc6, 0x2a, 0x47, 0x73, 0xea, 0x78, 0xfa, 0x65,
+ 0x47, 0x69, 0x39, 0x10, 0x08, 0x55, 0x6a, 0xdd,
+ 0xbf, 0x77, 0xe1, 0x9a, 0x69, 0x73, 0xba, 0x66,
+ 0x37, 0x08, 0x93, 0x9e, 0xdb, 0x5d, 0x01, 0x08,
+ 0xb8, 0x3a, 0x73, 0xe9, 0x85, 0x5f, 0xa7, 0x2b,
+ 0x63, 0x7f, 0xd0, 0xc6, 0x4c, 0xdc, 0xfc, 0x8b,
+ 0xa6, 0x03, 0xc9, 0x9c, 0x80, 0x5e, 0xec, 0xc6,
+ 0x21, 0x23, 0xf7, 0x8e, 0xa4, 0x7b, 0x77, 0x83,
+ 0x02, 0x44, 0xf8, 0x05, 0xd7, 0x36, 0x52, 0x13,
+ 0x57, 0x78, 0x97, 0xf3, 0x7b, 0xcf, 0x1f, 0xc9,
+ 0x2a, 0xa4, 0x71, 0x9d, 0xa8, 0xd8, 0x5d, 0xc5,
+ 0x3b, 0x64, 0x3a, 0x72, 0x60, 0x62, 0xb0, 0xb8,
+ 0xf3, 0xb1, 0xe7, 0xb9, 0x76, 0xdf, 0x74, 0xbe,
+ 0x87, 0x6a, 0xd2, 0xf1, 0xa9, 0x44, 0x8b, 0x63,
+ 0x76, 0x4f, 0x5d, 0x21, 0x63, 0xb5, 0x4f, 0x3c,
+ 0x7b, 0x61, 0xb2, 0xf3, 0xea, 0xc5, 0xd8, 0xef,
+ 0x30, 0x50, 0x59, 0x33, 0x61, 0xc0, 0xf3, 0x6e,
+ 0x21, 0xcf, 0x15, 0x35, 0x4a, 0x87, 0x2b, 0xc3,
+ 0xf6, 0x5a, 0x1f, 0x24, 0x22, 0xc5, 0xeb, 0x47,
+ 0x34, 0x4a, 0x1b, 0xb5, 0x2e, 0x71, 0x52, 0x8f,
+ 0x2d, 0x7d, 0xa9, 0x96, 0x8a, 0x7c, 0x61, 0xdb,
+ 0xc0, 0xdc, 0xf1, 0xca, 0x28, 0x69, 0x1c, 0x97,
+ 0xad, 0xea, 0x0d, 0x9e, 0x02, 0xe6, 0xe5, 0x7d,
+ 0xad, 0xe0, 0x42, 0x91, 0x4d, 0xfa, 0xe2, 0x81,
+ 0x16, 0x2b, 0xc2, 0x96, 0x3b, 0x32, 0x8c, 0x20,
+ 0x69, 0x8b, 0x5b, 0x17, 0x3c, 0xf9, 0x13, 0x6c,
+ 0x98, 0x27, 0x1c, 0xca, 0xcf, 0x33, 0xaa, 0x93,
+ 0x21, 0xaf, 0x17, 0x6e, 0x5e, 0x00, 0x37, 0xd9,
+ 0x34, 0x8a, 0x47, 0xd2, 0x1c, 0x67, 0x32, 0x60,
+ 0xb6, 0xc7, 0xb0, 0xfd, 0x32, 0x90, 0x93, 0x32,
+ 0xaa, 0x11, 0xba, 0x23, 0x19, 0x39, 0x6a, 0x42,
+ 0x7c, 0x1f, 0xb7, 0x28, 0xdb, 0x64, 0xad, 0xd9 };
+static const unsigned char Q[] = { 0,
+ 0xe6, 0xa3, 0xc9, 0xc6, 0x51, 0x92, 0x8b, 0xb3,
+ 0x98, 0x8f, 0x97, 0xb8, 0x31, 0x0d, 0x4a, 0x03,
+ 0x1e, 0xba, 0x4e, 0xe6, 0xc8, 0x90, 0x98, 0x1d,
+ 0x3a, 0x95, 0xf4, 0xf1 };
+static const unsigned char G[] = {
+ 0x70, 0x32, 0x58, 0x5d, 0xb3, 0xbf, 0xc3, 0x62,
+ 0x63, 0x0b, 0xf8, 0xa5, 0xe1, 0xed, 0xeb, 0x79,
+ 0xac, 0x18, 0x41, 0x64, 0xb3, 0xda, 0x4c, 0xa7,
+ 0x92, 0x63, 0xb1, 0x33, 0x7c, 0xcb, 0x43, 0xdc,
+ 0x1f, 0x38, 0x63, 0x5e, 0x0e, 0x6d, 0x45, 0xd1,
+ 0xc9, 0x67, 0xf3, 0xcf, 0x3d, 0x2d, 0x16, 0x4e,
+ 0x92, 0x16, 0x06, 0x59, 0x29, 0x89, 0x6f, 0x54,
+ 0xff, 0xc5, 0x71, 0xc8, 0x3a, 0x95, 0x84, 0xb6,
+ 0x7e, 0x7b, 0x1e, 0x8b, 0x47, 0x9d, 0x7a, 0x3a,
+ 0x36, 0x9b, 0x70, 0x2f, 0xd1, 0xbd, 0xef, 0xe8,
+ 0x3a, 0x41, 0xd4, 0xf3, 0x1f, 0x81, 0xc7, 0x1f,
+ 0x96, 0x7c, 0x30, 0xab, 0xf4, 0x7a, 0xac, 0x93,
+ 0xed, 0x6f, 0x67, 0xb0, 0xc9, 0x5b, 0xf3, 0x83,
+ 0x9d, 0xa0, 0xd7, 0xb9, 0x01, 0xed, 0x28, 0xae,
+ 0x1c, 0x6e, 0x2e, 0x48, 0xac, 0x9f, 0x7d, 0xf3,
+ 0x00, 0x48, 0xee, 0x0e, 0xfb, 0x7e, 0x5e, 0xcb,
+ 0xf5, 0x39, 0xd8, 0x92, 0x90, 0x61, 0x2d, 0x1e,
+ 0x3c, 0xd3, 0x55, 0x0d, 0x34, 0xd1, 0x81, 0xc4,
+ 0x89, 0xea, 0x94, 0x2b, 0x56, 0x33, 0x73, 0x58,
+ 0x48, 0xbf, 0x23, 0x72, 0x19, 0x5f, 0x19, 0xac,
+ 0xff, 0x09, 0xc8, 0xcd, 0xab, 0x71, 0xef, 0x9e,
+ 0x20, 0xfd, 0xe3, 0xb8, 0x27, 0x9e, 0x65, 0xb1,
+ 0x85, 0xcd, 0x88, 0xfe, 0xd4, 0xd7, 0x64, 0x4d,
+ 0xe1, 0xe8, 0xa6, 0xe5, 0x96, 0xc8, 0x5d, 0x9c,
+ 0xc6, 0x70, 0x6b, 0xba, 0x77, 0x4e, 0x90, 0x4a,
+ 0xb0, 0x96, 0xc5, 0xa0, 0x9e, 0x2c, 0x01, 0x03,
+ 0xbe, 0xbd, 0x71, 0xba, 0x0a, 0x6f, 0x9f, 0xe5,
+ 0xdb, 0x04, 0x08, 0xf2, 0x9e, 0x0f, 0x1b, 0xac,
+ 0xcd, 0xbb, 0x65, 0x12, 0xcf, 0x77, 0xc9, 0x7d,
+ 0xbe, 0x94, 0x4b, 0x9c, 0x5b, 0xde, 0x0d, 0xfa,
+ 0x57, 0xdd, 0x77, 0x32, 0xf0, 0x5b, 0x34, 0xfd,
+ 0x19, 0x95, 0x33, 0x60, 0x87, 0xe2, 0xa2, 0xf4
+};
+
+/* P, Q, G have been generated using the NSS makepqg utility:
+ * makepqg -l 2048 -g 224 -r
+ * (see also: bug 1170322)
+ *
+ * h: 1 (0x1)
+ * SEED:
+ * d2:0b:c5:63:1b:af:dc:36:b7:7c:b9:3e:36:01:a0:8f:
+ * 0e:be:d0:38:e4:78:d5:3c:7c:9e:a9:9a:d2:0b:c5:63:
+ * 1b:af:dc:36:b7:7c:b9:3e:36:01:a0:8f:0e:be:d0:38:
+ * e4:78:d5:3c:7c:9e:c7:70:d2:0b:c5:63:1b:af:dc:36:
+ * b7:7c:b9:3e:36:01:a0:8f:0e:be:d0:38:e4:78:d5:3c:
+ * 7c:9e:aa:3e
+ * g: 672
+ * counter: 0
+ */
+
+static const SECKEYPQGParams default_pqg_params = {
+ NULL,
+ { 0, (unsigned char *)P, sizeof(P) },
+ { 0, (unsigned char *)Q, sizeof(Q) },
+ { 0, (unsigned char *)G, sizeof(G) }
+};
+
+static SECKEYPQGParams *
+decode_pqg_params(const char *str)
+{
+ char *buf;
+ unsigned int len;
+ PLArenaPool *arena;
+ SECKEYPQGParams *params;
+ SECStatus status;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (arena == NULL)
+ return NULL;
+
+ params = PORT_ArenaZAlloc(arena, sizeof(SECKEYPQGParams));
+ if (params == NULL)
+ goto loser;
+ params->arena = arena;
+
+ buf = (char *)ATOB_AsciiToData(str, &len);
+ if ((buf == NULL) || (len == 0))
+ goto loser;
+
+ status = SEC_ASN1Decode(arena, params, SECKEY_PQGParamsTemplate, buf, len);
+ if (status != SECSuccess)
+ goto loser;
+
+ return params;
+
+loser:
+ if (arena != NULL)
+ PORT_FreeArena(arena, PR_FALSE);
+ return NULL;
+}
+
+void
+CERTUTIL_DestroyParamsPQG(SECKEYPQGParams *params)
+{
+ if (params->arena) {
+ PORT_FreeArena(params->arena, PR_FALSE);
+ }
+}
+
+static int
+pqg_prime_bits(const SECKEYPQGParams *params)
+{
+ int primeBits = 0;
+
+ if (params != NULL) {
+ int i;
+ for (i = 0; params->prime.data[i] == 0; i++) {
+ /* empty */;
+ }
+ primeBits = (params->prime.len - i) * 8;
+ }
+
+ return primeBits;
+}
+
+static char *
+getPQGString(const char *filename)
+{
+ unsigned char *buf = NULL;
+ PRFileDesc *src;
+ PRInt32 numBytes;
+ PRStatus prStatus;
+ PRFileInfo info;
+
+ src = PR_Open(filename, PR_RDONLY, 0);
+ if (!src) {
+ fprintf(stderr, "Failed to open PQG file %s\n", filename);
+ return NULL;
+ }
+
+ prStatus = PR_GetOpenFileInfo(src, &info);
+
+ if (prStatus == PR_SUCCESS) {
+ buf = (unsigned char *)PORT_Alloc(info.size + 1);
+ }
+ if (!buf) {
+ PR_Close(src);
+ fprintf(stderr, "Failed to read PQG file %s\n", filename);
+ return NULL;
+ }
+
+ numBytes = PR_Read(src, buf, info.size);
+ PR_Close(src);
+ if (numBytes != info.size) {
+ PORT_Free(buf);
+ fprintf(stderr, "Failed to read PQG file %s\n", filename);
+ PORT_SetError(SEC_ERROR_IO);
+ return NULL;
+ }
+
+ if (buf[numBytes - 1] == '\n')
+ numBytes--;
+ if (buf[numBytes - 1] == '\r')
+ numBytes--;
+ buf[numBytes] = 0;
+
+ return (char *)buf;
+}
+
+static SECKEYPQGParams *
+getpqgfromfile(int keyBits, const char *pqgFile)
+{
+ char *end, *str, *pqgString;
+ SECKEYPQGParams *params = NULL;
+
+ str = pqgString = getPQGString(pqgFile);
+ if (!str)
+ return NULL;
+
+ do {
+ end = PORT_Strchr(str, ',');
+ if (end)
+ *end = '\0';
+ params = decode_pqg_params(str);
+ if (params) {
+ int primeBits = pqg_prime_bits(params);
+ if (keyBits == primeBits)
+ break;
+ CERTUTIL_DestroyParamsPQG(params);
+ params = NULL;
+ }
+ if (end)
+ str = end + 1;
+ } while (end);
+
+ PORT_Free(pqgString);
+ return params;
+}
+
+static SECStatus
+CERTUTIL_FileForRNG(const char *noise)
+{
+ char buf[2048];
+ PRFileDesc *fd;
+ PRInt32 count;
+
+ fd = PR_Open(noise, PR_RDONLY, 0);
+ if (!fd) {
+ fprintf(stderr, "failed to open noise file.");
+ return SECFailure;
+ }
+
+ do {
+ count = PR_Read(fd, buf, sizeof(buf));
+ if (count > 0) {
+ PK11_RandomUpdate(buf, count);
+ }
+ } while (count > 0);
+
+ PR_Close(fd);
+ return SECSuccess;
+}
+
+#ifndef NSS_DISABLE_ECC
+typedef struct curveNameTagPairStr {
+ char *curveName;
+ SECOidTag curveOidTag;
+} CurveNameTagPair;
+
+static CurveNameTagPair nameTagPair[] =
+ {
+ { "sect163k1", SEC_OID_SECG_EC_SECT163K1 },
+ { "nistk163", SEC_OID_SECG_EC_SECT163K1 },
+ { "sect163r1", SEC_OID_SECG_EC_SECT163R1 },
+ { "sect163r2", SEC_OID_SECG_EC_SECT163R2 },
+ { "nistb163", SEC_OID_SECG_EC_SECT163R2 },
+ { "sect193r1", SEC_OID_SECG_EC_SECT193R1 },
+ { "sect193r2", SEC_OID_SECG_EC_SECT193R2 },
+ { "sect233k1", SEC_OID_SECG_EC_SECT233K1 },
+ { "nistk233", SEC_OID_SECG_EC_SECT233K1 },
+ { "sect233r1", SEC_OID_SECG_EC_SECT233R1 },
+ { "nistb233", SEC_OID_SECG_EC_SECT233R1 },
+ { "sect239k1", SEC_OID_SECG_EC_SECT239K1 },
+ { "sect283k1", SEC_OID_SECG_EC_SECT283K1 },
+ { "nistk283", SEC_OID_SECG_EC_SECT283K1 },
+ { "sect283r1", SEC_OID_SECG_EC_SECT283R1 },
+ { "nistb283", SEC_OID_SECG_EC_SECT283R1 },
+ { "sect409k1", SEC_OID_SECG_EC_SECT409K1 },
+ { "nistk409", SEC_OID_SECG_EC_SECT409K1 },
+ { "sect409r1", SEC_OID_SECG_EC_SECT409R1 },
+ { "nistb409", SEC_OID_SECG_EC_SECT409R1 },
+ { "sect571k1", SEC_OID_SECG_EC_SECT571K1 },
+ { "nistk571", SEC_OID_SECG_EC_SECT571K1 },
+ { "sect571r1", SEC_OID_SECG_EC_SECT571R1 },
+ { "nistb571", SEC_OID_SECG_EC_SECT571R1 },
+ { "secp160k1", SEC_OID_SECG_EC_SECP160K1 },
+ { "secp160r1", SEC_OID_SECG_EC_SECP160R1 },
+ { "secp160r2", SEC_OID_SECG_EC_SECP160R2 },
+ { "secp192k1", SEC_OID_SECG_EC_SECP192K1 },
+ { "secp192r1", SEC_OID_SECG_EC_SECP192R1 },
+ { "nistp192", SEC_OID_SECG_EC_SECP192R1 },
+ { "secp224k1", SEC_OID_SECG_EC_SECP224K1 },
+ { "secp224r1", SEC_OID_SECG_EC_SECP224R1 },
+ { "nistp224", SEC_OID_SECG_EC_SECP224R1 },
+ { "secp256k1", SEC_OID_SECG_EC_SECP256K1 },
+ { "secp256r1", SEC_OID_SECG_EC_SECP256R1 },
+ { "nistp256", SEC_OID_SECG_EC_SECP256R1 },
+ { "secp384r1", SEC_OID_SECG_EC_SECP384R1 },
+ { "nistp384", SEC_OID_SECG_EC_SECP384R1 },
+ { "secp521r1", SEC_OID_SECG_EC_SECP521R1 },
+ { "nistp521", SEC_OID_SECG_EC_SECP521R1 },
+
+ { "prime192v1", SEC_OID_ANSIX962_EC_PRIME192V1 },
+ { "prime192v2", SEC_OID_ANSIX962_EC_PRIME192V2 },
+ { "prime192v3", SEC_OID_ANSIX962_EC_PRIME192V3 },
+ { "prime239v1", SEC_OID_ANSIX962_EC_PRIME239V1 },
+ { "prime239v2", SEC_OID_ANSIX962_EC_PRIME239V2 },
+ { "prime239v3", SEC_OID_ANSIX962_EC_PRIME239V3 },
+
+ { "c2pnb163v1", SEC_OID_ANSIX962_EC_C2PNB163V1 },
+ { "c2pnb163v2", SEC_OID_ANSIX962_EC_C2PNB163V2 },
+ { "c2pnb163v3", SEC_OID_ANSIX962_EC_C2PNB163V3 },
+ { "c2pnb176v1", SEC_OID_ANSIX962_EC_C2PNB176V1 },
+ { "c2tnb191v1", SEC_OID_ANSIX962_EC_C2TNB191V1 },
+ { "c2tnb191v2", SEC_OID_ANSIX962_EC_C2TNB191V2 },
+ { "c2tnb191v3", SEC_OID_ANSIX962_EC_C2TNB191V3 },
+ { "c2onb191v4", SEC_OID_ANSIX962_EC_C2ONB191V4 },
+ { "c2onb191v5", SEC_OID_ANSIX962_EC_C2ONB191V5 },
+ { "c2pnb208w1", SEC_OID_ANSIX962_EC_C2PNB208W1 },
+ { "c2tnb239v1", SEC_OID_ANSIX962_EC_C2TNB239V1 },
+ { "c2tnb239v2", SEC_OID_ANSIX962_EC_C2TNB239V2 },
+ { "c2tnb239v3", SEC_OID_ANSIX962_EC_C2TNB239V3 },
+ { "c2onb239v4", SEC_OID_ANSIX962_EC_C2ONB239V4 },
+ { "c2onb239v5", SEC_OID_ANSIX962_EC_C2ONB239V5 },
+ { "c2pnb272w1", SEC_OID_ANSIX962_EC_C2PNB272W1 },
+ { "c2pnb304w1", SEC_OID_ANSIX962_EC_C2PNB304W1 },
+ { "c2tnb359v1", SEC_OID_ANSIX962_EC_C2TNB359V1 },
+ { "c2pnb368w1", SEC_OID_ANSIX962_EC_C2PNB368W1 },
+ { "c2tnb431r1", SEC_OID_ANSIX962_EC_C2TNB431R1 },
+
+ { "secp112r1", SEC_OID_SECG_EC_SECP112R1 },
+ { "secp112r2", SEC_OID_SECG_EC_SECP112R2 },
+ { "secp128r1", SEC_OID_SECG_EC_SECP128R1 },
+ { "secp128r2", SEC_OID_SECG_EC_SECP128R2 },
+
+ { "sect113r1", SEC_OID_SECG_EC_SECT113R1 },
+ { "sect113r2", SEC_OID_SECG_EC_SECT113R2 },
+ { "sect131r1", SEC_OID_SECG_EC_SECT131R1 },
+ { "sect131r2", SEC_OID_SECG_EC_SECT131R2 },
+ { "curve25519", SEC_OID_CURVE25519 },
+ };
+
+static SECKEYECParams *
+getECParams(const char *curve)
+{
+ SECKEYECParams *ecparams;
+ SECOidData *oidData = NULL;
+ SECOidTag curveOidTag = SEC_OID_UNKNOWN; /* default */
+ int i, numCurves;
+
+ if (curve != NULL) {
+ numCurves = sizeof(nameTagPair) / sizeof(CurveNameTagPair);
+ for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN));
+ i++) {
+ if (PL_strcmp(curve, nameTagPair[i].curveName) == 0)
+ curveOidTag = nameTagPair[i].curveOidTag;
+ }
+ }
+
+ /* Return NULL if curve name is not recognized */
+ if ((curveOidTag == SEC_OID_UNKNOWN) ||
+ (oidData = SECOID_FindOIDByTag(curveOidTag)) == NULL) {
+ fprintf(stderr, "Unrecognized elliptic curve %s\n", curve);
+ return NULL;
+ }
+
+ ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len));
+
+ /*
+ * ecparams->data needs to contain the ASN encoding of an object ID (OID)
+ * representing the named curve. The actual OID is in
+ * oidData->oid.data so we simply prepend 0x06 and OID length
+ */
+ ecparams->data[0] = SEC_ASN1_OBJECT_ID;
+ ecparams->data[1] = oidData->oid.len;
+ memcpy(ecparams->data + 2, oidData->oid.data, oidData->oid.len);
+
+ return ecparams;
+}
+#endif /* NSS_DISABLE_ECC */
+
+SECKEYPrivateKey *
+CERTUTIL_GeneratePrivateKey(KeyType keytype, PK11SlotInfo *slot, int size,
+ int publicExponent, const char *noise,
+ SECKEYPublicKey **pubkeyp, const char *pqgFile,
+ PK11AttrFlags attrFlags, CK_FLAGS opFlagsOn,
+ CK_FLAGS opFlagsOff, secuPWData *pwdata)
+{
+ CK_MECHANISM_TYPE mechanism;
+ PK11RSAGenParams rsaparams;
+ SECKEYPQGParams *dsaparams = NULL;
+ void *params;
+ SECKEYPrivateKey *privKey = NULL;
+
+ if (slot == NULL)
+ return NULL;
+
+ if (PK11_Authenticate(slot, PR_TRUE, pwdata) != SECSuccess)
+ return NULL;
+
+ /*
+ * Do some random-number initialization.
+ */
+
+ if (noise) {
+ SECStatus rv = CERTUTIL_FileForRNG(noise);
+ if (rv != SECSuccess) {
+ PORT_SetError(PR_END_OF_FILE_ERROR); /* XXX */
+ return NULL;
+ }
+ } else {
+ int rv = UpdateRNG();
+ if (rv) {
+ PORT_SetError(PR_END_OF_FILE_ERROR);
+ return NULL;
+ }
+ }
+
+ switch (keytype) {
+ case rsaKey:
+ rsaparams.keySizeInBits = size;
+ rsaparams.pe = publicExponent;
+ mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
+ params = &rsaparams;
+ break;
+ case dsaKey:
+ mechanism = CKM_DSA_KEY_PAIR_GEN;
+ if (pqgFile) {
+ dsaparams = getpqgfromfile(size, pqgFile);
+ if (dsaparams == NULL)
+ return NULL;
+ params = dsaparams;
+ } else {
+ /* cast away const, and don't set dsaparams */
+ params = (void *)&default_pqg_params;
+ }
+ break;
+#ifndef NSS_DISABLE_ECC
+ case ecKey:
+ mechanism = CKM_EC_KEY_PAIR_GEN;
+ /* For EC keys, PQGFile determines EC parameters */
+ if ((params = (void *)getECParams(pqgFile)) == NULL)
+ return NULL;
+ break;
+#endif /* NSS_DISABLE_ECC */
+ default:
+ return NULL;
+ }
+
+ fprintf(stderr, "\n\n");
+ fprintf(stderr, "Generating key. This may take a few moments...\n\n");
+
+ privKey = PK11_GenerateKeyPairWithOpFlags(slot, mechanism, params, pubkeyp,
+ attrFlags, opFlagsOn, opFlagsOn |
+ opFlagsOff,
+ pwdata /*wincx*/);
+ /* free up the params */
+ switch (keytype) {
+ case dsaKey:
+ if (dsaparams)
+ CERTUTIL_DestroyParamsPQG(dsaparams);
+ break;
+#ifndef NSS_DISABLE_ECC
+ case ecKey:
+ SECITEM_FreeItem((SECItem *)params, PR_TRUE);
+ break;
+#endif
+ default: /* nothing to free */
+ break;
+ }
+ return privKey;
+}
diff --git a/nss/cmd/certutil/manifest.mn b/nss/cmd/certutil/manifest.mn
new file mode 100644
index 0000000..c0bce4c
--- /dev/null
+++ b/nss/cmd/certutil/manifest.mn
@@ -0,0 +1,25 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+CORE_DEPTH = ../..
+
+DEFINES += -DNSPR20
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+CSRCS = \
+ certext.c \
+ certutil.c \
+ keystuff.c \
+ $(NULL)
+
+# The MODULE is always implicitly required.
+# Listing it here in REQUIRES makes it appear twice in the cc command line.
+REQUIRES = dbm seccmd
+
+PROGRAM = certutil
+
+#USE_STATIC_LIBS = 1
diff --git a/nss/cmd/chktest/Makefile b/nss/cmd/chktest/Makefile
new file mode 100644
index 0000000..3ffa387
--- /dev/null
+++ b/nss/cmd/chktest/Makefile
@@ -0,0 +1,47 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include ../platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+include ../platrules.mk
diff --git a/nss/cmd/chktest/chktest.c b/nss/cmd/chktest/chktest.c
new file mode 100644
index 0000000..a33d184
--- /dev/null
+++ b/nss/cmd/chktest/chktest.c
@@ -0,0 +1,45 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include
+#include
+
+#include "blapi.h"
+#include "secutil.h"
+
+static int
+Usage()
+{
+ fprintf(stderr, "Usage: chktest \n");
+ fprintf(stderr, " Will test for valid chk file.\n");
+ fprintf(stderr, " Will print SUCCESS or FAILURE.\n");
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ SECStatus rv = SECFailure;
+ PRBool good_result = PR_FALSE;
+
+ if (argc != 2)
+ return Usage();
+
+ rv = RNG_RNGInit();
+ if (rv != SECSuccess) {
+ SECU_PrintPRandOSError("");
+ return -1;
+ }
+ rv = BL_Init();
+ if (rv != SECSuccess) {
+ SECU_PrintPRandOSError("");
+ return -1;
+ }
+ RNG_SystemInfoForRNG();
+
+ good_result = BLAPI_SHVerifyFile(argv[1]);
+ printf("%s\n",
+ (good_result ? "SUCCESS" : "FAILURE"));
+ return (good_result) ? SECSuccess : SECFailure;
+}
diff --git a/nss/cmd/chktest/chktest.gyp b/nss/cmd/chktest/chktest.gyp
new file mode 100644
index 0000000..15abbcc
--- /dev/null
+++ b/nss/cmd/chktest/chktest.gyp
@@ -0,0 +1,32 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi',
+ '../../cmd/platlibs.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'chktest',
+ 'type': 'executable',
+ 'sources': [
+ 'chktest.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:dbm_exports',
+ '<(DEPTH)/exports.gyp:nss_exports',
+ '<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3'
+ ]
+ }
+ ],
+ 'target_defaults': {
+ 'defines': [
+ 'NSS_USE_STATIC_LIBS'
+ ]
+ },
+ 'variables': {
+ 'module': 'nss',
+ 'use_static_libs': 1
+ }
+}
\ No newline at end of file
diff --git a/nss/cmd/chktest/manifest.mn b/nss/cmd/chktest/manifest.mn
new file mode 100644
index 0000000..50b1ca1
--- /dev/null
+++ b/nss/cmd/chktest/manifest.mn
@@ -0,0 +1,27 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+CORE_DEPTH = ../..
+
+MODULE = nss
+
+#REQUIRES = seccmd dbm softoken
+REQUIRES = seccmd dbm
+
+#INCLUDES += -I$(CORE_DEPTH)/nss/lib/softoken
+
+PROGRAM = chktest
+
+ USE_STATIC_LIBS = 1
+
+EXPORTS = \
+ $(NULL)
+
+PRIVATE_EXPORTS = \
+ $(NULL)
+
+CSRCS = \
+ chktest.c \
+ $(NULL)
+
diff --git a/nss/cmd/clientProof/.gitignore b/nss/cmd/clientProof/.gitignore
new file mode 100644
index 0000000..f1d55a6
--- /dev/null
+++ b/nss/cmd/clientProof/.gitignore
@@ -0,0 +1,2 @@
+.cproject
+
diff --git a/nss/cmd/clientProof/.project b/nss/cmd/clientProof/.project
new file mode 100644
index 0000000..f3ab255
--- /dev/null
+++ b/nss/cmd/clientProof/.project
@@ -0,0 +1,27 @@
+
+
+ clientProof
+
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.core.ccnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+
+
diff --git a/nss/cmd/clientProof/Makefile b/nss/cmd/clientProof/Makefile
new file mode 100644
index 0000000..a27a3ce
--- /dev/null
+++ b/nss/cmd/clientProof/Makefile
@@ -0,0 +1,46 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include ../platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+#include ../platlibs.mk
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+include ../platrules.mk
+
diff --git a/nss/cmd/clientProof/client_db b/nss/cmd/clientProof/client_db
new file mode 120000
index 0000000..22ed056
--- /dev/null
+++ b/nss/cmd/clientProof/client_db
@@ -0,0 +1 @@
+../../../ca/client_db
\ No newline at end of file
diff --git a/nss/cmd/clientProof/main.c b/nss/cmd/clientProof/main.c
new file mode 100644
index 0000000..ba7eedb
--- /dev/null
+++ b/nss/cmd/clientProof/main.c
@@ -0,0 +1,315 @@
+#include
+#include
+#include
+#include
+
+#include "nspr.h"
+#include "plgetopt.h"
+#include "prerror.h"
+#include "prnetdb.h"
+
+#include "nss.h"
+#include "ssl.h"
+#include "sslproto.h"
+#include "tlsproofstr.h"
+#include
+
+#define SHA_256_LENGTH 32
+
+/*Global variables*/
+unsigned char merkleRoot[SHA_256_LENGTH]; //Merkle root
+FILE *messagesFile = NULL; // File to print the messages received and sent
+
+/*Error handler*/
+void error(const char *msg)
+{
+ PRErrorCode perr = PR_GetError();
+ const char *errString = PORT_ErrorToString(perr);
+
+ printf("!! ERROR function name: %s returned error %d:\n%s\n",msg, perr, errString);
+ exit(1);
+}
+
+/*Callback function that return the password of the certificate database.
+ * It is set when configuring NSS.*/
+char* getPwd(PK11SlotInfo *slot, PRBool retry, void *arg){
+ printf("Pass retrieved \n");
+
+ char *pwd= NULL;
+ pwd = PORT_Strdup("");
+
+ return pwd;
+}
+/*Add a message to the Merkle tree
+ * message is the input message and len the length
+ * This function print the input and output of the hash functions. */
+void saveMessage(char* message, unsigned int len)
+{
+ SECStatus rv;
+ PK11Context *ctx = NULL;
+ unsigned char *hashMessage = NULL;
+ unsigned int outLen =0;
+ hashMessage = malloc(32*sizeof(char));
+
+ printf("\nInput =>[");
+ for(int i = 0; i < len; i++) printf("%02x", message[i]);
+ printf("] = '");
+ for(int i = 0; i < len; i++) if(message[i]!= 0x0a) printf("%c", message[i]);
+ printf("'\n");
+
+ //Hash the input message
+ ctx = PK11_CreateDigestContext(SEC_OID_SHA256);
+ if (!ctx) error("PK11_CreateDigestContext");
+ rv = PK11_DigestBegin(ctx);
+ if(rv != SECSuccess) error("PK11_DigestBegin");
+ rv = PK11_DigestOp(ctx,(unsigned char*)message,len);
+ if(rv != SECSuccess) error("PK11_DigestOp");
+ rv = PK11_DigestFinal(ctx,hashMessage,&outLen,SHA_256_LENGTH);
+
+ printf("Message Hash=>[");
+ for(int i = 0; i < outLen; i++) printf("%02x", hashMessage[i]);
+ printf("]\n");
+
+ printf("Input =>[");
+ for(int i = 0; i < SHA_256_LENGTH; i++) printf("%02x", merkleRoot[i]);
+ for(int i = 0; i < SHA_256_LENGTH; i++) printf("%02x", hashMessage[i]);
+ printf("]\n");
+
+ //Hash the actual Merkle root with the previous computed hash
+ ctx = PK11_CreateDigestContext(SEC_OID_SHA256);
+ if (!ctx) error("PK11_CreateDigestContext");
+ rv = PK11_DigestBegin(ctx);
+ if(rv != SECSuccess) error("PK11_DigestBegin");
+ rv = PK11_DigestOp(ctx,merkleRoot,SHA_256_LENGTH);
+ if(rv != SECSuccess) error("PK11_DigestOp");
+ rv = PK11_DigestOp(ctx,hashMessage,SHA_256_LENGTH);
+ if(rv != SECSuccess) error("PK11_DigestOp");
+ rv = PK11_DigestFinal(ctx,hashMessage,&outLen,SHA_256_LENGTH);
+
+ printf("New Root=>[");
+ for(int i = 0; i < outLen; i++) printf("%02x", hashMessage[i]);
+ printf("]\n\n");
+
+ //Update the Merkle root with the new hash
+ memcpy(merkleRoot,hashMessage,SHA_256_LENGTH);
+
+ return;
+}
+
+
+SECStatus fetchTLSProofCallBack(unsigned char *proof, unsigned int length){
+ printf("Got proof of size: %i\n", length);
+ if(SSL_TLSProofCheckProof(proof, length) == SECSuccess){
+ printf("Proof successfully verified!\n");
+ } else {
+ printf("Proof is incorrect\n");
+ }
+ PORT_Free(proof);
+ exit(0);
+ return SECSuccess;
+}
+
+
+
+
+/*This is set when configuring TLS proof
+ * It will be called by NSS when it receive a signature from the server. */
+SECStatus myTLSPRoofCallBack(PRFileDesc *fd, unsigned char *signature, unsigned int length)
+{
+ SECItem sigItem;
+ sigItem.len = length;
+ sigItem.data = signature;
+ CERTCertificate *cert = NULL;
+ cert = PK11_FindCertFromNickname("tls-n.testserver",NULL); assert(cert);
+ SECKEYPublicKey *pubKey = NULL;
+ pubKey = CERT_ExtractPublicKey(cert); assert(pubKey);
+ SECStatus rv;
+ FILE *sigFile = fopen("sig.txt", "w");
+
+ printf("Proof received ! Contain the following signature :\n");
+
+ printf("[");
+ for(int i = 0; i < length; i++) printf("%02x", signature[i]);
+ printf("]\n");
+
+ //Save the signature in a file
+ for(int i = 0; i < length; i++) fprintf(sigFile,"%x", signature[i]);
+ fclose(sigFile);
+
+ //Read the message file
+ printf("\nPress enter to verify the signature ...");
+ while(getchar()!= '\n');
+ printf("Generate Merkle root from file...\n");
+ unsigned char c = 0x00;
+ int l = 0;
+ char buffer[256];
+ FILE *mess;
+ mess = fopen("messages.txt", "r");
+
+ if(!mess) return SECFailure;
+
+ while(c != 0xff){
+ c = getc(mess);
+ buffer[l] = c;
+ l++;
+
+ if(l >= 256) return SECFailure;
+
+ if(c == 0x0a){
+ //Add message to hash chain
+ saveMessage(buffer,l);
+ l = 0;
+ }
+ }
+
+ //Verify signature over the Merkle root
+ SECItem data;
+ data.type = siBuffer;
+ data.data = merkleRoot;
+ data.len = SHA_256_LENGTH;
+
+ rv = PK11_Verify(pubKey, &sigItem, &data, NULL);
+
+ printf("Verification of the signature: =>[%i] (0 = valid -1 = invalid)\n",(int)rv);
+
+
+
+ return SECSuccess;
+}
+
+int main(int argc, char *argv[])
+{
+ PRFileDesc* socketfd = NULL;
+ PRHostEnt host;
+ PRNetAddr addr;
+ SECStatus rv;
+ PRStatus pr;
+ char buffer[1024];
+ char buffParam[256];
+ int n;
+ PRSocketOptionData socketOption;
+ SSLVersionRange ver;
+
+ //Initialize the original Merkle root (root of the Merkle root) to "000..."
+ for(int i=0;i < SHA_256_LENGTH;i++) merkleRoot[i] = 0;
+
+ messagesFile = fopen("messages.txt", "w");
+
+ // 3 arguments are necessary for the client
+ if(argc < 3){
+ error("Specify host and port");
+ }
+
+ //Set the password callback
+ PK11_SetPasswordFunc(getPwd);
+
+ //Init
+ rv = NSS_Init("../client_db");
+ if(rv != SECSuccess) error("NSS_Init");
+
+ //Open
+ socketfd = PR_OpenTCPSocket(PR_AF_INET);
+ if (socketfd == NULL) error("PR_OpenTCPSocket");
+
+
+ //Set socket option
+ socketOption.option = PR_SockOpt_Nonblocking;
+ socketOption.value.non_blocking = PR_FALSE;
+ pr = PR_SetSocketOption(socketfd, &socketOption);
+ if (pr != PR_SUCCESS) error("PR_SetSocketOption");
+
+ //Import
+ socketfd = SSL_ImportFD(NULL, socketfd);
+ if (socketfd == NULL) error("SSL_ImportFD");
+
+ //Set server mode
+ rv = SSL_OptionSet(socketfd, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
+ if(rv != SECSuccess) error("SSL_OptionSet, SSL_HANDSHAKE_AS_CLIENT ");
+
+ //Force TLS 1.3
+ ver.max= SSL_LIBRARY_VERSION_TLS_1_3;
+ ver.min= SSL_LIBRARY_VERSION_TLS_1_3;
+ rv = SSL_VersionRangeSet(socketfd,&ver);
+ if(rv != SECSuccess) error("SSL_VersionRangeSet");
+
+ //Enable TLS Proof extension for non-repudiation
+ rv = SSL_OptionSet(socketfd, SSL_ENABLE_TLS_PROOF, PR_TRUE);
+ if(rv != SECSuccess) error("SSL_OptionSet, SSL_ENABLE_TLS_PROOF");
+
+ //Set the proof return callback
+ rv = SSL_TLSProofSetReturnCallBack(socketfd, fetchTLSProofCallBack, hidden_plaintext_proof);
+ if(rv != SECSuccess) error("SSL_TLSProofSetReturnCallBack");
+
+ //Set url for authentication
+ rv = SSL_SetURL(socketfd, "tls-n.testserver");
+ if(rv != SECSuccess) error("SSL_SetURL");
+
+ //Get host
+ pr = PR_GetHostByName(argv[1],buffParam,256,&host);
+ if (pr != PR_SUCCESS) error("PR_GetHostByName");
+ rv = PR_EnumerateHostEnt(0, &host, atoi(argv[2]), &addr);
+ if(rv < 0) error("PR_EnumerateHostEnt");
+
+ //Connect
+ pr = PR_Connect(socketfd, &addr, PR_INTERVAL_NO_TIMEOUT);
+ if(pr != PR_SUCCESS) error("PR_Connect");
+
+ PRBool val = PR_FALSE;
+
+ /*Our client will ask 3 times for some user input before terminating the exchange*/
+ for(int i=0 ; i < 3 ; i++)
+ {
+ printf("\nPlease enter the message: \n");
+ fgets(buffer,sizeof(buffer)-1,stdin);
+ /*Send the previously typed message
+ * Note that when doing the first Write NSS will triger the Handshake
+ * n is the number of packet sent*/
+ n = PR_Write(socketfd,buffer,strlen(buffer));
+ if (n < 0)
+ error("ERROR writing to socket");
+
+ //Update the merkle root and save the sent message
+ //saveMessage(buffer,n);
+ for(int i = 0; i < n; i++) fprintf(messagesFile,"%c", buffer[i]);
+
+
+ //See if the negotiation of TLS proof was successful
+ rv = SSL_TLSProofIsNegociated(socketfd,&val);
+ if(rv != SECSuccess) error("SSL_TLSProofIsNegociated");
+
+ //Get the TLS version used
+ rv = SSL_VersionRangeGet(socketfd,&ver);
+ if(rv != SECSuccess) error("SSL_VersionRangeGet");
+
+ /* Print the TLS version negotiated, for TLS 1.3 it should show [304:304] and if TLS proof was
+ * successfully negotiated */
+ printf("\nNew message ! Protocol[%x:%x], TLS Proof enable[%i] :\n",ver.min,ver.max,(int)val);
+
+ //Read an incoming message
+ bzero(buffer,sizeof(buffer));
+ n = PR_Read(socketfd,buffer,sizeof(buffer));
+ if (n < 0)
+ error("ERROR reading from socket");
+ printf("%s",buffer);
+
+ //Update the merkle root and save the received message
+ //saveMessage(buffer,n);
+ for(int i = 0; i < n; i++) fprintf(messagesFile,"%c", buffer[i]);
+ }
+
+ //Request the proof, NSS will call the associated callback when the proof arrive
+ rv = SSL_TLSProofRequestProof(socketfd);
+ if(rv != SECSuccess) error("SSL_TLSProofRequestProof");
+
+ fclose(messagesFile);
+
+ //This is necessary to get the signature but will never return
+ PR_Read(socketfd,buffer,255);
+
+ PR_Close(socketfd);
+
+
+ printf("\nEND\n");
+ return 0;
+}
+
diff --git a/nss/cmd/clientProof/manifest.mn b/nss/cmd/clientProof/manifest.mn
new file mode 100644
index 0000000..6c25b1e
--- /dev/null
+++ b/nss/cmd/clientProof/manifest.mn
@@ -0,0 +1,23 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+CORE_DEPTH = ../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+# This next line is used by .mk files
+# and gets translated into $LINCS in manifest.mnw
+# The MODULE is always implicitly required.
+# Listing it here in REQUIRES makes it appear twice in the cc command line.
+REQUIRES = seccmd dbm
+
+# DIRS =
+
+CSRCS = main.c
+DEFINES += -DDLL_PREFIX=\"$(DLL_PREFIX)\" -DDLL_SUFFIX=\"$(DLL_SUFFIX)\"
+
+PROGRAM = clientProof
+
diff --git a/nss/cmd/crlutil/Makefile b/nss/cmd/crlutil/Makefile
new file mode 100644
index 0000000..a61ae1c
--- /dev/null
+++ b/nss/cmd/crlutil/Makefile
@@ -0,0 +1,53 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include ../platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+#
+# crlgen_lex can be generated on linux by flex or solaris by lex
+#
+crlgen_lex:
+ ${LEX} -t crlgen_lex_orig.l > crlgen_lex_fix.c
+ sed -f crlgen_lex_fix.sed < crlgen_lex_fix.c > crlgen_lex.c
+ rm -f crlgen_lex_fix.c
+
+include ../platrules.mk
diff --git a/nss/cmd/crlutil/crlgen.c b/nss/cmd/crlutil/crlgen.c
new file mode 100644
index 0000000..1f9dc4b
--- /dev/null
+++ b/nss/cmd/crlutil/crlgen.c
@@ -0,0 +1,1542 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+** crlgen.c
+**
+** utility for managing certificates revocation lists generation
+**
+*/
+
+#include
+#include
+
+#include "nspr.h"
+#include "plgetopt.h"
+#include "nss.h"
+#include "secutil.h"
+#include "cert.h"
+#include "certi.h"
+#include "certdb.h"
+#include "pk11func.h"
+#include "crlgen.h"
+
+/* Destroys extHandle and data. data was create on heap.
+ * extHandle creaded by CERT_StartCRLEntryExtensions. entry
+ * was allocated on arena.*/
+static void
+destroyEntryData(CRLGENEntryData *data)
+{
+ if (!data)
+ return;
+ PORT_Assert(data->entry);
+ if (data->extHandle)
+ CERT_FinishExtensions(data->extHandle);
+ PORT_Free(data);
+}
+
+/* Prints error messages along with line number */
+void
+crlgen_PrintError(int line, char *msg, ...)
+{
+ va_list args;
+
+ va_start(args, msg);
+
+ fprintf(stderr, "crlgen: (line: %d) ", line);
+ vfprintf(stderr, msg, args);
+
+ va_end(args);
+}
+/* Finds CRLGENEntryData in hashtable according PRUint64 value
+ * - certId : cert serial number*/
+static CRLGENEntryData *
+crlgen_FindEntry(CRLGENGeneratorData *crlGenData, SECItem *certId)
+{
+ if (!crlGenData->entryDataHashTable || !certId)
+ return NULL;
+ return (CRLGENEntryData *)
+ PL_HashTableLookup(crlGenData->entryDataHashTable,
+ certId);
+}
+
+/* Removes CRLGENEntryData from hashtable according to certId
+ * - certId : cert serial number*/
+static SECStatus
+crlgen_RmEntry(CRLGENGeneratorData *crlGenData, SECItem *certId)
+{
+ CRLGENEntryData *data = NULL;
+ SECStatus rv = SECSuccess;
+
+ if (!crlGenData->entryDataHashTable) {
+ return SECSuccess;
+ }
+
+ data = crlgen_FindEntry(crlGenData, certId);
+ if (!data) {
+ return SECSuccess;
+ }
+
+ if (!PL_HashTableRemove(crlGenData->entryDataHashTable, certId)) {
+ rv = SECFailure;
+ }
+
+ destroyEntryData(data);
+ return rv;
+}
+
+/* Stores CRLGENEntryData in hashtable according to certId
+ * - certId : cert serial number*/
+static CRLGENEntryData *
+crlgen_PlaceAnEntry(CRLGENGeneratorData *crlGenData,
+ CERTCrlEntry *entry, SECItem *certId)
+{
+ CRLGENEntryData *newData = NULL;
+
+ PORT_Assert(crlGenData && crlGenData->entryDataHashTable &&
+ entry);
+ if (!crlGenData || !crlGenData->entryDataHashTable || !entry) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
+ }
+
+ newData = PORT_ZNew(CRLGENEntryData);
+ if (!newData) {
+ return NULL;
+ }
+ newData->entry = entry;
+ newData->certId = certId;
+ if (!PL_HashTableAdd(crlGenData->entryDataHashTable,
+ newData->certId, newData)) {
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "Can not add entryData structure\n");
+ return NULL;
+ }
+ return newData;
+}
+
+/* Use this structure to keep pointer when commiting entries extensions */
+struct commitData {
+ int pos;
+ CERTCrlEntry **entries;
+};
+
+/* HT PL_HashTableEnumerateEntries callback. Sorts hashtable entries of the
+ * table he. Returns value through arg parameter*/
+static PRIntn PR_CALLBACK
+crlgen_CommitEntryData(PLHashEntry *he, PRIntn i, void *arg)
+{
+ CRLGENEntryData *data = NULL;
+
+ PORT_Assert(he);
+ if (!he) {
+ return HT_ENUMERATE_NEXT;
+ }
+ data = (CRLGENEntryData *)he->value;
+
+ PORT_Assert(data);
+ PORT_Assert(arg);
+
+ if (data) {
+ struct commitData *dt = (struct commitData *)arg;
+ dt->entries[dt->pos++] = data->entry;
+ destroyEntryData(data);
+ }
+ return HT_ENUMERATE_NEXT;
+}
+
+/* Copy char * datainto allocated in arena SECItem */
+static SECStatus
+crlgen_SetString(PLArenaPool *arena, const char *dataIn, SECItem *value)
+{
+ SECItem item;
+
+ PORT_Assert(arena && dataIn);
+ if (!arena || !dataIn) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ item.data = (void *)dataIn;
+ item.len = PORT_Strlen(dataIn);
+
+ return SECITEM_CopyItem(arena, value, &item);
+}
+
+/* Creates CERTGeneralName from parsed data for the Authority Key Extension */
+static CERTGeneralName *
+crlgen_GetGeneralName(PLArenaPool *arena, CRLGENGeneratorData *crlGenData,
+ const char *data)
+{
+ CERTGeneralName *namesList = NULL;
+ CERTGeneralName *current;
+ CERTGeneralName *tail = NULL;
+ SECStatus rv = SECSuccess;
+ const char *nextChunk = NULL;
+ const char *currData = NULL;
+ int intValue;
+ char buffer[512];
+ void *mark;
+
+ if (!data)
+ return NULL;
+ PORT_Assert(arena);
+ if (!arena) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
+ }
+
+ mark = PORT_ArenaMark(arena);
+
+ nextChunk = data;
+ currData = data;
+ do {
+ int nameLen = 0;
+ char name[128];
+ const char *sepPrt = NULL;
+ nextChunk = PORT_Strchr(currData, '|');
+ if (!nextChunk)
+ nextChunk = data + strlen(data);
+ sepPrt = PORT_Strchr(currData, ':');
+ if (sepPrt == NULL || sepPrt >= nextChunk) {
+ *buffer = '\0';
+ sepPrt = nextChunk;
+ } else {
+ PORT_Memcpy(buffer, sepPrt + 1,
+ (nextChunk - sepPrt - 1));
+ buffer[nextChunk - sepPrt - 1] = '\0';
+ }
+ nameLen = PR_MIN(sepPrt - currData, sizeof(name) - 1);
+ PORT_Memcpy(name, currData, nameLen);
+ name[nameLen] = '\0';
+ currData = nextChunk + 1;
+
+ if (!PORT_Strcmp(name, "otherName"))
+ intValue = certOtherName;
+ else if (!PORT_Strcmp(name, "rfc822Name"))
+ intValue = certRFC822Name;
+ else if (!PORT_Strcmp(name, "dnsName"))
+ intValue = certDNSName;
+ else if (!PORT_Strcmp(name, "x400Address"))
+ intValue = certX400Address;
+ else if (!PORT_Strcmp(name, "directoryName"))
+ intValue = certDirectoryName;
+ else if (!PORT_Strcmp(name, "ediPartyName"))
+ intValue = certEDIPartyName;
+ else if (!PORT_Strcmp(name, "URI"))
+ intValue = certURI;
+ else if (!PORT_Strcmp(name, "ipAddress"))
+ intValue = certIPAddress;
+ else if (!PORT_Strcmp(name, "registerID"))
+ intValue = certRegisterID;
+ else
+ intValue = -1;
+
+ if (intValue >= certOtherName && intValue <= certRegisterID) {
+ if (namesList == NULL) {
+ namesList = current = tail = PORT_ArenaZNew(arena,
+ CERTGeneralName);
+ } else {
+ current = PORT_ArenaZNew(arena, CERTGeneralName);
+ }
+ if (current == NULL) {
+ rv = SECFailure;
+ break;
+ }
+ } else {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ break;
+ }
+ current->type = intValue;
+ switch (current->type) {
+ case certURI:
+ case certDNSName:
+ case certRFC822Name:
+ current->name.other.data = PORT_ArenaAlloc(arena, strlen(buffer));
+ if (current->name.other.data == NULL) {
+ rv = SECFailure;
+ break;
+ }
+ PORT_Memcpy(current->name.other.data, buffer,
+ current->name.other.len = strlen(buffer));
+ break;
+
+ case certEDIPartyName:
+ case certIPAddress:
+ case certOtherName:
+ case certRegisterID:
+ case certX400Address: {
+
+ current->name.other.data = PORT_ArenaAlloc(arena, strlen(buffer) + 2);
+ if (current->name.other.data == NULL) {
+ rv = SECFailure;
+ break;
+ }
+
+ PORT_Memcpy(current->name.other.data + 2, buffer, strlen(buffer));
+ /* This may not be accurate for all cases.For now, use this tag type */
+ current->name.other.data[0] = (char)(((current->type - 1) & 0x1f) | 0x80);
+ current->name.other.data[1] = (char)strlen(buffer);
+ current->name.other.len = strlen(buffer) + 2;
+ break;
+ }
+
+ case certDirectoryName: {
+ CERTName *directoryName = NULL;
+
+ directoryName = CERT_AsciiToName(buffer);
+ if (!directoryName) {
+ rv = SECFailure;
+ break;
+ }
+
+ rv = CERT_CopyName(arena, ¤t->name.directoryName, directoryName);
+ CERT_DestroyName(directoryName);
+
+ break;
+ }
+ }
+ if (rv != SECSuccess)
+ break;
+ current->l.next = &(namesList->l);
+ current->l.prev = &(tail->l);
+ tail->l.next = &(current->l);
+ tail = current;
+
+ } while (nextChunk != data + strlen(data));
+
+ if (rv != SECSuccess) {
+ PORT_ArenaRelease(arena, mark);
+ namesList = NULL;
+ }
+ return (namesList);
+}
+
+/* Creates CERTGeneralName from parsed data for the Authority Key Extension */
+static CERTGeneralName *
+crlgen_DistinguishedName(PLArenaPool *arena, CRLGENGeneratorData *crlGenData,
+ const char *data)
+{
+ CERTName *directoryName = NULL;
+ CERTGeneralName *current;
+ SECStatus rv = SECFailure;
+ void *mark;
+
+ if (!data)
+ return NULL;
+ PORT_Assert(arena);
+ if (!arena) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
+ }
+
+ mark = PORT_ArenaMark(arena);
+
+ current = PORT_ArenaZNew(arena, CERTGeneralName);
+ if (current == NULL) {
+ goto loser;
+ }
+ current->type = certDirectoryName;
+ current->l.next = ¤t->l;
+ current->l.prev = ¤t->l;
+
+ directoryName = CERT_AsciiToName((char *)data);
+ if (!directoryName) {
+ goto loser;
+ }
+
+ rv = CERT_CopyName(arena, ¤t->name.directoryName, directoryName);
+ CERT_DestroyName(directoryName);
+
+loser:
+ if (rv != SECSuccess) {
+ PORT_SetError(rv);
+ PORT_ArenaRelease(arena, mark);
+ current = NULL;
+ }
+ return (current);
+}
+
+/* Adding Authority Key ID extension to extension handle. */
+static SECStatus
+crlgen_AddAuthKeyID(CRLGENGeneratorData *crlGenData,
+ const char **dataArr)
+{
+ void *extHandle = NULL;
+ CERTAuthKeyID *authKeyID = NULL;
+ PLArenaPool *arena = NULL;
+ SECStatus rv = SECSuccess;
+
+ PORT_Assert(dataArr && crlGenData);
+ if (!crlGenData || !dataArr) {
+ return SECFailure;
+ }
+
+ extHandle = crlGenData->crlExtHandle;
+
+ if (!dataArr[0] || !dataArr[1] || !dataArr[2]) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "insufficient number of parameters.\n");
+ return SECFailure;
+ }
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ return SECFailure;
+ }
+
+ authKeyID = PORT_ArenaZNew(arena, CERTAuthKeyID);
+ if (authKeyID == NULL) {
+ rv = SECFailure;
+ goto loser;
+ }
+
+ if (dataArr[3] == NULL) {
+ rv = crlgen_SetString(arena, dataArr[2], &authKeyID->keyID);
+ if (rv != SECSuccess)
+ goto loser;
+ } else {
+ rv = crlgen_SetString(arena, dataArr[3],
+ &authKeyID->authCertSerialNumber);
+ if (rv != SECSuccess)
+ goto loser;
+
+ authKeyID->authCertIssuer =
+ crlgen_DistinguishedName(arena, crlGenData, dataArr[2]);
+ if (authKeyID->authCertIssuer == NULL && SECFailure == PORT_GetError()) {
+ crlgen_PrintError(crlGenData->parsedLineNum, "syntax error.\n");
+ rv = SECFailure;
+ goto loser;
+ }
+ }
+
+ rv =
+ SECU_EncodeAndAddExtensionValue(arena, extHandle, authKeyID,
+ (*dataArr[1] == '1') ? PR_TRUE : PR_FALSE,
+ SEC_OID_X509_AUTH_KEY_ID,
+ (EXTEN_EXT_VALUE_ENCODER)CERT_EncodeAuthKeyID);
+loser:
+ if (arena)
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+/* Creates and add Subject Alternative Names extension */
+static SECStatus
+crlgen_AddIssuerAltNames(CRLGENGeneratorData *crlGenData,
+ const char **dataArr)
+{
+ CERTGeneralName *nameList = NULL;
+ PLArenaPool *arena = NULL;
+ void *extHandle = NULL;
+ SECStatus rv = SECSuccess;
+
+ PORT_Assert(dataArr && crlGenData);
+ if (!crlGenData || !dataArr) {
+ return SECFailure;
+ }
+
+ if (!dataArr || !dataArr[0] || !dataArr[1] || !dataArr[2]) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "insufficient number of arguments.\n");
+ return SECFailure;
+ }
+
+ PORT_Assert(dataArr && crlGenData);
+ if (!crlGenData || !dataArr) {
+ return SECFailure;
+ }
+
+ extHandle = crlGenData->crlExtHandle;
+
+ if (!dataArr[0] || !dataArr[1] || !dataArr[2]) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "insufficient number of parameters.\n");
+ return SECFailure;
+ }
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ return SECFailure;
+ }
+
+ nameList = crlgen_GetGeneralName(arena, crlGenData, dataArr[2]);
+ if (nameList == NULL) {
+ crlgen_PrintError(crlGenData->parsedLineNum, "syntax error.\n");
+ rv = SECFailure;
+ goto loser;
+ }
+
+ rv =
+ SECU_EncodeAndAddExtensionValue(arena, extHandle, nameList,
+ (*dataArr[1] == '1') ? PR_TRUE : PR_FALSE,
+ SEC_OID_X509_ISSUER_ALT_NAME,
+ (EXTEN_EXT_VALUE_ENCODER)CERT_EncodeAltNameExtension);
+loser:
+ if (arena)
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+/* Creates and adds CRLNumber extension to extension handle.
+ * Since, this is CRL extension, extension handle is the one
+ * related to CRL extensions */
+static SECStatus
+crlgen_AddCrlNumber(CRLGENGeneratorData *crlGenData, const char **dataArr)
+{
+ PLArenaPool *arena = NULL;
+ SECItem encodedItem;
+ void *dummy;
+ SECStatus rv = SECFailure;
+ int code = 0;
+
+ PORT_Assert(dataArr && crlGenData);
+ if (!crlGenData || !dataArr) {
+ goto loser;
+ }
+
+ if (!dataArr[0] || !dataArr[1] || !dataArr[2]) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "insufficient number of arguments.\n");
+ goto loser;
+ }
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (arena == NULL) {
+ goto loser;
+ }
+
+ code = atoi(dataArr[2]);
+ if (code == 0 && *dataArr[2] != '0') {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ goto loser;
+ }
+
+ dummy = SEC_ASN1EncodeInteger(arena, &encodedItem, code);
+ if (!dummy) {
+ rv = SECFailure;
+ goto loser;
+ }
+
+ rv = CERT_AddExtension(crlGenData->crlExtHandle, SEC_OID_X509_CRL_NUMBER,
+ &encodedItem,
+ (*dataArr[1] == '1') ? PR_TRUE : PR_FALSE,
+ PR_TRUE);
+
+loser:
+ if (arena)
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+/* Creates Cert Revocation Reason code extension. Encodes it and
+ * returns as SECItem structure */
+static SECItem *
+crlgen_CreateReasonCode(PLArenaPool *arena, const char **dataArr,
+ int *extCode)
+{
+ SECItem *encodedItem;
+ void *dummy;
+ void *mark = NULL;
+ int code = 0;
+
+ PORT_Assert(arena && dataArr);
+ if (!arena || !dataArr) {
+ goto loser;
+ }
+
+ mark = PORT_ArenaMark(arena);
+
+ encodedItem = PORT_ArenaZNew(arena, SECItem);
+ if (encodedItem == NULL) {
+ goto loser;
+ }
+
+ if (dataArr[2] == NULL) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ goto loser;
+ }
+
+ code = atoi(dataArr[2]);
+ /* aACompromise(10) is the last possible of the values
+ * for the Reason Core Extension */
+ if ((code == 0 && *dataArr[2] != '0') || code > 10) {
+
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ goto loser;
+ }
+
+ dummy = SEC_ASN1EncodeInteger(arena, encodedItem, code);
+ if (!dummy) {
+ goto loser;
+ }
+
+ *extCode = SEC_OID_X509_REASON_CODE;
+ return encodedItem;
+
+loser:
+ if (mark) {
+ PORT_ArenaRelease(arena, mark);
+ }
+ return NULL;
+}
+
+/* Creates Cert Invalidity Date extension. Encodes it and
+ * returns as SECItem structure */
+static SECItem *
+crlgen_CreateInvalidityDate(PLArenaPool *arena, const char **dataArr,
+ int *extCode)
+{
+ SECItem *encodedItem;
+ int length = 0;
+ void *mark = NULL;
+
+ PORT_Assert(arena && dataArr);
+ if (!arena || !dataArr) {
+ goto loser;
+ }
+
+ mark = PORT_ArenaMark(arena);
+
+ encodedItem = PORT_ArenaZNew(arena, SECItem);
+ if (encodedItem == NULL) {
+ goto loser;
+ }
+
+ length = PORT_Strlen(dataArr[2]);
+
+ encodedItem->type = siGeneralizedTime;
+ encodedItem->data = PORT_ArenaAlloc(arena, length);
+ if (!encodedItem->data) {
+ goto loser;
+ }
+
+ PORT_Memcpy(encodedItem->data, dataArr[2], (encodedItem->len = length) *
+ sizeof(char));
+
+ *extCode = SEC_OID_X509_INVALID_DATE;
+ return encodedItem;
+
+loser:
+ if (mark) {
+ PORT_ArenaRelease(arena, mark);
+ }
+ return NULL;
+}
+
+/* Creates(by calling extCreator function) and adds extension to a set
+ * of already added certs. Uses values of rangeFrom and rangeTo from
+ * CRLGENCrlGenCtl structure for identifying the inclusive set of certs */
+static SECStatus
+crlgen_AddEntryExtension(CRLGENGeneratorData *crlGenData,
+ const char **dataArr, char *extName,
+ SECItem *(*extCreator)(PLArenaPool *arena,
+ const char **dataArr,
+ int *extCode))
+{
+ PRUint64 i = 0;
+ SECStatus rv = SECFailure;
+ int extCode = 0;
+ PRUint64 lastRange;
+ SECItem *ext = NULL;
+ PLArenaPool *arena = NULL;
+
+ PORT_Assert(crlGenData && dataArr);
+ if (!crlGenData || !dataArr) {
+ goto loser;
+ }
+
+ if (!dataArr[0] || !dataArr[1]) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "insufficient number of arguments.\n");
+ }
+
+ lastRange = crlGenData->rangeTo - crlGenData->rangeFrom + 1;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (arena == NULL) {
+ goto loser;
+ }
+
+ ext = extCreator(arena, dataArr, &extCode);
+ if (ext == NULL) {
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "got error while creating extension: %s\n",
+ extName);
+ goto loser;
+ }
+
+ for (i = 0; i < lastRange; i++) {
+ CRLGENEntryData *extData = NULL;
+ void *extHandle = NULL;
+ SECItem *certIdItem =
+ SEC_ASN1EncodeInteger(arena, NULL,
+ crlGenData->rangeFrom + i);
+ if (!certIdItem) {
+ rv = SECFailure;
+ goto loser;
+ }
+
+ extData = crlgen_FindEntry(crlGenData, certIdItem);
+ if (!extData) {
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "can not add extension: crl entry "
+ "(serial number: %d) is not in the list yet.\n",
+ crlGenData->rangeFrom + i);
+ continue;
+ }
+
+ extHandle = extData->extHandle;
+ if (extHandle == NULL) {
+ extHandle = extData->extHandle =
+ CERT_StartCRLEntryExtensions(&crlGenData->signCrl->crl,
+ (CERTCrlEntry *)extData->entry);
+ }
+ rv = CERT_AddExtension(extHandle, extCode, ext,
+ (*dataArr[1] == '1') ? PR_TRUE : PR_FALSE,
+ PR_TRUE);
+ if (rv == SECFailure) {
+ goto loser;
+ }
+ }
+
+loser:
+ if (arena)
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+/* Commits all added entries and their's extensions into CRL. */
+SECStatus
+CRLGEN_CommitExtensionsAndEntries(CRLGENGeneratorData *crlGenData)
+{
+ int size = 0;
+ CERTCrl *crl;
+ PLArenaPool *arena;
+ SECStatus rv = SECSuccess;
+ void *mark;
+
+ PORT_Assert(crlGenData && crlGenData->signCrl && crlGenData->signCrl->arena);
+ if (!crlGenData || !crlGenData->signCrl || !crlGenData->signCrl->arena) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ arena = crlGenData->signCrl->arena;
+ crl = &crlGenData->signCrl->crl;
+
+ mark = PORT_ArenaMark(arena);
+
+ if (crlGenData->crlExtHandle)
+ CERT_FinishExtensions(crlGenData->crlExtHandle);
+
+ size = crlGenData->entryDataHashTable->nentries;
+ crl->entries = NULL;
+ if (size) {
+ crl->entries = PORT_ArenaZNewArray(arena, CERTCrlEntry *, size + 1);
+ if (!crl->entries) {
+ rv = SECFailure;
+ } else {
+ struct commitData dt;
+ dt.entries = crl->entries;
+ dt.pos = 0;
+ PL_HashTableEnumerateEntries(crlGenData->entryDataHashTable,
+ &crlgen_CommitEntryData, &dt);
+ /* Last should be NULL */
+ crl->entries[size] = NULL;
+ }
+ }
+
+ if (rv != SECSuccess)
+ PORT_ArenaRelease(arena, mark);
+ return rv;
+}
+
+/* Initializes extHandle with data from extensions array */
+static SECStatus
+crlgen_InitExtensionHandle(void *extHandle,
+ CERTCertExtension **extensions)
+{
+ CERTCertExtension *extension = NULL;
+
+ if (!extensions)
+ return SECSuccess;
+
+ PORT_Assert(extHandle != NULL);
+ if (!extHandle) {
+ return SECFailure;
+ }
+
+ extension = *extensions;
+ while (extension) {
+ SECOidTag oidTag = SECOID_FindOIDTag(&extension->id);
+ /* shell we skip unknown extensions? */
+ CERT_AddExtension(extHandle, oidTag, &extension->value,
+ (extension->critical.len != 0) ? PR_TRUE : PR_FALSE,
+ PR_FALSE);
+ extension = *(++extensions);
+ }
+ return SECSuccess;
+}
+
+/* Used for initialization of extension handles for crl and certs
+ * extensions from existing CRL data then modifying existing CRL.*/
+SECStatus
+CRLGEN_ExtHandleInit(CRLGENGeneratorData *crlGenData)
+{
+ CERTCrl *crl = NULL;
+ PRUint64 maxSN = 0;
+
+ PORT_Assert(crlGenData && crlGenData->signCrl &&
+ crlGenData->entryDataHashTable);
+ if (!crlGenData || !crlGenData->signCrl ||
+ !crlGenData->entryDataHashTable) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ crl = &crlGenData->signCrl->crl;
+ crlGenData->crlExtHandle = CERT_StartCRLExtensions(crl);
+ crlgen_InitExtensionHandle(crlGenData->crlExtHandle,
+ crl->extensions);
+ crl->extensions = NULL;
+
+ if (crl->entries) {
+ CERTCrlEntry **entry = crl->entries;
+ while (*entry) {
+ PRUint64 sn = DER_GetInteger(&(*entry)->serialNumber);
+ CRLGENEntryData *extData =
+ crlgen_PlaceAnEntry(crlGenData, *entry, &(*entry)->serialNumber);
+ if ((*entry)->extensions) {
+ extData->extHandle =
+ CERT_StartCRLEntryExtensions(&crlGenData->signCrl->crl,
+ (CERTCrlEntry *)extData->entry);
+ if (crlgen_InitExtensionHandle(extData->extHandle,
+ (*entry)->extensions) == SECFailure)
+ return SECFailure;
+ }
+ (*entry)->extensions = NULL;
+ entry++;
+ maxSN = PR_MAX(maxSN, sn);
+ }
+ }
+
+ crlGenData->rangeFrom = crlGenData->rangeTo = maxSN + 1;
+ return SECSuccess;
+}
+
+/*****************************************************************************
+ * Parser trigger functions start here
+ */
+
+/* Sets new internal range value for add/rm certs.*/
+static SECStatus
+crlgen_SetNewRangeField(CRLGENGeneratorData *crlGenData, char *value)
+{
+ long rangeFrom = 0, rangeTo = 0;
+ char *dashPos = NULL;
+
+ PORT_Assert(crlGenData);
+ if (!crlGenData) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ if (value == NULL) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "insufficient number of arguments.\n");
+ return SECFailure;
+ }
+
+ if ((dashPos = strchr(value, '-')) != NULL) {
+ char *rangeToS, *rangeFromS = value;
+ *dashPos = '\0';
+ rangeFrom = atoi(rangeFromS);
+ *dashPos = '-';
+
+ rangeToS = (char *)(dashPos + 1);
+ rangeTo = atol(rangeToS);
+ } else {
+ rangeFrom = atol(value);
+ rangeTo = rangeFrom;
+ }
+
+ if (rangeFrom < 1 || rangeTo < rangeFrom) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "bad cert id range: %s.\n", value);
+ return SECFailure;
+ }
+
+ crlGenData->rangeFrom = rangeFrom;
+ crlGenData->rangeTo = rangeTo;
+
+ return SECSuccess;
+}
+
+/* Changes issuer subject field in CRL. By default this data is taken from
+ * issuer cert subject field.Not yet implemented */
+static SECStatus
+crlgen_SetIssuerField(CRLGENGeneratorData *crlGenData, char *value)
+{
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "Can not change CRL issuer field.\n");
+ return SECFailure;
+}
+
+/* Encode and sets CRL thisUpdate and nextUpdate time fields*/
+static SECStatus
+crlgen_SetTimeField(CRLGENGeneratorData *crlGenData, char *value,
+ PRBool setThisUpdate)
+{
+ CERTSignedCrl *signCrl;
+ PLArenaPool *arena;
+ CERTCrl *crl;
+ int length = 0;
+ SECItem *timeDest = NULL;
+
+ PORT_Assert(crlGenData && crlGenData->signCrl &&
+ crlGenData->signCrl->arena);
+ if (!crlGenData || !crlGenData->signCrl || !crlGenData->signCrl->arena) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ signCrl = crlGenData->signCrl;
+ arena = signCrl->arena;
+ crl = &signCrl->crl;
+
+ if (value == NULL) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "insufficient number of arguments.\n");
+ return SECFailure;
+ }
+ length = PORT_Strlen(value);
+
+ if (setThisUpdate == PR_TRUE) {
+ timeDest = &crl->lastUpdate;
+ } else {
+ timeDest = &crl->nextUpdate;
+ }
+
+ timeDest->type = siGeneralizedTime;
+ timeDest->data = PORT_ArenaAlloc(arena, length);
+ if (!timeDest->data) {
+ return SECFailure;
+ }
+ PORT_Memcpy(timeDest->data, value, length);
+ timeDest->len = length;
+
+ return SECSuccess;
+}
+
+/* Adds new extension into CRL or added cert handles */
+static SECStatus
+crlgen_AddExtension(CRLGENGeneratorData *crlGenData, const char **extData)
+{
+ PORT_Assert(crlGenData && crlGenData->crlExtHandle);
+ if (!crlGenData || !crlGenData->crlExtHandle) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ if (extData == NULL || *extData == NULL) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "insufficient number of arguments.\n");
+ return SECFailure;
+ }
+ if (!PORT_Strcmp(*extData, "authKeyId"))
+ return crlgen_AddAuthKeyID(crlGenData, extData);
+ else if (!PORT_Strcmp(*extData, "issuerAltNames"))
+ return crlgen_AddIssuerAltNames(crlGenData, extData);
+ else if (!PORT_Strcmp(*extData, "crlNumber"))
+ return crlgen_AddCrlNumber(crlGenData, extData);
+ else if (!PORT_Strcmp(*extData, "reasonCode"))
+ return crlgen_AddEntryExtension(crlGenData, extData, "reasonCode",
+ crlgen_CreateReasonCode);
+ else if (!PORT_Strcmp(*extData, "invalidityDate"))
+ return crlgen_AddEntryExtension(crlGenData, extData, "invalidityDate",
+ crlgen_CreateInvalidityDate);
+ else {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "insufficient number of arguments.\n");
+ return SECFailure;
+ }
+}
+
+/* Created CRLGENEntryData for cert with serial number certId and
+ * adds it to entryDataHashTable. certId can be a single cert serial
+ * number or an inclusive rage of certs */
+static SECStatus
+crlgen_AddCert(CRLGENGeneratorData *crlGenData,
+ char *certId, char *revocationDate)
+{
+ CERTSignedCrl *signCrl;
+ SECItem *certIdItem;
+ PLArenaPool *arena;
+ PRUint64 rangeFrom = 0, rangeTo = 0, i = 0;
+ int timeValLength = -1;
+ SECStatus rv = SECFailure;
+ void *mark;
+
+ PORT_Assert(crlGenData && crlGenData->signCrl &&
+ crlGenData->signCrl->arena);
+ if (!crlGenData || !crlGenData->signCrl || !crlGenData->signCrl->arena) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ signCrl = crlGenData->signCrl;
+ arena = signCrl->arena;
+
+ if (!certId || !revocationDate) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "insufficient number of arguments.\n");
+ return SECFailure;
+ }
+
+ timeValLength = strlen(revocationDate);
+
+ if (crlgen_SetNewRangeField(crlGenData, certId) == SECFailure &&
+ certId) {
+ return SECFailure;
+ }
+ rangeFrom = crlGenData->rangeFrom;
+ rangeTo = crlGenData->rangeTo;
+
+ for (i = 0; i < rangeTo - rangeFrom + 1; i++) {
+ CERTCrlEntry *entry;
+ mark = PORT_ArenaMark(arena);
+ entry = PORT_ArenaZNew(arena, CERTCrlEntry);
+ if (entry == NULL) {
+ goto loser;
+ }
+
+ certIdItem = SEC_ASN1EncodeInteger(arena, &entry->serialNumber,
+ rangeFrom + i);
+ if (!certIdItem) {
+ goto loser;
+ }
+
+ if (crlgen_FindEntry(crlGenData, certIdItem)) {
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "entry already exists. Use \"range\" "
+ "and \"rmcert\" before adding a new one with the "
+ "same serial number %ld\n",
+ rangeFrom + i);
+ goto loser;
+ }
+
+ entry->serialNumber.type = siBuffer;
+
+ entry->revocationDate.type = siGeneralizedTime;
+
+ entry->revocationDate.data =
+ PORT_ArenaAlloc(arena, timeValLength);
+ if (entry->revocationDate.data == NULL) {
+ goto loser;
+ }
+
+ PORT_Memcpy(entry->revocationDate.data, revocationDate,
+ timeValLength * sizeof(char));
+ entry->revocationDate.len = timeValLength;
+
+ entry->extensions = NULL;
+ if (!crlgen_PlaceAnEntry(crlGenData, entry, certIdItem)) {
+ goto loser;
+ }
+ mark = NULL;
+ }
+
+ rv = SECSuccess;
+loser:
+ if (mark) {
+ PORT_ArenaRelease(arena, mark);
+ }
+ return rv;
+}
+
+/* Removes certs from entryDataHashTable which have certId serial number.
+ * certId can have value of a range of certs */
+static SECStatus
+crlgen_RmCert(CRLGENGeneratorData *crlGenData, char *certId)
+{
+ PRUint64 i = 0;
+
+ PORT_Assert(crlGenData && certId);
+ if (!crlGenData || !certId) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ if (crlgen_SetNewRangeField(crlGenData, certId) == SECFailure &&
+ certId) {
+ return SECFailure;
+ }
+
+ for (i = 0; i < crlGenData->rangeTo - crlGenData->rangeFrom + 1; i++) {
+ SECItem *certIdItem = SEC_ASN1EncodeInteger(NULL, NULL,
+ crlGenData->rangeFrom + i);
+ if (certIdItem) {
+ CRLGENEntryData *extData =
+ crlgen_FindEntry(crlGenData, certIdItem);
+ if (!extData) {
+ printf("Cert with id %s is not in the list\n", certId);
+ } else {
+ crlgen_RmEntry(crlGenData, certIdItem);
+ }
+ SECITEM_FreeItem(certIdItem, PR_TRUE);
+ }
+ }
+
+ return SECSuccess;
+}
+
+/*************************************************************************
+ * Lex Parser Helper functions are used to store parsed information
+ * in context related structures. Context(or state) is identified base on
+ * a type of a instruction parser currently is going through. New context
+ * is identified by first token in a line. It can be addcert context,
+ * addext context, etc. */
+
+/* Updates CRL field depending on current context */
+static SECStatus
+crlgen_updateCrlFn_field(CRLGENGeneratorData *crlGenData, void *str)
+{
+ CRLGENCrlField *fieldStr = (CRLGENCrlField *)str;
+
+ PORT_Assert(crlGenData);
+ if (!crlGenData) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ switch (crlGenData->contextId) {
+ case CRLGEN_ISSUER_CONTEXT:
+ crlgen_SetIssuerField(crlGenData, fieldStr->value);
+ break;
+ case CRLGEN_UPDATE_CONTEXT:
+ return crlgen_SetTimeField(crlGenData, fieldStr->value, PR_TRUE);
+ break;
+ case CRLGEN_NEXT_UPDATE_CONTEXT:
+ return crlgen_SetTimeField(crlGenData, fieldStr->value, PR_FALSE);
+ break;
+ case CRLGEN_CHANGE_RANGE_CONTEXT:
+ return crlgen_SetNewRangeField(crlGenData, fieldStr->value);
+ break;
+ default:
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "syntax error (unknow token type: %d)\n",
+ crlGenData->contextId);
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+/* Sets parsed data for CRL field update into temporary structure */
+static SECStatus
+crlgen_setNextDataFn_field(CRLGENGeneratorData *crlGenData, void *str,
+ void *data, unsigned short dtype)
+{
+ CRLGENCrlField *fieldStr = (CRLGENCrlField *)str;
+
+ PORT_Assert(crlGenData);
+ if (!crlGenData) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ switch (crlGenData->contextId) {
+ case CRLGEN_CHANGE_RANGE_CONTEXT:
+ if (dtype != CRLGEN_TYPE_DIGIT && dtype != CRLGEN_TYPE_DIGIT_RANGE) {
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "range value should have "
+ "numeric or numeric range values.\n");
+ return SECFailure;
+ }
+ break;
+ case CRLGEN_NEXT_UPDATE_CONTEXT:
+ case CRLGEN_UPDATE_CONTEXT:
+ if (dtype != CRLGEN_TYPE_ZDATE) {
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "bad formated date. Should be "
+ "YYYYMMDDHHMMSSZ.\n");
+ return SECFailure;
+ }
+ break;
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "syntax error (unknow token type: %d).\n",
+ crlGenData->contextId, data);
+ return SECFailure;
+ }
+ fieldStr->value = PORT_Strdup(data);
+ if (!fieldStr->value) {
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+/* Triggers cert entries update depending on current context */
+static SECStatus
+crlgen_updateCrlFn_cert(CRLGENGeneratorData *crlGenData, void *str)
+{
+ CRLGENCertEntry *certStr = (CRLGENCertEntry *)str;
+
+ PORT_Assert(crlGenData);
+ if (!crlGenData) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ switch (crlGenData->contextId) {
+ case CRLGEN_ADD_CERT_CONTEXT:
+ return crlgen_AddCert(crlGenData, certStr->certId,
+ certStr->revocationTime);
+ case CRLGEN_RM_CERT_CONTEXT:
+ return crlgen_RmCert(crlGenData, certStr->certId);
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "syntax error (unknow token type: %d).\n",
+ crlGenData->contextId);
+ return SECFailure;
+ }
+}
+
+/* Sets parsed data for CRL entries update into temporary structure */
+static SECStatus
+crlgen_setNextDataFn_cert(CRLGENGeneratorData *crlGenData, void *str,
+ void *data, unsigned short dtype)
+{
+ CRLGENCertEntry *certStr = (CRLGENCertEntry *)str;
+
+ PORT_Assert(crlGenData);
+ if (!crlGenData) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ switch (dtype) {
+ case CRLGEN_TYPE_DIGIT:
+ case CRLGEN_TYPE_DIGIT_RANGE:
+ certStr->certId = PORT_Strdup(data);
+ if (!certStr->certId) {
+ return SECFailure;
+ }
+ break;
+ case CRLGEN_TYPE_DATE:
+ case CRLGEN_TYPE_ZDATE:
+ certStr->revocationTime = PORT_Strdup(data);
+ if (!certStr->revocationTime) {
+ return SECFailure;
+ }
+ break;
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "syntax error (unknow token type: %d).\n",
+ crlGenData->contextId);
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+/* Triggers cert entries/crl extension update */
+static SECStatus
+crlgen_updateCrlFn_extension(CRLGENGeneratorData *crlGenData, void *str)
+{
+ CRLGENExtensionEntry *extStr = (CRLGENExtensionEntry *)str;
+
+ return crlgen_AddExtension(crlGenData, (const char **)extStr->extData);
+}
+
+/* Defines maximum number of fields extension may have */
+#define MAX_EXT_DATA_LENGTH 10
+
+/* Sets parsed extension data for CRL entries/CRL extensions update
+ * into temporary structure */
+static SECStatus
+crlgen_setNextDataFn_extension(CRLGENGeneratorData *crlGenData, void *str,
+ void *data, unsigned short dtype)
+{
+ CRLGENExtensionEntry *extStr = (CRLGENExtensionEntry *)str;
+
+ PORT_Assert(crlGenData);
+ if (!crlGenData) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ if (extStr->extData == NULL) {
+ extStr->extData = PORT_ZNewArray(char *, MAX_EXT_DATA_LENGTH);
+ if (!extStr->extData) {
+ return SECFailure;
+ }
+ }
+ if (extStr->nextUpdatedData >= MAX_EXT_DATA_LENGTH) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "number of fields in extension "
+ "exceeded maximum allowed data length: %d.\n",
+ MAX_EXT_DATA_LENGTH);
+ return SECFailure;
+ }
+ extStr->extData[extStr->nextUpdatedData] = PORT_Strdup(data);
+ if (!extStr->extData[extStr->nextUpdatedData]) {
+ return SECFailure;
+ }
+ extStr->nextUpdatedData += 1;
+
+ return SECSuccess;
+}
+
+/****************************************************************************************
+ * Top level functions are triggered directly by parser.
+ */
+
+/*
+ * crl generation script parser recreates a temporary data staructure
+ * for each line it is going through. This function cleans temp structure.
+ */
+void
+crlgen_destroyTempData(CRLGENGeneratorData *crlGenData)
+{
+ if (crlGenData->contextId != CRLGEN_UNKNOWN_CONTEXT) {
+ switch (crlGenData->contextId) {
+ case CRLGEN_ISSUER_CONTEXT:
+ case CRLGEN_UPDATE_CONTEXT:
+ case CRLGEN_NEXT_UPDATE_CONTEXT:
+ case CRLGEN_CHANGE_RANGE_CONTEXT:
+ if (crlGenData->crlField->value)
+ PORT_Free(crlGenData->crlField->value);
+ PORT_Free(crlGenData->crlField);
+ break;
+ case CRLGEN_ADD_CERT_CONTEXT:
+ case CRLGEN_RM_CERT_CONTEXT:
+ if (crlGenData->certEntry->certId)
+ PORT_Free(crlGenData->certEntry->certId);
+ if (crlGenData->certEntry->revocationTime)
+ PORT_Free(crlGenData->certEntry->revocationTime);
+ PORT_Free(crlGenData->certEntry);
+ break;
+ case CRLGEN_ADD_EXTENSION_CONTEXT:
+ if (crlGenData->extensionEntry->extData) {
+ int i = 0;
+ for (; i < crlGenData->extensionEntry->nextUpdatedData; i++)
+ PORT_Free(*(crlGenData->extensionEntry->extData + i));
+ PORT_Free(crlGenData->extensionEntry->extData);
+ }
+ PORT_Free(crlGenData->extensionEntry);
+ break;
+ }
+ crlGenData->contextId = CRLGEN_UNKNOWN_CONTEXT;
+ }
+}
+
+SECStatus
+crlgen_updateCrl(CRLGENGeneratorData *crlGenData)
+{
+ SECStatus rv = SECSuccess;
+
+ PORT_Assert(crlGenData);
+ if (!crlGenData) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ switch (crlGenData->contextId) {
+ case CRLGEN_ISSUER_CONTEXT:
+ case CRLGEN_UPDATE_CONTEXT:
+ case CRLGEN_NEXT_UPDATE_CONTEXT:
+ case CRLGEN_CHANGE_RANGE_CONTEXT:
+ rv = crlGenData->crlField->updateCrlFn(crlGenData, crlGenData->crlField);
+ break;
+ case CRLGEN_RM_CERT_CONTEXT:
+ case CRLGEN_ADD_CERT_CONTEXT:
+ rv = crlGenData->certEntry->updateCrlFn(crlGenData, crlGenData->certEntry);
+ break;
+ case CRLGEN_ADD_EXTENSION_CONTEXT:
+ rv = crlGenData->extensionEntry->updateCrlFn(crlGenData, crlGenData->extensionEntry);
+ break;
+ case CRLGEN_UNKNOWN_CONTEXT:
+ break;
+ default:
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "unknown lang context type code: %d.\n",
+ crlGenData->contextId);
+ PORT_Assert(0);
+ return SECFailure;
+ }
+ /* Clrean structures after crl update */
+ crlgen_destroyTempData(crlGenData);
+
+ crlGenData->parsedLineNum += 1;
+
+ return rv;
+}
+
+SECStatus
+crlgen_setNextData(CRLGENGeneratorData *crlGenData, void *data,
+ unsigned short dtype)
+{
+ SECStatus rv = SECSuccess;
+
+ PORT_Assert(crlGenData);
+ if (!crlGenData) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ switch (crlGenData->contextId) {
+ case CRLGEN_ISSUER_CONTEXT:
+ case CRLGEN_UPDATE_CONTEXT:
+ case CRLGEN_NEXT_UPDATE_CONTEXT:
+ case CRLGEN_CHANGE_RANGE_CONTEXT:
+ rv = crlGenData->crlField->setNextDataFn(crlGenData, crlGenData->crlField,
+ data, dtype);
+ break;
+ case CRLGEN_ADD_CERT_CONTEXT:
+ case CRLGEN_RM_CERT_CONTEXT:
+ rv = crlGenData->certEntry->setNextDataFn(crlGenData, crlGenData->certEntry,
+ data, dtype);
+ break;
+ case CRLGEN_ADD_EXTENSION_CONTEXT:
+ rv =
+ crlGenData->extensionEntry->setNextDataFn(crlGenData, crlGenData->extensionEntry, data, dtype);
+ break;
+ case CRLGEN_UNKNOWN_CONTEXT:
+ break;
+ default:
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "unknown context type: %d.\n",
+ crlGenData->contextId);
+ PORT_Assert(0);
+ return SECFailure;
+ }
+ return rv;
+}
+
+SECStatus
+crlgen_createNewLangStruct(CRLGENGeneratorData *crlGenData,
+ unsigned structType)
+{
+ PORT_Assert(crlGenData &&
+ crlGenData->contextId == CRLGEN_UNKNOWN_CONTEXT);
+ if (!crlGenData ||
+ crlGenData->contextId != CRLGEN_UNKNOWN_CONTEXT) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ switch (structType) {
+ case CRLGEN_ISSUER_CONTEXT:
+ case CRLGEN_UPDATE_CONTEXT:
+ case CRLGEN_NEXT_UPDATE_CONTEXT:
+ case CRLGEN_CHANGE_RANGE_CONTEXT:
+ crlGenData->crlField = PORT_New(CRLGENCrlField);
+ if (!crlGenData->crlField) {
+ return SECFailure;
+ }
+ crlGenData->contextId = structType;
+ crlGenData->crlField->value = NULL;
+ crlGenData->crlField->updateCrlFn = &crlgen_updateCrlFn_field;
+ crlGenData->crlField->setNextDataFn = &crlgen_setNextDataFn_field;
+ break;
+ case CRLGEN_RM_CERT_CONTEXT:
+ case CRLGEN_ADD_CERT_CONTEXT:
+ crlGenData->certEntry = PORT_New(CRLGENCertEntry);
+ if (!crlGenData->certEntry) {
+ return SECFailure;
+ }
+ crlGenData->contextId = structType;
+ crlGenData->certEntry->certId = 0;
+ crlGenData->certEntry->revocationTime = NULL;
+ crlGenData->certEntry->updateCrlFn = &crlgen_updateCrlFn_cert;
+ crlGenData->certEntry->setNextDataFn = &crlgen_setNextDataFn_cert;
+ break;
+ case CRLGEN_ADD_EXTENSION_CONTEXT:
+ crlGenData->extensionEntry = PORT_New(CRLGENExtensionEntry);
+ if (!crlGenData->extensionEntry) {
+ return SECFailure;
+ }
+ crlGenData->contextId = structType;
+ crlGenData->extensionEntry->extData = NULL;
+ crlGenData->extensionEntry->nextUpdatedData = 0;
+ crlGenData->extensionEntry->updateCrlFn =
+ &crlgen_updateCrlFn_extension;
+ crlGenData->extensionEntry->setNextDataFn =
+ &crlgen_setNextDataFn_extension;
+ break;
+ case CRLGEN_UNKNOWN_CONTEXT:
+ break;
+ default:
+ crlgen_PrintError(crlGenData->parsedLineNum,
+ "unknown context type: %d.\n", structType);
+ PORT_Assert(0);
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+/* Parser initialization function */
+CRLGENGeneratorData *
+CRLGEN_InitCrlGeneration(CERTSignedCrl *signCrl, PRFileDesc *src)
+{
+ CRLGENGeneratorData *crlGenData = NULL;
+
+ PORT_Assert(signCrl && src);
+ if (!signCrl || !src) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
+ }
+
+ crlGenData = PORT_ZNew(CRLGENGeneratorData);
+ if (!crlGenData) {
+ return NULL;
+ }
+
+ crlGenData->entryDataHashTable =
+ PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare,
+ PL_CompareValues, NULL, NULL);
+ if (!crlGenData->entryDataHashTable) {
+ PORT_Free(crlGenData);
+ return NULL;
+ }
+
+ crlGenData->src = src;
+ crlGenData->parsedLineNum = 1;
+ crlGenData->contextId = CRLGEN_UNKNOWN_CONTEXT;
+ crlGenData->signCrl = signCrl;
+ crlGenData->rangeFrom = 0;
+ crlGenData->rangeTo = 0;
+ crlGenData->crlExtHandle = NULL;
+
+ PORT_SetError(0);
+
+ return crlGenData;
+}
+
+void
+CRLGEN_FinalizeCrlGeneration(CRLGENGeneratorData *crlGenData)
+{
+ if (!crlGenData)
+ return;
+ if (crlGenData->src)
+ PR_Close(crlGenData->src);
+ PL_HashTableDestroy(crlGenData->entryDataHashTable);
+ PORT_Free(crlGenData);
+}
diff --git a/nss/cmd/crlutil/crlgen.h b/nss/cmd/crlutil/crlgen.h
new file mode 100644
index 0000000..3ec7921
--- /dev/null
+++ b/nss/cmd/crlutil/crlgen.h
@@ -0,0 +1,178 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef _CRLGEN_H_
+#define _CRLGEN_H_
+
+#include "prio.h"
+#include "prprf.h"
+#include "plhash.h"
+#include "seccomon.h"
+#include "certt.h"
+#include "secoidt.h"
+
+#define CRLGEN_UNKNOWN_CONTEXT 0
+#define CRLGEN_ISSUER_CONTEXT 1
+#define CRLGEN_UPDATE_CONTEXT 2
+#define CRLGEN_NEXT_UPDATE_CONTEXT 3
+#define CRLGEN_ADD_EXTENSION_CONTEXT 4
+#define CRLGEN_ADD_CERT_CONTEXT 6
+#define CRLGEN_CHANGE_RANGE_CONTEXT 7
+#define CRLGEN_RM_CERT_CONTEXT 8
+
+#define CRLGEN_TYPE_DATE 0
+#define CRLGEN_TYPE_ZDATE 1
+#define CRLGEN_TYPE_DIGIT 2
+#define CRLGEN_TYPE_DIGIT_RANGE 3
+#define CRLGEN_TYPE_OID 4
+#define CRLGEN_TYPE_STRING 5
+#define CRLGEN_TYPE_ID 6
+
+typedef struct CRLGENGeneratorDataStr CRLGENGeneratorData;
+typedef struct CRLGENEntryDataStr CRLGENEntryData;
+typedef struct CRLGENExtensionEntryStr CRLGENExtensionEntry;
+typedef struct CRLGENCertEntrySrt CRLGENCertEntry;
+typedef struct CRLGENCrlFieldStr CRLGENCrlField;
+typedef struct CRLGENEntriesSortedDataStr CRLGENEntriesSortedData;
+
+/* Exported functions */
+
+/* Used for initialization of extension handles for crl and certs
+ * extensions from existing CRL data then modifying existing CRL.*/
+extern SECStatus CRLGEN_ExtHandleInit(CRLGENGeneratorData *crlGenData);
+
+/* Commits all added entries and their's extensions into CRL. */
+extern SECStatus CRLGEN_CommitExtensionsAndEntries(CRLGENGeneratorData *crlGenData);
+
+/* Lunches the crl generation script parse */
+extern SECStatus CRLGEN_StartCrlGen(CRLGENGeneratorData *crlGenData);
+
+/* Closes crl generation script file and frees crlGenData */
+extern void CRLGEN_FinalizeCrlGeneration(CRLGENGeneratorData *crlGenData);
+
+/* Parser initialization function. Creates CRLGENGeneratorData structure
+ * for the current thread */
+extern CRLGENGeneratorData *CRLGEN_InitCrlGeneration(CERTSignedCrl *newCrl,
+ PRFileDesc *src);
+
+/* This lock is defined in crlgen_lex.c(derived from crlgen_lex.l).
+ * It controls access to invocation of yylex, allows to parse one
+ * script at a time */
+extern void CRLGEN_InitCrlGenParserLock();
+extern void CRLGEN_DestroyCrlGenParserLock();
+
+/* The following function types are used to define functions for each of
+ * CRLGENExtensionEntryStr, CRLGENCertEntrySrt, CRLGENCrlFieldStr to
+ * provide functionality needed for these structures*/
+typedef SECStatus updateCrlFn_t(CRLGENGeneratorData *crlGenData, void *str);
+typedef SECStatus setNextDataFn_t(CRLGENGeneratorData *crlGenData, void *str,
+ void *data, unsigned short dtype);
+typedef SECStatus createNewLangStructFn_t(CRLGENGeneratorData *crlGenData,
+ void *str, unsigned i);
+
+/* Sets reports failure to parser if anything goes wrong */
+extern void crlgen_setFailure(CRLGENGeneratorData *str, char *);
+
+/* Collects data in to one of the current data structure that corresponds
+ * to the correct context type. This function gets called after each token
+ * is found for a particular line */
+extern SECStatus crlgen_setNextData(CRLGENGeneratorData *str, void *data,
+ unsigned short dtype);
+
+/* initiates crl update with collected data. This function is called at the
+ * end of each line */
+extern SECStatus crlgen_updateCrl(CRLGENGeneratorData *str);
+
+/* Creates new context structure depending on token that was parsed
+ * at the beginning of a line */
+extern SECStatus crlgen_createNewLangStruct(CRLGENGeneratorData *str,
+ unsigned structType);
+
+/* CRLGENExtensionEntry is used to store addext request data for either
+ * CRL extensions or CRL entry extensions. The differentiation between
+ * is based on order and type of extension been added.
+ * - extData : all data in request staring from name of the extension are
+ * in saved here.
+ * - nextUpdatedData: counter of elements added to extData
+ */
+struct CRLGENExtensionEntryStr {
+ char **extData;
+ int nextUpdatedData;
+ updateCrlFn_t *updateCrlFn;
+ setNextDataFn_t *setNextDataFn;
+};
+
+/* CRLGENCeryestEntry is used to store addcert request data
+ * - certId : certificate id or range of certificate with dash as a delimiter
+ * All certs from range will be inclusively added to crl
+ * - revocationTime: revocation time of cert(s)
+ */
+struct CRLGENCertEntrySrt {
+ char *certId;
+ char *revocationTime;
+ updateCrlFn_t *updateCrlFn;
+ setNextDataFn_t *setNextDataFn;
+};
+
+/* CRLGENCrlField is used to store crl fields record like update time, next
+ * update time, etc.
+ * - value: value of the parsed field data*/
+struct CRLGENCrlFieldStr {
+ char *value;
+ updateCrlFn_t *updateCrlFn;
+ setNextDataFn_t *setNextDataFn;
+};
+
+/* Can not create entries extension until completely done with parsing.
+ * Therefore need to keep joined data
+ * - certId : serial number of certificate
+ * - extHandle: head pointer to a list of extensions that belong to
+ * entry
+ * - entry : CERTCrlEntry structure pointer*/
+struct CRLGENEntryDataStr {
+ SECItem *certId;
+ void *extHandle;
+ CERTCrlEntry *entry;
+};
+
+/* Crl generator/parser main structure. Keeps info regarding current state of
+ * parser(context, status), parser helper functions pointers, parsed data and
+ * generated data.
+ * - contextId : current parsing context. Context in this parser environment
+ * defines what type of crl operations parser is going through
+ * in the current line of crl generation script.
+ * setting or new cert or an extension addition, etc.
+ * - createNewLangStructFn: pointer to top level function which creates
+ * data structures according contextId
+ * - setNextDataFn : pointer to top level function which sets new parsed data
+ * in temporary structure
+ * - updateCrlFn : pointer to top level function which triggers actual
+ * crl update functions with gathered data
+ * - union : data union create according to contextId
+ * - rangeFrom, rangeTo : holds last range in which certs was added
+ * - newCrl : pointer to CERTSignedCrl newly created crl
+ * - crlExtHandle : pointer to crl extension handle
+ * - entryDataHashTable: hash of CRLGENEntryData.
+ * key: cert serial number
+ * data: CRLGENEntryData pointer
+ * - parserStatus : current status of parser. Triggers parser to abort when
+ * set to SECFailure
+ * - src : PRFileDesc structure pointer of crl generator config file
+ * - parsedLineNum : currently parsing line. Keeping it to report errors */
+struct CRLGENGeneratorDataStr {
+ unsigned short contextId;
+ CRLGENCrlField *crlField;
+ CRLGENCertEntry *certEntry;
+ CRLGENExtensionEntry *extensionEntry;
+ PRUint64 rangeFrom;
+ PRUint64 rangeTo;
+ CERTSignedCrl *signCrl;
+ void *crlExtHandle;
+ PLHashTable *entryDataHashTable;
+
+ PRFileDesc *src;
+ int parsedLineNum;
+};
+
+#endif /* _CRLGEN_H_ */
diff --git a/nss/cmd/crlutil/crlgen_lex.c b/nss/cmd/crlutil/crlgen_lex.c
new file mode 100644
index 0000000..fb53ec8
--- /dev/null
+++ b/nss/cmd/crlutil/crlgen_lex.c
@@ -0,0 +1,1773 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include
+#ifdef _WIN32
+#include
+#else
+#include
+#endif
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+#ifdef __cplusplus
+
+#include
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef __TURBOC__
+#pragma warn - rch
+#pragma warn - use
+#include
+#include
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int)(unsigned char)c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart(yyin)
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator). This
+ * avoids problems with code like:
+ *
+ * if ( condition_holds )
+ * yyless( 5 );
+ * else
+ * do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+ do { \
+ /* Undo effects of setting up yytext. */ \
+ *yy_cp = yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } while (0)
+
+#define unput(c) yyunput(c, yytext_ptr)
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+struct yy_buffer_state {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+/* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+};
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *)0;
+static int yy_init = 1; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO((FILE * input_file));
+
+void yy_switch_to_buffer YY_PROTO((YY_BUFFER_STATE new_buffer));
+void yy_load_buffer_state YY_PROTO((void));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO((FILE * file, int size));
+void yy_delete_buffer YY_PROTO((YY_BUFFER_STATE b));
+void yy_init_buffer YY_PROTO((YY_BUFFER_STATE b, FILE *file));
+void yy_flush_buffer YY_PROTO((YY_BUFFER_STATE b));
+#define YY_FLUSH_BUFFER yy_flush_buffer(yy_current_buffer)
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO((char *base, yy_size_t size));
+YY_BUFFER_STATE yy_scan_string YY_PROTO((yyconst char *yy_str));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO((yyconst char *bytes, int len));
+
+static void *yy_flex_alloc YY_PROTO((yy_size_t));
+static void *yy_flex_realloc YY_PROTO((void *, yy_size_t));
+static void yy_flex_free YY_PROTO((void *));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if (!yy_current_buffer) \
+ yy_current_buffer = yy_create_buffer(yyin, YY_BUF_SIZE); \
+ yy_current_buffer->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if (!yy_current_buffer) \
+ yy_current_buffer = yy_create_buffer(yyin, YY_BUF_SIZE); \
+ yy_current_buffer->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *)0, *yyout = (FILE *)0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO((void));
+static yy_state_type yy_try_NUL_trans YY_PROTO((yy_state_type current_state));
+static int yy_get_next_buffer YY_PROTO((void));
+static void yy_fatal_error YY_PROTO((yyconst char msg[]));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yytext_ptr = yy_bp; \
+ yytext_ptr -= yy_more_len; \
+ yyleng = (int)(yy_cp - yytext_ptr); \
+ yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 17
+#define YY_END_OF_BUFFER 18
+/* clang-format off */
+static yyconst short int yy_accept[67] =
+ { 0,
+ 0, 0, 18, 16, 14, 15, 16, 11, 12, 2,
+ 10, 9, 9, 9, 9, 9, 13, 14, 15, 11,
+ 12, 0, 12, 2, 9, 9, 9, 9, 9, 13,
+ 3, 4, 2, 9, 9, 9, 9, 2, 9, 9,
+ 9, 9, 2, 2, 9, 9, 8, 9, 2, 5,
+ 9, 6, 2, 9, 2, 9, 2, 9, 2, 7,
+ 2, 2, 2, 2, 1, 0
+ } ;
+
+static yyconst int yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 1, 5, 6, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 7, 8, 1, 9, 9, 10,
+ 11, 12, 12, 12, 13, 13, 13, 14, 1, 1,
+ 15, 1, 1, 1, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 17,
+ 1, 1, 1, 1, 1, 1, 18, 16, 16, 19,
+
+ 20, 16, 21, 16, 22, 16, 16, 16, 16, 23,
+ 16, 24, 16, 25, 26, 27, 28, 16, 16, 29,
+ 16, 16, 1, 14, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst int yy_meta[30] =
+ { 0,
+ 1, 1, 2, 1, 3, 1, 1, 4, 5, 5,
+ 5, 5, 5, 4, 1, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4
+ } ;
+
+static yyconst short int yy_base[72] =
+ { 0,
+ 0, 149, 154, 205, 138, 205, 103, 0, 0, 23,
+ 205, 29, 30, 31, 32, 33, 0, 99, 205, 0,
+ 0, 0, 50, 55, 34, 61, 41, 63, 64, 0,
+ 0, 0, 79, 65, 68, 86, 66, 99, 105, 88,
+ 106, 90, 118, 76, 107, 110, 89, 125, 43, 91,
+ 127, 128, 138, 144, 113, 129, 154, 160, 160, 130,
+ 172, 166, 177, 144, 0, 205, 190, 192, 194, 199,
+ 76
+ } ;
+
+static yyconst short int yy_def[72] =
+ { 0,
+ 66, 1, 66, 66, 66, 66, 66, 67, 68, 68,
+ 66, 69, 69, 69, 69, 69, 70, 66, 66, 67,
+ 68, 71, 68, 10, 69, 69, 69, 69, 69, 70,
+ 71, 23, 10, 69, 69, 69, 69, 10, 69, 69,
+ 69, 69, 10, 38, 69, 69, 69, 69, 38, 69,
+ 69, 69, 38, 69, 38, 69, 38, 69, 38, 69,
+ 38, 38, 38, 38, 68, 0, 66, 66, 66, 66,
+ 66
+ } ;
+
+static yyconst short int yy_nxt[235] =
+ { 0,
+ 4, 5, 6, 7, 8, 4, 4, 9, 10, 10,
+ 10, 10, 10, 9, 11, 12, 12, 12, 12, 12,
+ 12, 13, 14, 12, 15, 12, 12, 16, 12, 22,
+ 23, 24, 24, 24, 24, 24, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 28,
+ 27, 53, 53, 53, 21, 26, 29, 32, 32, 32,
+ 32, 32, 32, 33, 33, 33, 33, 33, 21, 35,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 31, 21, 37, 42, 44, 36, 34, 38, 38, 38,
+ 38, 38, 39, 21, 40, 21, 21, 21, 21, 21,
+
+ 18, 21, 21, 21, 21, 19, 41, 43, 44, 44,
+ 44, 44, 21, 21, 21, 46, 48, 21, 21, 21,
+ 21, 57, 57, 21, 45, 47, 49, 49, 49, 49,
+ 49, 50, 21, 51, 21, 21, 21, 21, 21, 18,
+ 21, 21, 21, 21, 52, 54, 55, 55, 55, 55,
+ 55, 21, 44, 66, 17, 58, 66, 21, 66, 66,
+ 65, 56, 59, 59, 59, 59, 59, 21, 61, 61,
+ 61, 61, 66, 21, 63, 63, 63, 63, 66, 60,
+ 62, 62, 62, 62, 62, 64, 64, 64, 64, 64,
+ 20, 20, 66, 20, 20, 21, 21, 25, 25, 30,
+
+ 66, 30, 30, 30, 3, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66
+ } ;
+
+static yyconst short int yy_chk[235] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 10,
+ 10, 10, 10, 10, 10, 10, 12, 13, 14, 15,
+ 16, 25, 12, 13, 14, 15, 16, 25, 27, 15,
+ 14, 49, 49, 49, 27, 13, 16, 23, 23, 23,
+ 23, 23, 23, 24, 24, 24, 24, 24, 26, 27,
+ 28, 29, 34, 37, 26, 35, 28, 29, 34, 37,
+ 71, 35, 29, 37, 44, 28, 26, 33, 33, 33,
+ 33, 33, 34, 36, 35, 40, 47, 42, 50, 36,
+
+ 18, 40, 47, 42, 50, 7, 36, 38, 38, 38,
+ 38, 38, 39, 41, 45, 40, 42, 46, 39, 41,
+ 45, 55, 55, 46, 39, 41, 43, 43, 43, 43,
+ 43, 45, 48, 46, 51, 52, 56, 60, 48, 5,
+ 51, 52, 56, 60, 48, 51, 53, 53, 53, 53,
+ 53, 54, 64, 3, 2, 56, 0, 54, 0, 0,
+ 64, 54, 57, 57, 57, 57, 57, 58, 59, 59,
+ 59, 59, 0, 58, 62, 62, 62, 62, 0, 58,
+ 61, 61, 61, 61, 61, 63, 63, 63, 63, 63,
+ 67, 67, 0, 67, 67, 68, 68, 69, 69, 70,
+
+ 0, 70, 70, 70, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 66, 66
+ } ;
+/* clang-format on */
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+static int yy_more_flag = 0;
+static int yy_more_len = 0;
+#define yymore() (yy_more_flag = 1)
+#define YY_MORE_ADJ yy_more_len
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "crlgen_lex_orig.l"
+#define INITIAL 0
+#line 2 "crlgen_lex_orig.l"
+
+#include "crlgen.h"
+
+static SECStatus parserStatus = SECSuccess;
+static CRLGENGeneratorData *parserData;
+static PRFileDesc *src;
+
+#define YY_INPUT(buf, result, max_size) \
+ if (parserStatus != SECFailure) { \
+ if (((result = PR_Read(src, buf, max_size)) == 0) && \
+ ferror(yyin)) \
+ return SECFailure; \
+ } else { \
+ return SECFailure; \
+ }
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO((void));
+#else
+extern int yywrap YY_PROTO((void));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO((int c, char *buf_ptr));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO((char *, yyconst char *, int));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO((yyconst char *));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO((void));
+#else
+static int input YY_PROTO((void));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO((int new_state));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO((void));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO((void));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include
+#endif
+#else
+/* Just try to get by without declaring the routines. This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void)fwrite(yytext, yyleng, 1, yyout)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf, result, max_size) \
+ if (yy_current_buffer->yy_is_interactive) { \
+ int c = '*', n; \
+ for (n = 0; n < max_size && \
+ (c = getc(yyin)) != EOF && c != '\n'; \
+ ++n) \
+ buf[n] = (char)c; \
+ if (c == '\n') \
+ buf[n++] = (char)c; \
+ if (c == EOF && ferror(yyin)) \
+ YY_FATAL_ERROR("input in flex scanner failed"); \
+ result = n; \
+ } else if (((result = fread(buf, 1, max_size, yyin)) == 0) && \
+ ferror(yyin)) \
+ YY_FATAL_ERROR("input in flex scanner failed");
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error(msg)
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO((void))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ if (yyleng > 0) \
+ yy_current_buffer->yy_at_bol = \
+ (yytext[yyleng - 1] == '\n'); \
+ YY_USER_ACTION
+
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp = NULL, *yy_bp = NULL;
+ register int yy_act;
+
+#line 28 "crlgen_lex_orig.l"
+
+ if (yy_init) {
+ yy_init = 0;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if (!yy_start)
+ yy_start = 1; /* first start state */
+
+ if (!yyin)
+ yyin = stdin;
+
+ if (!yyout)
+ yyout = stdout;
+
+ if (!yy_current_buffer)
+ yy_current_buffer =
+ yy_create_buffer(yyin, YY_BUF_SIZE);
+
+ yy_load_buffer_state();
+ }
+
+ while (1) /* loops until end-of-file is reached */
+ {
+ yy_more_len = 0;
+ if (yy_more_flag) {
+ yy_more_len = yy_c_buf_p - yytext_ptr;
+ yy_more_flag = 0;
+ }
+ yy_cp = yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yy_start;
+ yy_current_state += YY_AT_BOL();
+ yy_match:
+ do {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if (yy_accept[yy_current_state]) {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state) {
+ yy_current_state = (int)yy_def[yy_current_state];
+ if (yy_current_state >= 67)
+ yy_c = yy_meta[(unsigned int)yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int)yy_c];
+ ++yy_cp;
+ } while (yy_base[yy_current_state] != 205);
+
+ yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if (yy_act == 0) { /* have to back up */
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+ do_action: /* This label is used only to access EOF actions. */
+
+ switch (yy_act) { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yy_hold_char;
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ goto yy_find_action;
+
+ case 1:
+ YY_RULE_SETUP
+#line 30 "crlgen_lex_orig.l"
+ {
+ parserStatus =
+ crlgen_setNextData(parserData, yytext, CRLGEN_TYPE_ZDATE);
+ if (parserStatus !=
+ SECSuccess)
+ return parserStatus;
+ }
+ YY_BREAK
+ case 2:
+ YY_RULE_SETUP
+#line 36 "crlgen_lex_orig.l"
+ {
+ parserStatus =
+ crlgen_setNextData(parserData, yytext, CRLGEN_TYPE_DIGIT);
+ if (parserStatus !=
+ SECSuccess)
+ return parserStatus;
+ }
+ YY_BREAK
+ case 3:
+ YY_RULE_SETUP
+#line 42 "crlgen_lex_orig.l"
+ {
+ parserStatus =
+ crlgen_setNextData(parserData, yytext, CRLGEN_TYPE_DIGIT_RANGE);
+ if (parserStatus !=
+ SECSuccess)
+ return parserStatus;
+ }
+ YY_BREAK
+ case 4:
+ YY_RULE_SETUP
+#line 48 "crlgen_lex_orig.l"
+ {
+ parserStatus =
+ crlgen_setNextData(parserData, yytext, CRLGEN_TYPE_OID);
+ if (parserStatus !=
+ SECSuccess)
+ return parserStatus;
+ }
+ YY_BREAK
+ case 5:
+ YY_RULE_SETUP
+#line 54 "crlgen_lex_orig.l"
+ {
+ parserStatus =
+ crlgen_createNewLangStruct(parserData, CRLGEN_ISSUER_CONTEXT);
+ if (parserStatus !=
+ SECSuccess)
+ return parserStatus;
+ }
+ YY_BREAK
+ case 6:
+ YY_RULE_SETUP
+#line 60 "crlgen_lex_orig.l"
+ {
+ parserStatus =
+ crlgen_createNewLangStruct(parserData, CRLGEN_UPDATE_CONTEXT);
+ if (parserStatus !=
+ SECSuccess)
+ return parserStatus;
+ }
+ YY_BREAK
+ case 7:
+ YY_RULE_SETUP
+#line 65 "crlgen_lex_orig.l"
+ {
+ parserStatus =
+ crlgen_createNewLangStruct(parserData, CRLGEN_NEXT_UPDATE_CONTEXT);
+ if (parserStatus !=
+ SECSuccess)
+ return parserStatus;
+ }
+ YY_BREAK
+ case 8:
+ YY_RULE_SETUP
+#line 71 "crlgen_lex_orig.l"
+ {
+ parserStatus =
+ crlgen_createNewLangStruct(parserData, CRLGEN_CHANGE_RANGE_CONTEXT);
+ if (parserStatus !=
+ SECSuccess)
+ return parserStatus;
+ }
+ YY_BREAK
+ case 9:
+ YY_RULE_SETUP
+#line 77 "crlgen_lex_orig.l"
+ {
+ if (strcmp(yytext, "addcert") ==
+ 0) {
+ parserStatus =
+ crlgen_createNewLangStruct(parserData,
+ CRLGEN_ADD_CERT_CONTEXT);
+ if (parserStatus !=
+ SECSuccess)
+ return parserStatus;
+ } else if (strcmp(yytext, "rmcert") ==
+ 0) {
+ parserStatus =
+ crlgen_createNewLangStruct(parserData,
+ CRLGEN_RM_CERT_CONTEXT);
+ if (parserStatus !=
+ SECSuccess)
+ return parserStatus;
+ } else if (strcmp(yytext, "addext") ==
+ 0) {
+ parserStatus =
+ crlgen_createNewLangStruct(parserData,
+ CRLGEN_ADD_EXTENSION_CONTEXT);
+ if (parserStatus !=
+ SECSuccess)
+ return parserStatus;
+ } else {
+ parserStatus =
+ crlgen_setNextData(parserData, yytext, CRLGEN_TYPE_ID);
+ if (parserStatus !=
+ SECSuccess)
+ return parserStatus;
+ }
+ }
+ YY_BREAK
+ case 10:
+ YY_RULE_SETUP
+#line 100 "crlgen_lex_orig.l"
+
+ YY_BREAK
+ case 11:
+ YY_RULE_SETUP
+#line 102 "crlgen_lex_orig.l"
+ {
+ if (yytext[yyleng -
+ 1] ==
+ '\\') {
+ yymore();
+ } else {
+ register int c;
+ c =
+ input();
+ if (c !=
+ '\"') {
+ printf("Error: Line ending \" is missing: %c\n", c);
+ unput(c);
+ } else {
+ parserStatus =
+ crlgen_setNextData(parserData, yytext + 1,
+ CRLGEN_TYPE_STRING);
+ if (parserStatus !=
+ SECSuccess)
+ return parserStatus;
+ }
+ }
+ }
+ YY_BREAK
+ case 12:
+ YY_RULE_SETUP
+#line 120 "crlgen_lex_orig.l"
+ {
+ parserStatus =
+ crlgen_setNextData(parserData, yytext, CRLGEN_TYPE_STRING);
+ if (parserStatus !=
+ SECSuccess)
+ return parserStatus;
+ }
+ YY_BREAK
+ case 13:
+ YY_RULE_SETUP
+#line 128 "crlgen_lex_orig.l"
+ /* eat up one-line comments */ {}
+ YY_BREAK
+ case 14:
+ YY_RULE_SETUP
+#line 130 "crlgen_lex_orig.l"
+ {
+ }
+ YY_BREAK
+ case 15:
+ YY_RULE_SETUP
+#line 132 "crlgen_lex_orig.l"
+ {
+ parserStatus =
+ crlgen_updateCrl(parserData);
+ if (parserStatus !=
+ SECSuccess)
+ return parserStatus;
+ }
+ YY_BREAK
+ case 16:
+ YY_RULE_SETUP
+#line 138 "crlgen_lex_orig.l"
+ {
+ fprintf(stderr, "Syntax error at line %d: unknown token %s\n",
+ parserData->parsedLineNum, yytext);
+ return SECFailure;
+ }
+ YY_BREAK
+ case 17:
+ YY_RULE_SETUP
+#line 144 "crlgen_lex_orig.l"
+ ECHO;
+ YY_BREAK
+ case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ case YY_END_OF_BUFFER: {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int)(yy_cp - yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if (yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW) {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between yy_current_buffer and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yy_current_buffer->yy_input_file = yyin;
+ yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if (yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars]) { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans(yy_current_state);
+
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+ if (yy_next_state) {
+ /* Consume the NUL. */
+ yy_cp = ++yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else {
+ yy_cp = yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else
+ switch (yy_get_next_buffer()) {
+ case EOB_ACT_END_OF_FILE: {
+ yy_did_buffer_switch_on_eof = 0;
+
+ if (yywrap()) {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else {
+ if (!yy_did_buffer_switch_on_eof)
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p =
+ yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yy_c_buf_p =
+ &yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found");
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int
+yy_get_next_buffer()
+{
+ register char *dest = yy_current_buffer->yy_ch_buf;
+ register char *source = yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if (yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1])
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed");
+
+ if (yy_current_buffer->yy_fill_buffer == 0) { /* Don't try to fill the buffer, so this is an EOF. */
+ if (yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1) {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int)(yy_c_buf_p - yytext_ptr) - 1;
+
+ for (i = 0; i < number_to_move; ++i)
+ *(dest++) = *(source++);
+
+ if (yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING)
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+ else {
+ int num_to_read =
+ yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+ while (num_to_read <= 0) { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+ YY_FATAL_ERROR(
+ "input buffer overflow, can't enlarge buffer because scanner uses REJECT");
+#else
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = yy_current_buffer;
+
+ int yy_c_buf_p_offset =
+ (int)(yy_c_buf_p - b->yy_ch_buf);
+
+ if (b->yy_is_our_buffer) {
+ int new_size = b->yy_buf_size * 2;
+
+ if (new_size <= 0)
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yy_flex_realloc((void *)b->yy_ch_buf,
+ b->yy_buf_size + 2);
+ } else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if (!b->yy_ch_buf)
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow");
+
+ yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = yy_current_buffer->yy_buf_size -
+ number_to_move - 1;
+#endif
+ }
+
+ if (num_to_read > YY_READ_BUF_SIZE)
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT((&yy_current_buffer->yy_ch_buf[number_to_move]),
+ yy_n_chars, num_to_read);
+
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ if (yy_n_chars == 0) {
+ if (number_to_move == YY_MORE_ADJ) {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart(yyin);
+ }
+
+ else {
+ ret_val = EOB_ACT_LAST_MATCH;
+ yy_current_buffer->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ yy_n_chars += number_to_move;
+ yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type
+yy_get_previous_state()
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = yy_start;
+ yy_current_state += YY_AT_BOL();
+
+ for (yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp) {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if (yy_accept[yy_current_state]) {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state) {
+ yy_current_state = (int)yy_def[yy_current_state];
+ if (yy_current_state >= 67)
+ yy_c = yy_meta[(unsigned int)yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int)yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type
+yy_try_NUL_trans(yy_state_type yy_current_state)
+#else
+static yy_state_type yy_try_NUL_trans(yy_current_state)
+ yy_state_type yy_current_state;
+#endif
+{
+ register int yy_is_jam;
+ register char *yy_cp = yy_c_buf_p;
+
+ register YY_CHAR yy_c = 1;
+ if (yy_accept[yy_current_state]) {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state) {
+ yy_current_state = (int)yy_def[yy_current_state];
+ if (yy_current_state >= 67)
+ yy_c = yy_meta[(unsigned int)yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int)yy_c];
+ yy_is_jam = (yy_current_state == 66);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void
+yyunput(int c, register char *yy_bp)
+#else
+static void yyunput(c, yy_bp) int c;
+register char *yy_bp;
+#endif
+{
+ register char *yy_cp = yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yy_hold_char;
+
+ if (yy_cp < yy_current_buffer->yy_ch_buf + 2) { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = yy_n_chars + 2;
+ register char *dest = &yy_current_buffer->yy_ch_buf[yy_current_buffer->yy_buf_size +
+ 2];
+ register char *source =
+ &yy_current_buffer->yy_ch_buf[number_to_move];
+
+ while (source > yy_current_buffer->yy_ch_buf)
+ *--dest = *--source;
+
+ yy_cp += (int)(dest - source);
+ yy_bp += (int)(dest - source);
+ yy_current_buffer->yy_n_chars =
+ yy_n_chars = yy_current_buffer->yy_buf_size;
+
+ if (yy_cp < yy_current_buffer->yy_ch_buf + 2)
+ YY_FATAL_ERROR("flex scanner push-back overflow");
+ }
+
+ *--yy_cp = (char)c;
+
+ yytext_ptr = yy_bp;
+ yy_hold_char = *yy_cp;
+ yy_c_buf_p = yy_cp;
+}
+#endif /* ifndef YY_NO_UNPUT */
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int
+yyinput()
+#else
+static int
+input()
+#endif
+{
+ int c;
+
+ *yy_c_buf_p = yy_hold_char;
+
+ if (*yy_c_buf_p == YY_END_OF_BUFFER_CHAR) {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if (yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars])
+ /* This was really a NUL. */
+ *yy_c_buf_p = '\0';
+
+ else { /* need more input */
+ int offset = yy_c_buf_p - yytext_ptr;
+ ++yy_c_buf_p;
+
+ switch (yy_get_next_buffer()) {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart(yyin);
+
+ /* fall through */
+
+ case EOB_ACT_END_OF_FILE: {
+ if (yywrap())
+ return EOF;
+
+ if (!yy_did_buffer_switch_on_eof)
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p = yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *)yy_c_buf_p; /* cast for 8-bit char's */
+ *yy_c_buf_p = '\0'; /* preserve yytext */
+ yy_hold_char = *++yy_c_buf_p;
+
+ yy_current_buffer->yy_at_bol = (c == '\n');
+
+ return c;
+}
+#endif /* YY_NO_INPUT */
+
+#ifdef YY_USE_PROTOS
+void
+yyrestart(FILE *input_file)
+#else
+void yyrestart(input_file)
+ FILE *input_file;
+#endif
+{
+ if (!yy_current_buffer)
+ yy_current_buffer = yy_create_buffer(yyin, YY_BUF_SIZE);
+
+ yy_init_buffer(yy_current_buffer, input_file);
+ yy_load_buffer_state();
+}
+
+#ifdef YY_USE_PROTOS
+void
+yy_switch_to_buffer(YY_BUFFER_STATE new_buffer)
+#else
+void yy_switch_to_buffer(new_buffer)
+ YY_BUFFER_STATE new_buffer;
+#endif
+{
+ if (yy_current_buffer == new_buffer)
+ return;
+
+ if (yy_current_buffer) {
+ /* Flush out information for old buffer. */
+ *yy_c_buf_p = yy_hold_char;
+ yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ yy_current_buffer = new_buffer;
+ yy_load_buffer_state();
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yy_did_buffer_switch_on_eof = 1;
+}
+
+#ifdef YY_USE_PROTOS
+void
+yy_load_buffer_state(void)
+#else
+void
+yy_load_buffer_state()
+#endif
+{
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+ yyin = yy_current_buffer->yy_input_file;
+ yy_hold_char = *yy_c_buf_p;
+}
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE
+yy_create_buffer(FILE *file, int size)
+#else
+YY_BUFFER_STATE yy_create_buffer(file, size)
+ FILE *file;
+int size;
+#endif
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE)yy_flex_alloc(sizeof(struct yy_buffer_state));
+ if (!b)
+ YY_FATAL_ERROR("out of dynamic memory in yy_create_buffer()");
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *)yy_flex_alloc(b->yy_buf_size + 2);
+ if (!b->yy_ch_buf)
+ YY_FATAL_ERROR("out of dynamic memory in yy_create_buffer()");
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer(b, file);
+
+ return b;
+}
+
+#ifdef YY_USE_PROTOS
+void
+yy_delete_buffer(YY_BUFFER_STATE b)
+#else
+void yy_delete_buffer(b)
+ YY_BUFFER_STATE b;
+#endif
+{
+ if (!b)
+ return;
+
+ if (b == yy_current_buffer)
+ yy_current_buffer = (YY_BUFFER_STATE)0;
+
+ if (b->yy_is_our_buffer)
+ yy_flex_free((void *)b->yy_ch_buf);
+
+ yy_flex_free((void *)b);
+}
+
+#ifdef YY_USE_PROTOS
+void
+yy_init_buffer(YY_BUFFER_STATE b, FILE *file)
+#else
+void yy_init_buffer(b, file)
+ YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+{
+ yy_flush_buffer(b);
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+ b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+ b->yy_is_interactive = 0;
+#else
+ b->yy_is_interactive = file ? (isatty(fileno(file)) > 0) : 0;
+#endif
+#endif
+}
+
+#ifdef YY_USE_PROTOS
+void
+yy_flush_buffer(YY_BUFFER_STATE b)
+#else
+void yy_flush_buffer(b)
+ YY_BUFFER_STATE b;
+#endif
+
+{
+ if (!b)
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if (b == yy_current_buffer)
+ yy_load_buffer_state();
+}
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE
+yy_scan_buffer(char *base, yy_size_t size)
+#else
+YY_BUFFER_STATE yy_scan_buffer(base, size) char *base;
+yy_size_t size;
+#endif
+{
+ YY_BUFFER_STATE b;
+
+ if (size < 2 ||
+ base[size - 2] != YY_END_OF_BUFFER_CHAR ||
+ base[size - 1] != YY_END_OF_BUFFER_CHAR)
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE)yy_flex_alloc(sizeof(struct yy_buffer_state));
+ if (!b)
+ YY_FATAL_ERROR("out of dynamic memory in yy_scan_buffer()");
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer(b);
+
+ return b;
+}
+#endif
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE
+yy_scan_string(yyconst char *yy_str)
+#else
+YY_BUFFER_STATE yy_scan_string(yy_str)
+ yyconst char *yy_str;
+#endif
+{
+ int len;
+ for (len = 0; yy_str[len]; ++len)
+ ;
+
+ return yy_scan_bytes(yy_str, len);
+}
+#endif
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE
+yy_scan_bytes(yyconst char *bytes, int len)
+#else
+YY_BUFFER_STATE yy_scan_bytes(bytes, len)
+ yyconst char *bytes;
+int len;
+#endif
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = len + 2;
+ buf = (char *)yy_flex_alloc(n);
+ if (!buf)
+ YY_FATAL_ERROR("out of dynamic memory in yy_scan_bytes()");
+
+ for (i = 0; i < len; ++i)
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len + 1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer(buf, n);
+ if (!b)
+ YY_FATAL_ERROR("bad buffer in yy_scan_bytes()");
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+#endif
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void
+yy_push_state(int new_state)
+#else
+static void yy_push_state(new_state) int new_state;
+#endif
+{
+ if (yy_start_stack_ptr >= yy_start_stack_depth) {
+ yy_size_t new_size;
+
+ yy_start_stack_depth += YY_START_STACK_INCR;
+ new_size = yy_start_stack_depth * sizeof(int);
+
+ if (!yy_start_stack)
+ yy_start_stack = (int *)yy_flex_alloc(new_size);
+
+ else
+ yy_start_stack = (int *)yy_flex_realloc(
+ (void *)yy_start_stack, new_size);
+
+ if (!yy_start_stack)
+ YY_FATAL_ERROR(
+ "out of memory expanding start-condition stack");
+ }
+
+ yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+ BEGIN(new_state);
+}
+#endif
+
+#ifndef YY_NO_POP_STATE
+static void
+yy_pop_state()
+{
+ if (--yy_start_stack_ptr < 0)
+ YY_FATAL_ERROR("start-condition stack underflow");
+
+ BEGIN(yy_start_stack[yy_start_stack_ptr]);
+}
+#endif
+
+#ifndef YY_NO_TOP_STATE
+static int
+yy_top_state()
+{
+ return yy_start_stack[yy_start_stack_ptr - 1];
+}
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void
+yy_fatal_error(yyconst char msg[])
+#else
+static void yy_fatal_error(msg) char msg[];
+#endif
+{
+ (void)fprintf(stderr, "%s\n", msg);
+ exit(YY_EXIT_FAILURE);
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do { \
+ /* Undo effects of setting up yytext. */ \
+ yytext[yyleng] = yy_hold_char; \
+ yy_c_buf_p = yytext + n; \
+ yy_hold_char = *yy_c_buf_p; \
+ *yy_c_buf_p = '\0'; \
+ yyleng = n; \
+ } while (0)
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void
+yy_flex_strncpy(char *s1, yyconst char *s2, int n)
+#else
+static void yy_flex_strncpy(s1, s2, n) char *s1;
+yyconst char *s2;
+int n;
+#endif
+{
+ register int i;
+ for (i = 0; i < n; ++i)
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int
+yy_flex_strlen(yyconst char *s)
+#else
+static int yy_flex_strlen(s)
+ yyconst char *s;
+#endif
+{
+ register int n;
+ for (n = 0; s[n]; ++n)
+ ;
+
+ return n;
+}
+#endif
+
+#ifdef YY_USE_PROTOS
+static void *
+yy_flex_alloc(yy_size_t size)
+#else
+static void *yy_flex_alloc(size)
+ yy_size_t size;
+#endif
+{
+ return (void *)malloc(size);
+}
+
+#ifdef YY_USE_PROTOS
+static void *
+yy_flex_realloc(void *ptr, yy_size_t size)
+#else
+static void *yy_flex_realloc(ptr, size) void *ptr;
+yy_size_t size;
+#endif
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *)realloc((char *)ptr, size);
+}
+
+#ifdef YY_USE_PROTOS
+static void
+yy_flex_free(void *ptr)
+#else
+static void yy_flex_free(ptr) void *ptr;
+#endif
+{
+ free(ptr);
+}
+
+#if YY_MAIN
+int
+main()
+{
+ yylex();
+ return 0;
+}
+#endif
+#line 144 "crlgen_lex_orig.l"
+
+#include "prlock.h"
+
+static PRLock *parserInvocationLock;
+
+void
+CRLGEN_InitCrlGenParserLock()
+{
+ parserInvocationLock = PR_NewLock();
+}
+
+void
+CRLGEN_DestroyCrlGenParserLock()
+{
+ PR_DestroyLock(parserInvocationLock);
+}
+
+SECStatus
+CRLGEN_StartCrlGen(CRLGENGeneratorData *parserCtlData)
+{
+ SECStatus rv;
+
+ PR_Lock(parserInvocationLock);
+
+ parserStatus = SECSuccess;
+ parserData = parserCtlData;
+ src = parserCtlData->src;
+
+ rv = yylex();
+
+ PR_Unlock(parserInvocationLock);
+
+ return rv;
+}
+
+int
+yywrap()
+{
+ return 1;
+}
diff --git a/nss/cmd/crlutil/crlgen_lex_fix.sed b/nss/cmd/crlutil/crlgen_lex_fix.sed
new file mode 100644
index 0000000..603dd2d
--- /dev/null
+++ b/nss/cmd/crlutil/crlgen_lex_fix.sed
@@ -0,0 +1,6 @@
+// {
+ i #ifdef _WIN32
+ i #include
+ i #else
+ a #endif
+}
diff --git a/nss/cmd/crlutil/crlgen_lex_orig.l b/nss/cmd/crlutil/crlgen_lex_orig.l
new file mode 100644
index 0000000..a412e98
--- /dev/null
+++ b/nss/cmd/crlutil/crlgen_lex_orig.l
@@ -0,0 +1,181 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+%{
+
+#include "crlgen.h"
+
+static SECStatus parserStatus = SECSuccess;
+static CRLGENGeneratorData *parserData;
+static PRFileDesc *src;
+
+#define YY_INPUT(buf,result,max_size) \
+ if ( parserStatus != SECFailure) { \
+ if (((result = PR_Read(src, buf, max_size)) == 0) && \
+ ferror( yyin )) \
+ return SECFailure; \
+ } else { return SECFailure; }
+
+
+%}
+
+%a 5000
+DIGIT [0-9]+
+DIGIT_RANGE [0-9]+-[0-9]+
+ID [a-zA-Z][a-zA-Z0-9]*
+OID [0-9]+\.[\.0-9]+
+DATE [0-9]{4}[01][0-9][0-3][0-9][0-2][0-9][0-6][0-9][0-6][0-9]
+ZDATE [0-9]{4}[01][0-9][0-3][0-9][0-2][0-9][0-6][0-9][0-6][0-9]Z
+N_SP_STRING [a-zA-Z0-9\:\|\.]+
+
+%%
+
+{ZDATE} {
+parserStatus = crlgen_setNextData(parserData, yytext, CRLGEN_TYPE_ZDATE);
+if (parserStatus != SECSuccess)
+ return parserStatus;
+}
+
+{DIGIT} {
+parserStatus = crlgen_setNextData(parserData, yytext, CRLGEN_TYPE_DIGIT);
+if (parserStatus != SECSuccess)
+ return parserStatus;
+}
+
+{DIGIT_RANGE} {
+parserStatus = crlgen_setNextData(parserData, yytext, CRLGEN_TYPE_DIGIT_RANGE);
+if (parserStatus != SECSuccess)
+ return parserStatus;
+}
+
+{OID} {
+parserStatus = crlgen_setNextData(parserData, yytext, CRLGEN_TYPE_OID);
+if (parserStatus != SECSuccess)
+ return parserStatus;
+}
+
+issuer {
+parserStatus = crlgen_createNewLangStruct(parserData, CRLGEN_ISSUER_CONTEXT);
+if (parserStatus != SECSuccess)
+ return parserStatus;
+}
+
+update {
+parserStatus = crlgen_createNewLangStruct(parserData, CRLGEN_UPDATE_CONTEXT);
+if (parserStatus != SECSuccess)
+ return parserStatus;
+}
+nextupdate {
+parserStatus = crlgen_createNewLangStruct(parserData, CRLGEN_NEXT_UPDATE_CONTEXT);
+if (parserStatus != SECSuccess)
+ return parserStatus;
+}
+
+range {
+parserStatus = crlgen_createNewLangStruct(parserData, CRLGEN_CHANGE_RANGE_CONTEXT);
+if (parserStatus != SECSuccess)
+ return parserStatus;
+}
+
+{ID} {
+if (strcmp(yytext, "addcert") == 0) {
+ parserStatus = crlgen_createNewLangStruct(parserData,
+ CRLGEN_ADD_CERT_CONTEXT);
+ if (parserStatus != SECSuccess)
+ return parserStatus;
+} else if (strcmp(yytext, "rmcert") == 0) {
+ parserStatus = crlgen_createNewLangStruct(parserData,
+ CRLGEN_RM_CERT_CONTEXT);
+ if (parserStatus != SECSuccess)
+ return parserStatus;
+} else if (strcmp(yytext, "addext") == 0) {
+ parserStatus = crlgen_createNewLangStruct(parserData,
+ CRLGEN_ADD_EXTENSION_CONTEXT);
+ if (parserStatus != SECSuccess)
+ return parserStatus;
+} else {
+ parserStatus = crlgen_setNextData(parserData, yytext, CRLGEN_TYPE_ID);
+ if (parserStatus != SECSuccess)
+ return parserStatus;
+}
+}
+
+"="
+
+\"[^\"]* {
+if (yytext[yyleng-1] == '\\') {
+ yymore();
+} else {
+ register int c;
+ c = input();
+ if (c != '\"') {
+ printf( "Error: Line ending \" is missing: %c\n", c);
+ unput(c);
+ } else {
+ parserStatus = crlgen_setNextData(parserData, yytext + 1,
+ CRLGEN_TYPE_STRING);
+ if (parserStatus != SECSuccess)
+ return parserStatus;
+ }
+}
+}
+
+{N_SP_STRING} {
+parserStatus = crlgen_setNextData(parserData, yytext, CRLGEN_TYPE_STRING);
+if (parserStatus != SECSuccess)
+ return parserStatus;
+}
+
+
+
+^#[^\n]* /* eat up one-line comments */ {}
+
+[ \t]+ {}
+
+(\n|\r\n) {
+parserStatus = crlgen_updateCrl(parserData);
+if (parserStatus != SECSuccess)
+ return parserStatus;
+}
+
+. {
+ fprintf(stderr, "Syntax error at line %d: unknown token %s\n",
+ parserData->parsedLineNum, yytext);
+ return SECFailure;
+}
+
+%%
+#include "prlock.h"
+
+static PRLock *parserInvocationLock;
+
+void CRLGEN_InitCrlGenParserLock()
+{
+ parserInvocationLock = PR_NewLock();
+}
+
+void CRLGEN_DestroyCrlGenParserLock()
+{
+ PR_DestroyLock(parserInvocationLock);
+}
+
+
+SECStatus CRLGEN_StartCrlGen(CRLGENGeneratorData *parserCtlData)
+{
+ SECStatus rv;
+
+ PR_Lock(parserInvocationLock);
+
+ parserStatus = SECSuccess;
+ parserData = parserCtlData;
+ src = parserCtlData->src;
+
+ rv = yylex();
+
+ PR_Unlock(parserInvocationLock);
+
+ return rv;
+}
+
+int yywrap() {return 1;}
diff --git a/nss/cmd/crlutil/crlutil.c b/nss/cmd/crlutil/crlutil.c
new file mode 100644
index 0000000..c008ecc
--- /dev/null
+++ b/nss/cmd/crlutil/crlutil.c
@@ -0,0 +1,1156 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+** certutil.c
+**
+** utility for managing certificates and the cert database
+**
+*/
+/* test only */
+
+#include "nspr.h"
+#include "plgetopt.h"
+#include "secutil.h"
+#include "cert.h"
+#include "certi.h"
+#include "certdb.h"
+#include "nss.h"
+#include "pk11func.h"
+#include "crlgen.h"
+
+#define SEC_CERT_DB_EXISTS 0
+#define SEC_CREATE_CERT_DB 1
+
+static char *progName;
+
+static CERTSignedCrl *
+FindCRL(CERTCertDBHandle *certHandle, char *name, int type)
+{
+ CERTSignedCrl *crl = NULL;
+ CERTCertificate *cert = NULL;
+ SECItem derName;
+
+ derName.data = NULL;
+ derName.len = 0;
+
+ cert = CERT_FindCertByNicknameOrEmailAddr(certHandle, name);
+ if (!cert) {
+ CERTName *certName = NULL;
+ PLArenaPool *arena = NULL;
+ SECStatus rv = SECSuccess;
+
+ certName = CERT_AsciiToName(name);
+ if (certName) {
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (arena) {
+ SECItem *nameItem =
+ SEC_ASN1EncodeItem(arena, NULL, (void *)certName,
+ SEC_ASN1_GET(CERT_NameTemplate));
+ if (nameItem) {
+ rv = SECITEM_CopyItem(NULL, &derName, nameItem);
+ }
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+ CERT_DestroyName(certName);
+ }
+
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "SECITEM_CopyItem failed, out of memory");
+ return ((CERTSignedCrl *)NULL);
+ }
+
+ if (!derName.len || !derName.data) {
+ SECU_PrintError(progName, "could not find certificate named '%s'", name);
+ return ((CERTSignedCrl *)NULL);
+ }
+ } else {
+ SECStatus rv = SECITEM_CopyItem(NULL, &derName, &cert->derSubject);
+ CERT_DestroyCertificate(cert);
+ if (rv != SECSuccess) {
+ return ((CERTSignedCrl *)NULL);
+ }
+ }
+
+ crl = SEC_FindCrlByName(certHandle, &derName, type);
+ if (crl == NULL)
+ SECU_PrintError(progName, "could not find %s's CRL", name);
+ if (derName.data) {
+ SECITEM_FreeItem(&derName, PR_FALSE);
+ }
+ return (crl);
+}
+
+static SECStatus
+DisplayCRL(CERTCertDBHandle *certHandle, char *nickName, int crlType)
+{
+ CERTSignedCrl *crl = NULL;
+
+ crl = FindCRL(certHandle, nickName, crlType);
+
+ if (crl) {
+ SECU_PrintCRLInfo(stdout, &crl->crl, "CRL Info:\n", 0);
+ SEC_DestroyCrl(crl);
+ return SECSuccess;
+ }
+ return SECFailure;
+}
+
+static void
+ListCRLNames(CERTCertDBHandle *certHandle, int crlType, PRBool deletecrls)
+{
+ CERTCrlHeadNode *crlList = NULL;
+ CERTCrlNode *crlNode = NULL;
+ CERTName *name = NULL;
+ PLArenaPool *arena = NULL;
+ SECStatus rv;
+
+ do {
+ arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
+ if (arena == NULL) {
+ fprintf(stderr, "%s: fail to allocate memory\n", progName);
+ break;
+ }
+
+ name = PORT_ArenaZAlloc(arena, sizeof(*name));
+ if (name == NULL) {
+ fprintf(stderr, "%s: fail to allocate memory\n", progName);
+ break;
+ }
+ name->arena = arena;
+
+ rv = SEC_LookupCrls(certHandle, &crlList, crlType);
+ if (rv != SECSuccess) {
+ fprintf(stderr, "%s: fail to look up CRLs (%s)\n", progName,
+ SECU_Strerror(PORT_GetError()));
+ break;
+ }
+
+ /* just in case */
+ if (!crlList)
+ break;
+
+ crlNode = crlList->first;
+
+ fprintf(stdout, "\n");
+ fprintf(stdout, "\n%-40s %-5s\n\n", "CRL names", "CRL Type");
+ while (crlNode) {
+ char *asciiname = NULL;
+ CERTCertificate *cert = NULL;
+ if (crlNode->crl && crlNode->crl->crl.derName.data != NULL) {
+ cert = CERT_FindCertByName(certHandle,
+ &crlNode->crl->crl.derName);
+ if (!cert) {
+ SECU_PrintError(progName, "could not find signing "
+ "certificate in database");
+ }
+ }
+ if (cert) {
+ char *certName = NULL;
+ if (cert->nickname && PORT_Strlen(cert->nickname) > 0) {
+ certName = cert->nickname;
+ } else if (cert->emailAddr && PORT_Strlen(cert->emailAddr) > 0) {
+ certName = cert->emailAddr;
+ }
+ if (certName) {
+ asciiname = PORT_Strdup(certName);
+ }
+ CERT_DestroyCertificate(cert);
+ }
+
+ if (!asciiname) {
+ name = &crlNode->crl->crl.name;
+ if (!name) {
+ SECU_PrintError(progName, "fail to get the CRL "
+ "issuer name");
+ continue;
+ }
+ asciiname = CERT_NameToAscii(name);
+ }
+ fprintf(stdout, "%-40s %-5s\n", asciiname, "CRL");
+ if (asciiname) {
+ PORT_Free(asciiname);
+ }
+ if (PR_TRUE == deletecrls) {
+ CERTSignedCrl *acrl = NULL;
+ SECItem *issuer = &crlNode->crl->crl.derName;
+ acrl = SEC_FindCrlByName(certHandle, issuer, crlType);
+ if (acrl) {
+ SEC_DeletePermCRL(acrl);
+ SEC_DestroyCrl(acrl);
+ }
+ }
+ crlNode = crlNode->next;
+ }
+
+ } while (0);
+ if (crlList)
+ PORT_FreeArena(crlList->arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
+}
+
+static SECStatus
+ListCRL(CERTCertDBHandle *certHandle, char *nickName, int crlType)
+{
+ if (nickName == NULL) {
+ ListCRLNames(certHandle, crlType, PR_FALSE);
+ return SECSuccess;
+ }
+
+ return DisplayCRL(certHandle, nickName, crlType);
+}
+
+static SECStatus
+DeleteCRL(CERTCertDBHandle *certHandle, char *name, int type)
+{
+ CERTSignedCrl *crl = NULL;
+ SECStatus rv = SECFailure;
+
+ crl = FindCRL(certHandle, name, type);
+ if (!crl) {
+ SECU_PrintError(progName, "could not find the issuer %s's CRL", name);
+ return SECFailure;
+ }
+ rv = SEC_DeletePermCRL(crl);
+ SEC_DestroyCrl(crl);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "fail to delete the issuer %s's CRL "
+ "from the perm database (reason: %s)",
+ name, SECU_Strerror(PORT_GetError()));
+ return SECFailure;
+ }
+ return (rv);
+}
+
+SECStatus
+ImportCRL(CERTCertDBHandle *certHandle, char *url, int type,
+ PRFileDesc *inFile, PRInt32 importOptions, PRInt32 decodeOptions,
+ secuPWData *pwdata)
+{
+ CERTSignedCrl *crl = NULL;
+ SECItem crlDER;
+ PK11SlotInfo *slot = NULL;
+ int rv;
+#if defined(DEBUG_jp96085)
+ PRIntervalTime starttime, endtime, elapsed;
+ PRUint32 mins, secs, msecs;
+#endif
+
+ crlDER.data = NULL;
+
+ /* Read in the entire file specified with the -f argument */
+ rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE, PR_FALSE);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "unable to read input file");
+ return (SECFailure);
+ }
+
+ decodeOptions |= CRL_DECODE_DONT_COPY_DER;
+
+ slot = PK11_GetInternalKeySlot();
+
+ if (PK11_NeedLogin(slot)) {
+ rv = PK11_Authenticate(slot, PR_TRUE, pwdata);
+ if (rv != SECSuccess)
+ goto loser;
+ }
+
+#if defined(DEBUG_jp96085)
+ starttime = PR_IntervalNow();
+#endif
+ crl = PK11_ImportCRL(slot, &crlDER, url, type,
+ NULL, importOptions, NULL, decodeOptions);
+#if defined(DEBUG_jp96085)
+ endtime = PR_IntervalNow();
+ elapsed = endtime - starttime;
+ mins = PR_IntervalToSeconds(elapsed) / 60;
+ secs = PR_IntervalToSeconds(elapsed) % 60;
+ msecs = PR_IntervalToMilliseconds(elapsed) % 1000;
+ printf("Elapsed : %2d:%2d.%3d\n", mins, secs, msecs);
+#endif
+ if (!crl) {
+ const char *errString;
+
+ rv = SECFailure;
+ errString = SECU_Strerror(PORT_GetError());
+ if (errString && PORT_Strlen(errString) == 0)
+ SECU_PrintError(progName,
+ "CRL is not imported (error: input CRL is not up to date.)");
+ else
+ SECU_PrintError(progName, "unable to import CRL");
+ } else {
+ SEC_DestroyCrl(crl);
+ }
+loser:
+ if (slot) {
+ PK11_FreeSlot(slot);
+ }
+ SECITEM_FreeItem(&crlDER, PR_FALSE);
+ return (rv);
+}
+
+SECStatus
+DumpCRL(PRFileDesc *inFile)
+{
+ int rv;
+ PLArenaPool *arena = NULL;
+ CERTSignedCrl *newCrl = NULL;
+
+ SECItem crlDER;
+ crlDER.data = NULL;
+
+ /* Read in the entire file specified with the -f argument */
+ rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE, PR_FALSE);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "unable to read input file");
+ return (SECFailure);
+ }
+
+ rv = SEC_ERROR_NO_MEMORY;
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena)
+ return rv;
+
+ newCrl = CERT_DecodeDERCrlWithFlags(arena, &crlDER, SEC_CRL_TYPE,
+ CRL_DECODE_DEFAULT_OPTIONS);
+ if (!newCrl)
+ return SECFailure;
+
+ SECU_PrintCRLInfo(stdout, &newCrl->crl, "CRL file contents", 0);
+
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+static CERTCertificate *
+FindSigningCert(CERTCertDBHandle *certHandle, CERTSignedCrl *signCrl,
+ char *certNickName)
+{
+ CERTCertificate *cert = NULL, *certTemp = NULL;
+ SECStatus rv = SECFailure;
+ CERTAuthKeyID *authorityKeyID = NULL;
+ SECItem *subject = NULL;
+
+ PORT_Assert(certHandle != NULL);
+ if (!certHandle || (!signCrl && !certNickName)) {
+ SECU_PrintError(progName, "invalid args for function "
+ "FindSigningCert \n");
+ return NULL;
+ }
+
+ if (signCrl) {
+#if 0
+ authorityKeyID = SECU_FindCRLAuthKeyIDExten(tmpArena, scrl);
+#endif
+ subject = &signCrl->crl.derName;
+ } else {
+ certTemp = CERT_FindCertByNickname(certHandle, certNickName);
+ if (!certTemp) {
+ SECU_PrintError(progName, "could not find certificate \"%s\" "
+ "in database",
+ certNickName);
+ goto loser;
+ }
+ subject = &certTemp->derSubject;
+ }
+
+ cert = SECU_FindCrlIssuer(certHandle, subject, authorityKeyID, PR_Now());
+ if (!cert) {
+ SECU_PrintError(progName, "could not find signing certificate "
+ "in database");
+ goto loser;
+ } else {
+ rv = SECSuccess;
+ }
+
+loser:
+ if (certTemp)
+ CERT_DestroyCertificate(certTemp);
+ if (cert && rv != SECSuccess)
+ CERT_DestroyCertificate(cert);
+ return cert;
+}
+
+static CERTSignedCrl *
+CreateModifiedCRLCopy(PLArenaPool *arena, CERTCertDBHandle *certHandle,
+ CERTCertificate **cert, char *certNickName,
+ PRFileDesc *inFile, PRInt32 decodeOptions,
+ PRInt32 importOptions, secuPWData *pwdata)
+{
+ SECItem crlDER = { 0, NULL, 0 };
+ CERTSignedCrl *signCrl = NULL;
+ CERTSignedCrl *modCrl = NULL;
+ PLArenaPool *modArena = NULL;
+ SECStatus rv = SECSuccess;
+
+ if (!arena || !certHandle || !certNickName) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ SECU_PrintError(progName, "CreateModifiedCRLCopy: invalid args\n");
+ return NULL;
+ }
+
+ modArena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
+ if (!modArena) {
+ SECU_PrintError(progName, "fail to allocate memory\n");
+ return NULL;
+ }
+
+ if (inFile != NULL) {
+ rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE, PR_FALSE);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "unable to read input file");
+ PORT_FreeArena(modArena, PR_FALSE);
+ goto loser;
+ }
+
+ decodeOptions |= CRL_DECODE_DONT_COPY_DER;
+
+ modCrl = CERT_DecodeDERCrlWithFlags(modArena, &crlDER, SEC_CRL_TYPE,
+ decodeOptions);
+ if (!modCrl) {
+ SECU_PrintError(progName, "fail to decode CRL");
+ goto loser;
+ }
+
+ if (0 == (importOptions & CRL_IMPORT_BYPASS_CHECKS)) {
+ /* If caCert is a v2 certificate, make sure that it
+ * can be used for crl signing purpose */
+ *cert = FindSigningCert(certHandle, modCrl, NULL);
+ if (!*cert) {
+ goto loser;
+ }
+
+ rv = CERT_VerifySignedData(&modCrl->signatureWrap, *cert,
+ PR_Now(), pwdata);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "fail to verify signed data\n");
+ goto loser;
+ }
+ }
+ } else {
+ modCrl = FindCRL(certHandle, certNickName, SEC_CRL_TYPE);
+ if (!modCrl) {
+ SECU_PrintError(progName, "fail to find crl %s in database\n",
+ certNickName);
+ goto loser;
+ }
+ }
+
+ signCrl = PORT_ArenaZNew(arena, CERTSignedCrl);
+ if (signCrl == NULL) {
+ SECU_PrintError(progName, "fail to allocate memory\n");
+ goto loser;
+ }
+
+ rv = SECU_CopyCRL(arena, &signCrl->crl, &modCrl->crl);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "unable to dublicate crl for "
+ "modification.");
+ goto loser;
+ }
+
+ /* Make sure the update time is current. It can be modified later
+ * by "update " command from crl generation script */
+ rv = DER_EncodeTimeChoice(arena, &signCrl->crl.lastUpdate, PR_Now());
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "fail to encode current time\n");
+ goto loser;
+ }
+
+ signCrl->arena = arena;
+ signCrl->referenceCount = 1;
+
+loser:
+ if (crlDER.data) {
+ SECITEM_FreeItem(&crlDER, PR_FALSE);
+ }
+ if (modArena && (!modCrl || modCrl->arena != modArena)) {
+ PORT_FreeArena(modArena, PR_FALSE);
+ }
+ if (modCrl)
+ SEC_DestroyCrl(modCrl);
+ if (rv != SECSuccess && signCrl) {
+ SEC_DestroyCrl(signCrl);
+ signCrl = NULL;
+ }
+ return signCrl;
+}
+
+static CERTSignedCrl *
+CreateNewCrl(PLArenaPool *arena, CERTCertDBHandle *certHandle,
+ CERTCertificate *cert)
+{
+ CERTSignedCrl *signCrl = NULL;
+ void *dummy = NULL;
+ SECStatus rv;
+ void *mark = NULL;
+
+ /* if the CERTSignedCrl structure changes, this function will need to be
+ updated as well */
+ if (!cert || !arena) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ SECU_PrintError(progName, "invalid args for function "
+ "CreateNewCrl\n");
+ return NULL;
+ }
+
+ mark = PORT_ArenaMark(arena);
+
+ signCrl = PORT_ArenaZNew(arena, CERTSignedCrl);
+ if (signCrl == NULL) {
+ SECU_PrintError(progName, "fail to allocate memory\n");
+ return NULL;
+ }
+
+ dummy = SEC_ASN1EncodeInteger(arena, &signCrl->crl.version,
+ SEC_CRL_VERSION_2);
+ /* set crl->version */
+ if (!dummy) {
+ SECU_PrintError(progName, "fail to create crl version data "
+ "container\n");
+ goto loser;
+ }
+
+ /* copy SECItem name from cert */
+ rv = SECITEM_CopyItem(arena, &signCrl->crl.derName, &cert->derSubject);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "fail to duplicate der name from "
+ "certificate.\n");
+ goto loser;
+ }
+
+ /* copy CERTName name structure from cert issuer */
+ rv = CERT_CopyName(arena, &signCrl->crl.name, &cert->subject);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "fail to duplicate RD name from "
+ "certificate.\n");
+ goto loser;
+ }
+
+ rv = DER_EncodeTimeChoice(arena, &signCrl->crl.lastUpdate, PR_Now());
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "fail to encode current time\n");
+ goto loser;
+ }
+
+ /* set fields */
+ signCrl->arena = arena;
+ signCrl->dbhandle = certHandle;
+ signCrl->crl.arena = arena;
+
+ PORT_ArenaUnmark(arena, mark);
+
+ return signCrl;
+
+loser:
+ PORT_ArenaRelease(arena, mark);
+ return NULL;
+}
+
+static SECStatus
+UpdateCrl(CERTSignedCrl *signCrl, PRFileDesc *inCrlInitFile)
+{
+ CRLGENGeneratorData *crlGenData = NULL;
+ SECStatus rv;
+
+ if (!signCrl || !inCrlInitFile) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ SECU_PrintError(progName, "invalid args for function "
+ "CreateNewCrl\n");
+ return SECFailure;
+ }
+
+ crlGenData = CRLGEN_InitCrlGeneration(signCrl, inCrlInitFile);
+ if (!crlGenData) {
+ SECU_PrintError(progName, "can not initialize parser structure.\n");
+ return SECFailure;
+ }
+
+ rv = CRLGEN_ExtHandleInit(crlGenData);
+ if (rv == SECFailure) {
+ SECU_PrintError(progName, "can not initialize entries handle.\n");
+ goto loser;
+ }
+
+ rv = CRLGEN_StartCrlGen(crlGenData);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "crl generation failed");
+ goto loser;
+ }
+
+loser:
+ /* CommitExtensionsAndEntries is partially responsible for freeing
+ * up memory that was used for CRL generation. Should be called regardless
+ * of previouse call status, but only after initialization of
+ * crlGenData was done. It will commit all changes that was done before
+ * an error has occurred.
+ */
+ if (SECSuccess != CRLGEN_CommitExtensionsAndEntries(crlGenData)) {
+ SECU_PrintError(progName, "crl generation failed");
+ rv = SECFailure;
+ }
+ CRLGEN_FinalizeCrlGeneration(crlGenData);
+ return rv;
+}
+
+static SECStatus
+SignAndStoreCrl(CERTSignedCrl *signCrl, CERTCertificate *cert,
+ char *outFileName, SECOidTag hashAlgTag, int ascii,
+ char *slotName, char *url, secuPWData *pwdata)
+{
+ PK11SlotInfo *slot = NULL;
+ PRFileDesc *outFile = NULL;
+ SECStatus rv;
+ SignAndEncodeFuncExitStat errCode;
+
+ PORT_Assert(signCrl && (!ascii || outFileName));
+ if (!signCrl || (ascii && !outFileName)) {
+ SECU_PrintError(progName, "invalid args for function "
+ "SignAndStoreCrl\n");
+ return SECFailure;
+ }
+
+ if (!slotName || !PL_strcmp(slotName, "internal"))
+ slot = PK11_GetInternalKeySlot();
+ else
+ slot = PK11_FindSlotByName(slotName);
+ if (!slot) {
+ SECU_PrintError(progName, "can not find requested slot");
+ return SECFailure;
+ }
+
+ if (PK11_NeedLogin(slot)) {
+ rv = PK11_Authenticate(slot, PR_TRUE, pwdata);
+ if (rv != SECSuccess)
+ goto loser;
+ }
+
+ rv = SECU_SignAndEncodeCRL(cert, signCrl, hashAlgTag, &errCode);
+ if (rv != SECSuccess) {
+ char *errMsg = NULL;
+ switch (errCode) {
+ case noKeyFound:
+ errMsg = "No private key found of signing cert";
+ break;
+
+ case noSignatureMatch:
+ errMsg = "Key and Algorithm OId are do not match";
+ break;
+
+ default:
+ case failToEncode:
+ errMsg = "Failed to encode crl structure";
+ break;
+
+ case failToSign:
+ errMsg = "Failed to sign crl structure";
+ break;
+
+ case noMem:
+ errMsg = "Can not allocate memory";
+ break;
+ }
+ SECU_PrintError(progName, "%s\n", errMsg);
+ goto loser;
+ }
+
+ if (outFileName) {
+ outFile = PR_Open(outFileName, PR_WRONLY | PR_CREATE_FILE, PR_IRUSR | PR_IWUSR);
+ if (!outFile) {
+ SECU_PrintError(progName, "unable to open \"%s\" for writing\n",
+ outFileName);
+ goto loser;
+ }
+ }
+
+ rv = SECU_StoreCRL(slot, signCrl->derCrl, outFile, ascii, url);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "fail to save CRL\n");
+ }
+
+loser:
+ if (outFile)
+ PR_Close(outFile);
+ if (slot)
+ PK11_FreeSlot(slot);
+ return rv;
+}
+
+static SECStatus
+GenerateCRL(CERTCertDBHandle *certHandle, char *certNickName,
+ PRFileDesc *inCrlInitFile, PRFileDesc *inFile,
+ char *outFileName, int ascii, char *slotName,
+ PRInt32 importOptions, char *alg, PRBool quiet,
+ PRInt32 decodeOptions, char *url, secuPWData *pwdata,
+ int modifyFlag)
+{
+ CERTCertificate *cert = NULL;
+ CERTSignedCrl *signCrl = NULL;
+ PLArenaPool *arena = NULL;
+ SECStatus rv;
+ SECOidTag hashAlgTag = SEC_OID_UNKNOWN;
+
+ if (alg) {
+ hashAlgTag = SECU_StringToSignatureAlgTag(alg);
+ if (hashAlgTag == SEC_OID_UNKNOWN) {
+ SECU_PrintError(progName, "%s -Z: %s is not a recognized type.\n",
+ progName, alg);
+ return SECFailure;
+ }
+ } else {
+ hashAlgTag = SEC_OID_UNKNOWN;
+ }
+
+ arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
+ if (!arena) {
+ SECU_PrintError(progName, "fail to allocate memory\n");
+ return SECFailure;
+ }
+
+ if (modifyFlag == PR_TRUE) {
+ signCrl = CreateModifiedCRLCopy(arena, certHandle, &cert, certNickName,
+ inFile, decodeOptions, importOptions,
+ pwdata);
+ if (signCrl == NULL) {
+ rv = SECFailure;
+ goto loser;
+ }
+ }
+
+ if (!cert) {
+ cert = FindSigningCert(certHandle, signCrl, certNickName);
+ if (cert == NULL) {
+ rv = SECFailure;
+ goto loser;
+ }
+ }
+
+ if (!signCrl) {
+ if (modifyFlag == PR_TRUE) {
+ if (!outFileName) {
+ int len = strlen(certNickName) + 5;
+ outFileName = PORT_ArenaAlloc(arena, len);
+ PR_snprintf(outFileName, len, "%s.crl", certNickName);
+ }
+ SECU_PrintError(progName, "Will try to generate crl. "
+ "It will be saved in file: %s",
+ outFileName);
+ }
+ signCrl = CreateNewCrl(arena, certHandle, cert);
+ if (!signCrl) {
+ rv = SECFailure;
+ goto loser;
+ }
+ }
+
+ rv = UpdateCrl(signCrl, inCrlInitFile);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ rv = SignAndStoreCrl(signCrl, cert, outFileName, hashAlgTag, ascii,
+ slotName, url, pwdata);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ if (signCrl && !quiet) {
+ SECU_PrintCRLInfo(stdout, &signCrl->crl, "CRL Info:\n", 0);
+ }
+
+loser:
+ if (arena && (!signCrl || !signCrl->arena))
+ PORT_FreeArena(arena, PR_FALSE);
+ if (signCrl)
+ SEC_DestroyCrl(signCrl);
+ if (cert)
+ CERT_DestroyCertificate(cert);
+ return (rv);
+}
+
+static void
+Usage(char *progName)
+{
+ fprintf(stderr,
+ "Usage: %s -L [-n nickname] [-d keydir] [-P dbprefix] [-t crlType]\n"
+ " %s -D -n nickname [-d keydir] [-P dbprefix]\n"
+ " %s -S -i crl\n"
+ " %s -I -i crl -t crlType [-u url] [-d keydir] [-P dbprefix] [-B] "
+ "[-p pwd-file] -w [pwd-string]\n"
+ " %s -E -t crlType [-d keydir] [-P dbprefix]\n"
+ " %s -T\n"
+ " %s -G|-M -c crl-init-file -n nickname [-i crl] [-u url] "
+ "[-d keydir] [-P dbprefix] [-Z alg] ] [-p pwd-file] -w [pwd-string] "
+ "[-a] [-B]\n",
+ progName, progName, progName, progName, progName, progName, progName);
+
+ fprintf(stderr, "%-15s List CRL\n", "-L");
+ fprintf(stderr, "%-20s Specify the nickname of the CA certificate\n",
+ "-n nickname");
+ fprintf(stderr, "%-20s Key database directory (default is ~/.netscape)\n",
+ "-d keydir");
+ fprintf(stderr, "%-20s Cert & Key database prefix (default is \"\")\n",
+ "-P dbprefix");
+
+ fprintf(stderr, "%-15s Delete a CRL from the cert database\n", "-D");
+ fprintf(stderr, "%-20s Specify the nickname for the CA certificate\n",
+ "-n nickname");
+ fprintf(stderr, "%-20s Specify the crl type.\n", "-t crlType");
+ fprintf(stderr, "%-20s Key database directory (default is ~/.netscape)\n",
+ "-d keydir");
+ fprintf(stderr, "%-20s Cert & Key database prefix (default is \"\")\n",
+ "-P dbprefix");
+
+ fprintf(stderr, "%-15s Erase all CRLs of specified type from hte cert database\n", "-E");
+ fprintf(stderr, "%-20s Specify the crl type.\n", "-t crlType");
+ fprintf(stderr, "%-20s Key database directory (default is ~/.netscape)\n",
+ "-d keydir");
+ fprintf(stderr, "%-20s Cert & Key database prefix (default is \"\")\n",
+ "-P dbprefix");
+
+ fprintf(stderr, "%-15s Show contents of a CRL file (without database)\n", "-S");
+ fprintf(stderr, "%-20s Specify the file which contains the CRL to show\n",
+ "-i crl");
+
+ fprintf(stderr, "%-15s Import a CRL to the cert database\n", "-I");
+ fprintf(stderr, "%-20s Specify the file which contains the CRL to import\n",
+ "-i crl");
+ fprintf(stderr, "%-20s Specify the url.\n", "-u url");
+ fprintf(stderr, "%-20s Specify the crl type.\n", "-t crlType");
+ fprintf(stderr, "%-20s Key database directory (default is ~/.netscape)\n",
+ "-d keydir");
+ fprintf(stderr, "%-20s Cert & Key database prefix (default is \"\")\n",
+ "-P dbprefix");
+#ifdef DEBUG
+ fprintf(stderr, "%-15s Test . Only for debugging purposes. See source code\n", "-T");
+#endif
+ fprintf(stderr, "%-20s CRL Types (default is SEC_CRL_TYPE):\n", " ");
+ fprintf(stderr, "%-20s \t 0 - SEC_KRL_TYPE\n", " ");
+ fprintf(stderr, "%-20s \t 1 - SEC_CRL_TYPE\n", " ");
+ fprintf(stderr, "\n%-20s Bypass CA certificate checks.\n", "-B");
+ fprintf(stderr, "\n%-20s Partial decode for faster operation.\n", "-p");
+ fprintf(stderr, "%-20s Repeat the operation.\n", "-r ");
+ fprintf(stderr, "\n%-15s Create CRL\n", "-G");
+ fprintf(stderr, "%-15s Modify CRL\n", "-M");
+ fprintf(stderr, "%-20s Specify crl initialization file\n",
+ "-c crl-conf-file");
+ fprintf(stderr, "%-20s Specify the nickname of the CA certificate\n",
+ "-n nickname");
+ fprintf(stderr, "%-20s Specify the file which contains the CRL to import\n",
+ "-i crl");
+ fprintf(stderr, "%-20s Specify a CRL output file\n",
+ "-o crl-output-file");
+ fprintf(stderr, "%-20s Specify to use base64 encoded CRL output format\n",
+ "-a");
+ fprintf(stderr, "%-20s Key database directory (default is ~/.netscape)\n",
+ "-d keydir");
+ fprintf(stderr, "%-20s Provide path to a default pwd file\n",
+ "-f pwd-file");
+ fprintf(stderr, "%-20s Provide db password in command line\n",
+ "-w pwd-string");
+ fprintf(stderr, "%-20s Cert & Key database prefix (default is \"\")\n",
+ "-P dbprefix");
+ fprintf(stderr, "%-20s Specify the url.\n", "-u url");
+ fprintf(stderr, "\n%-20s Bypass CA certificate checks.\n", "-B");
+
+ exit(-1);
+}
+
+int
+main(int argc, char **argv)
+{
+ CERTCertDBHandle *certHandle;
+ PRFileDesc *inFile;
+ PRFileDesc *inCrlInitFile = NULL;
+ int generateCRL;
+ int modifyCRL;
+ int listCRL;
+ int importCRL;
+ int showFileCRL;
+ int deleteCRL;
+ int rv;
+ char *nickName;
+ char *url;
+ char *dbPrefix = PORT_Strdup("");
+ char *alg = NULL;
+ char *outFile = NULL;
+ char *slotName = NULL;
+ int ascii = 0;
+ int crlType;
+ PLOptState *optstate;
+ PLOptStatus status;
+ SECStatus secstatus;
+ PRInt32 decodeOptions = CRL_DECODE_DEFAULT_OPTIONS;
+ PRInt32 importOptions = CRL_IMPORT_DEFAULT_OPTIONS;
+ PRBool quiet = PR_FALSE;
+ PRBool test = PR_FALSE;
+ PRBool erase = PR_FALSE;
+ PRInt32 i = 0;
+ PRInt32 iterations = 1;
+ PRBool readonly = PR_FALSE;
+
+ secuPWData pwdata = { PW_NONE, 0 };
+
+ progName = strrchr(argv[0], '/');
+ progName = progName ? progName + 1 : argv[0];
+
+ rv = 0;
+ deleteCRL = importCRL = listCRL = generateCRL = modifyCRL = showFileCRL = 0;
+ inFile = NULL;
+ nickName = url = NULL;
+ certHandle = NULL;
+ crlType = SEC_CRL_TYPE;
+ /*
+ * Parse command line arguments
+ */
+ optstate = PL_CreateOptState(argc, argv, "sqBCDGILMSTEP:f:d:i:h:n:p:t:u:r:aZ:o:c:");
+ while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
+ switch (optstate->option) {
+ case '?':
+ Usage(progName);
+ break;
+
+ case 'T':
+ test = PR_TRUE;
+ break;
+
+ case 'E':
+ erase = PR_TRUE;
+ break;
+
+ case 'B':
+ importOptions |= CRL_IMPORT_BYPASS_CHECKS;
+ break;
+
+ case 'G':
+ generateCRL = 1;
+ break;
+
+ case 'M':
+ modifyCRL = 1;
+ break;
+
+ case 'D':
+ deleteCRL = 1;
+ break;
+
+ case 'I':
+ importCRL = 1;
+ break;
+
+ case 'S':
+ showFileCRL = 1;
+ break;
+
+ case 'C':
+ case 'L':
+ listCRL = 1;
+ break;
+
+ case 'P':
+ PORT_Free(dbPrefix);
+ dbPrefix = PORT_Strdup(optstate->value);
+ break;
+
+ case 'Z':
+ alg = PORT_Strdup(optstate->value);
+ break;
+
+ case 'a':
+ ascii = 1;
+ break;
+
+ case 'c':
+ inCrlInitFile = PR_Open(optstate->value, PR_RDONLY, 0);
+ if (!inCrlInitFile) {
+ PR_fprintf(PR_STDERR, "%s: unable to open \"%s\" for reading\n",
+ progName, optstate->value);
+ rv = SECFailure;
+ goto loser;
+ }
+ break;
+
+ case 'd':
+ SECU_ConfigDirectory(optstate->value);
+ break;
+
+ case 'f':
+ pwdata.source = PW_FROMFILE;
+ pwdata.data = PORT_Strdup(optstate->value);
+ break;
+
+ case 'h':
+ slotName = PORT_Strdup(optstate->value);
+ break;
+
+ case 'i':
+ inFile = PR_Open(optstate->value, PR_RDONLY, 0);
+ if (!inFile) {
+ PR_fprintf(PR_STDERR, "%s: unable to open \"%s\" for reading\n",
+ progName, optstate->value);
+ rv = SECFailure;
+ goto loser;
+ }
+ break;
+
+ case 'n':
+ nickName = PORT_Strdup(optstate->value);
+ break;
+
+ case 'o':
+ outFile = PORT_Strdup(optstate->value);
+ break;
+
+ case 'p':
+ decodeOptions |= CRL_DECODE_SKIP_ENTRIES;
+ break;
+
+ case 'r': {
+ const char *str = optstate->value;
+ if (str && atoi(str) > 0)
+ iterations = atoi(str);
+ } break;
+
+ case 't': {
+ crlType = atoi(optstate->value);
+ if (crlType != SEC_CRL_TYPE && crlType != SEC_KRL_TYPE) {
+ PR_fprintf(PR_STDERR, "%s: invalid crl type\n", progName);
+ rv = SECFailure;
+ goto loser;
+ }
+ break;
+
+ case 'q':
+ quiet = PR_TRUE;
+ break;
+
+ case 'w':
+ pwdata.source = PW_PLAINTEXT;
+ pwdata.data = PORT_Strdup(optstate->value);
+ break;
+
+ case 'u':
+ url = PORT_Strdup(optstate->value);
+ break;
+ }
+ }
+ }
+
+ if (deleteCRL && !nickName)
+ Usage(progName);
+ if (importCRL && !inFile)
+ Usage(progName);
+ if (showFileCRL && !inFile)
+ Usage(progName);
+ if ((generateCRL && !nickName) ||
+ (modifyCRL && !inFile && !nickName))
+ Usage(progName);
+ if (!(listCRL || deleteCRL || importCRL || showFileCRL || generateCRL ||
+ modifyCRL || test || erase))
+ Usage(progName);
+
+ if (listCRL || showFileCRL) {
+ readonly = PR_TRUE;
+ }
+
+ PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
+
+ PK11_SetPasswordFunc(SECU_GetModulePassword);
+
+ if (showFileCRL) {
+ NSS_NoDB_Init(NULL);
+ } else {
+ secstatus = NSS_Initialize(SECU_ConfigDirectory(NULL), dbPrefix, dbPrefix,
+ "secmod.db", readonly ? NSS_INIT_READONLY : 0);
+ if (secstatus != SECSuccess) {
+ SECU_PrintPRandOSError(progName);
+ rv = SECFailure;
+ goto loser;
+ }
+ }
+
+ SECU_RegisterDynamicOids();
+
+ certHandle = CERT_GetDefaultCertDB();
+ if (certHandle == NULL) {
+ SECU_PrintError(progName, "unable to open the cert db");
+ rv = SECFailure;
+ goto loser;
+ }
+
+ CRLGEN_InitCrlGenParserLock();
+
+ for (i = 0; i < iterations; i++) {
+ /* Read in the private key info */
+ if (deleteCRL)
+ DeleteCRL(certHandle, nickName, crlType);
+ else if (listCRL) {
+ rv = ListCRL(certHandle, nickName, crlType);
+ } else if (importCRL) {
+ rv = ImportCRL(certHandle, url, crlType, inFile, importOptions,
+ decodeOptions, &pwdata);
+ } else if (showFileCRL) {
+ rv = DumpCRL(inFile);
+ } else if (generateCRL || modifyCRL) {
+ if (!inCrlInitFile)
+ inCrlInitFile = PR_STDIN;
+ rv = GenerateCRL(certHandle, nickName, inCrlInitFile,
+ inFile, outFile, ascii, slotName,
+ importOptions, alg, quiet,
+ decodeOptions, url, &pwdata,
+ modifyCRL);
+ } else if (erase) {
+ /* list and delete all CRLs */
+ ListCRLNames(certHandle, crlType, PR_TRUE);
+ }
+#ifdef DEBUG
+ else if (test) {
+ /* list and delete all CRLs */
+ ListCRLNames(certHandle, crlType, PR_TRUE);
+ /* list CRLs */
+ ListCRLNames(certHandle, crlType, PR_FALSE);
+ /* import CRL as a blob */
+ rv = ImportCRL(certHandle, url, crlType, inFile, importOptions,
+ decodeOptions, &pwdata);
+ /* list CRLs */
+ ListCRLNames(certHandle, crlType, PR_FALSE);
+ }
+#endif
+ }
+
+ CRLGEN_DestroyCrlGenParserLock();
+
+loser:
+ PL_DestroyOptState(optstate);
+
+ if (inFile) {
+ PR_Close(inFile);
+ }
+ if (alg) {
+ PORT_Free(alg);
+ }
+ if (slotName) {
+ PORT_Free(slotName);
+ }
+ if (nickName) {
+ PORT_Free(nickName);
+ }
+ if (outFile) {
+ PORT_Free(outFile);
+ }
+ if (url) {
+ PORT_Free(url);
+ }
+ if (pwdata.data) {
+ PORT_Free(pwdata.data);
+ }
+
+ PORT_Free(dbPrefix);
+
+ if (NSS_Shutdown() != SECSuccess) {
+ rv = SECFailure;
+ }
+
+ return (rv != SECSuccess);
+}
diff --git a/nss/cmd/crlutil/crlutil.gyp b/nss/cmd/crlutil/crlutil.gyp
new file mode 100644
index 0000000..470449b
--- /dev/null
+++ b/nss/cmd/crlutil/crlutil.gyp
@@ -0,0 +1,32 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi',
+ '../../cmd/platlibs.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'crlutil',
+ 'type': 'executable',
+ 'sources': [
+ 'crlgen.c',
+ 'crlgen_lex.c',
+ 'crlutil.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:dbm_exports',
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'target_defaults': {
+ 'defines': [
+ 'NSPR20'
+ ]
+ },
+ 'variables': {
+ 'module': 'nss'
+ }
+}
\ No newline at end of file
diff --git a/nss/cmd/crlutil/manifest.mn b/nss/cmd/crlutil/manifest.mn
new file mode 100644
index 0000000..cd0549c
--- /dev/null
+++ b/nss/cmd/crlutil/manifest.mn
@@ -0,0 +1,25 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+CORE_DEPTH = ../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+# This next line is used by .mk files
+# and gets translated into $LINCS in manifest.mnw
+# The MODULE is always implicitly required.
+# Listing it here in REQUIRES makes it appear twice in the cc command line.
+REQUIRES = seccmd dbm
+
+DEFINES = -DNSPR20
+
+CSRCS = crlgen_lex.c crlgen.c crlutil.c
+
+# this has to be different for NT and UNIX.
+# PROGRAM = ./$(OBJDIR)/crlutil.exe
+PROGRAM = crlutil
+
+#USE_STATIC_LIBS = 1
diff --git a/nss/cmd/crmf-cgi/Makefile b/nss/cmd/crmf-cgi/Makefile
new file mode 100644
index 0000000..f817268
--- /dev/null
+++ b/nss/cmd/crmf-cgi/Makefile
@@ -0,0 +1,53 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+ifeq (,$(filter-out WIN%,$(OS_TARGET)))
+EXTRA_LIBS += $(DIST)/lib/crmf.lib
+else
+EXTRA_LIBS += $(DIST)/lib/libcrmf.$(LIB_SUFFIX)
+endif
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include ../platlibs.mk
+
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+include ../platrules.mk
+
diff --git a/nss/cmd/crmf-cgi/config.mk b/nss/cmd/crmf-cgi/config.mk
new file mode 100644
index 0000000..77fca36
--- /dev/null
+++ b/nss/cmd/crmf-cgi/config.mk
@@ -0,0 +1,16 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+#
+# Override TARGETS variable so that only static libraries
+# are specifed as dependencies within rules.mk.
+#
+
+TARGETS = $(PROGRAM)
+SHARED_LIBRARY =
+IMPORT_LIBRARY =
+LIBRARY =
+
diff --git a/nss/cmd/crmf-cgi/crmfcgi.c b/nss/cmd/crmf-cgi/crmfcgi.c
new file mode 100644
index 0000000..07b81f2
--- /dev/null
+++ b/nss/cmd/crmf-cgi/crmfcgi.c
@@ -0,0 +1,1090 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "seccomon.h"
+#include "nss.h"
+#include "key.h"
+#include "cert.h"
+#include "pk11func.h"
+#include "secmod.h"
+#include "cmmf.h"
+#include "crmf.h"
+#include "base64.h"
+#include "secasn1.h"
+#include "cryptohi.h"
+#include
+#include
+#include
+
+#define DEFAULT_ALLOC_SIZE 200
+#define DEFAULT_CGI_VARS 20
+
+typedef struct CGIVariableStr {
+ char *name;
+ char *value;
+} CGIVariable;
+
+typedef struct CGIVarTableStr {
+ CGIVariable **variables;
+ int numVars;
+ int numAlloc;
+} CGIVarTable;
+
+typedef struct CertResponseInfoStr {
+ CERTCertificate *cert;
+ long certReqID;
+} CertResponseInfo;
+
+typedef struct ChallengeCreationInfoStr {
+ long random;
+ SECKEYPublicKey *pubKey;
+} ChallengeCreationInfo;
+
+char *missingVar = NULL;
+
+/*
+ * Error values.
+ */
+typedef enum {
+ NO_ERROR = 0,
+ NSS_INIT_FAILED,
+ AUTH_FAILED,
+ REQ_CGI_VAR_NOT_PRESENT,
+ CRMF_REQ_NOT_PRESENT,
+ BAD_ASCII_FOR_REQ,
+ CGI_VAR_MISSING,
+ COULD_NOT_FIND_CA,
+ COULD_NOT_DECODE_REQS,
+ OUT_OF_MEMORY,
+ ERROR_RETRIEVING_REQUEST_MSG,
+ ERROR_RETRIEVING_CERT_REQUEST,
+ ERROR_RETRIEVING_SUBJECT_FROM_REQ,
+ ERROR_RETRIEVING_PUBLIC_KEY_FROM_REQ,
+ ERROR_CREATING_NEW_CERTIFICATE,
+ COULD_NOT_START_EXTENSIONS,
+ ERROR_RETRIEVING_EXT_FROM_REQ,
+ ERROR_ADDING_EXT_TO_CERT,
+ ERROR_ENDING_EXTENSIONS,
+ COULD_NOT_FIND_ISSUER_PRIVATE_KEY,
+ UNSUPPORTED_SIGN_OPERATION_FOR_ISSUER,
+ ERROR_SETTING_SIGN_ALG,
+ ERROR_ENCODING_NEW_CERT,
+ ERROR_SIGNING_NEW_CERT,
+ ERROR_CREATING_CERT_REP_CONTENT,
+ ERROR_CREATING_SINGLE_CERT_RESPONSE,
+ ERROR_SETTING_CERT_RESPONSES,
+ ERROR_CREATING_CA_LIST,
+ ERROR_ADDING_ISSUER_TO_CA_LIST,
+ ERROR_ENCODING_CERT_REP_CONTENT,
+ NO_POP_FOR_REQUEST,
+ UNSUPPORTED_POP,
+ ERROR_RETRIEVING_POP_SIGN_KEY,
+ ERROR_RETRIEVING_ALG_ID_FROM_SIGN_KEY,
+ ERROR_RETRIEVING_SIGNATURE_FROM_POP_SIGN_KEY,
+ DO_CHALLENGE_RESPONSE,
+ ERROR_RETRIEVING_PUB_KEY_FROM_NEW_CERT,
+ ERROR_ENCODING_CERT_REQ_FOR_POP,
+ ERROR_VERIFYING_SIGNATURE_POP,
+ ERROR_RETRIEVING_PUB_KEY_FOR_CHALL,
+ ERROR_CREATING_EMPTY_CHAL_CONTENT,
+ ERROR_EXTRACTING_GEN_NAME_FROM_ISSUER,
+ ERROR_SETTING_CHALLENGE,
+ ERROR_ENCODING_CHALL,
+ ERROR_CONVERTING_CHALL_TO_BASE64,
+ ERROR_CONVERTING_RESP_FROM_CHALL_TO_BIN,
+ ERROR_CREATING_KEY_RESP_FROM_DER,
+ ERROR_RETRIEVING_CLIENT_RESPONSE_TO_CHALLENGE,
+ ERROR_RETURNED_CHALL_NOT_VALUE_EXPECTED,
+ ERROR_GETTING_KEY_ENCIPHERMENT,
+ ERROR_NO_POP_FOR_PRIVKEY,
+ ERROR_UNSUPPORTED_POPOPRIVKEY_TYPE
+} ErrorCode;
+
+const char *
+CGITableFindValue(CGIVarTable *varTable, const char *key);
+
+void
+spitOutHeaders(void)
+{
+ printf("Content-type: text/html\n\n");
+}
+
+void
+dumpRequest(CGIVarTable *varTable)
+{
+ int i;
+ CGIVariable *var;
+
+ printf("\n");
+ printf("Variable Name "
+ "Value \n");
+ for (i = 0; i < varTable->numVars; i++) {
+ var = varTable->variables[i];
+ printf("%s %s \n",
+ var->name, var->value);
+ }
+ printf("
\n");
+}
+
+void
+echo_request(CGIVarTable *varTable)
+{
+ spitOutHeaders();
+ printf("CGI Echo Page \n"
+ "Got the following request \n");
+ dumpRequest(varTable);
+ printf("");
+}
+
+void
+processVariable(CGIVariable *var)
+{
+ char *plusSign, *percentSign;
+
+ /*First look for all of the '+' and convert them to spaces */
+ plusSign = var->value;
+ while ((plusSign = strchr(plusSign, '+')) != NULL) {
+ *plusSign = ' ';
+ }
+ percentSign = var->value;
+ while ((percentSign = strchr(percentSign, '%')) != NULL) {
+ char string[3];
+ int value;
+
+ string[0] = percentSign[1];
+ string[1] = percentSign[2];
+ string[2] = '\0';
+
+ sscanf(string, "%x", &value);
+ *percentSign = (char)value;
+ memmove(&percentSign[1], &percentSign[3], 1 + strlen(&percentSign[3]));
+ }
+}
+
+char *
+parseNextVariable(CGIVarTable *varTable, char *form_output)
+{
+ char *ampersand, *equal;
+ CGIVariable *var;
+
+ if (varTable->numVars == varTable->numAlloc) {
+ CGIVariable **newArr = realloc(varTable->variables,
+ (varTable->numAlloc + DEFAULT_CGI_VARS) * sizeof(CGIVariable *));
+ if (newArr == NULL) {
+ return NULL;
+ }
+ varTable->variables = newArr;
+ varTable->numAlloc += DEFAULT_CGI_VARS;
+ }
+ equal = strchr(form_output, '=');
+ if (equal == NULL) {
+ return NULL;
+ }
+ ampersand = strchr(equal, '&');
+ if (ampersand == NULL) {
+ return NULL;
+ }
+ equal[0] = '\0';
+ if (ampersand != NULL) {
+ ampersand[0] = '\0';
+ }
+ var = malloc(sizeof(CGIVariable));
+ var->name = form_output;
+ var->value = &equal[1];
+ varTable->variables[varTable->numVars] = var;
+ varTable->numVars++;
+ processVariable(var);
+ return (ampersand != NULL) ? &ersand[1] : NULL;
+}
+
+void
+ParseInputVariables(CGIVarTable *varTable, char *form_output)
+{
+ varTable->variables = malloc(sizeof(CGIVariable *) * DEFAULT_CGI_VARS);
+ varTable->numVars = 0;
+ varTable->numAlloc = DEFAULT_CGI_VARS;
+ while (form_output && form_output[0] != '\0') {
+ form_output = parseNextVariable(varTable, form_output);
+ }
+}
+
+const char *
+CGITableFindValue(CGIVarTable *varTable, const char *key)
+{
+ const char *retVal = NULL;
+ int i;
+
+ for (i = 0; i < varTable->numVars; i++) {
+ if (strcmp(varTable->variables[i]->name, key) == 0) {
+ retVal = varTable->variables[i]->value;
+ break;
+ }
+ }
+ return retVal;
+}
+
+char *
+passwordCallback(PK11SlotInfo *slot, PRBool retry, void *arg)
+{
+ const char *passwd;
+ if (retry) {
+ return NULL;
+ }
+ passwd = CGITableFindValue((CGIVarTable *)arg, "dbPassword");
+ if (passwd == NULL) {
+ return NULL;
+ }
+ return PORT_Strdup(passwd);
+}
+
+ErrorCode
+initNSS(CGIVarTable *varTable)
+{
+ const char *nssDir;
+ PK11SlotInfo *keySlot;
+ SECStatus rv;
+
+ nssDir = CGITableFindValue(varTable, "NSSDirectory");
+ if (nssDir == NULL) {
+ missingVar = "NSSDirectory";
+ return REQ_CGI_VAR_NOT_PRESENT;
+ }
+ rv = NSS_Init(nssDir);
+ if (rv != SECSuccess) {
+ return NSS_INIT_FAILED;
+ }
+ PK11_SetPasswordFunc(passwordCallback);
+ keySlot = PK11_GetInternalKeySlot();
+ rv = PK11_Authenticate(keySlot, PR_FALSE, varTable);
+ PK11_FreeSlot(keySlot);
+ if (rv != SECSuccess) {
+ return AUTH_FAILED;
+ }
+ return NO_ERROR;
+}
+
+void
+dumpErrorMessage(ErrorCode errNum)
+{
+ spitOutHeaders();
+ printf("Error Error processing "
+ "data Received the error %d",
+ errNum);
+ if (errNum == REQ_CGI_VAR_NOT_PRESENT) {
+ printf("The missing variable is %s.", missingVar);
+ }
+ printf("More useful information here in the future. ");
+}
+
+ErrorCode
+initOldCertReq(CERTCertificateRequest *oldCertReq,
+ CERTName *subject, CERTSubjectPublicKeyInfo *spki)
+{
+ PLArenaPool *poolp;
+
+ poolp = oldCertReq->arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ SEC_ASN1EncodeInteger(poolp, &oldCertReq->version,
+ SEC_CERTIFICATE_VERSION_3);
+ CERT_CopyName(poolp, &oldCertReq->subject, subject);
+ SECKEY_CopySubjectPublicKeyInfo(poolp, &oldCertReq->subjectPublicKeyInfo,
+ spki);
+ oldCertReq->attributes = NULL;
+ return NO_ERROR;
+}
+
+ErrorCode
+addExtensions(CERTCertificate *newCert, CRMFCertRequest *certReq)
+{
+ int numExtensions, i;
+ void *extHandle;
+ ErrorCode rv = NO_ERROR;
+ CRMFCertExtension *ext;
+ SECStatus srv;
+
+ numExtensions = CRMF_CertRequestGetNumberOfExtensions(certReq);
+ if (numExtensions == 0) {
+ /* No extensions to add */
+ return NO_ERROR;
+ }
+ extHandle = CERT_StartCertExtensions(newCert);
+ if (extHandle == NULL) {
+ rv = COULD_NOT_START_EXTENSIONS;
+ goto loser;
+ }
+ for (i = 0; i < numExtensions; i++) {
+ ext = CRMF_CertRequestGetExtensionAtIndex(certReq, i);
+ if (ext == NULL) {
+ rv = ERROR_RETRIEVING_EXT_FROM_REQ;
+ }
+ srv = CERT_AddExtension(extHandle, CRMF_CertExtensionGetOidTag(ext),
+ CRMF_CertExtensionGetValue(ext),
+ CRMF_CertExtensionGetIsCritical(ext), PR_FALSE);
+ if (srv != SECSuccess) {
+ rv = ERROR_ADDING_EXT_TO_CERT;
+ }
+ }
+ srv = CERT_FinishExtensions(extHandle);
+ if (srv != SECSuccess) {
+ rv = ERROR_ENDING_EXTENSIONS;
+ goto loser;
+ }
+ return NO_ERROR;
+loser:
+ return rv;
+}
+
+void
+writeOutItem(const char *filePath, SECItem *der)
+{
+ PRFileDesc *outfile;
+
+ outfile = PR_Open(filePath,
+ PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
+ 0666);
+ PR_Write(outfile, der->data, der->len);
+ PR_Close(outfile);
+}
+
+ErrorCode
+createNewCert(CERTCertificate **issuedCert, CERTCertificateRequest *oldCertReq,
+ CRMFCertReqMsg *currReq, CRMFCertRequest *certReq,
+ CERTCertificate *issuerCert, CGIVarTable *varTable)
+{
+ CERTCertificate *newCert = NULL;
+ CERTValidity *validity;
+ PRExplodedTime printableTime;
+ PRTime now, after;
+ ErrorCode rv = NO_ERROR;
+ SECKEYPrivateKey *issuerPrivKey;
+ SECItem derCert = { 0 };
+ SECOidTag signTag;
+ SECStatus srv;
+ long version;
+
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_GMTParameters, &printableTime);
+ printableTime.tm_month += 9;
+ after = PR_ImplodeTime(&printableTime);
+ validity = CERT_CreateValidity(now, after);
+ newCert = *issuedCert =
+ CERT_CreateCertificate(rand(), &(issuerCert->subject), validity,
+ oldCertReq);
+ if (newCert == NULL) {
+ rv = ERROR_CREATING_NEW_CERTIFICATE;
+ goto loser;
+ }
+ rv = addExtensions(newCert, certReq);
+ if (rv != NO_ERROR) {
+ goto loser;
+ }
+ issuerPrivKey = PK11_FindKeyByAnyCert(issuerCert, varTable);
+ if (issuerPrivKey == NULL) {
+ rv = COULD_NOT_FIND_ISSUER_PRIVATE_KEY;
+ }
+ signTag = SEC_GetSignatureAlgorithmOidTag(issuerPrivatekey->keytype,
+ SEC_OID_UNKNOWN);
+ if (signTag == SEC_OID_UNKNOWN) {
+ rv = UNSUPPORTED_SIGN_OPERATION_FOR_ISSUER;
+ goto loser;
+ }
+ srv = SECOID_SetAlgorithmID(newCert->arena, &newCert->signature,
+ signTag, 0);
+ if (srv != SECSuccess) {
+ rv = ERROR_SETTING_SIGN_ALG;
+ goto loser;
+ }
+ srv = CRMF_CertRequestGetCertTemplateVersion(certReq, &version);
+ if (srv != SECSuccess) {
+ /* No version included in the request */
+ *(newCert->version.data) = SEC_CERTIFICATE_VERSION_3;
+ } else {
+ SECITEM_FreeItem(&newCert->version, PR_FALSE);
+ SEC_ASN1EncodeInteger(newCert->arena, &newCert->version, version);
+ }
+ SEC_ASN1EncodeItem(newCert->arena, &derCert, newCert,
+ CERT_CertificateTemplate);
+ if (derCert.data == NULL) {
+ rv = ERROR_ENCODING_NEW_CERT;
+ goto loser;
+ }
+ srv = SEC_DerSignData(newCert->arena, &(newCert->derCert), derCert.data,
+ derCert.len, issuerPrivKey, signTag);
+ if (srv != SECSuccess) {
+ rv = ERROR_SIGNING_NEW_CERT;
+ goto loser;
+ }
+#ifdef WRITE_OUT_RESPONSE
+ writeOutItem("newcert.der", &newCert->derCert);
+#endif
+ return NO_ERROR;
+loser:
+ *issuedCert = NULL;
+ if (newCert) {
+ CERT_DestroyCertificate(newCert);
+ }
+ return rv;
+}
+
+void
+formatCMMFResponse(char *nickname, char *base64Response)
+{
+ char *currLine, *nextLine;
+
+ printf("var retVal = crypto.importUserCertificates(\"%s\",\n", nickname);
+ currLine = base64Response;
+ while (1) {
+ nextLine = strchr(currLine, '\n');
+ if (nextLine == NULL) {
+ /* print out the last line here. */
+ printf("\"%s\",\n", currLine);
+ break;
+ }
+ nextLine[0] = '\0';
+ printf("\"%s\\n\"+\n", currLine);
+ currLine = nextLine + 1;
+ }
+ printf("true);\n"
+ "if(retVal == '') {\n"
+ "\tdocument.write(\"
New Certificate Successfully Imported. \");\n"
+ "} else {\n"
+ "\tdocument.write(\"Unable to import New Certificate \");\n"
+ "\tdocument.write(\"crypto.importUserCertificates returned \");\n"
+ "\tdocument.write(retVal);\n"
+ "\tdocument.write(\" \");\n"
+ "}\n");
+}
+
+void
+spitOutCMMFResponse(char *nickname, char *base64Response)
+{
+ spitOutHeaders();
+ printf("\n\nCMMF Resonse Page \n\n\n"
+ "CMMF Response Page \n"
+ "\n\n");
+}
+
+char *
+getNickname(CERTCertificate *cert)
+{
+ char *nickname;
+
+ if (cert->nickname != NULL) {
+ return cert->nickname;
+ }
+ nickname = CERT_GetCommonName(&cert->subject);
+ if (nickname != NULL) {
+ return nickname;
+ }
+ return CERT_NameToAscii(&cert->subject);
+}
+
+ErrorCode
+createCMMFResponse(CertResponseInfo *issuedCerts, int numCerts,
+ CERTCertificate *issuerCert, char **base64der)
+{
+ CMMFCertRepContent *certRepContent = NULL;
+ ErrorCode rv = NO_ERROR;
+ CMMFCertResponse **responses, *currResponse;
+ CERTCertList *caList;
+ int i;
+ SECStatus srv;
+ PLArenaPool *poolp;
+ SECItem *der;
+
+ certRepContent = CMMF_CreateCertRepContent();
+ if (certRepContent == NULL) {
+ rv = ERROR_CREATING_CERT_REP_CONTENT;
+ goto loser;
+ }
+ responses = PORT_NewArray(CMMFCertResponse *, numCerts);
+ if (responses == NULL) {
+ rv = OUT_OF_MEMORY;
+ goto loser;
+ }
+ for (i = 0; i < numCerts; i++) {
+ responses[i] = currResponse =
+ CMMF_CreateCertResponse(issuedCerts[i].certReqID);
+ if (currResponse == NULL) {
+ rv = ERROR_CREATING_SINGLE_CERT_RESPONSE;
+ goto loser;
+ }
+ CMMF_CertResponseSetPKIStatusInfoStatus(currResponse, cmmfGranted);
+ CMMF_CertResponseSetCertificate(currResponse, issuedCerts[i].cert);
+ }
+ srv = CMMF_CertRepContentSetCertResponses(certRepContent, responses,
+ numCerts);
+ if (srv != SECSuccess) {
+ rv = ERROR_SETTING_CERT_RESPONSES;
+ goto loser;
+ }
+ caList = CERT_NewCertList();
+ if (caList == NULL) {
+ rv = ERROR_CREATING_CA_LIST;
+ goto loser;
+ }
+ srv = CERT_AddCertToListTail(caList, issuerCert);
+ if (srv != SECSuccess) {
+ rv = ERROR_ADDING_ISSUER_TO_CA_LIST;
+ goto loser;
+ }
+ srv = CMMF_CertRepContentSetCAPubs(certRepContent, caList);
+ CERT_DestroyCertList(caList);
+ poolp = PORT_NewArena(1024);
+ der = SEC_ASN1EncodeItem(poolp, NULL, certRepContent,
+ CMMFCertRepContentTemplate);
+ if (der == NULL) {
+ rv = ERROR_ENCODING_CERT_REP_CONTENT;
+ goto loser;
+ }
+#ifdef WRITE_OUT_RESPONSE
+ writeOutItem("CertRepContent.der", der);
+#endif
+ *base64der = BTOA_DataToAscii(der->data, der->len);
+ return NO_ERROR;
+loser:
+ return rv;
+}
+
+ErrorCode
+issueCerts(CertResponseInfo *issuedCerts, int numCerts,
+ CERTCertificate *issuerCert)
+{
+ ErrorCode rv;
+ char *base64Response;
+
+ rv = createCMMFResponse(issuedCerts, numCerts, issuerCert, &base64Response);
+ if (rv != NO_ERROR) {
+ goto loser;
+ }
+ spitOutCMMFResponse(getNickname(issuedCerts[0].cert), base64Response);
+ return NO_ERROR;
+loser:
+ return rv;
+}
+
+ErrorCode
+verifySignature(CGIVarTable *varTable, CRMFCertReqMsg *currReq,
+ CRMFCertRequest *certReq, CERTCertificate *newCert)
+{
+ SECStatus srv;
+ ErrorCode rv = NO_ERROR;
+ CRMFPOPOSigningKey *signKey = NULL;
+ SECAlgorithmID *algID = NULL;
+ SECItem *signature = NULL;
+ SECKEYPublicKey *pubKey = NULL;
+ SECItem *reqDER = NULL;
+
+ srv = CRMF_CertReqMsgGetPOPOSigningKey(currReq, &signKey);
+ if (srv != SECSuccess || signKey == NULL) {
+ rv = ERROR_RETRIEVING_POP_SIGN_KEY;
+ goto loser;
+ }
+ algID = CRMF_POPOSigningKeyGetAlgID(signKey);
+ if (algID == NULL) {
+ rv = ERROR_RETRIEVING_ALG_ID_FROM_SIGN_KEY;
+ goto loser;
+ }
+ signature = CRMF_POPOSigningKeyGetSignature(signKey);
+ if (signature == NULL) {
+ rv = ERROR_RETRIEVING_SIGNATURE_FROM_POP_SIGN_KEY;
+ goto loser;
+ }
+ /* Make the length the number of bytes instead of bits */
+ signature->len = (signature->len + 7) / 8;
+ pubKey = CERT_ExtractPublicKey(newCert);
+ if (pubKey == NULL) {
+ rv = ERROR_RETRIEVING_PUB_KEY_FROM_NEW_CERT;
+ goto loser;
+ }
+ reqDER = SEC_ASN1EncodeItem(NULL, NULL, certReq, CRMFCertRequestTemplate);
+ if (reqDER == NULL) {
+ rv = ERROR_ENCODING_CERT_REQ_FOR_POP;
+ goto loser;
+ }
+ srv = VFY_VerifyDataWithAlgorithmID(reqDER->data, reqDER->len, pubKey,
+ signature, &algID->algorithm, NULL, varTable);
+ if (srv != SECSuccess) {
+ rv = ERROR_VERIFYING_SIGNATURE_POP;
+ goto loser;
+ }
+/* Fall thru in successfull case. */
+loser:
+ if (pubKey != NULL) {
+ SECKEY_DestroyPublicKey(pubKey);
+ }
+ if (reqDER != NULL) {
+ SECITEM_FreeItem(reqDER, PR_TRUE);
+ }
+ if (signature != NULL) {
+ SECITEM_FreeItem(signature, PR_TRUE);
+ }
+ if (algID != NULL) {
+ SECOID_DestroyAlgorithmID(algID, PR_TRUE);
+ }
+ if (signKey != NULL) {
+ CRMF_DestroyPOPOSigningKey(signKey);
+ }
+ return rv;
+}
+
+ErrorCode
+doChallengeResponse(CGIVarTable *varTable, CRMFCertReqMsg *currReq,
+ CRMFCertRequest *certReq, CERTCertificate *newCert,
+ ChallengeCreationInfo *challs, int *numChall)
+{
+ CRMFPOPOPrivKey *privKey = NULL;
+ CRMFPOPOPrivKeyChoice privKeyChoice;
+ SECStatus srv;
+ ErrorCode rv = NO_ERROR;
+
+ srv = CRMF_CertReqMsgGetPOPKeyEncipherment(currReq, &privKey);
+ if (srv != SECSuccess || privKey == NULL) {
+ rv = ERROR_GETTING_KEY_ENCIPHERMENT;
+ goto loser;
+ }
+ privKeyChoice = CRMF_POPOPrivKeyGetChoice(privKey);
+ CRMF_DestroyPOPOPrivKey(privKey);
+ switch (privKeyChoice) {
+ case crmfSubsequentMessage:
+ challs = &challs[*numChall];
+ challs->random = rand();
+ challs->pubKey = CERT_ExtractPublicKey(newCert);
+ if (challs->pubKey == NULL) {
+ rv =
+ ERROR_RETRIEVING_PUB_KEY_FOR_CHALL;
+ goto loser;
+ }
+ (*numChall)++;
+ rv = DO_CHALLENGE_RESPONSE;
+ break;
+ case crmfThisMessage:
+ /* There'd better be a PKIArchiveControl in this message */
+ if (!CRMF_CertRequestIsControlPresent(certReq,
+ crmfPKIArchiveOptionsControl)) {
+ rv =
+ ERROR_NO_POP_FOR_PRIVKEY;
+ goto loser;
+ }
+ break;
+ default:
+ rv = ERROR_UNSUPPORTED_POPOPRIVKEY_TYPE;
+ goto loser;
+ }
+loser:
+ return rv;
+}
+
+ErrorCode
+doProofOfPossession(CGIVarTable *varTable, CRMFCertReqMsg *currReq,
+ CRMFCertRequest *certReq, CERTCertificate *newCert,
+ ChallengeCreationInfo *challs, int *numChall)
+{
+ CRMFPOPChoice popChoice;
+ ErrorCode rv = NO_ERROR;
+
+ popChoice = CRMF_CertReqMsgGetPOPType(currReq);
+ if (popChoice == crmfNoPOPChoice) {
+ rv = NO_POP_FOR_REQUEST;
+ goto loser;
+ }
+ switch (popChoice) {
+ case crmfSignature:
+ rv = verifySignature(varTable, currReq, certReq, newCert);
+ break;
+ case crmfKeyEncipherment:
+ rv = doChallengeResponse(varTable, currReq, certReq, newCert,
+ challs, numChall);
+ break;
+ case crmfRAVerified:
+ case crmfKeyAgreement:
+ default:
+ rv = UNSUPPORTED_POP;
+ goto loser;
+ }
+loser:
+ return rv;
+}
+
+void
+convertB64ToJS(char *base64)
+{
+ int i;
+
+ for (i = 0; base64[i] != '\0'; i++) {
+ if (base64[i] == '\n') {
+ printf("\\n");
+ } else {
+ printf("%c", base64[i]);
+ }
+ }
+}
+
+void
+formatChallenge(char *chall64, char *certRepContentDER,
+ ChallengeCreationInfo *challInfo, int numChalls)
+{
+ printf("function respondToChallenge() {\n"
+ " var chalForm = document.chalForm;\n\n"
+ " chalForm.CertRepContent.value = '");
+ convertB64ToJS(certRepContentDER);
+ printf("';\n"
+ " chalForm.ChallResponse.value = crypto.popChallengeResponse('");
+ convertB64ToJS(chall64);
+ printf("');\n"
+ " chalForm.submit();\n"
+ "}\n");
+}
+
+void
+spitOutChallenge(char *chall64, char *certRepContentDER,
+ ChallengeCreationInfo *challInfo, int numChalls,
+ char *nickname)
+{
+ int i;
+
+ spitOutHeaders();
+ printf("\n"
+ "\n"
+ "Challenge Page \n"
+ "\n"
+ "\n"
+ "\n"
+ "Cartman is now responding to the Challenge "
+ "presented by the CGI \n"
+ "\n"
+ " \n"
+ " \n");
+ for (i = 0; i < numChalls; i++) {
+ printf(" \n",
+ i + 1, challInfo[i].random);
+ }
+ printf(" \n", nickname);
+ printf(" \n\n");
+}
+
+ErrorCode
+issueChallenge(CertResponseInfo *issuedCerts, int numCerts,
+ ChallengeCreationInfo *challInfo, int numChalls,
+ CERTCertificate *issuer, CGIVarTable *varTable)
+{
+ ErrorCode rv = NO_ERROR;
+ CMMFPOPODecKeyChallContent *chalContent = NULL;
+ int i;
+ SECStatus srv;
+ PLArenaPool *poolp;
+ CERTGeneralName *genName;
+ SECItem *challDER = NULL;
+ char *chall64, *certRepContentDER;
+
+ rv = createCMMFResponse(issuedCerts, numCerts, issuer,
+ &certRepContentDER);
+ if (rv != NO_ERROR) {
+ goto loser;
+ }
+ chalContent = CMMF_CreatePOPODecKeyChallContent();
+ if (chalContent == NULL) {
+ rv = ERROR_CREATING_EMPTY_CHAL_CONTENT;
+ goto loser;
+ }
+ poolp = PORT_NewArena(1024);
+ if (poolp == NULL) {
+ rv = OUT_OF_MEMORY;
+ goto loser;
+ }
+ genName = CERT_GetCertificateNames(issuer, poolp);
+ if (genName == NULL) {
+ rv = ERROR_EXTRACTING_GEN_NAME_FROM_ISSUER;
+ goto loser;
+ }
+ for (i = 0; i < numChalls; i++) {
+ srv = CMMF_POPODecKeyChallContentSetNextChallenge(chalContent,
+ challInfo[i].random,
+ genName,
+ challInfo[i].pubKey,
+ varTable);
+ SECKEY_DestroyPublicKey(challInfo[i].pubKey);
+ if (srv != SECSuccess) {
+ rv = ERROR_SETTING_CHALLENGE;
+ goto loser;
+ }
+ }
+ challDER = SEC_ASN1EncodeItem(NULL, NULL, chalContent,
+ CMMFPOPODecKeyChallContentTemplate);
+ if (challDER == NULL) {
+ rv = ERROR_ENCODING_CHALL;
+ goto loser;
+ }
+ chall64 = BTOA_DataToAscii(challDER->data, challDER->len);
+ SECITEM_FreeItem(challDER, PR_TRUE);
+ if (chall64 == NULL) {
+ rv = ERROR_CONVERTING_CHALL_TO_BASE64;
+ goto loser;
+ }
+ spitOutChallenge(chall64, certRepContentDER, challInfo, numChalls,
+ getNickname(issuedCerts[0].cert));
+loser:
+ return rv;
+}
+
+ErrorCode
+processRequest(CGIVarTable *varTable)
+{
+ CERTCertDBHandle *certdb;
+ SECKEYKeyDBHandle *keydb;
+ CRMFCertReqMessages *certReqs = NULL;
+ const char *crmfReq;
+ const char *caNickname;
+ CERTCertificate *caCert = NULL;
+ CertResponseInfo *issuedCerts = NULL;
+ CERTSubjectPublicKeyInfo spki = { 0 };
+ ErrorCode rv = NO_ERROR;
+ PRBool doChallengeResponse = PR_FALSE;
+ SECItem der = { 0 };
+ SECStatus srv;
+ CERTCertificateRequest oldCertReq = { 0 };
+ CRMFCertReqMsg **reqMsgs = NULL, *currReq = NULL;
+ CRMFCertRequest **reqs = NULL, *certReq = NULL;
+ CERTName subject = { 0 };
+ int numReqs, i;
+ ChallengeCreationInfo *challInfo = NULL;
+ int numChalls = 0;
+
+ certdb = CERT_GetDefaultCertDB();
+ keydb = SECKEY_GetDefaultKeyDB();
+ crmfReq = CGITableFindValue(varTable, "CRMFRequest");
+ if (crmfReq == NULL) {
+ rv = CGI_VAR_MISSING;
+ missingVar = "CRMFRequest";
+ goto loser;
+ }
+ caNickname = CGITableFindValue(varTable, "CANickname");
+ if (caNickname == NULL) {
+ rv = CGI_VAR_MISSING;
+ missingVar = "CANickname";
+ goto loser;
+ }
+ caCert = CERT_FindCertByNickname(certdb, caNickname);
+ if (caCert == NULL) {
+ rv = COULD_NOT_FIND_CA;
+ goto loser;
+ }
+ srv = ATOB_ConvertAsciiToItem(&der, crmfReq);
+ if (srv != SECSuccess) {
+ rv = BAD_ASCII_FOR_REQ;
+ goto loser;
+ }
+ certReqs = CRMF_CreateCertReqMessagesFromDER(der.data, der.len);
+ SECITEM_FreeItem(&der, PR_FALSE);
+ if (certReqs == NULL) {
+ rv = COULD_NOT_DECODE_REQS;
+ goto loser;
+ }
+ numReqs = CRMF_CertReqMessagesGetNumMessages(certReqs);
+ issuedCerts = PORT_ZNewArray(CertResponseInfo, numReqs);
+ challInfo = PORT_ZNewArray(ChallengeCreationInfo, numReqs);
+ if (issuedCerts == NULL || challInfo == NULL) {
+ rv = OUT_OF_MEMORY;
+ goto loser;
+ }
+ reqMsgs = PORT_ZNewArray(CRMFCertReqMsg *, numReqs);
+ reqs = PORT_ZNewArray(CRMFCertRequest *, numReqs);
+ if (reqMsgs == NULL || reqs == NULL) {
+ rv = OUT_OF_MEMORY;
+ goto loser;
+ }
+ for (i = 0; i < numReqs; i++) {
+ currReq = reqMsgs[i] =
+ CRMF_CertReqMessagesGetCertReqMsgAtIndex(certReqs, i);
+ if (currReq == NULL) {
+ rv = ERROR_RETRIEVING_REQUEST_MSG;
+ goto loser;
+ }
+ certReq = reqs[i] = CRMF_CertReqMsgGetCertRequest(currReq);
+ if (certReq == NULL) {
+ rv = ERROR_RETRIEVING_CERT_REQUEST;
+ goto loser;
+ }
+ srv = CRMF_CertRequestGetCertTemplateSubject(certReq, &subject);
+ if (srv != SECSuccess) {
+ rv = ERROR_RETRIEVING_SUBJECT_FROM_REQ;
+ goto loser;
+ }
+ srv = CRMF_CertRequestGetCertTemplatePublicKey(certReq, &spki);
+ if (srv != SECSuccess) {
+ rv = ERROR_RETRIEVING_PUBLIC_KEY_FROM_REQ;
+ goto loser;
+ }
+ rv = initOldCertReq(&oldCertReq, &subject, &spki);
+ if (rv != NO_ERROR) {
+ goto loser;
+ }
+ rv = createNewCert(&issuedCerts[i].cert, &oldCertReq, currReq, certReq,
+ caCert, varTable);
+ if (rv != NO_ERROR) {
+ goto loser;
+ }
+ rv = doProofOfPossession(varTable, currReq, certReq, issuedCerts[i].cert,
+ challInfo, &numChalls);
+ if (rv != NO_ERROR) {
+ if (rv == DO_CHALLENGE_RESPONSE) {
+ doChallengeResponse = PR_TRUE;
+ } else {
+ goto loser;
+ }
+ }
+ CRMF_CertReqMsgGetID(currReq, &issuedCerts[i].certReqID);
+ CRMF_DestroyCertReqMsg(currReq);
+ CRMF_DestroyCertRequest(certReq);
+ }
+ if (doChallengeResponse) {
+ rv = issueChallenge(issuedCerts, numReqs, challInfo, numChalls, caCert,
+ varTable);
+ } else {
+ rv = issueCerts(issuedCerts, numReqs, caCert);
+ }
+loser:
+ if (certReqs != NULL) {
+ CRMF_DestroyCertReqMessages(certReqs);
+ }
+ return rv;
+}
+
+ErrorCode
+processChallengeResponse(CGIVarTable *varTable, const char *certRepContent)
+{
+ SECItem binDER = { 0 };
+ SECStatus srv;
+ ErrorCode rv = NO_ERROR;
+ const char *clientResponse;
+ const char *formChalValue;
+ const char *nickname;
+ CMMFPOPODecKeyRespContent *respContent = NULL;
+ int numResponses, i;
+ long curResponse, expectedResponse;
+ char cgiChalVar[10];
+#ifdef WRITE_OUT_RESPONSE
+ SECItem certRepBinDER = { 0 };
+
+ ATOB_ConvertAsciiToItem(&certRepBinDER, certRepContent);
+ writeOutItem("challCertRepContent.der", &certRepBinDER);
+ PORT_Free(certRepBinDER.data);
+#endif
+ clientResponse = CGITableFindValue(varTable, "ChallResponse");
+ if (clientResponse == NULL) {
+ rv = REQ_CGI_VAR_NOT_PRESENT;
+ missingVar = "ChallResponse";
+ goto loser;
+ }
+ srv = ATOB_ConvertAsciiToItem(&binDER, clientResponse);
+ if (srv != SECSuccess) {
+ rv = ERROR_CONVERTING_RESP_FROM_CHALL_TO_BIN;
+ goto loser;
+ }
+ respContent = CMMF_CreatePOPODecKeyRespContentFromDER(binDER.data,
+ binDER.len);
+ SECITEM_FreeItem(&binDER, PR_FALSE);
+ binDER.data = NULL;
+ if (respContent == NULL) {
+ rv = ERROR_CREATING_KEY_RESP_FROM_DER;
+ goto loser;
+ }
+ numResponses = CMMF_POPODecKeyRespContentGetNumResponses(respContent);
+ for (i = 0; i < numResponses; i++) {
+ srv = CMMF_POPODecKeyRespContentGetResponse(respContent, i, &curResponse);
+ if (srv != SECSuccess) {
+ rv = ERROR_RETRIEVING_CLIENT_RESPONSE_TO_CHALLENGE;
+ goto loser;
+ }
+ sprintf(cgiChalVar, "chal%d", i + 1);
+ formChalValue = CGITableFindValue(varTable, cgiChalVar);
+ if (formChalValue == NULL) {
+ rv = REQ_CGI_VAR_NOT_PRESENT;
+ missingVar = strdup(cgiChalVar);
+ goto loser;
+ }
+ sscanf(formChalValue, "%ld", &expectedResponse);
+ if (expectedResponse != curResponse) {
+ rv = ERROR_RETURNED_CHALL_NOT_VALUE_EXPECTED;
+ goto loser;
+ }
+ }
+ nickname = CGITableFindValue(varTable, "nickname");
+ if (nickname == NULL) {
+ rv = REQ_CGI_VAR_NOT_PRESENT;
+ missingVar = "nickname";
+ goto loser;
+ }
+ spitOutCMMFResponse(nickname, certRepContent);
+loser:
+ if (respContent != NULL) {
+ CMMF_DestroyPOPODecKeyRespContent(respContent);
+ }
+ return rv;
+}
+
+int
+main()
+{
+ char *form_output = NULL;
+ int form_output_len, form_output_used;
+ CGIVarTable varTable = { 0 };
+ ErrorCode errNum = 0;
+ char *certRepContent;
+
+#ifdef ATTACH_CGI
+ /* Put an ifinite loop in here so I can attach to
+ * the process after the process is spun off
+ */
+ {
+ int stupid = 1;
+ while (stupid)
+ ;
+ }
+#endif
+
+ form_output_used = 0;
+ srand(time(NULL));
+ while (feof(stdin) == 0) {
+ if (form_output == NULL) {
+ form_output = PORT_NewArray(char, DEFAULT_ALLOC_SIZE + 1);
+ form_output_len = DEFAULT_ALLOC_SIZE;
+ } else if ((form_output_used + DEFAULT_ALLOC_SIZE) >= form_output_len) {
+ form_output_len += DEFAULT_ALLOC_SIZE;
+ form_output = PORT_Realloc(form_output, form_output_len + 1);
+ }
+ form_output_used += fread(&form_output[form_output_used], sizeof(char),
+ DEFAULT_ALLOC_SIZE, stdin);
+ }
+ ParseInputVariables(&varTable, form_output);
+ certRepContent = CGITableFindValue(&varTable, "CertRepContent");
+ if (certRepContent == NULL) {
+ errNum = initNSS(&varTable);
+ if (errNum != 0) {
+ goto loser;
+ }
+ errNum = processRequest(&varTable);
+ } else {
+ errNum = processChallengeResponse(&varTable, certRepContent);
+ }
+ if (errNum != NO_ERROR) {
+ goto loser;
+ }
+ goto done;
+loser:
+ dumpErrorMessage(errNum);
+done:
+ free(form_output);
+ return 0;
+}
diff --git a/nss/cmd/crmf-cgi/crmfcgi.html b/nss/cmd/crmf-cgi/crmfcgi.html
new file mode 100644
index 0000000..537b0f5
--- /dev/null
+++ b/nss/cmd/crmf-cgi/crmfcgi.html
@@ -0,0 +1,136 @@
+
+
+
+
+CRMF Test Page for PSM
+
+
+
+CRMF Test page for PSM
+This page is designed to be used in combination with the executable
+produced by ns/security/cmd/crmf-cgi in a CGI environment. In order
+to successfully use this page, modify its action to post to a a server
+where you have installed the crmfcgi executable and you'll be able to
+test the functionality.
+
+
+Certificate Database information
+First, enter all the information for the CGI to use for initializing
+NSS. The CGI will use the directory entered below as the directory
+where to look for the certificate and key databases.
+
+Path for NSS Config:
+
+Enter the password for the certificate database found in the direcotry
+above.
+
+Database Password:
+
+Now enter the nickname of the certificate to use for signing the
+certificate issued during this test.
+
+CA Nickname:
+
+Now, figure out which type of key generation you want to test:
+`
+Signing Only-RSA
+ Encryption Only-RSA
+ Sign and Encrypt Single Key -RSA
+ Dual Keys-RSA
+ DSA Key Gen
+
+
+
+
+
+
+
diff --git a/nss/cmd/crmf-cgi/manifest.mn b/nss/cmd/crmf-cgi/manifest.mn
new file mode 100644
index 0000000..1212424
--- /dev/null
+++ b/nss/cmd/crmf-cgi/manifest.mn
@@ -0,0 +1,33 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+CORE_DEPTH = ../..
+MODULE = sectools
+
+EXPORTS = \
+ $(NULL)
+
+CSRCS = \
+ crmfcgi.c \
+ $(NULL)
+
+
+REQUIRES = nss dbm seccmd
+
+ifdef ATTACH_CGI
+DEFINES += -DATTACH_CGI
+endif
+
+ifdef WRITE_OUT_RESPONSE
+DEFINES += -DWRITE_OUT_RESPONSE
+endif
+
+PROGRAM = crmfcgi
+
+USE_STATIC_LIBS = 1
+
+INCLUDES =
+
+DEFINES = -DNSPR20
diff --git a/nss/cmd/crmftest/Makefile b/nss/cmd/crmftest/Makefile
new file mode 100644
index 0000000..369cdc8
--- /dev/null
+++ b/nss/cmd/crmftest/Makefile
@@ -0,0 +1,64 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+include config.mk
+
+ifeq ($(OS_TARGET)$(OS_RELEASE), AIX4.2)
+OS_LIBS += -lsvld
+endif
+
+ifeq ($(OS_TARGET)$(OS_RELEASE), SunOS5.6)
+OS_LIBS += -ldl -lxnet -lposix4 -lsocket -lnsl
+endif
+
+EXTRA_LIBS += $(DIST)/lib/$(LIB_PREFIX)crmf.$(LIB_SUFFIX)
+
+include ../platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+LDDIST = $(DIST)/lib
+
+ifeq (,$(filter-out WIN%,$(OS_TARGET)))
+EXTRA_LIBS += $(LDDIST)/sectool.lib
+endif
+
+include ../platrules.mk
diff --git a/nss/cmd/crmftest/config.mk b/nss/cmd/crmftest/config.mk
new file mode 100644
index 0000000..9838ef1
--- /dev/null
+++ b/nss/cmd/crmftest/config.mk
@@ -0,0 +1,15 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#
+# Override TARGETS variable so that only static libraries
+# are specifed as dependencies within rules.mk.
+#
+
+TARGETS = $(PROGRAM)
+SHARED_LIBRARY =
+IMPORT_LIBRARY =
+LIBRARY =
+
diff --git a/nss/cmd/crmftest/crmftest.gyp b/nss/cmd/crmftest/crmftest.gyp
new file mode 100644
index 0000000..c14bd19
--- /dev/null
+++ b/nss/cmd/crmftest/crmftest.gyp
@@ -0,0 +1,25 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi',
+ '../../cmd/platlibs.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'crmftest',
+ 'type': 'executable',
+ 'sources': [
+ 'testcrmf.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports',
+ '<(DEPTH)/lib/crmf/crmf.gyp:crmf'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
\ No newline at end of file
diff --git a/nss/cmd/crmftest/manifest.mn b/nss/cmd/crmftest/manifest.mn
new file mode 100644
index 0000000..578729e
--- /dev/null
+++ b/nss/cmd/crmftest/manifest.mn
@@ -0,0 +1,25 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+CORE_DEPTH = ../..
+DEPTH = .
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+EXPORTS = \
+ $(NULL)
+
+CSRCS = \
+ testcrmf.c \
+ $(NULL)
+
+
+# The MODULE is always implicitly required.
+# Listing it here in REQUIRES makes it appear twice in the cc command line.
+# REQUIRES = dbm
+
+PROGRAM = crmftest
+
diff --git a/nss/cmd/crmftest/testcrmf.c b/nss/cmd/crmftest/testcrmf.c
new file mode 100644
index 0000000..fefa689
--- /dev/null
+++ b/nss/cmd/crmftest/testcrmf.c
@@ -0,0 +1,1654 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * This program does 5 separate functions. By default, it does them all.
+ * It can be told to do any subset of them.
+ * It does them in this order:
+ *
+ * 1. Generate file of CRMF cert requests.
+ * Generates 2 keys pairs, one for signing, one for encryption.
+ * Can generate RSA or DSA (XXX - DSA is only useful for signing).
+ * Generate a cert request for each of the two public keys.
+ * Generate a single CRMF cert request message that requests both certs.
+ * Leave the generated CRMF request message in file
+ * configdir/CertReqMessages.der
+ *
+ * 2. Decode CRMF Request(s) Message.
+ * Reads in the file configdir/CertReqMessages.der
+ * (either generated by step 1 above, or user supplied).
+ * Decodes it. NOTHING MORE. Drops these decoded results on the floor.
+ * The CMMF response (below) contains a completely unrelated cert. :-(
+ *
+ * 3. CMMF "Stuff".
+ * a) Generates a CMMF response, containing a single cert chain, as if
+ * it was a response to a received CRMF request. But the cert is
+ * simply a user cert from the user's local soft token, whose
+ * nickname is given in the -p option. The CMMF response has no
+ * relationship to the request generated above. The CMMF message
+ * is placed in configdir/CertRepContent.der.
+ * b) Decodes the newly generated CMMF response found in file
+ * configdir/CertRepContent.der and discards the result. 8-/
+ * c) Generate a CMMF Key Escrow message
+ * needs 2 nicknames:
+ * It takes the public and private keys for the cert identified
+ * by -p nickname, and wraps them with a sym key that is in turn
+ * wrapped with the pubkey in the CA cert, whose nickname is
+ * given with the -s option.
+ * Store the message in configdir/KeyRecRepContent.der
+ * d) Decode the CMMF Key Escrow message generated just above.
+ * Get it from file configdir/KeyRecRepContent.der
+ * This is just a decoder test. Results are discarded.
+ *
+ * 4. Key Recovery
+ * This code does not yet compile, and what it was intended to do
+ * has not been fully determined.
+ *
+ * 5. Challenge/Response.
+ * Haven't analyzed this code yet.
+ *
+ *
+ */
+
+/* KNOWN BUGS:
+** 1. generates BOTH signing and encryption cert requests, even for DSA keys.
+**
+** 2. Does not verify the siganture in the "Proof of Posession" in the
+** decoded cert requests. It only checks syntax of the POP.
+** 3. CMMF "Stuff" should be broken up into separate steps, each of
+** which may be optionally selected.
+*/
+
+#include
+#include "nspr.h"
+#include "nss.h"
+#include "crmf.h"
+#include "secerr.h"
+#include "pk11func.h"
+#include "key.h"
+#include "cmmf.h"
+#include "plgetopt.h"
+#include "secutil.h"
+#include "pk11pqg.h"
+
+#if 0
+#include "pkcs11.h"
+#include "secmod.h"
+#include "secmodi.h"
+#include "pqggen.h"
+#include "secmod.h"
+#include "secmodi.h"
+#include "pkcs11.h"
+#include "secitem.h"
+#include "secasn1.h"
+#include "sechash.h"
+#endif
+
+#define MAX_KEY_LEN 512
+#define PATH_LEN 150
+#define BUFF_SIZE 150
+#define UID_BITS 800
+#define BPB 8
+#define CRMF_FILE "CertReqMessages.der"
+
+PRTime notBefore;
+char *personalCert = NULL;
+char *recoveryEncrypter = NULL;
+char *caCertName = NULL;
+static secuPWData pwdata = { PW_NONE, 0 };
+char *configdir;
+PRBool doingDSA = PR_FALSE;
+
+CERTCertDBHandle *db;
+
+typedef struct {
+ SECKEYPrivateKey *privKey;
+ SECKEYPublicKey *pubKey;
+ CRMFCertRequest *certReq;
+ CRMFCertReqMsg *certReqMsg;
+} TESTKeyPair;
+
+void
+debug_test(SECItem *src, char *filePath)
+{
+ PRFileDesc *fileDesc;
+
+ fileDesc = PR_Open(filePath, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
+ 0666);
+ if (fileDesc == NULL) {
+ printf("Could not cretae file %s.\n", filePath);
+ return;
+ }
+ PR_Write(fileDesc, src->data, src->len);
+}
+
+SECStatus
+get_serial_number(long *dest)
+{
+ SECStatus rv;
+
+ if (dest == NULL) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ rv = PK11_GenerateRandom((unsigned char *)dest, sizeof(long));
+ if (rv != SECSuccess) {
+ /* PK11_GenerateRandom calls PORT_SetError */
+ return SECFailure;
+ }
+ /* make serial number positive */
+ if (*dest < 0L)
+ *dest = -*dest;
+ return SECSuccess;
+}
+
+PK11RSAGenParams *
+GetRSAParams(void)
+{
+ PK11RSAGenParams *rsaParams;
+
+ rsaParams = PORT_ZNew(PK11RSAGenParams);
+
+ if (rsaParams == NULL)
+ return NULL;
+
+ rsaParams->keySizeInBits = MAX_KEY_LEN;
+ rsaParams->pe = 0x10001;
+
+ return rsaParams;
+}
+
+PQGParams *
+GetDSAParams(void)
+{
+ PQGParams *params = NULL;
+ PQGVerify *vfy = NULL;
+
+ SECStatus rv;
+
+ rv = PK11_PQG_ParamGen(0, ¶ms, &vfy);
+ if (rv != SECSuccess) {
+ return NULL;
+ }
+ PK11_PQG_DestroyVerify(vfy);
+ return params;
+}
+
+/* Generate a key pair, and then generate a subjectPublicKeyInfo
+** for the public key in that pair. return all 3.
+*/
+CERTSubjectPublicKeyInfo *
+GetSubjectPubKeyInfo(TESTKeyPair *pair)
+{
+ CERTSubjectPublicKeyInfo *spki = NULL;
+ SECKEYPrivateKey *privKey = NULL;
+ SECKEYPublicKey *pubKey = NULL;
+ PK11SlotInfo *keySlot = NULL;
+
+ keySlot = PK11_GetInternalKeySlot();
+ PK11_Authenticate(keySlot, PR_FALSE, &pwdata);
+
+ if (!doingDSA) {
+ PK11RSAGenParams *rsaParams = GetRSAParams();
+ if (rsaParams == NULL) {
+ PK11_FreeSlot(keySlot);
+ return NULL;
+ }
+ privKey = PK11_GenerateKeyPair(keySlot, CKM_RSA_PKCS_KEY_PAIR_GEN,
+ (void *)rsaParams, &pubKey, PR_FALSE,
+ PR_FALSE, &pwdata);
+ } else {
+ PQGParams *dsaParams = GetDSAParams();
+ if (dsaParams == NULL) {
+ PK11_FreeSlot(keySlot);
+ return NULL;
+ }
+ privKey = PK11_GenerateKeyPair(keySlot, CKM_DSA_KEY_PAIR_GEN,
+ (void *)dsaParams, &pubKey, PR_FALSE,
+ PR_FALSE, &pwdata);
+ }
+ PK11_FreeSlot(keySlot);
+ if (privKey == NULL || pubKey == NULL) {
+ if (pubKey) {
+ SECKEY_DestroyPublicKey(pubKey);
+ }
+ if (privKey) {
+ SECKEY_DestroyPrivateKey(privKey);
+ }
+ return NULL;
+ }
+
+ spki = SECKEY_CreateSubjectPublicKeyInfo(pubKey);
+ pair->privKey = privKey;
+ pair->pubKey = pubKey;
+ return spki;
+}
+
+SECStatus
+InitPKCS11(void)
+{
+ PK11SlotInfo *keySlot;
+
+ PK11_SetPasswordFunc(SECU_GetModulePassword);
+
+ keySlot = PK11_GetInternalKeySlot();
+
+ if (PK11_NeedUserInit(keySlot) && PK11_NeedLogin(keySlot)) {
+ if (SECU_ChangePW(keySlot, NULL, NULL) != SECSuccess) {
+ printf("Initializing the PINs failed.\n");
+ return SECFailure;
+ }
+ }
+
+ PK11_FreeSlot(keySlot);
+ return SECSuccess;
+}
+
+void
+WriteItOut(void *arg, const char *buf, unsigned long len)
+{
+ PRFileDesc *fileDesc = (PRFileDesc *)arg;
+
+ PR_Write(fileDesc, (void *)buf, len);
+}
+
+CRMFCertExtCreationInfo *
+GetExtensions(void)
+{
+ unsigned char keyUsage[4] = { 0x03, 0x02, 0x07, KU_DIGITAL_SIGNATURE };
+ /* What are these magic numbers? */
+ SECItem data = { 0, NULL, 0 };
+ CRMFCertExtension *extension;
+ CRMFCertExtCreationInfo *extInfo =
+ PORT_ZNew(CRMFCertExtCreationInfo);
+
+ data.data = keyUsage;
+ data.len = sizeof keyUsage;
+
+ extension =
+ CRMF_CreateCertExtension(SEC_OID_X509_KEY_USAGE, PR_FALSE, &data);
+ if (extension && extInfo) {
+ extInfo->numExtensions = 1;
+ extInfo->extensions = PORT_ZNewArray(CRMFCertExtension *, 1);
+ extInfo->extensions[0] = extension;
+ }
+ return extInfo;
+}
+
+void
+FreeExtInfo(CRMFCertExtCreationInfo *extInfo)
+{
+ int i;
+
+ for (i = 0; i < extInfo->numExtensions; i++) {
+ CRMF_DestroyCertExtension(extInfo->extensions[i]);
+ }
+ PORT_Free(extInfo->extensions);
+ PORT_Free(extInfo);
+}
+
+int
+InjectCertName(CRMFCertRequest *certReq,
+ CRMFCertTemplateField inTemplateField,
+ const char *inNameString)
+{
+ char *nameStr;
+ CERTName *name;
+ int irv = 0;
+
+ nameStr = PORT_Strdup(inNameString);
+ if (!nameStr)
+ return 5;
+ name = CERT_AsciiToName(nameStr);
+ if (name == NULL) {
+ printf("Could not create CERTName structure from %s.\n", nameStr);
+ irv = 5;
+ goto finish;
+ }
+
+ irv = CRMF_CertRequestSetTemplateField(certReq, inTemplateField, (void *)name);
+ if (irv != SECSuccess) {
+ printf("Could not add name to cert template\n");
+ irv = 6;
+ }
+
+finish:
+ PORT_Free(nameStr);
+ if (name)
+ CERT_DestroyName(name);
+ return irv;
+}
+
+int
+CreateCertRequest(TESTKeyPair *pair, long inRequestID)
+{
+ CERTCertificate *caCert;
+ CERTSubjectPublicKeyInfo *spki;
+ CRMFCertExtCreationInfo *extInfo;
+ CRMFCertRequest *certReq;
+ CRMFEncryptedKey *encKey;
+ CRMFPKIArchiveOptions *pkiArchOpt;
+ SECAlgorithmID *algID;
+ long serialNumber;
+ long version = 3;
+ SECStatus rv;
+ CRMFValidityCreationInfo validity;
+ unsigned char UIDbuf[UID_BITS / BPB];
+ SECItem issuerUID = { siBuffer, NULL, 0 };
+ SECItem subjectUID = { siBuffer, NULL, 0 };
+
+ /* len in bits */
+ issuerUID.data = UIDbuf;
+ issuerUID.len = UID_BITS;
+ subjectUID.data = UIDbuf;
+ subjectUID.len = UID_BITS;
+
+ pair->certReq = NULL;
+ certReq = CRMF_CreateCertRequest(inRequestID);
+ if (certReq == NULL) {
+ printf("Could not initialize a certificate request.\n");
+ return 1;
+ }
+
+ /* set to version 3 */
+ rv = CRMF_CertRequestSetTemplateField(certReq, crmfVersion,
+ (void *)(&version));
+ if (rv != SECSuccess) {
+ printf("Could not add the version number to the "
+ "Certificate Request.\n");
+ CRMF_DestroyCertRequest(certReq);
+ return 2;
+ }
+
+ /* set serial number */
+ if (get_serial_number(&serialNumber) != SECSuccess) {
+ printf("Could not generate a serial number for cert request.\n");
+ CRMF_DestroyCertRequest(certReq);
+ return 3;
+ }
+ rv = CRMF_CertRequestSetTemplateField(certReq, crmfSerialNumber,
+ (void *)(&serialNumber));
+ if (rv != SECSuccess) {
+ printf("Could not add serial number to certificate template\n.");
+ CRMF_DestroyCertRequest(certReq);
+ return 4;
+ }
+
+ /* Set issuer name */
+ rv = InjectCertName(certReq, crmfIssuer,
+ "CN=mozilla CA Shack,O=Information Systems");
+ if (rv) {
+ printf("Could not add issuer to cert template\n");
+ CRMF_DestroyCertRequest(certReq);
+ return 5;
+ }
+
+ /* Set Subject Name */
+ rv = InjectCertName(certReq, crmfSubject,
+ "CN=mozilla CA Shack ID,O=Engineering,C=US");
+ if (rv) {
+ printf("Could not add Subject to cert template\n");
+ CRMF_DestroyCertRequest(certReq);
+ return 5;
+ }
+
+ /* Set Algorithm ID */
+ algID = PK11_CreatePBEAlgorithmID(SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC,
+ 1, NULL);
+ if (algID == NULL) {
+ printf("Couldn't create algorithm ID\n");
+ CRMF_DestroyCertRequest(certReq);
+ return 9;
+ }
+ rv = CRMF_CertRequestSetTemplateField(certReq, crmfSigningAlg, (void *)algID);
+ SECOID_DestroyAlgorithmID(algID, PR_TRUE);
+ if (rv != SECSuccess) {
+ printf("Could not add the signing algorithm to the cert template.\n");
+ CRMF_DestroyCertRequest(certReq);
+ return 10;
+ }
+
+ /* Set Validity Dates */
+ validity.notBefore = ¬Before;
+ validity.notAfter = NULL;
+ notBefore = PR_Now();
+ rv = CRMF_CertRequestSetTemplateField(certReq, crmfValidity, (void *)(&validity));
+ if (rv != SECSuccess) {
+ printf("Could not add validity to cert template\n");
+ CRMF_DestroyCertRequest(certReq);
+ return 11;
+ }
+
+ /* Generate a key pair and Add the spki to the request */
+ spki = GetSubjectPubKeyInfo(pair);
+ if (spki == NULL) {
+ printf("Could not create a Subject Public Key Info to add\n");
+ CRMF_DestroyCertRequest(certReq);
+ return 12;
+ }
+ rv = CRMF_CertRequestSetTemplateField(certReq, crmfPublicKey, (void *)spki);
+ SECKEY_DestroySubjectPublicKeyInfo(spki);
+ if (rv != SECSuccess) {
+ printf("Could not add the public key to the template\n");
+ CRMF_DestroyCertRequest(certReq);
+ return 13;
+ }
+
+ /* Set the requested isser Unique ID */
+ PK11_GenerateRandom(UIDbuf, sizeof UIDbuf);
+ CRMF_CertRequestSetTemplateField(certReq, crmfIssuerUID, (void *)&issuerUID);
+
+ /* Set the requested Subject Unique ID */
+ PK11_GenerateRandom(UIDbuf, sizeof UIDbuf);
+ CRMF_CertRequestSetTemplateField(certReq, crmfSubjectUID, (void *)&subjectUID);
+
+ /* Add extensions - XXX need to understand these magic numbers */
+ extInfo = GetExtensions();
+ CRMF_CertRequestSetTemplateField(certReq, crmfExtension, (void *)extInfo);
+ FreeExtInfo(extInfo);
+
+ /* get the recipient CA's cert */
+ caCert = CERT_FindCertByNickname(db, caCertName);
+ if (caCert == NULL) {
+ printf("Could not find the certificate for %s\n", caCertName);
+ CRMF_DestroyCertRequest(certReq);
+ return 50;
+ }
+ encKey = CRMF_CreateEncryptedKeyWithEncryptedValue(pair->privKey, caCert);
+ CERT_DestroyCertificate(caCert);
+ if (encKey == NULL) {
+ printf("Could not create Encrypted Key with Encrypted Value.\n");
+ return 14;
+ }
+ pkiArchOpt = CRMF_CreatePKIArchiveOptions(crmfEncryptedPrivateKey, encKey);
+ CRMF_DestroyEncryptedKey(encKey);
+ if (pkiArchOpt == NULL) {
+ printf("Could not create PKIArchiveOptions.\n");
+ return 15;
+ }
+ rv = CRMF_CertRequestSetPKIArchiveOptions(certReq, pkiArchOpt);
+ CRMF_DestroyPKIArchiveOptions(pkiArchOpt);
+ if (rv != SECSuccess) {
+ printf("Could not add the PKIArchiveControl to Cert Request.\n");
+ return 16;
+ }
+ pair->certReq = certReq;
+ return 0;
+}
+
+int
+Encode(CRMFCertReqMsg *inCertReq1, CRMFCertReqMsg *inCertReq2)
+{
+ PRFileDesc *fileDesc;
+ SECStatus rv;
+ int irv = 0;
+ CRMFCertReqMsg *msgArr[3];
+ char filePath[PATH_LEN];
+
+ PR_snprintf(filePath, PATH_LEN, "%s/%s", configdir, CRMF_FILE);
+ fileDesc = PR_Open(filePath, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
+ 0666);
+ if (fileDesc == NULL) {
+ printf("Could not open file %s\n", filePath);
+ irv = 14;
+ goto finish;
+ }
+ msgArr[0] = inCertReq1;
+ msgArr[1] = inCertReq2;
+ msgArr[2] = NULL;
+ rv = CRMF_EncodeCertReqMessages(msgArr, WriteItOut, (void *)fileDesc);
+ if (rv != SECSuccess) {
+ printf("An error occurred while encoding.\n");
+ irv = 15;
+ }
+finish:
+ PR_Close(fileDesc);
+ return irv;
+}
+
+int
+AddProofOfPossession(TESTKeyPair *pair,
+ CRMFPOPChoice inPOPChoice)
+{
+
+ switch (inPOPChoice) {
+ case crmfSignature:
+ CRMF_CertReqMsgSetSignaturePOP(pair->certReqMsg, pair->privKey,
+ pair->pubKey, NULL, NULL, &pwdata);
+ break;
+ case crmfRAVerified:
+ CRMF_CertReqMsgSetRAVerifiedPOP(pair->certReqMsg);
+ break;
+ case crmfKeyEncipherment:
+ CRMF_CertReqMsgSetKeyEnciphermentPOP(pair->certReqMsg,
+ crmfSubsequentMessage,
+ crmfChallengeResp, NULL);
+ break;
+ case crmfKeyAgreement: {
+ SECItem pendejo;
+ unsigned char lame[] = { 0xf0, 0x0f, 0xf0, 0x0f, 0xf0 };
+
+ pendejo.data = lame;
+ pendejo.len = 5;
+
+ CRMF_CertReqMsgSetKeyAgreementPOP(pair->certReqMsg, crmfThisMessage,
+ crmfNoSubseqMess, &pendejo);
+ } break;
+ default:
+ return 1;
+ }
+ return 0;
+}
+
+int
+Decode(void)
+{
+ PRFileDesc *fileDesc;
+ CRMFCertReqMsg *certReqMsg;
+ CRMFCertRequest *certReq;
+ CRMFCertReqMessages *certReqMsgs;
+ SECStatus rv;
+ int numMsgs, i;
+ long lame;
+ CRMFGetValidity validity = { NULL, NULL };
+ SECItem item = { siBuffer, NULL, 0 };
+ char filePath[PATH_LEN];
+
+ PR_snprintf(filePath, PATH_LEN, "%s/%s", configdir, CRMF_FILE);
+ fileDesc = PR_Open(filePath, PR_RDONLY, 0644);
+ if (fileDesc == NULL) {
+ printf("Could not open file %s\n", filePath);
+ return 214;
+ }
+ rv = SECU_FileToItem(&item, fileDesc);
+ PR_Close(fileDesc);
+ if (rv != SECSuccess) {
+ return 215;
+ }
+
+ certReqMsgs = CRMF_CreateCertReqMessagesFromDER((char *)item.data, item.len);
+ if (certReqMsgs == NULL) {
+ printf("Error decoding CertReqMessages.\n");
+ return 202;
+ }
+ numMsgs = CRMF_CertReqMessagesGetNumMessages(certReqMsgs);
+ if (numMsgs <= 0) {
+ printf("WARNING: The DER contained %d messages.\n", numMsgs);
+ }
+ for (i = 0; i < numMsgs; i++) {
+ SECStatus rv;
+ printf("crmftest: Processing cert request %d\n", i);
+ certReqMsg = CRMF_CertReqMessagesGetCertReqMsgAtIndex(certReqMsgs, i);
+ if (certReqMsg == NULL) {
+ printf("ERROR: Could not access the message at index %d of %s\n",
+ i, filePath);
+ }
+ rv = CRMF_CertReqMsgGetID(certReqMsg, &lame);
+ if (rv) {
+ SECU_PrintError("crmftest", "CRMF_CertReqMsgGetID");
+ }
+ certReq = CRMF_CertReqMsgGetCertRequest(certReqMsg);
+ if (!certReq) {
+ SECU_PrintError("crmftest", "CRMF_CertReqMsgGetCertRequest");
+ }
+ rv = CRMF_CertRequestGetCertTemplateValidity(certReq, &validity);
+ if (rv) {
+ SECU_PrintError("crmftest", "CRMF_CertRequestGetCertTemplateValidity");
+ }
+ if (!validity.notBefore) {
+ /* We encoded a notBefore, so somthing's wrong if it's not here. */
+ printf("ERROR: Validity period notBefore date missing.\n");
+ }
+ /* XXX It's all parsed now. We probably should DO SOMETHING with it.
+ ** But nope. We just throw it all away.
+ ** Maybe this was intended to be no more than a decoder test.
+ */
+ CRMF_DestroyGetValidity(&validity);
+ CRMF_DestroyCertRequest(certReq);
+ CRMF_DestroyCertReqMsg(certReqMsg);
+ }
+ CRMF_DestroyCertReqMessages(certReqMsgs);
+ SECITEM_FreeItem(&item, PR_FALSE);
+ return 0;
+}
+
+int
+GetBitsFromFile(const char *filePath, SECItem *item)
+{
+ PRFileDesc *fileDesc;
+ SECStatus rv;
+
+ fileDesc = PR_Open(filePath, PR_RDONLY, 0644);
+ if (fileDesc == NULL) {
+ printf("Could not open file %s\n", filePath);
+ return 14;
+ }
+
+ rv = SECU_FileToItem(item, fileDesc);
+ PR_Close(fileDesc);
+
+ if (rv != SECSuccess) {
+ item->data = NULL;
+ item->len = 0;
+ return 15;
+ }
+ return 0;
+}
+
+int
+DecodeCMMFCertRepContent(char *derFile)
+{
+ CMMFCertRepContent *certRepContent;
+ int irv = 0;
+ SECItem fileBits = { siBuffer, NULL, 0 };
+
+ GetBitsFromFile(derFile, &fileBits);
+ if (fileBits.data == NULL) {
+ printf("Could not get bits from file %s\n", derFile);
+ return 304;
+ }
+ certRepContent = CMMF_CreateCertRepContentFromDER(db,
+ (char *)fileBits.data, fileBits.len);
+ if (certRepContent == NULL) {
+ printf("Error while decoding %s\n", derFile);
+ irv = 303;
+ } else {
+ /* That was fun. Now, let's throw it away! */
+ CMMF_DestroyCertRepContent(certRepContent);
+ }
+ SECITEM_FreeItem(&fileBits, PR_FALSE);
+ return irv;
+}
+
+int
+EncodeCMMFCertReply(const char *filePath,
+ CERTCertificate *cert,
+ CERTCertList *list)
+{
+ int rv = 0;
+ SECStatus srv;
+ PRFileDesc *fileDesc = NULL;
+ CMMFCertRepContent *certRepContent = NULL;
+ CMMFCertResponse *certResp = NULL;
+ CMMFCertResponse *certResponses[3];
+
+ certResp = CMMF_CreateCertResponse(0xff123);
+ CMMF_CertResponseSetPKIStatusInfoStatus(certResp, cmmfGranted);
+
+ CMMF_CertResponseSetCertificate(certResp, cert);
+
+ certResponses[0] = certResp;
+ certResponses[1] = NULL;
+ certResponses[2] = NULL;
+
+ certRepContent = CMMF_CreateCertRepContent();
+ CMMF_CertRepContentSetCertResponses(certRepContent, certResponses, 1);
+
+ CMMF_CertRepContentSetCAPubs(certRepContent, list);
+
+ fileDesc = PR_Open(filePath, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
+ 0666);
+ if (fileDesc == NULL) {
+ printf("Could not open file %s\n", filePath);
+ rv = 400;
+ goto finish;
+ }
+
+ srv = CMMF_EncodeCertRepContent(certRepContent, WriteItOut,
+ (void *)fileDesc);
+ PR_Close(fileDesc);
+ if (srv != SECSuccess) {
+ printf("CMMF_EncodeCertRepContent failed,\n");
+ rv = 401;
+ }
+finish:
+ if (certRepContent) {
+ CMMF_DestroyCertRepContent(certRepContent);
+ }
+ if (certResp) {
+ CMMF_DestroyCertResponse(certResp);
+ }
+ return rv;
+}
+
+/* Extract the public key from the cert whose nickname is given. */
+int
+extractPubKeyFromNamedCert(const char *nickname, SECKEYPublicKey **pPubKey)
+{
+ CERTCertificate *caCert = NULL;
+ SECKEYPublicKey *caPubKey = NULL;
+ int rv = 0;
+
+ caCert = CERT_FindCertByNickname(db, (char *)nickname);
+ if (caCert == NULL) {
+ printf("Could not get the certifcate for %s\n", caCertName);
+ rv = 411;
+ goto finish;
+ }
+ caPubKey = CERT_ExtractPublicKey(caCert);
+ if (caPubKey == NULL) {
+ printf("Could not extract the public from the "
+ "certificate for \n%s\n",
+ caCertName);
+ rv = 412;
+ }
+finish:
+ *pPubKey = caPubKey;
+ CERT_DestroyCertificate(caCert);
+ caCert = NULL;
+ return rv;
+}
+
+int
+EncodeCMMFRecoveryMessage(const char *filePath,
+ CERTCertificate *cert,
+ CERTCertList *list)
+{
+ SECKEYPublicKey *caPubKey = NULL;
+ SECKEYPrivateKey *privKey = NULL;
+ CMMFKeyRecRepContent *repContent = NULL;
+ PRFileDesc *fileDesc;
+ int rv = 0;
+ SECStatus srv;
+
+ /* Extract the public key from the cert whose nickname is given in
+ ** the -s option.
+ */
+ rv = extractPubKeyFromNamedCert(caCertName, &caPubKey);
+ if (rv)
+ goto finish;
+
+ repContent = CMMF_CreateKeyRecRepContent();
+ if (repContent == NULL) {
+ printf("Could not allocate a CMMFKeyRecRepContent structure\n");
+ rv = 407;
+ goto finish;
+ }
+ srv = CMMF_KeyRecRepContentSetPKIStatusInfoStatus(repContent,
+ cmmfGrantedWithMods);
+ if (srv != SECSuccess) {
+ printf("Error trying to set PKIStatusInfo for "
+ "CMMFKeyRecRepContent.\n");
+ rv = 406;
+ goto finish;
+ }
+ srv = CMMF_KeyRecRepContentSetNewSignCert(repContent, cert);
+ if (srv != SECSuccess) {
+ printf("Error trying to set the new signing certificate for "
+ "key recovery\n");
+ rv = 408;
+ goto finish;
+ }
+ srv = CMMF_KeyRecRepContentSetCACerts(repContent, list);
+ if (srv != SECSuccess) {
+ printf("Errory trying to add the list of CA certs to the "
+ "CMMFKeyRecRepContent structure.\n");
+ rv = 409;
+ goto finish;
+ }
+ privKey = PK11_FindKeyByAnyCert(cert, &pwdata);
+ if (privKey == NULL) {
+ printf("Could not get the private key associated with the\n"
+ "certificate %s\n",
+ personalCert);
+ rv = 410;
+ goto finish;
+ }
+
+ srv = CMMF_KeyRecRepContentSetCertifiedKeyPair(repContent, cert, privKey,
+ caPubKey);
+ if (srv != SECSuccess) {
+ printf("Could not set the Certified Key Pair\n");
+ rv = 413;
+ goto finish;
+ }
+ fileDesc = PR_Open(filePath, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
+ 0666);
+ if (fileDesc == NULL) {
+ printf("Could not open file %s\n", filePath);
+ rv = 414;
+ goto finish;
+ }
+
+ srv = CMMF_EncodeKeyRecRepContent(repContent, WriteItOut,
+ (void *)fileDesc);
+ PR_Close(fileDesc);
+ if (srv != SECSuccess) {
+ printf("CMMF_EncodeKeyRecRepContent failed\n");
+ rv = 415;
+ }
+finish:
+ if (privKey)
+ SECKEY_DestroyPrivateKey(privKey);
+ if (caPubKey)
+ SECKEY_DestroyPublicKey(caPubKey);
+ if (repContent)
+ CMMF_DestroyKeyRecRepContent(repContent);
+ return rv;
+}
+
+int
+decodeCMMFRecoveryMessage(const char *filePath)
+{
+ CMMFKeyRecRepContent *repContent = NULL;
+ int rv = 0;
+ SECItem fileBits = { siBuffer, NULL, 0 };
+
+ GetBitsFromFile(filePath, &fileBits);
+ if (!fileBits.len) {
+ rv = 451;
+ goto finish;
+ }
+ repContent =
+ CMMF_CreateKeyRecRepContentFromDER(db, (const char *)fileBits.data,
+ fileBits.len);
+ if (repContent == NULL) {
+ printf("ERROR: CMMF_CreateKeyRecRepContentFromDER failed on file:\n"
+ "\t%s\n",
+ filePath);
+ rv = 452;
+ }
+finish:
+ if (repContent) {
+ CMMF_DestroyKeyRecRepContent(repContent);
+ }
+ SECITEM_FreeItem(&fileBits, PR_FALSE);
+ return rv;
+}
+
+int
+DoCMMFStuff(void)
+{
+ CERTCertificate *cert = NULL;
+ CERTCertList *list = NULL;
+ int rv = 0;
+ char filePath[PATH_LEN];
+
+ /* Do common setup for the following steps.
+ */
+ PR_snprintf(filePath, PATH_LEN, "%s/%s", configdir, "CertRepContent.der");
+
+ cert = CERT_FindCertByNickname(db, personalCert);
+ if (cert == NULL) {
+ printf("Could not find the certificate for %s\n", personalCert);
+ rv = 416;
+ goto finish;
+ }
+ list = CERT_GetCertChainFromCert(cert, PR_Now(), certUsageEmailSigner);
+ if (list == NULL) {
+ printf("Could not find the certificate chain for %s\n", personalCert);
+ rv = 418;
+ goto finish;
+ }
+
+ /* a) Generate the CMMF response message, using a user cert named
+ ** by -p option, rather than a cert generated from the CRMF
+ ** request itself. The CMMF message is placed in
+ ** configdir/CertRepContent.der.
+ */
+ rv = EncodeCMMFCertReply(filePath, cert, list);
+ if (rv != 0) {
+ goto finish;
+ }
+
+ /* b) Decode the CMMF Cert granting message encoded just above,
+ ** found in configdir/CertRepContent.der.
+ ** This only tests the decoding. The decoded content is discarded.
+ */
+ rv = DecodeCMMFCertRepContent(filePath);
+ if (rv != 0) {
+ goto finish;
+ }
+
+ /* c) Generate a CMMF Key Excrow message
+ ** It takes the public and private keys for the cert identified
+ ** by -p nickname, and wraps them with a sym key that is in turn
+ ** wrapped with the pubkey in the CA cert, whose nickname is
+ ** given by the -s option.
+ ** Store the message in configdir/KeyRecRepContent.der
+ */
+ PR_snprintf(filePath, PATH_LEN, "%s/%s", configdir,
+ "KeyRecRepContent.der");
+
+ rv = EncodeCMMFRecoveryMessage(filePath, cert, list);
+ if (rv)
+ goto finish;
+
+ /* d) Decode the CMMF Key Excrow message generated just above.
+ ** Get it from file configdir/KeyRecRepContent.der
+ ** This is just a decoder test. Results are discarded.
+ */
+
+ rv = decodeCMMFRecoveryMessage(filePath);
+
+finish:
+ if (cert) {
+ CERT_DestroyCertificate(cert);
+ }
+ if (list) {
+ CERT_DestroyCertList(list);
+ }
+ return rv;
+}
+
+#define KNOWN_MESSAGE_LENGTH 20 /*160 bits*/
+
+int
+DoKeyRecovery(SECKEYPrivateKey *privKey)
+{
+#ifdef DOING_KEY_RECOVERY /* Doesn't compile yet. */
+ SECKEYPublicKey *pubKey;
+ PK11SlotInfo *slot;
+ unsigned char *ciphertext;
+ unsigned char *text_compared;
+ SECKEYPrivateKey *unwrappedPrivKey;
+ SECKEYPrivateKey *caPrivKey;
+ CMMFKeyRecRepContent *keyRecRep;
+ CMMFCertifiedKeyPair *certKeyPair;
+ CERTCertificate *caCert;
+ CERTCertificate *myCert;
+ SECKEYPublicKey *caPubKey;
+ PRFileDesc *fileDesc;
+ CK_ULONG max_bytes_encrypted;
+ CK_ULONG bytes_encrypted;
+ CK_ULONG bytes_compared;
+ CK_ULONG bytes_decrypted;
+ CK_RV crv;
+ CK_OBJECT_HANDLE id;
+ CK_MECHANISM mech = { CKM_INVALID_MECHANISM, NULL, 0 };
+ SECStatus rv;
+ SECItem fileBits;
+ SECItem nickname;
+ unsigned char plaintext[KNOWN_MESSAGE_LENGTH];
+ char filePath[PATH_LEN];
+ static const unsigned char known_message[] = { "Known Crypto Message" };
+
+ /*caCert = CERT_FindCertByNickname(db, caCertName);*/
+ myCert = CERT_FindCertByNickname(db, personalCert);
+ if (myCert == NULL) {
+ printf("Could not find the certificate for %s\n", personalCert);
+ return 700;
+ }
+ caCert = CERT_FindCertByNickname(db, recoveryEncrypter);
+ if (caCert == NULL) {
+ printf("Could not find the certificate for %s\n", recoveryEncrypter);
+ return 701;
+ }
+ caPubKey = CERT_ExtractPublicKey(caCert);
+ pubKey = SECKEY_ConvertToPublicKey(privKey);
+ max_bytes_encrypted = PK11_GetPrivateModulusLen(privKey);
+ slot = PK11_GetBestSlotWithAttributes(mapWrapKeyType(privKey->keyType),
+ CKF_ENCRYPT, 0, NULL);
+ id = PK11_ImportPublicKey(slot, pubKey, PR_FALSE);
+
+ switch (privKey->keyType) {
+ case rsaKey:
+ mech.mechanism = CKM_RSA_PKCS;
+ break;
+ case dsaKey:
+ mech.mechanism = CKM_DSA;
+ break;
+ case dhKey:
+ mech.mechanism = CKM_DH_PKCS_DERIVE;
+ break;
+ default:
+ printf("Bad Key type in key recovery.\n");
+ return 512;
+ }
+ PK11_EnterSlotMonitor(slot);
+ crv = PK11_GETTAB(slot)->C_EncryptInit(slot->session, &mech, id);
+ if (crv != CKR_OK) {
+ PK11_ExitSlotMonitor(slot);
+ PK11_FreeSlot(slot);
+ printf("C_EncryptInit failed in KeyRecovery\n");
+ return 500;
+ }
+ ciphertext = PORT_NewArray(unsigned char, max_bytes_encrypted);
+ if (ciphertext == NULL) {
+ PK11_ExitSlotMonitor(slot);
+ PK11_FreeSlot(slot);
+ printf("Could not allocate memory for ciphertext.\n");
+ return 501;
+ }
+ bytes_encrypted = max_bytes_encrypted;
+ crv = PK11_GETTAB(slot)->C_Encrypt(slot->session,
+ known_message,
+ KNOWN_MESSAGE_LENGTH,
+ ciphertext,
+ &bytes_encrypted);
+ PK11_ExitSlotMonitor(slot);
+ PK11_FreeSlot(slot);
+ if (crv != CKR_OK) {
+ PORT_Free(ciphertext);
+ return 502;
+ }
+ /* Always use the smaller of these two values . . . */
+ bytes_compared = (bytes_encrypted > KNOWN_MESSAGE_LENGTH)
+ ? KNOWN_MESSAGE_LENGTH
+ : bytes_encrypted;
+
+ /* If there was a failure, the plaintext */
+ /* goes at the end, therefore . . . */
+ text_compared = (bytes_encrypted > KNOWN_MESSAGE_LENGTH)
+ ? (ciphertext + bytes_encrypted -
+ KNOWN_MESSAGE_LENGTH)
+ : ciphertext;
+
+ keyRecRep = CMMF_CreateKeyRecRepContent();
+ if (keyRecRep == NULL) {
+ PORT_Free(ciphertext);
+ PK11_FreeSlot(slot);
+ CMMF_DestroyKeyRecRepContent(keyRecRep);
+ printf("Could not allocate a CMMFKeyRecRepContent structre.\n");
+ return 503;
+ }
+ rv = CMMF_KeyRecRepContentSetPKIStatusInfoStatus(keyRecRep,
+ cmmfGranted);
+ if (rv != SECSuccess) {
+ PORT_Free(ciphertext);
+ PK11_FreeSlot(slot);
+ CMMF_DestroyKeyRecRepContent(keyRecRep);
+ printf("Could not set the status for the KeyRecRepContent\n");
+ return 504;
+ }
+ /* The myCert here should correspond to the certificate corresponding
+ * to the private key, but for this test any certificate will do.
+ */
+ rv = CMMF_KeyRecRepContentSetCertifiedKeyPair(keyRecRep, myCert,
+ privKey, caPubKey);
+ if (rv != SECSuccess) {
+ PORT_Free(ciphertext);
+ PK11_FreeSlot(slot);
+ CMMF_DestroyKeyRecRepContent(keyRecRep);
+ printf("Could not set the Certified Key Pair\n");
+ return 505;
+ }
+ PR_snprintf(filePath, PATH_LEN, "%s/%s", configdir,
+ "KeyRecRepContent.der");
+ fileDesc = PR_Open(filePath, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
+ 0666);
+ if (fileDesc == NULL) {
+ PORT_Free(ciphertext);
+ PK11_FreeSlot(slot);
+ CMMF_DestroyKeyRecRepContent(keyRecRep);
+ printf("Could not open file %s\n", filePath);
+ return 506;
+ }
+ rv = CMMF_EncodeKeyRecRepContent(keyRecRep, WriteItOut, fileDesc);
+ CMMF_DestroyKeyRecRepContent(keyRecRep);
+ PR_Close(fileDesc);
+
+ if (rv != SECSuccess) {
+ PORT_Free(ciphertext);
+ PK11_FreeSlot(slot);
+ printf("Error while encoding CMMFKeyRecRepContent\n");
+ return 507;
+ }
+ GetBitsFromFile(filePath, &fileBits);
+ if (fileBits.data == NULL) {
+ PORT_Free(ciphertext);
+ PK11_FreeSlot(slot);
+ printf("Could not get the bits from file %s\n", filePath);
+ return 508;
+ }
+ keyRecRep =
+ CMMF_CreateKeyRecRepContentFromDER(db, (const char *)fileBits.data,
+ fileBits.len);
+ if (keyRecRep == NULL) {
+ printf("Could not decode the KeyRecRepContent in file %s\n",
+ filePath);
+ PORT_Free(ciphertext);
+ PK11_FreeSlot(slot);
+ return 509;
+ }
+ caPrivKey = PK11_FindKeyByAnyCert(caCert, &pwdata);
+ if (CMMF_KeyRecRepContentGetPKIStatusInfoStatus(keyRecRep) !=
+ cmmfGranted) {
+ PORT_Free(ciphertext);
+ PK11_FreeSlot(slot);
+ CMMF_DestroyKeyRecRepContent(keyRecRep);
+ printf("A bad status came back with the "
+ "KeyRecRepContent structure\n");
+ return 510;
+ }
+
+#define NICKNAME "Key Recovery Test Key"
+ nickname.data = (unsigned char *)NICKNAME;
+ nickname.len = PORT_Strlen(NICKNAME);
+
+ certKeyPair = CMMF_KeyRecRepContentGetCertKeyAtIndex(keyRecRep, 0);
+ CMMF_DestroyKeyRecRepContent(keyRecRep);
+ rv = CMMF_CertifiedKeyPairUnwrapPrivKey(certKeyPair,
+ caPrivKey,
+ &nickname,
+ PK11_GetInternalKeySlot(),
+ db,
+ &unwrappedPrivKey, &pwdata);
+ CMMF_DestroyCertifiedKeyPair(certKeyPair);
+ if (rv != SECSuccess) {
+ printf("Unwrapping the private key failed.\n");
+ return 511;
+ }
+ /*Now let's try to decrypt the ciphertext with the "recovered" key*/
+ PK11_EnterSlotMonitor(slot);
+ crv =
+ PK11_GETTAB(slot)->C_DecryptInit(unwrappedPrivKey->pkcs11Slot->session,
+ &mech,
+ unwrappedPrivKey->pkcs11ID);
+ if (crv != CKR_OK) {
+ PK11_ExitSlotMonitor(slot);
+ PORT_Free(ciphertext);
+ PK11_FreeSlot(slot);
+ printf("Decrypting with the recovered key failed.\n");
+ return 513;
+ }
+ bytes_decrypted = KNOWN_MESSAGE_LENGTH;
+ crv = PK11_GETTAB(slot)->C_Decrypt(unwrappedPrivKey->pkcs11Slot->session,
+ ciphertext,
+ bytes_encrypted, plaintext,
+ &bytes_decrypted);
+ SECKEY_DestroyPrivateKey(unwrappedPrivKey);
+ PK11_ExitSlotMonitor(slot);
+ PORT_Free(ciphertext);
+ if (crv != CKR_OK) {
+ PK11_FreeSlot(slot);
+ printf("Decrypting the ciphertext with recovered key failed.\n");
+ return 514;
+ }
+ if ((bytes_decrypted != KNOWN_MESSAGE_LENGTH) ||
+ (PORT_Memcmp(plaintext, known_message, KNOWN_MESSAGE_LENGTH) != 0)) {
+ PK11_FreeSlot(slot);
+ printf("The recovered plaintext does not equal the known message:\n"
+ "\tKnown message: %s\n"
+ "\tRecovered plaintext: %s\n",
+ known_message, plaintext);
+ return 515;
+ }
+#endif
+ return 0;
+}
+
+int
+DoChallengeResponse(SECKEYPrivateKey *privKey,
+ SECKEYPublicKey *pubKey)
+{
+ CMMFPOPODecKeyChallContent *chalContent = NULL;
+ CMMFPOPODecKeyRespContent *respContent = NULL;
+ CERTCertificate *myCert = NULL;
+ CERTGeneralName *myGenName = NULL;
+ PLArenaPool *poolp = NULL;
+ PRFileDesc *fileDesc;
+ SECItem *publicValue;
+ SECItem *keyID;
+ SECKEYPrivateKey *foundPrivKey;
+ long *randomNums;
+ int numChallengesFound = 0;
+ int numChallengesSet = 1;
+ int i;
+ long retrieved;
+ SECStatus rv;
+ SECItem DecKeyChallBits;
+ char filePath[PATH_LEN];
+
+ chalContent = CMMF_CreatePOPODecKeyChallContent();
+ myCert = CERT_FindCertByNickname(db, personalCert);
+ if (myCert == NULL) {
+ printf("Could not find the certificate for %s\n", personalCert);
+ return 900;
+ }
+ poolp = PORT_NewArena(1024);
+ if (poolp == NULL) {
+ printf("Could no allocate a new arena in DoChallengeResponse\n");
+ return 901;
+ }
+ myGenName = CERT_GetCertificateNames(myCert, poolp);
+ if (myGenName == NULL) {
+ printf("Could not get the general names for %s certificate\n",
+ personalCert);
+ return 902;
+ }
+ randomNums = PORT_ArenaNewArray(poolp, long, numChallengesSet);
+ PK11_GenerateRandom((unsigned char *)randomNums,
+ numChallengesSet * sizeof(long));
+ for (i = 0; i < numChallengesSet; i++) {
+ rv = CMMF_POPODecKeyChallContentSetNextChallenge(chalContent,
+ randomNums[i],
+ myGenName,
+ pubKey,
+ &pwdata);
+ if (rv != SECSuccess) {
+ printf("Could not set the challenge in DoChallengeResponse\n");
+ return 903;
+ }
+ }
+ PR_snprintf(filePath, PATH_LEN, "%s/POPODecKeyChallContent.der",
+ configdir);
+ fileDesc = PR_Open(filePath, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
+ 0666);
+ if (fileDesc == NULL) {
+ printf("Could not open file %s\n", filePath);
+ return 904;
+ }
+ rv = CMMF_EncodePOPODecKeyChallContent(chalContent, WriteItOut,
+ (void *)fileDesc);
+ PR_Close(fileDesc);
+ CMMF_DestroyPOPODecKeyChallContent(chalContent);
+ if (rv != SECSuccess) {
+ printf("Could not encode the POPODecKeyChallContent.\n");
+ return 905;
+ }
+ GetBitsFromFile(filePath, &DecKeyChallBits);
+ chalContent = CMMF_CreatePOPODecKeyChallContentFromDER((const char *)DecKeyChallBits.data, DecKeyChallBits.len);
+ SECITEM_FreeItem(&DecKeyChallBits, PR_FALSE);
+ if (chalContent == NULL) {
+ printf("Could not create the POPODecKeyChallContent from DER\n");
+ return 906;
+ }
+ numChallengesFound =
+ CMMF_POPODecKeyChallContentGetNumChallenges(chalContent);
+ if (numChallengesFound != numChallengesSet) {
+ printf("Number of Challenges Found (%d) does not equal the number "
+ "set (%d)\n",
+ numChallengesFound, numChallengesSet);
+ return 907;
+ }
+ for (i = 0; i < numChallengesSet; i++) {
+ publicValue = CMMF_POPODecKeyChallContentGetPublicValue(chalContent, i);
+ if (publicValue == NULL) {
+ printf("Could not get the public value for challenge at index %d\n",
+ i);
+ return 908;
+ }
+ keyID = PK11_MakeIDFromPubKey(publicValue);
+ if (keyID == NULL) {
+ printf("Could not make the keyID from the public value\n");
+ return 909;
+ }
+ foundPrivKey = PK11_FindKeyByKeyID(privKey->pkcs11Slot, keyID, &pwdata);
+ if (foundPrivKey == NULL) {
+ printf("Could not find the private key corresponding to the public"
+ " value.\n");
+ return 910;
+ }
+ rv = CMMF_POPODecKeyChallContDecryptChallenge(chalContent, i,
+ foundPrivKey);
+ if (rv != SECSuccess) {
+ printf("Could not decrypt the challenge at index %d\n", i);
+ return 911;
+ }
+ rv = CMMF_POPODecKeyChallContentGetRandomNumber(chalContent, i,
+ &retrieved);
+ if (rv != SECSuccess) {
+ printf("Could not get the random number from the challenge at "
+ "index %d\n",
+ i);
+ return 912;
+ }
+ if (retrieved != randomNums[i]) {
+ printf("Retrieved the number (%ld), expected (%ld)\n", retrieved,
+ randomNums[i]);
+ return 913;
+ }
+ }
+ CMMF_DestroyPOPODecKeyChallContent(chalContent);
+ PR_snprintf(filePath, PATH_LEN, "%s/POPODecKeyRespContent.der",
+ configdir);
+ fileDesc = PR_Open(filePath, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
+ 0666);
+ if (fileDesc == NULL) {
+ printf("Could not open file %s\n", filePath);
+ return 914;
+ }
+ rv = CMMF_EncodePOPODecKeyRespContent(randomNums, numChallengesSet,
+ WriteItOut, fileDesc);
+ PR_Close(fileDesc);
+ if (rv != 0) {
+ printf("Could not encode the POPODecKeyRespContent\n");
+ return 915;
+ }
+ GetBitsFromFile(filePath, &DecKeyChallBits);
+ respContent =
+ CMMF_CreatePOPODecKeyRespContentFromDER((const char *)DecKeyChallBits.data,
+ DecKeyChallBits.len);
+ if (respContent == NULL) {
+ printf("Could not decode the contents of the file %s\n", filePath);
+ return 916;
+ }
+ numChallengesFound =
+ CMMF_POPODecKeyRespContentGetNumResponses(respContent);
+ if (numChallengesFound != numChallengesSet) {
+ printf("Number of responses found (%d) does not match the number "
+ "of challenges set (%d)\n",
+ numChallengesFound, numChallengesSet);
+ return 917;
+ }
+ for (i = 0; i < numChallengesSet; i++) {
+ rv = CMMF_POPODecKeyRespContentGetResponse(respContent, i, &retrieved);
+ if (rv != SECSuccess) {
+ printf("Could not retrieve the response at index %d\n", i);
+ return 918;
+ }
+ if (retrieved != randomNums[i]) {
+ printf("Retrieved the number (%ld), expected (%ld)\n", retrieved,
+ randomNums[i]);
+ return 919;
+ }
+ }
+ CMMF_DestroyPOPODecKeyRespContent(respContent);
+ return 0;
+}
+
+int
+MakeCertRequest(TESTKeyPair *pair, CRMFPOPChoice inPOPChoice, long inRequestID)
+{
+ int irv;
+
+ /* Generate a key pair and a cert request for it. */
+ irv = CreateCertRequest(pair, inRequestID);
+ if (irv != 0 || pair->certReq == NULL) {
+ goto loser;
+ }
+
+ pair->certReqMsg = CRMF_CreateCertReqMsg();
+ if (!pair->certReqMsg) {
+ irv = 999;
+ goto loser;
+ }
+ /* copy certReq into certReqMsg */
+ CRMF_CertReqMsgSetCertRequest(pair->certReqMsg, pair->certReq);
+ irv = AddProofOfPossession(pair, inPOPChoice);
+loser:
+ return irv;
+}
+
+int
+DestroyPairReqAndMsg(TESTKeyPair *pair)
+{
+ SECStatus rv = SECSuccess;
+ int irv = 0;
+
+ if (pair->certReq) {
+ rv = CRMF_DestroyCertRequest(pair->certReq);
+ pair->certReq = NULL;
+ if (rv != SECSuccess) {
+ printf("Error when destroying cert request.\n");
+ irv = 100;
+ }
+ }
+ if (pair->certReqMsg) {
+ rv = CRMF_DestroyCertReqMsg(pair->certReqMsg);
+ pair->certReqMsg = NULL;
+ if (rv != SECSuccess) {
+ printf("Error when destroying cert request msg.\n");
+ if (!irv)
+ irv = 101;
+ }
+ }
+ return irv;
+}
+
+int
+DestroyPair(TESTKeyPair *pair)
+{
+ int irv = 0;
+
+ if (pair->pubKey) {
+ SECKEY_DestroyPublicKey(pair->pubKey);
+ pair->pubKey = NULL;
+ }
+ if (pair->privKey) {
+ SECKEY_DestroyPrivateKey(pair->privKey);
+ pair->privKey = NULL;
+ }
+ DestroyPairReqAndMsg(pair);
+ return irv;
+}
+
+int
+DoCRMFRequest(TESTKeyPair *signPair, TESTKeyPair *cryptPair)
+{
+ int irv, tirv = 0;
+
+ /* Generate a key pair and a cert request for it. */
+ irv = MakeCertRequest(signPair, crmfSignature, 0x0f020304);
+ if (irv != 0 || signPair->certReq == NULL) {
+ goto loser;
+ }
+
+ if (!doingDSA) {
+ irv = MakeCertRequest(cryptPair, crmfKeyAgreement, 0x0f050607);
+ if (irv != 0 || cryptPair->certReq == NULL) {
+ goto loser;
+ }
+ }
+
+ /* encode the cert request messages into a unified request message.
+ ** leave it in a file with a fixed name. :(
+ */
+ irv = Encode(signPair->certReqMsg, cryptPair->certReqMsg);
+
+loser:
+ if (signPair->certReq) {
+ tirv = DestroyPairReqAndMsg(signPair);
+ if (tirv && !irv)
+ irv = tirv;
+ }
+ if (cryptPair->certReq) {
+ tirv = DestroyPairReqAndMsg(cryptPair);
+ if (tirv && !irv)
+ irv = tirv;
+ }
+ return irv;
+}
+
+void
+Usage(void)
+{
+ printf("Usage:\n"
+ "\tcrmftest -d [Database Directory] -p [Personal Cert]\n"
+ "\t -e [Encrypter] -s [CA Certificate] [-P password]\n\n"
+ "\t [crmf] [dsa] [decode] [cmmf] [recover] [challenge]\n"
+ "\t [-f password_file]\n"
+ "Database Directory\n"
+ "\tThis is the directory where the key3.db, cert7.db, and\n"
+ "\tsecmod.db files are located. This is also the directory\n"
+ "\twhere the program will place CRMF/CMMF der files\n"
+ "Personal Cert\n"
+ "\tThis is the certificate that already exists in the cert\n"
+ "\tdatabase to use while encoding the response. The private\n"
+ "\tkey associated with the certificate must also exist in the\n"
+ "\tkey database.\n"
+ "Encrypter\n"
+ "\tThis is the certificate to use when encrypting the the \n"
+ "\tkey recovery response. The private key for this cert\n"
+ "\tmust also be present in the key database.\n"
+ "CA Certificate\n"
+ "\tThis is the nickname of the certificate to use as the\n"
+ "\tCA when doing all of the encoding.\n");
+}
+
+#define TEST_MAKE_CRMF_REQ 0x0001
+#define TEST_USE_DSA 0x0002
+#define TEST_DECODE_CRMF_REQ 0x0004
+#define TEST_DO_CMMF_STUFF 0x0008
+#define TEST_KEY_RECOVERY 0x0010
+#define TEST_CHALLENGE_RESPONSE 0x0020
+
+SECStatus
+parsePositionalParam(const char *arg, PRUint32 *flags)
+{
+ if (!strcmp(arg, "crmf")) {
+ *flags |= TEST_MAKE_CRMF_REQ;
+ } else if (!strcmp(arg, "dsa")) {
+ *flags |= TEST_MAKE_CRMF_REQ | TEST_USE_DSA;
+ doingDSA = PR_TRUE;
+ } else if (!strcmp(arg, "decode")) {
+ *flags |= TEST_DECODE_CRMF_REQ;
+ } else if (!strcmp(arg, "cmmf")) {
+ *flags |= TEST_DO_CMMF_STUFF;
+ } else if (!strcmp(arg, "recover")) {
+ *flags |= TEST_KEY_RECOVERY;
+ } else if (!strcmp(arg, "challenge")) {
+ *flags |= TEST_CHALLENGE_RESPONSE;
+ } else {
+ printf("unknown positional paremeter: %s\n", arg);
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+/* it's not clear, in some cases, whether the desired key is from
+** the sign pair or the crypt pair, so we're guessing in some places.
+** This define serves to remind us of the places where we're guessing.
+*/
+#define WHICH_KEY cryptPair
+
+int
+main(int argc, char **argv)
+{
+ TESTKeyPair signPair, cryptPair;
+ PLOptState *optstate;
+ PLOptStatus status;
+ char *password = NULL;
+ char *pwfile = NULL;
+ int irv = 0;
+ PRUint32 flags = 0;
+ SECStatus rv;
+ PRBool nssInit = PR_FALSE;
+
+ memset(&signPair, 0, sizeof signPair);
+ memset(&cryptPair, 0, sizeof cryptPair);
+ printf("\ncrmftest v1.0\n");
+ optstate = PL_CreateOptState(argc, argv, "d:p:e:s:P:f:");
+ while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
+ switch (optstate->option) {
+ case 'd':
+ configdir = PORT_Strdup(optstate->value);
+ rv = NSS_Init(configdir);
+ if (rv != SECSuccess) {
+ printf("NSS_Init (-d) failed\n");
+ return 101;
+ }
+ nssInit = PR_TRUE;
+ break;
+ case 'p':
+ personalCert = PORT_Strdup(optstate->value);
+ if (personalCert == NULL) {
+ printf("-p failed\n");
+ return 603;
+ }
+ break;
+ case 'e':
+ recoveryEncrypter = PORT_Strdup(optstate->value);
+ if (recoveryEncrypter == NULL) {
+ printf("-e failed\n");
+ return 602;
+ }
+ break;
+ case 's':
+ caCertName = PORT_Strdup(optstate->value);
+ if (caCertName == NULL) {
+ printf("-s failed\n");
+ return 604;
+ }
+ break;
+ case 'P':
+ password = PORT_Strdup(optstate->value);
+ if (password == NULL) {
+ printf("-P failed\n");
+ return 606;
+ }
+ pwdata.source = PW_PLAINTEXT;
+ pwdata.data = password;
+ break;
+ case 'f':
+ pwfile = PORT_Strdup(optstate->value);
+ if (pwfile == NULL) {
+ printf("-f failed\n");
+ return 607;
+ }
+ pwdata.source = PW_FROMFILE;
+ pwdata.data = pwfile;
+ break;
+ case 0: /* positional parameter */
+ rv = parsePositionalParam(optstate->value, &flags);
+ if (rv) {
+ printf("bad positional parameter.\n");
+ return 605;
+ }
+ break;
+ default:
+ Usage();
+ return 601;
+ }
+ }
+ PL_DestroyOptState(optstate);
+ if (status == PL_OPT_BAD || !nssInit) {
+ Usage();
+ return 600;
+ }
+ if (!flags)
+ flags = ~TEST_USE_DSA;
+ db = CERT_GetDefaultCertDB();
+ InitPKCS11();
+
+ if (flags & TEST_MAKE_CRMF_REQ) {
+ printf("Generating CRMF request\n");
+ irv = DoCRMFRequest(&signPair, &cryptPair);
+ if (irv)
+ goto loser;
+ }
+
+ if (flags & TEST_DECODE_CRMF_REQ) {
+ printf("Decoding CRMF request\n");
+ irv = Decode();
+ if (irv != 0) {
+ printf("Error while decoding\n");
+ goto loser;
+ }
+ }
+
+ if (flags & TEST_DO_CMMF_STUFF) {
+ printf("Doing CMMF Stuff\n");
+ if ((irv = DoCMMFStuff()) != 0) {
+ printf("CMMF tests failed.\n");
+ goto loser;
+ }
+ }
+
+ if (flags & TEST_KEY_RECOVERY) {
+ /* Requires some other options be set.
+ ** Once we know exactly what hey are, test for them here.
+ */
+ printf("Doing Key Recovery\n");
+ irv = DoKeyRecovery(WHICH_KEY.privKey);
+ if (irv != 0) {
+ printf("Error doing key recovery\n");
+ goto loser;
+ }
+ }
+
+ if (flags & TEST_CHALLENGE_RESPONSE) {
+ printf("Doing Challenge / Response\n");
+ irv = DoChallengeResponse(WHICH_KEY.privKey, WHICH_KEY.pubKey);
+ if (irv != 0) {
+ printf("Error doing challenge-response\n");
+ goto loser;
+ }
+ }
+ printf("Exiting successfully!!!\n\n");
+ irv = 0;
+
+loser:
+ DestroyPair(&signPair);
+ DestroyPair(&cryptPair);
+ rv = NSS_Shutdown();
+ if (rv) {
+ printf("NSS_Shutdown did not shutdown cleanly!\n");
+ }
+ PORT_Free(configdir);
+ if (irv)
+ printf("crmftest returning %d\n", irv);
+ return irv;
+}
diff --git a/nss/cmd/dbck/Makefile b/nss/cmd/dbck/Makefile
new file mode 100644
index 0000000..ea1d2f4
--- /dev/null
+++ b/nss/cmd/dbck/Makefile
@@ -0,0 +1,47 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include ../platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+INCLUDES += -I ../../lib/softoken
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+
+include ../platrules.mk
+
diff --git a/nss/cmd/dbck/dbck.c b/nss/cmd/dbck/dbck.c
new file mode 100644
index 0000000..6791a0d
--- /dev/null
+++ b/nss/cmd/dbck/dbck.c
@@ -0,0 +1,1350 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+** dbck.c
+**
+** utility for fixing corrupt cert databases
+**
+*/
+#include
+#include
+
+#include "secutil.h"
+#include "cdbhdl.h"
+#include "certdb.h"
+#include "cert.h"
+#include "nspr.h"
+#include "prtypes.h"
+#include "prtime.h"
+#include "prlong.h"
+#include "pcert.h"
+#include "nss.h"
+
+static char *progName;
+
+/* placeholders for pointer error types */
+static void *WrongEntry;
+static void *NoNickname;
+static void *NoSMime;
+
+typedef enum {
+ /* 0*/ NoSubjectForCert = 0,
+ /* 1*/ SubjectHasNoKeyForCert,
+ /* 2*/ NoNicknameOrSMimeForSubject,
+ /* 3*/ WrongNicknameForSubject,
+ /* 4*/ NoNicknameEntry,
+ /* 5*/ WrongSMimeForSubject,
+ /* 6*/ NoSMimeEntry,
+ /* 7*/ NoSubjectForNickname,
+ /* 8*/ NoSubjectForSMime,
+ /* 9*/ NicknameAndSMimeEntries,
+ NUM_ERROR_TYPES
+} dbErrorType;
+
+static char *dbErrorString[NUM_ERROR_TYPES] = {
+ /* 0*/ "\nDid not find a subject entry for this certificate.",
+ /* 1*/ "\nSubject has certKey which is not in db.",
+ /* 2*/ "\nSubject does not have a nickname or email address.",
+ /* 3*/ "\nUsing this subject's nickname, found a nickname entry for a different subject.",
+ /* 4*/ "\nDid not find a nickname entry for this subject.",
+ /* 5*/ "\nUsing this subject's email, found an S/MIME entry for a different subject.",
+ /* 6*/ "\nDid not find an S/MIME entry for this subject.",
+ /* 7*/ "\nDid not find a subject entry for this nickname.",
+ /* 8*/ "\nDid not find a subject entry for this S/MIME profile.",
+};
+
+static char *errResult[NUM_ERROR_TYPES] = {
+ "Certificate entries that had no subject entry.",
+ "Subject entries with no corresponding Certificate entries.",
+ "Subject entries that had no nickname or S/MIME entries.",
+ "Redundant nicknames (subjects with the same nickname).",
+ "Subject entries that had no nickname entry.",
+ "Redundant email addresses (subjects with the same email address).",
+ "Subject entries that had no S/MIME entry.",
+ "Nickname entries that had no subject entry.",
+ "S/MIME entries that had no subject entry.",
+ "Subject entries with BOTH nickname and S/MIME entries."
+};
+
+enum {
+ GOBOTH = 0,
+ GORIGHT,
+ GOLEFT
+};
+
+typedef struct
+{
+ PRBool verbose;
+ PRBool dograph;
+ PRFileDesc *out;
+ PRFileDesc *graphfile;
+ int dbErrors[NUM_ERROR_TYPES];
+} dbDebugInfo;
+
+struct certDBEntryListNodeStr {
+ PRCList link;
+ certDBEntry entry;
+ void *appData;
+};
+typedef struct certDBEntryListNodeStr certDBEntryListNode;
+
+/*
+ * A list node for a cert db entry. The index is a unique identifier
+ * to use for creating generic maps of a db. This struct handles
+ * the cert, nickname, and smime db entry types, as all three have a
+ * single handle to a subject entry.
+ * This structure is pointed to by certDBEntryListNode->appData.
+ */
+typedef struct
+{
+ PLArenaPool *arena;
+ int index;
+ certDBEntryListNode *pSubject;
+} certDBEntryMap;
+
+/*
+ * Subject entry is special case, it has bidirectional handles. One
+ * subject entry can point to several certs (using the same DN), and
+ * a nickname and/or smime entry.
+ * This structure is pointed to by certDBEntryListNode->appData.
+ */
+typedef struct
+{
+ PLArenaPool *arena;
+ int index;
+ int numCerts;
+ certDBEntryListNode **pCerts;
+ certDBEntryListNode *pNickname;
+ certDBEntryListNode *pSMime;
+} certDBSubjectEntryMap;
+
+/*
+ * A map of a certdb.
+ */
+typedef struct
+{
+ int numCerts;
+ int numSubjects;
+ int numNicknames;
+ int numSMime;
+ int numRevocation;
+ certDBEntryListNode certs; /* pointer to head of cert list */
+ certDBEntryListNode subjects; /* pointer to head of subject list */
+ certDBEntryListNode nicknames; /* pointer to head of nickname list */
+ certDBEntryListNode smime; /* pointer to head of smime list */
+ certDBEntryListNode revocation; /* pointer to head of revocation list */
+} certDBArray;
+
+/* Cast list to the base element, a certDBEntryListNode. */
+#define LISTNODE_CAST(node) \
+ ((certDBEntryListNode *)(node))
+
+static void
+Usage(char *progName)
+{
+#define FPS fprintf(stderr,
+ FPS "Type %s -H for more detailed descriptions\n", progName);
+ FPS "Usage: %s -D [-d certdir] [-m] [-v [-f dumpfile]]\n",
+ progName);
+#ifdef DORECOVER
+ FPS " %s -R -o newdbname [-d certdir] [-aprsx] [-v [-f dumpfile]]\n",
+ progName);
+#endif
+ exit(-1);
+}
+
+static void
+LongUsage(char *progName)
+{
+ FPS "%-15s Display this help message.\n",
+ "-H");
+ FPS "%-15s Dump analysis. No changes will be made to the database.\n",
+ "-D");
+ FPS "%-15s Cert database directory (default is ~/.netscape)\n",
+ " -d certdir");
+ FPS "%-15s Put database graph in ./mailfile (default is stdout).\n",
+ " -m");
+ FPS "%-15s Verbose mode. Dumps the entire contents of your cert8.db.\n",
+ " -v");
+ FPS "%-15s File to dump verbose output into. (default is stdout)\n",
+ " -f dumpfile");
+#ifdef DORECOVER
+ FPS "%-15s Repair the database. The program will look for broken\n",
+ "-R");
+ FPS "%-15s dependencies between subject entries and certificates,\n",
+ "");
+ FPS "%-15s between nickname entries and subjects, and between SMIME\n",
+ "");
+ FPS "%-15s profiles and subjects. Any duplicate entries will be\n",
+ "");
+ FPS "%-15s removed, any missing entries will be created.\n",
+ "");
+ FPS "%-15s File to store new database in (default is new_cert8.db)\n",
+ " -o newdbname");
+ FPS "%-15s Cert database directory (default is ~/.netscape)\n",
+ " -d certdir");
+ FPS "%-15s Prompt before removing any certificates.\n",
+ " -p");
+ FPS "%-15s Keep all possible certificates. Only remove certificates\n",
+ " -a");
+ FPS "%-15s which prevent creation of a consistent database. Thus any\n",
+ "");
+ FPS "%-15s expired or redundant entries will be kept.\n",
+ "");
+ FPS "%-15s Keep redundant nickname/email entries. It is possible\n",
+ " -r");
+ FPS "%-15s only one such entry will be usable.\n",
+ "");
+ FPS "%-15s Don't require an S/MIME profile in order to keep an S/MIME\n",
+ " -s");
+ FPS "%-15s cert. An empty profile will be created.\n",
+ "");
+ FPS "%-15s Keep expired certificates.\n",
+ " -x");
+ FPS "%-15s Verbose mode - report all activity while recovering db.\n",
+ " -v");
+ FPS "%-15s File to dump verbose output into.\n",
+ " -f dumpfile");
+ FPS "\n");
+#endif
+ exit(-1);
+#undef FPS
+}
+
+/*******************************************************************
+ *
+ * Functions for dbck.
+ *
+ ******************************************************************/
+
+void
+printHexString(PRFileDesc *out, SECItem *hexval)
+{
+ unsigned int i;
+ for (i = 0; i < hexval->len; i++) {
+ if (i != hexval->len - 1) {
+ PR_fprintf(out, "%02x:", hexval->data[i]);
+ } else {
+ PR_fprintf(out, "%02x", hexval->data[i]);
+ }
+ }
+ PR_fprintf(out, "\n");
+}
+
+SECStatus
+dumpCertificate(CERTCertificate *cert, int num, PRFileDesc *outfile)
+{
+ int userCert = 0;
+ CERTCertTrust *trust = cert->trust;
+ userCert = (SEC_GET_TRUST_FLAGS(trust, trustSSL) & CERTDB_USER) ||
+ (SEC_GET_TRUST_FLAGS(trust, trustEmail) & CERTDB_USER) ||
+ (SEC_GET_TRUST_FLAGS(trust, trustObjectSigning) & CERTDB_USER);
+ if (num >= 0) {
+ PR_fprintf(outfile, "Certificate: %3d\n", num);
+ } else {
+ PR_fprintf(outfile, "Certificate:\n");
+ }
+ PR_fprintf(outfile, "----------------\n");
+ if (userCert)
+ PR_fprintf(outfile, "(User Cert)\n");
+ PR_fprintf(outfile, "## SUBJECT: %s\n", cert->subjectName);
+ PR_fprintf(outfile, "## ISSUER: %s\n", cert->issuerName);
+ PR_fprintf(outfile, "## SERIAL NUMBER: ");
+ printHexString(outfile, &cert->serialNumber);
+ { /* XXX should be separate function. */
+ PRTime timeBefore, timeAfter;
+ PRExplodedTime beforePrintable, afterPrintable;
+ char *beforestr, *afterstr;
+ DER_DecodeTimeChoice(&timeBefore, &cert->validity.notBefore);
+ DER_DecodeTimeChoice(&timeAfter, &cert->validity.notAfter);
+ PR_ExplodeTime(timeBefore, PR_GMTParameters, &beforePrintable);
+ PR_ExplodeTime(timeAfter, PR_GMTParameters, &afterPrintable);
+ beforestr = PORT_Alloc(100);
+ afterstr = PORT_Alloc(100);
+ PR_FormatTime(beforestr, 100, "%a %b %d %H:%M:%S %Y", &beforePrintable);
+ PR_FormatTime(afterstr, 100, "%a %b %d %H:%M:%S %Y", &afterPrintable);
+ PR_fprintf(outfile, "## VALIDITY: %s to %s\n", beforestr, afterstr);
+ }
+ PR_fprintf(outfile, "\n");
+ return SECSuccess;
+}
+
+SECStatus
+dumpCertEntry(certDBEntryCert *entry, int num, PRFileDesc *outfile)
+{
+#if 0
+ NSSLOWCERTCertificate *cert;
+ /* should we check for existing duplicates? */
+ cert = nsslowcert_DecodeDERCertificate(&entry->cert.derCert,
+ entry->cert.nickname);
+#else
+ CERTCertificate *cert;
+ cert = CERT_DecodeDERCertificate(&entry->derCert, PR_FALSE, NULL);
+#endif
+ if (!cert) {
+ fprintf(stderr, "Failed to decode certificate.\n");
+ return SECFailure;
+ }
+ cert->trust = (CERTCertTrust *)&entry->trust;
+ dumpCertificate(cert, num, outfile);
+ CERT_DestroyCertificate(cert);
+ return SECSuccess;
+}
+
+SECStatus
+dumpSubjectEntry(certDBEntrySubject *entry, int num, PRFileDesc *outfile)
+{
+ char *subjectName = CERT_DerNameToAscii(&entry->derSubject);
+
+ PR_fprintf(outfile, "Subject: %3d\n", num);
+ PR_fprintf(outfile, "------------\n");
+ PR_fprintf(outfile, "## %s\n", subjectName);
+ if (entry->nickname)
+ PR_fprintf(outfile, "## Subject nickname: %s\n", entry->nickname);
+ if (entry->emailAddrs) {
+ unsigned int n;
+ for (n = 0; n < entry->nemailAddrs && entry->emailAddrs[n]; ++n) {
+ char *emailAddr = entry->emailAddrs[n];
+ if (emailAddr[0]) {
+ PR_fprintf(outfile, "## Subject email address: %s\n",
+ emailAddr);
+ }
+ }
+ }
+ PR_fprintf(outfile, "## This subject has %d cert(s).\n", entry->ncerts);
+ PR_fprintf(outfile, "\n");
+ PORT_Free(subjectName);
+ return SECSuccess;
+}
+
+SECStatus
+dumpNicknameEntry(certDBEntryNickname *entry, int num, PRFileDesc *outfile)
+{
+ PR_fprintf(outfile, "Nickname: %3d\n", num);
+ PR_fprintf(outfile, "-------------\n");
+ PR_fprintf(outfile, "## \"%s\"\n\n", entry->nickname);
+ return SECSuccess;
+}
+
+SECStatus
+dumpSMimeEntry(certDBEntrySMime *entry, int num, PRFileDesc *outfile)
+{
+ PR_fprintf(outfile, "S/MIME Profile: %3d\n", num);
+ PR_fprintf(outfile, "-------------------\n");
+ PR_fprintf(outfile, "## \"%s\"\n", entry->emailAddr);
+#ifdef OLDWAY
+ PR_fprintf(outfile, "## OPTIONS: ");
+ printHexString(outfile, &entry->smimeOptions);
+ PR_fprintf(outfile, "## TIMESTAMP: ");
+ printHexString(outfile, &entry->optionsDate);
+#else
+ SECU_PrintAny(stdout, &entry->smimeOptions, "## OPTIONS ", 0);
+ fflush(stdout);
+ if (entry->optionsDate.len && entry->optionsDate.data)
+ PR_fprintf(outfile, "## TIMESTAMP: %.*s\n",
+ entry->optionsDate.len, entry->optionsDate.data);
+#endif
+ PR_fprintf(outfile, "\n");
+ return SECSuccess;
+}
+
+SECStatus
+mapCertEntries(certDBArray *dbArray)
+{
+ certDBEntryCert *certEntry;
+ certDBEntrySubject *subjectEntry;
+ certDBEntryListNode *certNode, *subjNode;
+ certDBSubjectEntryMap *smap;
+ certDBEntryMap *map;
+ PLArenaPool *tmparena;
+ SECItem derSubject;
+ SECItem certKey;
+ PRCList *cElem, *sElem;
+
+ /* Arena for decoded entries */
+ tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (tmparena == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return SECFailure;
+ }
+
+ /* Iterate over cert entries and map them to subject entries.
+ * NOTE: mapSubjectEntries must be called first to alloc memory
+ * for array of subject->cert map.
+ */
+ for (cElem = PR_LIST_HEAD(&dbArray->certs.link);
+ cElem != &dbArray->certs.link; cElem = PR_NEXT_LINK(cElem)) {
+ certNode = LISTNODE_CAST(cElem);
+ certEntry = (certDBEntryCert *)&certNode->entry;
+ map = (certDBEntryMap *)certNode->appData;
+ CERT_NameFromDERCert(&certEntry->derCert, &derSubject);
+ CERT_KeyFromDERCert(tmparena, &certEntry->derCert, &certKey);
+ /* Loop over found subjects for cert's DN. */
+ for (sElem = PR_LIST_HEAD(&dbArray->subjects.link);
+ sElem != &dbArray->subjects.link; sElem = PR_NEXT_LINK(sElem)) {
+ subjNode = LISTNODE_CAST(sElem);
+ subjectEntry = (certDBEntrySubject *)&subjNode->entry;
+ if (SECITEM_ItemsAreEqual(&derSubject, &subjectEntry->derSubject)) {
+ unsigned int i;
+ /* Found matching subject name, create link. */
+ map->pSubject = subjNode;
+ /* Make sure subject entry has cert's key. */
+ for (i = 0; i < subjectEntry->ncerts; i++) {
+ if (SECITEM_ItemsAreEqual(&certKey,
+ &subjectEntry->certKeys[i])) {
+ /* Found matching cert key. */
+ smap = (certDBSubjectEntryMap *)subjNode->appData;
+ smap->pCerts[i] = certNode;
+ break;
+ }
+ }
+ }
+ }
+ }
+ PORT_FreeArena(tmparena, PR_FALSE);
+ return SECSuccess;
+}
+
+SECStatus
+mapSubjectEntries(certDBArray *dbArray)
+{
+ certDBEntrySubject *subjectEntry;
+ certDBEntryListNode *subjNode;
+ certDBSubjectEntryMap *subjMap;
+ PRCList *sElem;
+
+ for (sElem = PR_LIST_HEAD(&dbArray->subjects.link);
+ sElem != &dbArray->subjects.link; sElem = PR_NEXT_LINK(sElem)) {
+ /* Iterate over subject entries and map subjects to nickname
+ * and smime entries. The cert<->subject map will be handled
+ * by a subsequent call to mapCertEntries.
+ */
+ subjNode = LISTNODE_CAST(sElem);
+ subjectEntry = (certDBEntrySubject *)&subjNode->entry;
+ subjMap = (certDBSubjectEntryMap *)subjNode->appData;
+ /* need to alloc memory here for array of matching certs. */
+ subjMap->pCerts = PORT_ArenaAlloc(subjMap->arena,
+ subjectEntry->ncerts * sizeof(int));
+ subjMap->numCerts = subjectEntry->ncerts;
+ subjMap->pNickname = NoNickname;
+ subjMap->pSMime = NoSMime;
+
+ if (subjectEntry->nickname) {
+ /* Subject should have a nickname entry, so create a link. */
+ PRCList *nElem;
+ for (nElem = PR_LIST_HEAD(&dbArray->nicknames.link);
+ nElem != &dbArray->nicknames.link;
+ nElem = PR_NEXT_LINK(nElem)) {
+ certDBEntryListNode *nickNode;
+ certDBEntryNickname *nicknameEntry;
+ /* Look for subject's nickname in nickname entries. */
+ nickNode = LISTNODE_CAST(nElem);
+ nicknameEntry = (certDBEntryNickname *)&nickNode->entry;
+ if (PL_strcmp(subjectEntry->nickname,
+ nicknameEntry->nickname) == 0) {
+ /* Found a nickname entry for subject's nickname. */
+ if (SECITEM_ItemsAreEqual(&subjectEntry->derSubject,
+ &nicknameEntry->subjectName)) {
+ certDBEntryMap *nickMap;
+ nickMap = (certDBEntryMap *)nickNode->appData;
+ /* Nickname and subject match. */
+ subjMap->pNickname = nickNode;
+ nickMap->pSubject = subjNode;
+ } else if (subjMap->pNickname == NoNickname) {
+ /* Nickname entry found is for diff. subject. */
+ subjMap->pNickname = WrongEntry;
+ }
+ }
+ }
+ }
+ if (subjectEntry->emailAddrs) {
+ unsigned int n;
+ for (n = 0; n < subjectEntry->nemailAddrs &&
+ subjectEntry->emailAddrs[n];
+ ++n) {
+ char *emailAddr = subjectEntry->emailAddrs[n];
+ if (emailAddr[0]) {
+ PRCList *mElem;
+ /* Subject should have an smime entry, so create a link. */
+ for (mElem = PR_LIST_HEAD(&dbArray->smime.link);
+ mElem != &dbArray->smime.link;
+ mElem = PR_NEXT_LINK(mElem)) {
+ certDBEntryListNode *smimeNode;
+ certDBEntrySMime *smimeEntry;
+ /* Look for subject's email in S/MIME entries. */
+ smimeNode = LISTNODE_CAST(mElem);
+ smimeEntry = (certDBEntrySMime *)&smimeNode->entry;
+ if (PL_strcmp(emailAddr,
+ smimeEntry->emailAddr) == 0) {
+ /* Found a S/MIME entry for subject's email. */
+ if (SECITEM_ItemsAreEqual(
+ &subjectEntry->derSubject,
+ &smimeEntry->subjectName)) {
+ certDBEntryMap *smimeMap;
+ /* S/MIME entry and subject match. */
+ subjMap->pSMime = smimeNode;
+ smimeMap = (certDBEntryMap *)smimeNode->appData;
+ smimeMap->pSubject = subjNode;
+ } else if (subjMap->pSMime == NoSMime) {
+ /* S/MIME entry found is for diff. subject. */
+ subjMap->pSMime = WrongEntry;
+ }
+ }
+ } /* end for */
+ } /* endif (emailAddr[0]) */
+ } /* end for */
+ } /* endif (subjectEntry->emailAddrs) */
+ }
+ return SECSuccess;
+}
+
+void
+printnode(dbDebugInfo *info, const char *str, int num)
+{
+ if (!info->dograph)
+ return;
+ if (num < 0) {
+ PR_fprintf(info->graphfile, str);
+ } else {
+ PR_fprintf(info->graphfile, str, num);
+ }
+}
+
+PRBool
+map_handle_is_ok(dbDebugInfo *info, void *mapPtr, int indent)
+{
+ if (mapPtr == NULL) {
+ if (indent > 0)
+ printnode(info, " ", -1);
+ if (indent >= 0)
+ printnode(info, "******************* ", -1);
+ return PR_FALSE;
+ } else if (mapPtr == WrongEntry) {
+ if (indent > 0)
+ printnode(info, " ", -1);
+ if (indent >= 0)
+ printnode(info, "??????????????????? ", -1);
+ return PR_FALSE;
+ } else {
+ return PR_TRUE;
+ }
+}
+
+/* these call each other */
+void print_smime_graph(dbDebugInfo *info, certDBEntryMap *smimeMap,
+ int direction);
+void print_nickname_graph(dbDebugInfo *info, certDBEntryMap *nickMap,
+ int direction);
+void print_subject_graph(dbDebugInfo *info, certDBSubjectEntryMap *subjMap,
+ int direction, int optindex, int opttype);
+void print_cert_graph(dbDebugInfo *info, certDBEntryMap *certMap,
+ int direction);
+
+/* Given an smime entry, print its unique identifier. If GOLEFT is
+ * specified, print the cert<-subject<-smime map, else just print
+ * the smime entry.
+ */
+void
+print_smime_graph(dbDebugInfo *info, certDBEntryMap *smimeMap, int direction)
+{
+ certDBSubjectEntryMap *subjMap;
+ certDBEntryListNode *subjNode;
+ if (direction == GOLEFT) {
+ /* Need to output subject and cert first, see print_subject_graph */
+ subjNode = smimeMap->pSubject;
+ if (map_handle_is_ok(info, (void *)subjNode, 1)) {
+ subjMap = (certDBSubjectEntryMap *)subjNode->appData;
+ print_subject_graph(info, subjMap, GOLEFT,
+ smimeMap->index, certDBEntryTypeSMimeProfile);
+ } else {
+ printnode(info, "<---- S/MIME %5d ", smimeMap->index);
+ info->dbErrors[NoSubjectForSMime]++;
+ }
+ } else {
+ printnode(info, "S/MIME %5d ", smimeMap->index);
+ }
+}
+
+/* Given a nickname entry, print its unique identifier. If GOLEFT is
+ * specified, print the cert<-subject<-nickname map, else just print
+ * the nickname entry.
+ */
+void
+print_nickname_graph(dbDebugInfo *info, certDBEntryMap *nickMap, int direction)
+{
+ certDBSubjectEntryMap *subjMap;
+ certDBEntryListNode *subjNode;
+ if (direction == GOLEFT) {
+ /* Need to output subject and cert first, see print_subject_graph */
+ subjNode = nickMap->pSubject;
+ if (map_handle_is_ok(info, (void *)subjNode, 1)) {
+ subjMap = (certDBSubjectEntryMap *)subjNode->appData;
+ print_subject_graph(info, subjMap, GOLEFT,
+ nickMap->index, certDBEntryTypeNickname);
+ } else {
+ printnode(info, "<---- Nickname %5d ", nickMap->index);
+ info->dbErrors[NoSubjectForNickname]++;
+ }
+ } else {
+ printnode(info, "Nickname %5d ", nickMap->index);
+ }
+}
+
+/* Given a subject entry, if going right print the graph of the nickname|smime
+ * that it maps to (by its unique identifier); and if going left
+ * print the list of certs that it points to.
+ */
+void
+print_subject_graph(dbDebugInfo *info, certDBSubjectEntryMap *subjMap,
+ int direction, int optindex, int opttype)
+{
+ certDBEntryMap *map;
+ certDBEntryListNode *node;
+ int i;
+ /* The first line of output always contains the cert id, subject id,
+ * and nickname|smime id. Subsequent lines may contain additional
+ * cert id's for the subject if going left or both directions.
+ * Ex. of printing the graph for a subject entry:
+ * Cert 3 <- Subject 5 -> Nickname 32
+ * Cert 8 /
+ * Cert 9 /
+ * means subject 5 has 3 certs, 3, 8, and 9, and corresponds
+ * to nickname entry 32.
+ * To accomplish the above, it is required to dump the entire first
+ * line left-to-right, regardless of the input direction, and then
+ * finish up any remaining cert entries. Hence the code is uglier
+ * than one may expect.
+ */
+ if (direction == GOLEFT || direction == GOBOTH) {
+ /* In this case, nothing should be output until the first cert is
+ * located and output (cert 3 in the above example).
+ */
+ if (subjMap->numCerts == 0 || subjMap->pCerts == NULL)
+ /* XXX uh-oh */
+ return;
+ /* get the first cert and dump it. */
+ node = subjMap->pCerts[0];
+ if (map_handle_is_ok(info, (void *)node, 0)) {
+ map = (certDBEntryMap *)node->appData;
+ /* going left here stops. */
+ print_cert_graph(info, map, GOLEFT);
+ } else {
+ info->dbErrors[SubjectHasNoKeyForCert]++;
+ }
+ /* Now it is safe to output the subject id. */
+ if (direction == GOLEFT)
+ printnode(info, "Subject %5d <---- ", subjMap->index);
+ else /* direction == GOBOTH */
+ printnode(info, "Subject %5d ----> ", subjMap->index);
+ }
+ if (direction == GORIGHT || direction == GOBOTH) {
+ /* Okay, now output the nickname|smime for this subject. */
+ if (direction != GOBOTH) /* handled above */
+ printnode(info, "Subject %5d ----> ", subjMap->index);
+ if (subjMap->pNickname) {
+ node = subjMap->pNickname;
+ if (map_handle_is_ok(info, (void *)node, 0)) {
+ map = (certDBEntryMap *)node->appData;
+ /* going right here stops. */
+ print_nickname_graph(info, map, GORIGHT);
+ }
+ }
+ if (subjMap->pSMime) {
+ node = subjMap->pSMime;
+ if (map_handle_is_ok(info, (void *)node, 0)) {
+ map = (certDBEntryMap *)node->appData;
+ /* going right here stops. */
+ print_smime_graph(info, map, GORIGHT);
+ }
+ }
+ if (!subjMap->pNickname && !subjMap->pSMime) {
+ printnode(info, "******************* ", -1);
+ info->dbErrors[NoNicknameOrSMimeForSubject]++;
+ }
+ if (subjMap->pNickname && subjMap->pSMime) {
+ info->dbErrors[NicknameAndSMimeEntries]++;
+ }
+ }
+ if (direction != GORIGHT) { /* going right has only one cert */
+ if (opttype == certDBEntryTypeNickname)
+ printnode(info, "Nickname %5d ", optindex);
+ else if (opttype == certDBEntryTypeSMimeProfile)
+ printnode(info, "S/MIME %5d ", optindex);
+ for (i = 1 /* 1st one already done */; i < subjMap->numCerts; i++) {
+ printnode(info, "\n", -1); /* start a new line */
+ node = subjMap->pCerts[i];
+ if (map_handle_is_ok(info, (void *)node, 0)) {
+ map = (certDBEntryMap *)node->appData;
+ /* going left here stops. */
+ print_cert_graph(info, map, GOLEFT);
+ printnode(info, "/", -1);
+ }
+ }
+ }
+}
+
+/* Given a cert entry, print its unique identifer. If GORIGHT is specified,
+ * print the cert->subject->nickname|smime map, else just print
+ * the cert entry.
+ */
+void
+print_cert_graph(dbDebugInfo *info, certDBEntryMap *certMap, int direction)
+{
+ certDBSubjectEntryMap *subjMap;
+ certDBEntryListNode *subjNode;
+ if (direction == GOLEFT) {
+ printnode(info, "Cert %5d <---- ", certMap->index);
+ /* only want cert entry, terminate here. */
+ return;
+ }
+ /* Keep going right then. */
+ printnode(info, "Cert %5d ----> ", certMap->index);
+ subjNode = certMap->pSubject;
+ if (map_handle_is_ok(info, (void *)subjNode, 0)) {
+ subjMap = (certDBSubjectEntryMap *)subjNode->appData;
+ print_subject_graph(info, subjMap, GORIGHT, -1, -1);
+ } else {
+ info->dbErrors[NoSubjectForCert]++;
+ }
+}
+
+SECStatus
+computeDBGraph(certDBArray *dbArray, dbDebugInfo *info)
+{
+ PRCList *cElem, *sElem, *nElem, *mElem;
+ certDBEntryListNode *node;
+ certDBEntryMap *map;
+ certDBSubjectEntryMap *subjMap;
+
+ /* Graph is of this form:
+ *
+ * certs:
+ * cert ---> subject ---> (nickname|smime)
+ *
+ * subjects:
+ * cert <--- subject ---> (nickname|smime)
+ *
+ * nicknames and smime:
+ * cert <--- subject <--- (nickname|smime)
+ */
+
+ /* Print cert graph. */
+ for (cElem = PR_LIST_HEAD(&dbArray->certs.link);
+ cElem != &dbArray->certs.link; cElem = PR_NEXT_LINK(cElem)) {
+ /* Print graph of everything to right of cert entry. */
+ node = LISTNODE_CAST(cElem);
+ map = (certDBEntryMap *)node->appData;
+ print_cert_graph(info, map, GORIGHT);
+ printnode(info, "\n", -1);
+ }
+ printnode(info, "\n", -1);
+
+ /* Print subject graph. */
+ for (sElem = PR_LIST_HEAD(&dbArray->subjects.link);
+ sElem != &dbArray->subjects.link; sElem = PR_NEXT_LINK(sElem)) {
+ /* Print graph of everything to both sides of subject entry. */
+ node = LISTNODE_CAST(sElem);
+ subjMap = (certDBSubjectEntryMap *)node->appData;
+ print_subject_graph(info, subjMap, GOBOTH, -1, -1);
+ printnode(info, "\n", -1);
+ }
+ printnode(info, "\n", -1);
+
+ /* Print nickname graph. */
+ for (nElem = PR_LIST_HEAD(&dbArray->nicknames.link);
+ nElem != &dbArray->nicknames.link; nElem = PR_NEXT_LINK(nElem)) {
+ /* Print graph of everything to left of nickname entry. */
+ node = LISTNODE_CAST(nElem);
+ map = (certDBEntryMap *)node->appData;
+ print_nickname_graph(info, map, GOLEFT);
+ printnode(info, "\n", -1);
+ }
+ printnode(info, "\n", -1);
+
+ /* Print smime graph. */
+ for (mElem = PR_LIST_HEAD(&dbArray->smime.link);
+ mElem != &dbArray->smime.link; mElem = PR_NEXT_LINK(mElem)) {
+ /* Print graph of everything to left of smime entry. */
+ node = LISTNODE_CAST(mElem);
+ if (node == NULL)
+ break;
+ map = (certDBEntryMap *)node->appData;
+ print_smime_graph(info, map, GOLEFT);
+ printnode(info, "\n", -1);
+ }
+ printnode(info, "\n", -1);
+
+ return SECSuccess;
+}
+
+/*
+ * List the entries in the db, showing handles between entry types.
+ */
+void
+verboseOutput(certDBArray *dbArray, dbDebugInfo *info)
+{
+ int i, ref;
+ PRCList *elem;
+ certDBEntryListNode *node;
+ certDBEntryMap *map;
+ certDBSubjectEntryMap *smap;
+ certDBEntrySubject *subjectEntry;
+
+ /* List certs */
+ for (elem = PR_LIST_HEAD(&dbArray->certs.link);
+ elem != &dbArray->certs.link; elem = PR_NEXT_LINK(elem)) {
+ node = LISTNODE_CAST(elem);
+ map = (certDBEntryMap *)node->appData;
+ dumpCertEntry((certDBEntryCert *)&node->entry, map->index, info->out);
+ /* walk the cert handle to it's subject entry */
+ if (map_handle_is_ok(info, map->pSubject, -1)) {
+ smap = (certDBSubjectEntryMap *)map->pSubject->appData;
+ ref = smap->index;
+ PR_fprintf(info->out, "-->(subject %d)\n\n\n", ref);
+ } else {
+ PR_fprintf(info->out, "-->(MISSING SUBJECT ENTRY)\n\n\n");
+ }
+ }
+ /* List subjects */
+ for (elem = PR_LIST_HEAD(&dbArray->subjects.link);
+ elem != &dbArray->subjects.link; elem = PR_NEXT_LINK(elem)) {
+ int refs = 0;
+ node = LISTNODE_CAST(elem);
+ subjectEntry = (certDBEntrySubject *)&node->entry;
+ smap = (certDBSubjectEntryMap *)node->appData;
+ dumpSubjectEntry(subjectEntry, smap->index, info->out);
+ /* iterate over subject's certs */
+ for (i = 0; i < smap->numCerts; i++) {
+ /* walk each subject handle to it's cert entries */
+ if (map_handle_is_ok(info, smap->pCerts[i], -1)) {
+ ref = ((certDBEntryMap *)smap->pCerts[i]->appData)->index;
+ PR_fprintf(info->out, "-->(%d. certificate %d)\n", i, ref);
+ } else {
+ PR_fprintf(info->out, "-->(%d. MISSING CERT ENTRY)\n", i);
+ }
+ }
+ if (subjectEntry->nickname) {
+ ++refs;
+ /* walk each subject handle to it's nickname entry */
+ if (map_handle_is_ok(info, smap->pNickname, -1)) {
+ ref = ((certDBEntryMap *)smap->pNickname->appData)->index;
+ PR_fprintf(info->out, "-->(nickname %d)\n", ref);
+ } else {
+ PR_fprintf(info->out, "-->(MISSING NICKNAME ENTRY)\n");
+ }
+ }
+ if (subjectEntry->nemailAddrs &&
+ subjectEntry->emailAddrs &&
+ subjectEntry->emailAddrs[0] &&
+ subjectEntry->emailAddrs[0][0]) {
+ ++refs;
+ /* walk each subject handle to it's smime entry */
+ if (map_handle_is_ok(info, smap->pSMime, -1)) {
+ ref = ((certDBEntryMap *)smap->pSMime->appData)->index;
+ PR_fprintf(info->out, "-->(s/mime %d)\n", ref);
+ } else {
+ PR_fprintf(info->out, "-->(MISSING S/MIME ENTRY)\n");
+ }
+ }
+ if (!refs) {
+ PR_fprintf(info->out, "-->(NO NICKNAME+S/MIME ENTRY)\n");
+ }
+ PR_fprintf(info->out, "\n\n");
+ }
+ for (elem = PR_LIST_HEAD(&dbArray->nicknames.link);
+ elem != &dbArray->nicknames.link; elem = PR_NEXT_LINK(elem)) {
+ node = LISTNODE_CAST(elem);
+ map = (certDBEntryMap *)node->appData;
+ dumpNicknameEntry((certDBEntryNickname *)&node->entry, map->index,
+ info->out);
+ if (map_handle_is_ok(info, map->pSubject, -1)) {
+ ref = ((certDBEntryMap *)map->pSubject->appData)->index;
+ PR_fprintf(info->out, "-->(subject %d)\n\n\n", ref);
+ } else {
+ PR_fprintf(info->out, "-->(MISSING SUBJECT ENTRY)\n\n\n");
+ }
+ }
+ for (elem = PR_LIST_HEAD(&dbArray->smime.link);
+ elem != &dbArray->smime.link; elem = PR_NEXT_LINK(elem)) {
+ node = LISTNODE_CAST(elem);
+ map = (certDBEntryMap *)node->appData;
+ dumpSMimeEntry((certDBEntrySMime *)&node->entry, map->index, info->out);
+ if (map_handle_is_ok(info, map->pSubject, -1)) {
+ ref = ((certDBEntryMap *)map->pSubject->appData)->index;
+ PR_fprintf(info->out, "-->(subject %d)\n\n\n", ref);
+ } else {
+ PR_fprintf(info->out, "-->(MISSING SUBJECT ENTRY)\n\n\n");
+ }
+ }
+ PR_fprintf(info->out, "\n\n");
+}
+
+/* A callback function, intended to be called from nsslowcert_TraverseDBEntries
+ * Builds a PRCList of DB entries of the specified type.
+ */
+SECStatus
+SEC_GetCertDBEntryList(SECItem *dbdata, SECItem *dbkey,
+ certDBEntryType entryType, void *pdata)
+{
+ certDBEntry *entry;
+ certDBEntryListNode *node;
+ PRCList *list = (PRCList *)pdata;
+
+ if (!dbdata || !dbkey || !pdata || !dbdata->data || !dbkey->data) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ entry = nsslowcert_DecodeAnyDBEntry(dbdata, dbkey, entryType, NULL);
+ if (!entry) {
+ return SECSuccess; /* skip it */
+ }
+ node = PORT_ArenaZNew(entry->common.arena, certDBEntryListNode);
+ if (!node) {
+ /* DestroyDBEntry(entry); */
+ PLArenaPool *arena = entry->common.arena;
+ PORT_Memset(&entry->common, 0, sizeof entry->common);
+ PORT_FreeArena(arena, PR_FALSE);
+ return SECFailure;
+ }
+ node->entry = *entry; /* crude but effective. */
+ PR_INIT_CLIST(&node->link);
+ PR_INSERT_BEFORE(&node->link, list);
+ return SECSuccess;
+}
+
+int
+fillDBEntryArray(NSSLOWCERTCertDBHandle *handle, certDBEntryType type,
+ certDBEntryListNode *list)
+{
+ PRCList *elem;
+ certDBEntryListNode *node;
+ certDBEntryMap *mnode;
+ certDBSubjectEntryMap *smnode;
+ PLArenaPool *arena;
+ int count = 0;
+
+ /* Initialize a dummy entry in the list. The list head will be the
+ * next element, so this element is skipped by for loops.
+ */
+ PR_INIT_CLIST((PRCList *)list);
+ /* Collect all of the cert db entries for this type into a list. */
+ nsslowcert_TraverseDBEntries(handle, type, SEC_GetCertDBEntryList, list);
+
+ for (elem = PR_LIST_HEAD(&list->link);
+ elem != &list->link; elem = PR_NEXT_LINK(elem)) {
+ /* Iterate over the entries and ... */
+ node = (certDBEntryListNode *)elem;
+ if (type != certDBEntryTypeSubject) {
+ arena = PORT_NewArena(sizeof(*mnode));
+ mnode = PORT_ArenaZNew(arena, certDBEntryMap);
+ mnode->arena = arena;
+ /* ... assign a unique index number to each node, and ... */
+ mnode->index = count;
+ /* ... set the map pointer for the node. */
+ node->appData = (void *)mnode;
+ } else {
+ /* allocate some room for the cert pointers also */
+ arena = PORT_NewArena(sizeof(*smnode) + 20 * sizeof(void *));
+ smnode = PORT_ArenaZNew(arena, certDBSubjectEntryMap);
+ smnode->arena = arena;
+ smnode->index = count;
+ node->appData = (void *)smnode;
+ }
+ count++;
+ }
+ return count;
+}
+
+void
+freeDBEntryList(PRCList *list)
+{
+ PRCList *next, *elem;
+ certDBEntryListNode *node;
+ certDBEntryMap *map;
+
+ for (elem = PR_LIST_HEAD(list); elem != list;) {
+ next = PR_NEXT_LINK(elem);
+ node = (certDBEntryListNode *)elem;
+ map = (certDBEntryMap *)node->appData;
+ PR_REMOVE_LINK(&node->link);
+ PORT_FreeArena(map->arena, PR_TRUE);
+ PORT_FreeArena(node->entry.common.arena, PR_TRUE);
+ elem = next;
+ }
+}
+
+void
+DBCK_DebugDB(NSSLOWCERTCertDBHandle *handle, PRFileDesc *out,
+ PRFileDesc *mailfile)
+{
+ int i, nCertsFound, nSubjFound, nErr;
+ int nCerts, nSubjects, nSubjCerts, nNicknames, nSMime, nRevocation;
+ PRCList *elem;
+ char c;
+ dbDebugInfo info;
+ certDBArray dbArray;
+
+ PORT_Memset(&dbArray, 0, sizeof(dbArray));
+ PORT_Memset(&info, 0, sizeof(info));
+ info.verbose = (PRBool)(out != NULL);
+ info.dograph = info.verbose;
+ info.out = (out) ? out : PR_STDOUT;
+ info.graphfile = mailfile ? mailfile : PR_STDOUT;
+
+ /* Fill the array structure with cert/subject/nickname/smime entries. */
+ dbArray.numCerts = fillDBEntryArray(handle, certDBEntryTypeCert,
+ &dbArray.certs);
+ dbArray.numSubjects = fillDBEntryArray(handle, certDBEntryTypeSubject,
+ &dbArray.subjects);
+ dbArray.numNicknames = fillDBEntryArray(handle, certDBEntryTypeNickname,
+ &dbArray.nicknames);
+ dbArray.numSMime = fillDBEntryArray(handle, certDBEntryTypeSMimeProfile,
+ &dbArray.smime);
+ dbArray.numRevocation = fillDBEntryArray(handle, certDBEntryTypeRevocation,
+ &dbArray.revocation);
+
+ /* Compute the map between the database entries. */
+ mapSubjectEntries(&dbArray);
+ mapCertEntries(&dbArray);
+ computeDBGraph(&dbArray, &info);
+
+ /* Store the totals for later reference. */
+ nCerts = dbArray.numCerts;
+ nSubjects = dbArray.numSubjects;
+ nNicknames = dbArray.numNicknames;
+ nSMime = dbArray.numSMime;
+ nRevocation = dbArray.numRevocation;
+ nSubjCerts = 0;
+ for (elem = PR_LIST_HEAD(&dbArray.subjects.link);
+ elem != &dbArray.subjects.link; elem = PR_NEXT_LINK(elem)) {
+ certDBSubjectEntryMap *smap;
+ smap = (certDBSubjectEntryMap *)LISTNODE_CAST(elem)->appData;
+ nSubjCerts += smap->numCerts;
+ }
+
+ if (info.verbose) {
+ /* Dump the database contents. */
+ verboseOutput(&dbArray, &info);
+ }
+
+ freeDBEntryList(&dbArray.certs.link);
+ freeDBEntryList(&dbArray.subjects.link);
+ freeDBEntryList(&dbArray.nicknames.link);
+ freeDBEntryList(&dbArray.smime.link);
+ freeDBEntryList(&dbArray.revocation.link);
+
+ PR_fprintf(info.out, "\n");
+ PR_fprintf(info.out, "Database statistics:\n");
+ PR_fprintf(info.out, "N0: Found %4d Certificate entries.\n",
+ nCerts);
+ PR_fprintf(info.out, "N1: Found %4d Subject entries (unique DN's).\n",
+ nSubjects);
+ PR_fprintf(info.out, "N2: Found %4d Cert keys within Subject entries.\n",
+ nSubjCerts);
+ PR_fprintf(info.out, "N3: Found %4d Nickname entries.\n",
+ nNicknames);
+ PR_fprintf(info.out, "N4: Found %4d S/MIME entries.\n",
+ nSMime);
+ PR_fprintf(info.out, "N5: Found %4d CRL entries.\n",
+ nRevocation);
+ PR_fprintf(info.out, "\n");
+
+ nErr = 0;
+ for (i = 0; i < NUM_ERROR_TYPES; i++) {
+ PR_fprintf(info.out, "E%d: Found %4d %s\n",
+ i, info.dbErrors[i], errResult[i]);
+ nErr += info.dbErrors[i];
+ }
+ PR_fprintf(info.out, "--------------\n Found %4d errors in database.\n",
+ nErr);
+
+ PR_fprintf(info.out, "\nCertificates:\n");
+ PR_fprintf(info.out, "N0 == N2 + E%d + E%d\n", NoSubjectForCert,
+ SubjectHasNoKeyForCert);
+ nCertsFound = nSubjCerts +
+ info.dbErrors[NoSubjectForCert] +
+ info.dbErrors[SubjectHasNoKeyForCert];
+ c = (nCertsFound == nCerts) ? '=' : '!';
+ PR_fprintf(info.out, "%d %c= %d + %d + %d\n", nCerts, c, nSubjCerts,
+ info.dbErrors[NoSubjectForCert],
+ info.dbErrors[SubjectHasNoKeyForCert]);
+ PR_fprintf(info.out, "\nSubjects:\n");
+ PR_fprintf(info.out,
+ "N1 == N3 + N4 + E%d + E%d + E%d + E%d + E%d - E%d - E%d - E%d\n",
+ NoNicknameOrSMimeForSubject,
+ WrongNicknameForSubject,
+ NoNicknameEntry,
+ WrongSMimeForSubject,
+ NoSMimeEntry,
+ NoSubjectForNickname,
+ NoSubjectForSMime,
+ NicknameAndSMimeEntries);
+ nSubjFound = nNicknames + nSMime +
+ info.dbErrors[NoNicknameOrSMimeForSubject] +
+ info.dbErrors[WrongNicknameForSubject] +
+ info.dbErrors[NoNicknameEntry] +
+ info.dbErrors[WrongSMimeForSubject] +
+ info.dbErrors[NoSMimeEntry] -
+ info.dbErrors[NoSubjectForNickname] -
+ info.dbErrors[NoSubjectForSMime] -
+ info.dbErrors[NicknameAndSMimeEntries];
+ c = (nSubjFound == nSubjects) ? '=' : '!';
+ PR_fprintf(info.out,
+ "%2d %c= %2d + %2d + %2d + %2d + %2d + %2d + %2d - %2d - %2d - %2d\n",
+ nSubjects, c, nNicknames, nSMime,
+ info.dbErrors[NoNicknameOrSMimeForSubject],
+ info.dbErrors[WrongNicknameForSubject],
+ info.dbErrors[NoNicknameEntry],
+ info.dbErrors[WrongSMimeForSubject],
+ info.dbErrors[NoSMimeEntry],
+ info.dbErrors[NoSubjectForNickname],
+ info.dbErrors[NoSubjectForSMime],
+ info.dbErrors[NicknameAndSMimeEntries]);
+ PR_fprintf(info.out, "\n");
+}
+
+#ifdef DORECOVER
+#include "dbrecover.c"
+#endif /* DORECOVER */
+
+enum {
+ cmd_Debug = 0,
+ cmd_LongUsage,
+ cmd_Recover
+};
+
+enum {
+ opt_KeepAll = 0,
+ opt_CertDir,
+ opt_Dumpfile,
+ opt_InputDB,
+ opt_OutputDB,
+ opt_Mailfile,
+ opt_Prompt,
+ opt_KeepRedundant,
+ opt_KeepNoSMimeProfile,
+ opt_Verbose,
+ opt_KeepExpired
+};
+
+static secuCommandFlag dbck_commands[] =
+ {
+ { /* cmd_Debug, */ 'D', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_LongUsage,*/ 'H', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_Recover, */ 'R', PR_FALSE, 0, PR_FALSE }
+ };
+
+static secuCommandFlag dbck_options[] =
+ {
+ { /* opt_KeepAll, */ 'a', PR_FALSE, 0, PR_FALSE },
+ { /* opt_CertDir, */ 'd', PR_TRUE, 0, PR_FALSE },
+ { /* opt_Dumpfile, */ 'f', PR_TRUE, 0, PR_FALSE },
+ { /* opt_InputDB, */ 'i', PR_TRUE, 0, PR_FALSE },
+ { /* opt_OutputDB, */ 'o', PR_TRUE, 0, PR_FALSE },
+ { /* opt_Mailfile, */ 'm', PR_FALSE, 0, PR_FALSE },
+ { /* opt_Prompt, */ 'p', PR_FALSE, 0, PR_FALSE },
+ { /* opt_KeepRedundant, */ 'r', PR_FALSE, 0, PR_FALSE },
+ { /* opt_KeepNoSMimeProfile,*/ 's', PR_FALSE, 0, PR_FALSE },
+ { /* opt_Verbose, */ 'v', PR_FALSE, 0, PR_FALSE },
+ { /* opt_KeepExpired, */ 'x', PR_FALSE, 0, PR_FALSE }
+ };
+
+#define CERT_DB_FMT "%s/cert%s.db"
+
+static char *
+dbck_certdb_name_cb(void *arg, int dbVersion)
+{
+ const char *configdir = (const char *)arg;
+ const char *dbver;
+ char *smpname = NULL;
+ char *dbname = NULL;
+
+ switch (dbVersion) {
+ case 8:
+ dbver = "8";
+ break;
+ case 7:
+ dbver = "7";
+ break;
+ case 6:
+ dbver = "6";
+ break;
+ case 5:
+ dbver = "5";
+ break;
+ case 4:
+ default:
+ dbver = "";
+ break;
+ }
+
+ /* make sure we return something allocated with PORT_ so we have properly
+ * matched frees at the end */
+ smpname = PR_smprintf(CERT_DB_FMT, configdir, dbver);
+ if (smpname) {
+ dbname = PORT_Strdup(smpname);
+ PR_smprintf_free(smpname);
+ }
+ return dbname;
+}
+
+int
+main(int argc, char **argv)
+{
+ NSSLOWCERTCertDBHandle *certHandle;
+
+ PRFileDesc *mailfile = NULL;
+ PRFileDesc *dumpfile = NULL;
+
+ char *pathname = 0;
+ char *fullname = 0;
+ char *newdbname = 0;
+
+ PRBool removeExpired, requireProfile, singleEntry;
+ SECStatus rv;
+ secuCommand dbck;
+
+ dbck.numCommands = sizeof(dbck_commands) / sizeof(secuCommandFlag);
+ dbck.numOptions = sizeof(dbck_options) / sizeof(secuCommandFlag);
+ dbck.commands = dbck_commands;
+ dbck.options = dbck_options;
+
+ progName = strrchr(argv[0], '/');
+ progName = progName ? progName + 1 : argv[0];
+
+ rv = SECU_ParseCommandLine(argc, argv, progName, &dbck);
+
+ if (rv != SECSuccess)
+ Usage(progName);
+
+ if (dbck.commands[cmd_LongUsage].activated)
+ LongUsage(progName);
+
+ if (!dbck.commands[cmd_Debug].activated &&
+ !dbck.commands[cmd_Recover].activated) {
+ PR_fprintf(PR_STDERR, "Please specify -H, -D or -R.\n");
+ Usage(progName);
+ }
+
+ removeExpired = !(dbck.options[opt_KeepAll].activated ||
+ dbck.options[opt_KeepExpired].activated);
+
+ requireProfile = !(dbck.options[opt_KeepAll].activated ||
+ dbck.options[opt_KeepNoSMimeProfile].activated);
+
+ singleEntry = !(dbck.options[opt_KeepAll].activated ||
+ dbck.options[opt_KeepRedundant].activated);
+
+ if (dbck.options[opt_OutputDB].activated) {
+ newdbname = PL_strdup(dbck.options[opt_OutputDB].arg);
+ } else {
+ newdbname = PL_strdup("new_cert8.db");
+ }
+
+ /* Create a generic graph of the database. */
+ if (dbck.options[opt_Mailfile].activated) {
+ mailfile = PR_Open("./mailfile", PR_RDWR | PR_CREATE_FILE, 00660);
+ if (!mailfile) {
+ fprintf(stderr, "Unable to create mailfile.\n");
+ return -1;
+ }
+ }
+
+ /* Dump all debugging info while running. */
+ if (dbck.options[opt_Verbose].activated) {
+ if (dbck.options[opt_Dumpfile].activated) {
+ dumpfile = PR_Open(dbck.options[opt_Dumpfile].arg,
+ PR_RDWR | PR_CREATE_FILE, 00660);
+ if (!dumpfile) {
+ fprintf(stderr, "Unable to create dumpfile.\n");
+ return -1;
+ }
+ } else {
+ dumpfile = PR_STDOUT;
+ }
+ }
+
+ /* Set the cert database directory. */
+ if (dbck.options[opt_CertDir].activated) {
+ SECU_ConfigDirectory(dbck.options[opt_CertDir].arg);
+ }
+
+ pathname = SECU_ConfigDirectory(NULL);
+
+ PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
+ rv = NSS_NoDB_Init(pathname);
+ if (rv != SECSuccess) {
+ fprintf(stderr, "NSS_NoDB_Init failed\n");
+ return -1;
+ }
+
+ certHandle = PORT_ZNew(NSSLOWCERTCertDBHandle);
+ if (!certHandle) {
+ SECU_PrintError(progName, "unable to get database handle");
+ return -1;
+ }
+ certHandle->ref = 1;
+
+#ifdef NOTYET
+ /* Open the possibly corrupt database. */
+ if (dbck.options[opt_InputDB].activated) {
+ PRFileInfo fileInfo;
+ fullname = PR_smprintf("%s/%s", pathname,
+ dbck.options[opt_InputDB].arg);
+ if (PR_GetFileInfo(fullname, &fileInfo) != PR_SUCCESS) {
+ fprintf(stderr, "Unable to read file \"%s\".\n", fullname);
+ return -1;
+ }
+ rv = CERT_OpenCertDBFilename(certHandle, fullname, PR_TRUE);
+ } else
+#endif
+ {
+/* Use the default. */
+#ifdef NOTYET
+ fullname = SECU_CertDBNameCallback(NULL, CERT_DB_FILE_VERSION);
+ if (PR_GetFileInfo(fullname, &fileInfo) != PR_SUCCESS) {
+ fprintf(stderr, "Unable to read file \"%s\".\n", fullname);
+ return -1;
+ }
+#endif
+ rv = nsslowcert_OpenCertDB(certHandle,
+ PR_TRUE, /* readOnly */
+ NULL, /* rdb appName */
+ "", /* rdb prefix */
+ dbck_certdb_name_cb, /* namecb */
+ pathname, /* configDir */
+ PR_FALSE); /* volatile */
+ }
+
+ if (rv) {
+ SECU_PrintError(progName, "unable to open cert database");
+ return -1;
+ }
+
+ if (dbck.commands[cmd_Debug].activated) {
+ DBCK_DebugDB(certHandle, dumpfile, mailfile);
+ return 0;
+ }
+
+#ifdef DORECOVER
+ if (dbck.commands[cmd_Recover].activated) {
+ DBCK_ReconstructDBFromCerts(certHandle, newdbname,
+ dumpfile, removeExpired,
+ requireProfile, singleEntry,
+ dbck.options[opt_Prompt].activated);
+ return 0;
+ }
+#endif
+
+ if (mailfile)
+ PR_Close(mailfile);
+ if (dumpfile)
+ PR_Close(dumpfile);
+ if (certHandle) {
+ nsslowcert_ClosePermCertDB(certHandle);
+ PORT_Free(certHandle);
+ }
+ return -1;
+}
diff --git a/nss/cmd/dbck/dbrecover.c b/nss/cmd/dbck/dbrecover.c
new file mode 100644
index 0000000..74d21d8
--- /dev/null
+++ b/nss/cmd/dbck/dbrecover.c
@@ -0,0 +1,668 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+enum {
+ dbInvalidCert = 0,
+ dbNoSMimeProfile,
+ dbOlderCert,
+ dbBadCertificate,
+ dbCertNotWrittenToDB
+};
+
+typedef struct dbRestoreInfoStr {
+ NSSLOWCERTCertDBHandle *handle;
+ PRBool verbose;
+ PRFileDesc *out;
+ int nCerts;
+ int nOldCerts;
+ int dbErrors[5];
+ PRBool removeType[3];
+ PRBool promptUser[3];
+} dbRestoreInfo;
+
+char *
+IsEmailCert(CERTCertificate *cert)
+{
+ char *email, *tmp1, *tmp2;
+ PRBool isCA;
+ int len;
+
+ if (!cert->subjectName) {
+ return NULL;
+ }
+
+ tmp1 = PORT_Strstr(cert->subjectName, "E=");
+ tmp2 = PORT_Strstr(cert->subjectName, "MAIL=");
+ /* XXX Nelson has cert for KTrilli which does not have either
+ * of above but is email cert (has cert->emailAddr).
+ */
+ if (!tmp1 && !tmp2 && !(cert->emailAddr && cert->emailAddr[0])) {
+ return NULL;
+ }
+
+ /* Server or CA cert, not personal email. */
+ isCA = CERT_IsCACert(cert, NULL);
+ if (isCA)
+ return NULL;
+
+ /* XXX CERT_IsCACert advertises checking the key usage ext.,
+ but doesn't appear to. */
+ /* Check the key usage extension. */
+ if (cert->keyUsagePresent) {
+ /* Must at least be able to sign or encrypt (not neccesarily
+ * both if it is one of a dual cert).
+ */
+ if (!((cert->rawKeyUsage & KU_DIGITAL_SIGNATURE) ||
+ (cert->rawKeyUsage & KU_KEY_ENCIPHERMENT)))
+ return NULL;
+
+ /* CA cert, not personal email. */
+ if (cert->rawKeyUsage & (KU_KEY_CERT_SIGN | KU_CRL_SIGN))
+ return NULL;
+ }
+
+ if (cert->emailAddr && cert->emailAddr[0]) {
+ email = PORT_Strdup(cert->emailAddr);
+ } else {
+ if (tmp1)
+ tmp1 += 2; /* "E=" */
+ else
+ tmp1 = tmp2 + 5; /* "MAIL=" */
+ len = strcspn(tmp1, ", ");
+ email = (char *)PORT_Alloc(len + 1);
+ PORT_Strncpy(email, tmp1, len);
+ email[len] = '\0';
+ }
+
+ return email;
+}
+
+SECStatus
+deleteit(CERTCertificate *cert, void *arg)
+{
+ return SEC_DeletePermCertificate(cert);
+}
+
+/* Different than DeleteCertificate - has the added bonus of removing
+ * all certs with the same DN.
+ */
+SECStatus
+deleteAllEntriesForCert(NSSLOWCERTCertDBHandle *handle, CERTCertificate *cert,
+ PRFileDesc *outfile)
+{
+#if 0
+ certDBEntrySubject *subjectEntry;
+ certDBEntryNickname *nicknameEntry;
+ certDBEntrySMime *smimeEntry;
+ int i;
+#endif
+
+ if (outfile) {
+ PR_fprintf(outfile, "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n");
+ PR_fprintf(outfile, "Deleting redundant certificate:\n");
+ dumpCertificate(cert, -1, outfile);
+ }
+
+ CERT_TraverseCertsForSubject(handle, cert->subjectList, deleteit, NULL);
+#if 0
+ CERT_LockDB(handle);
+ subjectEntry = ReadDBSubjectEntry(handle, &cert->derSubject);
+ /* It had better be there, or created a bad db. */
+ PORT_Assert(subjectEntry);
+ for (i=0; incerts; i++) {
+ DeleteDBCertEntry(handle, &subjectEntry->certKeys[i]);
+ }
+ DeleteDBSubjectEntry(handle, &cert->derSubject);
+ if (subjectEntry->emailAddr && subjectEntry->emailAddr[0]) {
+ smimeEntry = ReadDBSMimeEntry(handle, subjectEntry->emailAddr);
+ if (smimeEntry) {
+ if (SECITEM_ItemsAreEqual(&subjectEntry->derSubject,
+ &smimeEntry->subjectName))
+ /* Only delete it if it's for this subject! */
+ DeleteDBSMimeEntry(handle, subjectEntry->emailAddr);
+ SEC_DestroyDBEntry((certDBEntry*)smimeEntry);
+ }
+ }
+ if (subjectEntry->nickname) {
+ nicknameEntry = ReadDBNicknameEntry(handle, subjectEntry->nickname);
+ if (nicknameEntry) {
+ if (SECITEM_ItemsAreEqual(&subjectEntry->derSubject,
+ &nicknameEntry->subjectName))
+ /* Only delete it if it's for this subject! */
+ DeleteDBNicknameEntry(handle, subjectEntry->nickname);
+ SEC_DestroyDBEntry((certDBEntry*)nicknameEntry);
+ }
+ }
+ SEC_DestroyDBEntry((certDBEntry*)subjectEntry);
+ CERT_UnlockDB(handle);
+#endif
+ return SECSuccess;
+}
+
+void
+getCertsToDelete(char *numlist, int len, int *certNums, int nCerts)
+{
+ int j, num;
+ char *numstr, *numend, *end;
+
+ numstr = numlist;
+ end = numstr + len - 1;
+ while (numstr != end) {
+ numend = strpbrk(numstr, ", \n");
+ *numend = '\0';
+ if (PORT_Strlen(numstr) == 0)
+ return;
+ num = PORT_Atoi(numstr);
+ if (numstr == numlist)
+ certNums[0] = num;
+ for (j = 1; j < nCerts + 1; j++) {
+ if (num == certNums[j]) {
+ certNums[j] = -1;
+ break;
+ }
+ }
+ if (numend == end)
+ break;
+ numstr = strpbrk(numend + 1, "0123456789");
+ }
+}
+
+PRBool
+userSaysDeleteCert(CERTCertificate **certs, int nCerts,
+ int errtype, dbRestoreInfo *info, int *certNums)
+{
+ char response[32];
+ PRInt32 nb;
+ int i;
+ /* User wants to remove cert without prompting. */
+ if (info->promptUser[errtype] == PR_FALSE)
+ return (info->removeType[errtype]);
+ switch (errtype) {
+ case dbInvalidCert:
+ PR_fprintf(PR_STDOUT, "******** Expired ********\n");
+ PR_fprintf(PR_STDOUT, "Cert has expired.\n\n");
+ dumpCertificate(certs[0], -1, PR_STDOUT);
+ PR_fprintf(PR_STDOUT,
+ "Keep it? (y/n - this one, Y/N - all expired certs) [n] ");
+ break;
+ case dbNoSMimeProfile:
+ PR_fprintf(PR_STDOUT, "******** No Profile ********\n");
+ PR_fprintf(PR_STDOUT, "S/MIME cert has no profile.\n\n");
+ dumpCertificate(certs[0], -1, PR_STDOUT);
+ PR_fprintf(PR_STDOUT,
+ "Keep it? (y/n - this one, Y/N - all S/MIME w/o profile) [n] ");
+ break;
+ case dbOlderCert:
+ PR_fprintf(PR_STDOUT, "******* Redundant nickname/email *******\n\n");
+ PR_fprintf(PR_STDOUT, "These certs have the same nickname/email:\n");
+ for (i = 0; i < nCerts; i++)
+ dumpCertificate(certs[i], i, PR_STDOUT);
+ PR_fprintf(PR_STDOUT,
+ "Enter the certs you would like to keep from those listed above.\n");
+ PR_fprintf(PR_STDOUT,
+ "Use a comma-separated list of the cert numbers (ex. 0, 8, 12).\n");
+ PR_fprintf(PR_STDOUT,
+ "The first cert in the list will be the primary cert\n");
+ PR_fprintf(PR_STDOUT,
+ " accessed by the nickname/email handle.\n");
+ PR_fprintf(PR_STDOUT,
+ "List cert numbers to keep here, or hit enter\n");
+ PR_fprintf(PR_STDOUT,
+ " to always keep only the newest cert: ");
+ break;
+ default:
+ }
+ nb = PR_Read(PR_STDIN, response, sizeof(response));
+ PR_fprintf(PR_STDOUT, "\n\n");
+ if (errtype == dbOlderCert) {
+ if (!isdigit(response[0])) {
+ info->promptUser[errtype] = PR_FALSE;
+ info->removeType[errtype] = PR_TRUE;
+ return PR_TRUE;
+ }
+ getCertsToDelete(response, nb, certNums, nCerts);
+ return PR_TRUE;
+ }
+ /* User doesn't want to be prompted for this type anymore. */
+ if (response[0] == 'Y') {
+ info->promptUser[errtype] = PR_FALSE;
+ info->removeType[errtype] = PR_FALSE;
+ return PR_FALSE;
+ } else if (response[0] == 'N') {
+ info->promptUser[errtype] = PR_FALSE;
+ info->removeType[errtype] = PR_TRUE;
+ return PR_TRUE;
+ }
+ return (response[0] != 'y') ? PR_TRUE : PR_FALSE;
+}
+
+SECStatus
+addCertToDB(certDBEntryCert *certEntry, dbRestoreInfo *info,
+ NSSLOWCERTCertDBHandle *oldhandle)
+{
+ SECStatus rv = SECSuccess;
+ PRBool allowOverride;
+ PRBool userCert;
+ SECCertTimeValidity validity;
+ CERTCertificate *oldCert = NULL;
+ CERTCertificate *dbCert = NULL;
+ CERTCertificate *newCert = NULL;
+ CERTCertTrust *trust;
+ certDBEntrySMime *smimeEntry = NULL;
+ char *email = NULL;
+ char *nickname = NULL;
+ int nCertsForSubject = 1;
+
+ oldCert = CERT_DecodeDERCertificate(&certEntry->derCert, PR_FALSE,
+ certEntry->nickname);
+ if (!oldCert) {
+ info->dbErrors[dbBadCertificate]++;
+ SEC_DestroyDBEntry((certDBEntry *)certEntry);
+ return SECSuccess;
+ }
+
+ oldCert->dbEntry = certEntry;
+ oldCert->trust = &certEntry->trust;
+ oldCert->dbhandle = oldhandle;
+
+ trust = oldCert->trust;
+
+ info->nOldCerts++;
+
+ if (info->verbose)
+ PR_fprintf(info->out, "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n");
+
+ if (oldCert->nickname)
+ nickname = PORT_Strdup(oldCert->nickname);
+
+ /* Always keep user certs. Skip ahead. */
+ /* XXX if someone sends themselves a signed message, it is possible
+ for their cert to be imported as an "other" cert, not a user cert.
+ this mucks with smime entries... */
+ userCert = (SEC_GET_TRUST_FLAGS(trust, trustSSL) & CERTDB_USER) ||
+ (SEC_GET_TRUST_FLAGS(trust, trustEmail) & CERTDB_USER) ||
+ (SEC_GET_TRUST_FLAGS(trust, trustObjectSigning) & CERTDB_USER);
+ if (userCert)
+ goto createcert;
+
+ /* If user chooses so, ignore expired certificates. */
+ allowOverride = (PRBool)((oldCert->keyUsage == certUsageSSLServer) ||
+ (oldCert->keyUsage == certUsageSSLServerWithStepUp));
+ validity = CERT_CheckCertValidTimes(oldCert, PR_Now(), allowOverride);
+ /* If cert expired and user wants to delete it, ignore it. */
+ if ((validity != secCertTimeValid) &&
+ userSaysDeleteCert(&oldCert, 1, dbInvalidCert, info, 0)) {
+ info->dbErrors[dbInvalidCert]++;
+ if (info->verbose) {
+ PR_fprintf(info->out, "Deleting expired certificate:\n");
+ dumpCertificate(oldCert, -1, info->out);
+ }
+ goto cleanup;
+ }
+
+ /* New database will already have default certs, don't attempt
+ to overwrite them. */
+ dbCert = CERT_FindCertByDERCert(info->handle, &oldCert->derCert);
+ if (dbCert) {
+ info->nCerts++;
+ if (info->verbose) {
+ PR_fprintf(info->out, "Added certificate to database:\n");
+ dumpCertificate(oldCert, -1, info->out);
+ }
+ goto cleanup;
+ }
+
+ /* Determine if cert is S/MIME and get its email if so. */
+ email = IsEmailCert(oldCert);
+
+/*
+ XXX Just create empty profiles?
+ if (email) {
+ SECItem *profile = CERT_FindSMimeProfile(oldCert);
+ if (!profile &&
+ userSaysDeleteCert(&oldCert, 1, dbNoSMimeProfile, info, 0)) {
+ info->dbErrors[dbNoSMimeProfile]++;
+ if (info->verbose) {
+ PR_fprintf(info->out,
+ "Deleted cert missing S/MIME profile.\n");
+ dumpCertificate(oldCert, -1, info->out);
+ }
+ goto cleanup;
+ } else {
+ SECITEM_FreeItem(profile);
+ }
+ }
+ */
+
+createcert:
+
+ /* Sometimes happens... */
+ if (!nickname && userCert)
+ nickname = PORT_Strdup(oldCert->subjectName);
+
+ /* Create a new certificate, copy of the old one. */
+ newCert = CERT_NewTempCertificate(info->handle, &oldCert->derCert,
+ nickname, PR_FALSE, PR_TRUE);
+ if (!newCert) {
+ PR_fprintf(PR_STDERR, "Unable to create new certificate.\n");
+ dumpCertificate(oldCert, -1, PR_STDERR);
+ info->dbErrors[dbBadCertificate]++;
+ goto cleanup;
+ }
+
+ /* Add the cert to the new database. */
+ rv = CERT_AddTempCertToPerm(newCert, nickname, oldCert->trust);
+ if (rv) {
+ PR_fprintf(PR_STDERR, "Failed to write temp cert to perm database.\n");
+ dumpCertificate(oldCert, -1, PR_STDERR);
+ info->dbErrors[dbCertNotWrittenToDB]++;
+ goto cleanup;
+ }
+
+ if (info->verbose) {
+ PR_fprintf(info->out, "Added certificate to database:\n");
+ dumpCertificate(oldCert, -1, info->out);
+ }
+
+ /* If the cert is an S/MIME cert, and the first with it's subject,
+ * modify the subject entry to include the email address,
+ * CERT_AddTempCertToPerm does not do email addresses and S/MIME entries.
+ */
+ if (smimeEntry) { /*&& !userCert && nCertsForSubject == 1) { */
+#if 0
+ UpdateSubjectWithEmailAddr(newCert, email);
+#endif
+ SECItem emailProfile, profileTime;
+ rv = CERT_FindFullSMimeProfile(oldCert, &emailProfile, &profileTime);
+ /* calls UpdateSubjectWithEmailAddr */
+ if (rv == SECSuccess)
+ rv = CERT_SaveSMimeProfile(newCert, &emailProfile, &profileTime);
+ }
+
+ info->nCerts++;
+
+cleanup:
+
+ if (nickname)
+ PORT_Free(nickname);
+ if (email)
+ PORT_Free(email);
+ if (oldCert)
+ CERT_DestroyCertificate(oldCert);
+ if (dbCert)
+ CERT_DestroyCertificate(dbCert);
+ if (newCert)
+ CERT_DestroyCertificate(newCert);
+ if (smimeEntry)
+ SEC_DestroyDBEntry((certDBEntry *)smimeEntry);
+ return SECSuccess;
+}
+
+#if 0
+SECStatus
+copyDBEntry(SECItem *data, SECItem *key, certDBEntryType type, void *pdata)
+{
+ SECStatus rv;
+ NSSLOWCERTCertDBHandle *newdb = (NSSLOWCERTCertDBHandle *)pdata;
+ certDBEntryCommon common;
+ SECItem dbkey;
+
+ common.type = type;
+ common.version = CERT_DB_FILE_VERSION;
+ common.flags = data->data[2];
+ common.arena = NULL;
+
+ dbkey.len = key->len + SEC_DB_KEY_HEADER_LEN;
+ dbkey.data = (unsigned char *)PORT_Alloc(dbkey.len*sizeof(unsigned char));
+ PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], key->data, key->len);
+ dbkey.data[0] = type;
+
+ rv = WriteDBEntry(newdb, &common, &dbkey, data);
+
+ PORT_Free(dbkey.data);
+ return rv;
+}
+#endif
+
+int
+certIsOlder(CERTCertificate **cert1, CERTCertificate **cert2)
+{
+ return !CERT_IsNewer(*cert1, *cert2);
+}
+
+int
+findNewestSubjectForEmail(NSSLOWCERTCertDBHandle *handle, int subjectNum,
+ certDBArray *dbArray, dbRestoreInfo *info,
+ int *subjectWithSMime, int *smimeForSubject)
+{
+ int newestSubject;
+ int subjectsForEmail[50];
+ int i, j, ns, sNum;
+ certDBEntryListNode *subjects = &dbArray->subjects;
+ certDBEntryListNode *smime = &dbArray->smime;
+ certDBEntrySubject *subjectEntry1, *subjectEntry2;
+ certDBEntrySMime *smimeEntry;
+ CERTCertificate **certs;
+ CERTCertificate *cert;
+ CERTCertTrust *trust;
+ PRBool userCert;
+ int *certNums;
+
+ ns = 0;
+ subjectEntry1 = (certDBEntrySubject *)&subjects.entries[subjectNum];
+ subjectsForEmail[ns++] = subjectNum;
+
+ *subjectWithSMime = -1;
+ *smimeForSubject = -1;
+ newestSubject = subjectNum;
+
+ cert = CERT_FindCertByKey(handle, &subjectEntry1->certKeys[0]);
+ if (cert) {
+ trust = cert->trust;
+ userCert = (SEC_GET_TRUST_FLAGS(trust, trustSSL) & CERTDB_USER) ||
+ (SEC_GET_TRUST_FLAGS(trust, trustEmail) & CERTDB_USER) ||
+ (SEC_GET_TRUST_FLAGS(trust, trustObjectSigning) & CERTDB_USER);
+ CERT_DestroyCertificate(cert);
+ }
+
+ /*
+ * XXX Should we make sure that subjectEntry1->emailAddr is not
+ * a null pointer or an empty string before going into the next
+ * two for loops, which pass it to PORT_Strcmp?
+ */
+
+ /* Loop over the remaining subjects. */
+ for (i = subjectNum + 1; i < subjects.numEntries; i++) {
+ subjectEntry2 = (certDBEntrySubject *)&subjects.entries[i];
+ if (!subjectEntry2)
+ continue;
+ if (subjectEntry2->emailAddr && subjectEntry2->emailAddr[0] &&
+ PORT_Strcmp(subjectEntry1->emailAddr,
+ subjectEntry2->emailAddr) == 0) {
+ /* Found a subject using the same email address. */
+ subjectsForEmail[ns++] = i;
+ }
+ }
+
+ /* Find the S/MIME entry for this email address. */
+ for (i = 0; i < smime.numEntries; i++) {
+ smimeEntry = (certDBEntrySMime *)&smime.entries[i];
+ if (smimeEntry->common.arena == NULL)
+ continue;
+ if (smimeEntry->emailAddr && smimeEntry->emailAddr[0] &&
+ PORT_Strcmp(subjectEntry1->emailAddr, smimeEntry->emailAddr) == 0) {
+ /* Find which of the subjects uses this S/MIME entry. */
+ for (j = 0; j < ns && *subjectWithSMime < 0; j++) {
+ sNum = subjectsForEmail[j];
+ subjectEntry2 = (certDBEntrySubject *)&subjects.entries[sNum];
+ if (SECITEM_ItemsAreEqual(&smimeEntry->subjectName,
+ &subjectEntry2->derSubject)) {
+ /* Found the subject corresponding to the S/MIME entry. */
+ *subjectWithSMime = sNum;
+ *smimeForSubject = i;
+ }
+ }
+ SEC_DestroyDBEntry((certDBEntry *)smimeEntry);
+ PORT_Memset(smimeEntry, 0, sizeof(certDBEntry));
+ break;
+ }
+ }
+
+ if (ns <= 1)
+ return subjectNum;
+
+ if (userCert)
+ return *subjectWithSMime;
+
+ /* Now find which of the subjects has the newest cert. */
+ certs = (CERTCertificate **)PORT_Alloc(ns * sizeof(CERTCertificate *));
+ certNums = (int *)PORT_Alloc((ns + 1) * sizeof(int));
+ certNums[0] = 0;
+ for (i = 0; i < ns; i++) {
+ sNum = subjectsForEmail[i];
+ subjectEntry1 = (certDBEntrySubject *)&subjects.entries[sNum];
+ certs[i] = CERT_FindCertByKey(handle, &subjectEntry1->certKeys[0]);
+ certNums[i + 1] = i;
+ }
+ /* Sort the array by validity. */
+ qsort(certs, ns, sizeof(CERTCertificate *),
+ (int (*)(const void *, const void *))certIsOlder);
+ newestSubject = -1;
+ for (i = 0; i < ns; i++) {
+ sNum = subjectsForEmail[i];
+ subjectEntry1 = (certDBEntrySubject *)&subjects.entries[sNum];
+ if (SECITEM_ItemsAreEqual(&subjectEntry1->derSubject,
+ &certs[0]->derSubject))
+ newestSubject = sNum;
+ else
+ SEC_DestroyDBEntry((certDBEntry *)subjectEntry1);
+ }
+ if (info && userSaysDeleteCert(certs, ns, dbOlderCert, info, certNums)) {
+ for (i = 1; i < ns + 1; i++) {
+ if (certNums[i] >= 0 && certNums[i] != certNums[0]) {
+ deleteAllEntriesForCert(handle, certs[certNums[i]], info->out);
+ info->dbErrors[dbOlderCert]++;
+ }
+ }
+ }
+ CERT_DestroyCertArray(certs, ns);
+ return newestSubject;
+}
+
+NSSLOWCERTCertDBHandle *
+DBCK_ReconstructDBFromCerts(NSSLOWCERTCertDBHandle *oldhandle, char *newdbname,
+ PRFileDesc *outfile, PRBool removeExpired,
+ PRBool requireProfile, PRBool singleEntry,
+ PRBool promptUser)
+{
+ SECStatus rv;
+ dbRestoreInfo info;
+ certDBEntryContentVersion *oldContentVersion;
+ certDBArray dbArray;
+ int i;
+
+ PORT_Memset(&dbArray, 0, sizeof(dbArray));
+ PORT_Memset(&info, 0, sizeof(info));
+ info.verbose = (outfile) ? PR_TRUE : PR_FALSE;
+ info.out = (outfile) ? outfile : PR_STDOUT;
+ info.removeType[dbInvalidCert] = removeExpired;
+ info.removeType[dbNoSMimeProfile] = requireProfile;
+ info.removeType[dbOlderCert] = singleEntry;
+ info.promptUser[dbInvalidCert] = promptUser;
+ info.promptUser[dbNoSMimeProfile] = promptUser;
+ info.promptUser[dbOlderCert] = promptUser;
+
+ /* Allocate a handle to fill with CERT_OpenCertDB below. */
+ info.handle = PORT_ZNew(NSSLOWCERTCertDBHandle);
+ if (!info.handle) {
+ fprintf(stderr, "unable to get database handle");
+ return NULL;
+ }
+
+ /* Create a certdb with the most recent set of roots. */
+ rv = CERT_OpenCertDBFilename(info.handle, newdbname, PR_FALSE);
+
+ if (rv) {
+ fprintf(stderr, "could not open certificate database");
+ goto loser;
+ }
+
+ /* Create certificate, subject, nickname, and email records.
+ * mcom_db seems to have a sequential access bug. Though reads and writes
+ * should be allowed during traversal, they seem to screw up the sequence.
+ * So, stuff all the cert entries into an array, and loop over the array
+ * doing read/writes in the db.
+ */
+ fillDBEntryArray(oldhandle, certDBEntryTypeCert, &dbArray.certs);
+ for (elem = PR_LIST_HEAD(&dbArray->certs.link);
+ elem != &dbArray->certs.link; elem = PR_NEXT_LINK(elem)) {
+ node = LISTNODE_CAST(elem);
+ addCertToDB((certDBEntryCert *)&node->entry, &info, oldhandle);
+ /* entries get destroyed in addCertToDB */
+ }
+#if 0
+ rv = nsslowcert_TraverseDBEntries(oldhandle, certDBEntryTypeSMimeProfile,
+ copyDBEntry, info.handle);
+#endif
+
+/* Fix up the pointers between (nickname|S/MIME) --> (subject).
+ * Create S/MIME entries for S/MIME certs.
+ * Have the S/MIME entry point to the last-expiring cert using
+ * an email address.
+ */
+#if 0
+ CERT_RedoHandlesForSubjects(info.handle, singleEntry, &info);
+#endif
+
+ freeDBEntryList(&dbArray.certs.link);
+
+/* Copy over the version record. */
+/* XXX Already exists - and _must_ be correct... */
+/*
+ versionEntry = ReadDBVersionEntry(oldhandle);
+ rv = WriteDBVersionEntry(info.handle, versionEntry);
+ */
+
+/* Copy over the content version record. */
+/* XXX Can probably get useful info from old content version?
+ * Was this db created before/after this tool? etc.
+ */
+#if 0
+ oldContentVersion = ReadDBContentVersionEntry(oldhandle);
+ CERT_SetDBContentVersion(oldContentVersion->contentVersion, info.handle);
+#endif
+
+#if 0
+ /* Copy over the CRL & KRL records. */
+ rv = nsslowcert_TraverseDBEntries(oldhandle, certDBEntryTypeRevocation,
+ copyDBEntry, info.handle);
+ /* XXX Only one KRL, just do db->get? */
+ rv = nsslowcert_TraverseDBEntries(oldhandle, certDBEntryTypeKeyRevocation,
+ copyDBEntry, info.handle);
+#endif
+
+ PR_fprintf(info.out, "Database had %d certificates.\n", info.nOldCerts);
+
+ PR_fprintf(info.out, "Reconstructed %d certificates.\n", info.nCerts);
+ PR_fprintf(info.out, "(ax) Rejected %d expired certificates.\n",
+ info.dbErrors[dbInvalidCert]);
+ PR_fprintf(info.out, "(as) Rejected %d S/MIME certificates missing a profile.\n",
+ info.dbErrors[dbNoSMimeProfile]);
+ PR_fprintf(info.out, "(ar) Rejected %d certificates for which a newer certificate was found.\n",
+ info.dbErrors[dbOlderCert]);
+ PR_fprintf(info.out, " Rejected %d corrupt certificates.\n",
+ info.dbErrors[dbBadCertificate]);
+ PR_fprintf(info.out, " Rejected %d certificates which did not write to the DB.\n",
+ info.dbErrors[dbCertNotWrittenToDB]);
+
+ if (rv)
+ goto loser;
+
+ return info.handle;
+
+loser:
+ if (info.handle)
+ PORT_Free(info.handle);
+ return NULL;
+}
diff --git a/nss/cmd/dbck/manifest.mn b/nss/cmd/dbck/manifest.mn
new file mode 100644
index 0000000..ec8812e
--- /dev/null
+++ b/nss/cmd/dbck/manifest.mn
@@ -0,0 +1,22 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+CORE_DEPTH = ../..
+
+DEFINES += -DNSPR20
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+CSRCS = \
+ dbck.c \
+ $(NULL)
+
+# The MODULE is always implicitly required.
+# Listing it here in REQUIRES makes it appear twice in the cc command line.
+REQUIRES = dbm seccmd
+
+PROGRAM = dbck
+USE_STATIC_LIBS = 1
diff --git a/nss/cmd/dbtest/Makefile b/nss/cmd/dbtest/Makefile
new file mode 100644
index 0000000..a27a3ce
--- /dev/null
+++ b/nss/cmd/dbtest/Makefile
@@ -0,0 +1,46 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include ../platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+#include ../platlibs.mk
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+include ../platrules.mk
+
diff --git a/nss/cmd/dbtest/dbtest.c b/nss/cmd/dbtest/dbtest.c
new file mode 100644
index 0000000..9a6a034
--- /dev/null
+++ b/nss/cmd/dbtest/dbtest.c
@@ -0,0 +1,244 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+** dbtest.c
+**
+** QA test for cert and key databases, especially to open
+** database readonly (NSS_INIT_READONLY) and force initializations
+** even if the databases cannot be opened (NSS_INIT_FORCEOPEN)
+**
+*/
+#include
+#include
+
+#if defined(WIN32)
+#include "fcntl.h"
+#include "io.h"
+#endif
+
+#include "secutil.h"
+#include "pk11pub.h"
+
+#if defined(XP_UNIX)
+#include
+#endif
+
+#include "nspr.h"
+#include "prtypes.h"
+#include "certdb.h"
+#include "nss.h"
+#include "../modutil/modutil.h"
+
+#include "plgetopt.h"
+
+static char *progName;
+
+char *dbDir = NULL;
+
+static char *dbName[] = { "secmod.db", "cert8.db", "key3.db" };
+static char *dbprefix = "";
+static char *secmodName = "secmod.db";
+static char *userPassword = "";
+PRBool verbose;
+
+static char *
+getPassword(PK11SlotInfo *slot, PRBool retry, void *arg)
+{
+ int *success = (int *)arg;
+
+ if (retry) {
+ *success = 0;
+ return NULL;
+ }
+
+ *success = 1;
+ return PORT_Strdup(userPassword);
+}
+
+static void
+Usage(const char *progName)
+{
+ printf("Usage: %s [-r] [-f] [-i] [-d dbdir ] \n",
+ progName);
+ printf("%-20s open database readonly (NSS_INIT_READONLY)\n", "-r");
+ printf("%-20s Continue to force initializations even if the\n", "-f");
+ printf("%-20s databases cannot be opened (NSS_INIT_FORCEOPEN)\n", " ");
+ printf("%-20s Try to initialize the database\n", "-i");
+ printf("%-20s Supply a password with which to initialize the db\n", "-p");
+ printf("%-20s Directory with cert database (default is .\n",
+ "-d certdir");
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ PLOptState *optstate;
+ PLOptStatus optstatus;
+
+ PRUint32 flags = 0;
+ Error ret;
+ SECStatus rv;
+ char *dbString = NULL;
+ PRBool doInitTest = PR_FALSE;
+ int i;
+
+ progName = strrchr(argv[0], '/');
+ if (!progName)
+ progName = strrchr(argv[0], '\\');
+ progName = progName ? progName + 1 : argv[0];
+
+ optstate = PL_CreateOptState(argc, argv, "rfip:d:h");
+
+ while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
+ switch (optstate->option) {
+ case 'h':
+ default:
+ Usage(progName);
+ break;
+
+ case 'r':
+ flags |= NSS_INIT_READONLY;
+ break;
+
+ case 'f':
+ flags |= NSS_INIT_FORCEOPEN;
+ break;
+
+ case 'i':
+ doInitTest = PR_TRUE;
+ break;
+
+ case 'p':
+ userPassword = PORT_Strdup(optstate->value);
+ break;
+
+ case 'd':
+ dbDir = PORT_Strdup(optstate->value);
+ break;
+ }
+ }
+ PL_DestroyOptState(optstate);
+ if (optstatus == PL_OPT_BAD)
+ Usage(progName);
+
+ if (dbDir) {
+ char *tmp = dbDir;
+ dbDir = SECU_ConfigDirectory(tmp);
+ PORT_Free(tmp);
+ } else {
+ /* Look in $SSL_DIR */
+ dbDir = SECU_ConfigDirectory(SECU_DefaultSSLDir());
+ }
+ PR_fprintf(PR_STDERR, "dbdir selected is %s\n\n", dbDir);
+
+ if (dbDir[0] == '\0') {
+ PR_fprintf(PR_STDERR, errStrings[DIR_DOESNT_EXIST_ERR], dbDir);
+ ret = DIR_DOESNT_EXIST_ERR;
+ goto loser;
+ }
+
+ PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+
+ /* get the status of the directory and databases and output message */
+ if (PR_Access(dbDir, PR_ACCESS_EXISTS) != PR_SUCCESS) {
+ PR_fprintf(PR_STDERR, errStrings[DIR_DOESNT_EXIST_ERR], dbDir);
+ } else if (PR_Access(dbDir, PR_ACCESS_READ_OK) != PR_SUCCESS) {
+ PR_fprintf(PR_STDERR, errStrings[DIR_NOT_READABLE_ERR], dbDir);
+ } else {
+ if (!(flags & NSS_INIT_READONLY) &&
+ PR_Access(dbDir, PR_ACCESS_WRITE_OK) != PR_SUCCESS) {
+ PR_fprintf(PR_STDERR, errStrings[DIR_NOT_WRITEABLE_ERR], dbDir);
+ }
+ if (!doInitTest) {
+ for (i = 0; i < 3; i++) {
+ dbString = PR_smprintf("%s/%s", dbDir, dbName[i]);
+ PR_fprintf(PR_STDOUT, "database checked is %s\n", dbString);
+ if (PR_Access(dbString, PR_ACCESS_EXISTS) != PR_SUCCESS) {
+ PR_fprintf(PR_STDERR, errStrings[FILE_DOESNT_EXIST_ERR],
+ dbString);
+ } else if (PR_Access(dbString, PR_ACCESS_READ_OK) != PR_SUCCESS) {
+ PR_fprintf(PR_STDERR, errStrings[FILE_NOT_READABLE_ERR],
+ dbString);
+ } else if (!(flags & NSS_INIT_READONLY) &&
+ PR_Access(dbString, PR_ACCESS_WRITE_OK) != PR_SUCCESS) {
+ PR_fprintf(PR_STDERR, errStrings[FILE_NOT_WRITEABLE_ERR],
+ dbString);
+ }
+ PR_smprintf_free(dbString);
+ }
+ }
+ }
+
+ rv = NSS_Initialize(SECU_ConfigDirectory(dbDir), dbprefix, dbprefix,
+ secmodName, flags);
+ if (rv != SECSuccess) {
+ SECU_PrintPRandOSError(progName);
+ ret = NSS_INITIALIZE_FAILED_ERR;
+ } else {
+ ret = SUCCESS;
+ if (doInitTest) {
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot();
+ SECStatus rv;
+ int passwordSuccess = 0;
+ int type = CKM_DES3_CBC;
+ SECItem keyid = { 0, NULL, 0 };
+ unsigned char keyIdData[] = { 0xff, 0xfe };
+ PK11SymKey *key = NULL;
+
+ keyid.data = keyIdData;
+ keyid.len = sizeof(keyIdData);
+
+ PK11_SetPasswordFunc(getPassword);
+ rv = PK11_InitPin(slot, (char *)NULL, userPassword);
+ if (rv != SECSuccess) {
+ PR_fprintf(PR_STDERR, "Failed to Init DB: %s\n",
+ SECU_Strerror(PORT_GetError()));
+ ret = CHANGEPW_FAILED_ERR;
+ }
+ if (*userPassword && !PK11_IsLoggedIn(slot, &passwordSuccess)) {
+ PR_fprintf(PR_STDERR, "New DB did not log in after init\n");
+ ret = AUTHENTICATION_FAILED_ERR;
+ }
+ /* generate a symetric key */
+ key = PK11_TokenKeyGen(slot, type, NULL, 0, &keyid,
+ PR_TRUE, &passwordSuccess);
+
+ if (!key) {
+ PR_fprintf(PR_STDERR, "Could not generated symetric key: %s\n",
+ SECU_Strerror(PORT_GetError()));
+ exit(UNSPECIFIED_ERR);
+ }
+ PK11_FreeSymKey(key);
+ PK11_Logout(slot);
+
+ PK11_Authenticate(slot, PR_TRUE, &passwordSuccess);
+
+ if (*userPassword && !passwordSuccess) {
+ PR_fprintf(PR_STDERR, "New DB Did not initalize\n");
+ ret = AUTHENTICATION_FAILED_ERR;
+ }
+ key = PK11_FindFixedKey(slot, type, &keyid, &passwordSuccess);
+
+ if (!key) {
+ PR_fprintf(PR_STDERR, "Could not find generated key: %s\n",
+ SECU_Strerror(PORT_GetError()));
+ ret = UNSPECIFIED_ERR;
+ } else {
+ PK11_FreeSymKey(key);
+ }
+ PK11_FreeSlot(slot);
+ }
+
+ if (NSS_Shutdown() != SECSuccess) {
+ PR_fprintf(PR_STDERR, "Could not find generated key: %s\n",
+ SECU_Strerror(PORT_GetError()));
+ exit(1);
+ }
+ }
+
+loser:
+ return ret;
+}
diff --git a/nss/cmd/dbtest/dbtest.gyp b/nss/cmd/dbtest/dbtest.gyp
new file mode 100644
index 0000000..fb58573
--- /dev/null
+++ b/nss/cmd/dbtest/dbtest.gyp
@@ -0,0 +1,25 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi',
+ '../../cmd/platlibs.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'dbtest',
+ 'type': 'executable',
+ 'sources': [
+ 'dbtest.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:dbm_exports',
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
\ No newline at end of file
diff --git a/nss/cmd/dbtest/manifest.mn b/nss/cmd/dbtest/manifest.mn
new file mode 100644
index 0000000..8f9ec1f
--- /dev/null
+++ b/nss/cmd/dbtest/manifest.mn
@@ -0,0 +1,22 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+CORE_DEPTH = ../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+# This next line is used by .mk files
+# and gets translated into $LINCS in manifest.mnw
+# The MODULE is always implicitly required.
+# Listing it here in REQUIRES makes it appear twice in the cc command line.
+REQUIRES = seccmd dbm
+
+# DIRS =
+
+CSRCS = dbtest.c
+
+PROGRAM = dbtest
+
diff --git a/nss/cmd/derdump/Makefile b/nss/cmd/derdump/Makefile
new file mode 100644
index 0000000..c2039d8
--- /dev/null
+++ b/nss/cmd/derdump/Makefile
@@ -0,0 +1,48 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include ../platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+
+
+include ../platrules.mk
+
diff --git a/nss/cmd/derdump/derdump.c b/nss/cmd/derdump/derdump.c
new file mode 100644
index 0000000..d687a8b
--- /dev/null
+++ b/nss/cmd/derdump/derdump.c
@@ -0,0 +1,128 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "secutil.h"
+#include "nss.h"
+#include
+
+#if defined(XP_WIN) || (defined(__sun) && !defined(SVR4))
+#if !defined(WIN32)
+extern int fprintf(FILE *, char *, ...);
+#endif
+#endif
+#include "plgetopt.h"
+
+static void
+Usage(char *progName)
+{
+ fprintf(stderr,
+ "Usage: %s [-r] [-i input] [-o output]\n",
+ progName);
+ fprintf(stderr, "%-20s For formatted items, dump raw bytes as well\n",
+ "-r");
+ fprintf(stderr, "%-20s Define an input file to use (default is stdin)\n",
+ "-i input");
+ fprintf(stderr, "%-20s Define an output file to use (default is stdout)\n",
+ "-o output");
+ exit(-1);
+}
+
+int
+main(int argc, char **argv)
+{
+ char *progName;
+ FILE *outFile;
+ PRFileDesc *inFile;
+ SECItem der = { siBuffer, NULL, 0 };
+ SECStatus rv;
+ PRInt16 xp_error;
+ PRBool raw = PR_FALSE;
+ PLOptState *optstate;
+ PLOptStatus status;
+ int retval = -1;
+
+ progName = strrchr(argv[0], '/');
+ progName = progName ? progName + 1 : argv[0];
+
+ /* Parse command line arguments */
+ inFile = 0;
+ outFile = 0;
+ optstate = PL_CreateOptState(argc, argv, "i:o:r");
+ while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
+ switch (optstate->option) {
+ case 'i':
+ inFile = PR_Open(optstate->value, PR_RDONLY, 0);
+ if (!inFile) {
+ fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
+ progName, optstate->value);
+ goto cleanup;
+ }
+ break;
+
+ case 'o':
+ outFile = fopen(optstate->value, "w");
+ if (!outFile) {
+ fprintf(stderr, "%s: unable to open \"%s\" for writing\n",
+ progName, optstate->value);
+ goto cleanup;
+ }
+ break;
+
+ case 'r':
+ raw = PR_TRUE;
+ break;
+
+ default:
+ Usage(progName);
+ break;
+ }
+ }
+ if (status == PL_OPT_BAD)
+ Usage(progName);
+
+ if (!inFile)
+ inFile = PR_STDIN;
+ if (!outFile)
+ outFile = stdout;
+
+ rv = NSS_NoDB_Init(NULL);
+ if (rv != SECSuccess) {
+ SECU_PrintPRandOSError(progName);
+ goto cleanup;
+ }
+
+ rv = SECU_ReadDERFromFile(&der, inFile, PR_FALSE, PR_FALSE);
+ if (rv == SECSuccess) {
+ rv = DER_PrettyPrint(outFile, &der, raw);
+ if (rv == SECSuccess) {
+ retval = 0;
+ goto cleanup;
+ }
+ }
+
+ xp_error = PORT_GetError();
+ if (xp_error) {
+ SECU_PrintError(progName, "error %d", xp_error);
+ }
+ if (errno) {
+ SECU_PrintSystemError(progName, "errno=%d", errno);
+ }
+ retval = 1;
+
+cleanup:
+ retval |= NSS_Shutdown();
+ if (inFile) {
+ PR_Close(inFile);
+ }
+ if (outFile) {
+ fflush(outFile);
+ fclose(outFile);
+ }
+ PL_DestroyOptState(optstate);
+ if (der.data) {
+ PORT_Free(der.data);
+ }
+
+ return retval;
+}
diff --git a/nss/cmd/derdump/derdump.gyp b/nss/cmd/derdump/derdump.gyp
new file mode 100644
index 0000000..5637685
--- /dev/null
+++ b/nss/cmd/derdump/derdump.gyp
@@ -0,0 +1,30 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi',
+ '../../cmd/platlibs.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'derdump',
+ 'type': 'executable',
+ 'sources': [
+ 'derdump.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:dbm_exports',
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'target_defaults': {
+ 'defines': [
+ 'NSPR20'
+ ]
+ },
+ 'variables': {
+ 'module': 'nss'
+ }
+}
\ No newline at end of file
diff --git a/nss/cmd/derdump/manifest.mn b/nss/cmd/derdump/manifest.mn
new file mode 100644
index 0000000..0b55037
--- /dev/null
+++ b/nss/cmd/derdump/manifest.mn
@@ -0,0 +1,21 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+CORE_DEPTH = ../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+# This next line is used by .mk files
+# and gets translated into $LINCS in manifest.mnw
+# The MODULE is always implicitly required.
+# Listing it here in REQUIRES makes it appear twice in the cc command line.
+REQUIRES = seccmd dbm
+
+DEFINES = -DNSPR20
+
+CSRCS = derdump.c
+
+PROGRAM = derdump
diff --git a/nss/cmd/digest/Makefile b/nss/cmd/digest/Makefile
new file mode 100644
index 0000000..c2039d8
--- /dev/null
+++ b/nss/cmd/digest/Makefile
@@ -0,0 +1,48 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include ../platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+
+
+include ../platrules.mk
+
diff --git a/nss/cmd/digest/digest.c b/nss/cmd/digest/digest.c
new file mode 100644
index 0000000..8c4c149
--- /dev/null
+++ b/nss/cmd/digest/digest.c
@@ -0,0 +1,228 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "secutil.h"
+#include "pk11func.h"
+#include "secoid.h"
+
+#if defined(XP_WIN) || (defined(__sun) && !defined(SVR4))
+#if !defined(WIN32)
+extern int fread(char *, size_t, size_t, FILE *);
+extern int fwrite(char *, size_t, size_t, FILE *);
+extern int fprintf(FILE *, char *, ...);
+#endif
+#endif
+
+#include "plgetopt.h"
+
+static SECOidData *
+HashTypeToOID(HASH_HashType hashtype)
+{
+ SECOidTag hashtag;
+
+ if (hashtype <= HASH_AlgNULL || hashtype >= HASH_AlgTOTAL)
+ return NULL;
+
+ switch (hashtype) {
+ case HASH_AlgMD2:
+ hashtag = SEC_OID_MD2;
+ break;
+ case HASH_AlgMD5:
+ hashtag = SEC_OID_MD5;
+ break;
+ case HASH_AlgSHA1:
+ hashtag = SEC_OID_SHA1;
+ break;
+ default:
+ fprintf(stderr, "A new hash type has been added to HASH_HashType.\n");
+ fprintf(stderr, "This program needs to be updated!\n");
+ return NULL;
+ }
+
+ return SECOID_FindOIDByTag(hashtag);
+}
+
+static SECOidData *
+HashNameToOID(const char *hashName)
+{
+ HASH_HashType htype;
+ SECOidData *hashOID;
+
+ for (htype = HASH_AlgNULL + 1; htype < HASH_AlgTOTAL; htype++) {
+ hashOID = HashTypeToOID(htype);
+ if (PORT_Strcasecmp(hashName, hashOID->desc) == 0)
+ break;
+ }
+
+ if (htype == HASH_AlgTOTAL)
+ return NULL;
+
+ return hashOID;
+}
+
+static void
+Usage(char *progName)
+{
+ HASH_HashType htype;
+
+ fprintf(stderr,
+ "Usage: %s -t type [-i input] [-o output]\n",
+ progName);
+ fprintf(stderr, "%-20s Specify the digest method (must be one of\n",
+ "-t type");
+ fprintf(stderr, "%-20s ", "");
+ for (htype = HASH_AlgNULL + 1; htype < HASH_AlgTOTAL; htype++) {
+ fprintf(stderr, "%s", HashTypeToOID(htype)->desc);
+ if (htype == (HASH_AlgTOTAL - 2))
+ fprintf(stderr, " or ");
+ else if (htype != (HASH_AlgTOTAL - 1))
+ fprintf(stderr, ", ");
+ }
+ fprintf(stderr, " (case ignored))\n");
+ fprintf(stderr, "%-20s Define an input file to use (default is stdin)\n",
+ "-i input");
+ fprintf(stderr, "%-20s Define an output file to use (default is stdout)\n",
+ "-o output");
+ exit(-1);
+}
+
+static int
+DigestFile(FILE *outFile, FILE *inFile, SECOidData *hashOID)
+{
+ int nb;
+ unsigned char ibuf[4096], digest[32];
+ PK11Context *hashcx;
+ unsigned int len;
+ SECStatus rv;
+
+ hashcx = PK11_CreateDigestContext(hashOID->offset);
+ if (hashcx == NULL) {
+ return -1;
+ }
+ PK11_DigestBegin(hashcx);
+
+ for (;;) {
+ if (feof(inFile))
+ break;
+ nb = fread(ibuf, 1, sizeof(ibuf), inFile);
+ if (nb != sizeof(ibuf)) {
+ if (nb == 0) {
+ if (ferror(inFile)) {
+ PORT_SetError(SEC_ERROR_IO);
+ PK11_DestroyContext(hashcx, PR_TRUE);
+ return -1;
+ }
+ /* eof */
+ break;
+ }
+ }
+ rv = PK11_DigestOp(hashcx, ibuf, nb);
+ if (rv != SECSuccess) {
+ PK11_DestroyContext(hashcx, PR_TRUE);
+ return -1;
+ }
+ }
+
+ rv = PK11_DigestFinal(hashcx, digest, &len, 32);
+ PK11_DestroyContext(hashcx, PR_TRUE);
+
+ if (rv != SECSuccess)
+ return -1;
+
+ nb = fwrite(digest, 1, len, outFile);
+ if (nb != len) {
+ PORT_SetError(SEC_ERROR_IO);
+ return -1;
+ }
+
+ return 0;
+}
+
+#include "nss.h"
+
+int
+main(int argc, char **argv)
+{
+ char *progName;
+ FILE *inFile, *outFile;
+ char *hashName;
+ SECOidData *hashOID;
+ PLOptState *optstate;
+ PLOptStatus status;
+ SECStatus rv;
+
+ progName = strrchr(argv[0], '/');
+ progName = progName ? progName + 1 : argv[0];
+
+ inFile = NULL;
+ outFile = NULL;
+ hashName = NULL;
+
+ rv = NSS_Init("/tmp");
+ if (rv != SECSuccess) {
+ fprintf(stderr, "%s: NSS_Init failed in directory %s\n",
+ progName, "/tmp");
+ return -1;
+ }
+
+ /*
+ * Parse command line arguments
+ */
+ optstate = PL_CreateOptState(argc, argv, "t:i:o:");
+ while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
+ switch (optstate->option) {
+ case '?':
+ Usage(progName);
+ break;
+
+ case 'i':
+ inFile = fopen(optstate->value, "r");
+ if (!inFile) {
+ fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
+ progName, optstate->value);
+ return -1;
+ }
+ break;
+
+ case 'o':
+ outFile = fopen(optstate->value, "w");
+ if (!outFile) {
+ fprintf(stderr, "%s: unable to open \"%s\" for writing\n",
+ progName, optstate->value);
+ return -1;
+ }
+ break;
+
+ case 't':
+ hashName = strdup(optstate->value);
+ break;
+ }
+ }
+
+ if (!hashName)
+ Usage(progName);
+
+ if (!inFile)
+ inFile = stdin;
+ if (!outFile)
+ outFile = stdout;
+
+ hashOID = HashNameToOID(hashName);
+ if (hashOID == NULL) {
+ fprintf(stderr, "%s: invalid digest type\n", progName);
+ Usage(progName);
+ }
+
+ if (DigestFile(outFile, inFile, hashOID)) {
+ fprintf(stderr, "%s: problem digesting data (%s)\n",
+ progName, SECU_Strerror(PORT_GetError()));
+ return -1;
+ }
+
+ if (NSS_Shutdown() != SECSuccess) {
+ exit(1);
+ }
+
+ return 0;
+}
diff --git a/nss/cmd/digest/digest.gyp b/nss/cmd/digest/digest.gyp
new file mode 100644
index 0000000..c2e0028
--- /dev/null
+++ b/nss/cmd/digest/digest.gyp
@@ -0,0 +1,30 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi',
+ '../../cmd/platlibs.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'digest',
+ 'type': 'executable',
+ 'sources': [
+ 'digest.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:dbm_exports',
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'target_defaults': {
+ 'defines': [
+ 'NSPR20'
+ ]
+ },
+ 'variables': {
+ 'module': 'nss'
+ }
+}
\ No newline at end of file
diff --git a/nss/cmd/digest/manifest.mn b/nss/cmd/digest/manifest.mn
new file mode 100644
index 0000000..3e76406
--- /dev/null
+++ b/nss/cmd/digest/manifest.mn
@@ -0,0 +1,22 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+CORE_DEPTH = ../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+# This next line is used by .mk files
+# and gets translated into $LINCS in manifest.mnw
+# The MODULE is always implicitly required.
+# Listing it here in REQUIRES makes it appear twice in the cc command line.
+REQUIRES = seccmd dbm
+
+DEFINES = -DNSPR20
+
+CSRCS = digest.c
+
+PROGRAM = digest
+
diff --git a/nss/cmd/ecperf/Makefile b/nss/cmd/ecperf/Makefile
new file mode 100644
index 0000000..7b74b36
--- /dev/null
+++ b/nss/cmd/ecperf/Makefile
@@ -0,0 +1,46 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+include ../platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+
+include ../platrules.mk
+
diff --git a/nss/cmd/ecperf/ecperf.c b/nss/cmd/ecperf/ecperf.c
new file mode 100644
index 0000000..40ba3c8
--- /dev/null
+++ b/nss/cmd/ecperf/ecperf.c
@@ -0,0 +1,727 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "blapi.h"
+#include "ec.h"
+#include "ecl-curve.h"
+#include "prprf.h"
+#include "basicutil.h"
+#include "pkcs11.h"
+#include "nspr.h"
+#include
+
+#define __PASTE(x, y) x##y
+
+/*
+ * Get the NSS specific PKCS #11 function names.
+ */
+#undef CK_PKCS11_FUNCTION_INFO
+#undef CK_NEED_ARG_LIST
+
+#define CK_EXTERN extern
+#define CK_PKCS11_FUNCTION_INFO(func) \
+ CK_RV __PASTE(NS, func)
+#define CK_NEED_ARG_LIST 1
+
+#include "pkcs11f.h"
+
+/* mapping between ECCurveName enum and pointers to ECCurveParams */
+static SECOidTag ecCurve_oid_map[] = {
+ SEC_OID_UNKNOWN, /* ECCurve_noName */
+ SEC_OID_ANSIX962_EC_PRIME192V1, /* ECCurve_NIST_P192 */
+ SEC_OID_SECG_EC_SECP224R1, /* ECCurve_NIST_P224 */
+ SEC_OID_ANSIX962_EC_PRIME256V1, /* ECCurve_NIST_P256 */
+ SEC_OID_SECG_EC_SECP384R1, /* ECCurve_NIST_P384 */
+ SEC_OID_SECG_EC_SECP521R1, /* ECCurve_NIST_P521 */
+ SEC_OID_SECG_EC_SECT163K1, /* ECCurve_NIST_K163 */
+ SEC_OID_SECG_EC_SECT163R1, /* ECCurve_NIST_B163 */
+ SEC_OID_SECG_EC_SECT233K1, /* ECCurve_NIST_K233 */
+ SEC_OID_SECG_EC_SECT233R1, /* ECCurve_NIST_B233 */
+ SEC_OID_SECG_EC_SECT283K1, /* ECCurve_NIST_K283 */
+ SEC_OID_SECG_EC_SECT283R1, /* ECCurve_NIST_B283 */
+ SEC_OID_SECG_EC_SECT409K1, /* ECCurve_NIST_K409 */
+ SEC_OID_SECG_EC_SECT409R1, /* ECCurve_NIST_B409 */
+ SEC_OID_SECG_EC_SECT571K1, /* ECCurve_NIST_K571 */
+ SEC_OID_SECG_EC_SECT571R1, /* ECCurve_NIST_B571 */
+ SEC_OID_ANSIX962_EC_PRIME192V2,
+ SEC_OID_ANSIX962_EC_PRIME192V3,
+ SEC_OID_ANSIX962_EC_PRIME239V1,
+ SEC_OID_ANSIX962_EC_PRIME239V2,
+ SEC_OID_ANSIX962_EC_PRIME239V3,
+ SEC_OID_ANSIX962_EC_C2PNB163V1,
+ SEC_OID_ANSIX962_EC_C2PNB163V2,
+ SEC_OID_ANSIX962_EC_C2PNB163V3,
+ SEC_OID_ANSIX962_EC_C2PNB176V1,
+ SEC_OID_ANSIX962_EC_C2TNB191V1,
+ SEC_OID_ANSIX962_EC_C2TNB191V2,
+ SEC_OID_ANSIX962_EC_C2TNB191V3,
+ SEC_OID_ANSIX962_EC_C2PNB208W1,
+ SEC_OID_ANSIX962_EC_C2TNB239V1,
+ SEC_OID_ANSIX962_EC_C2TNB239V2,
+ SEC_OID_ANSIX962_EC_C2TNB239V3,
+ SEC_OID_ANSIX962_EC_C2PNB272W1,
+ SEC_OID_ANSIX962_EC_C2PNB304W1,
+ SEC_OID_ANSIX962_EC_C2TNB359V1,
+ SEC_OID_ANSIX962_EC_C2PNB368W1,
+ SEC_OID_ANSIX962_EC_C2TNB431R1,
+ SEC_OID_SECG_EC_SECP112R1,
+ SEC_OID_SECG_EC_SECP112R2,
+ SEC_OID_SECG_EC_SECP128R1,
+ SEC_OID_SECG_EC_SECP128R2,
+ SEC_OID_SECG_EC_SECP160K1,
+ SEC_OID_SECG_EC_SECP160R1,
+ SEC_OID_SECG_EC_SECP160R2,
+ SEC_OID_SECG_EC_SECP192K1,
+ SEC_OID_SECG_EC_SECP224K1,
+ SEC_OID_SECG_EC_SECP256K1,
+ SEC_OID_SECG_EC_SECT113R1,
+ SEC_OID_SECG_EC_SECT113R2,
+ SEC_OID_SECG_EC_SECT131R1,
+ SEC_OID_SECG_EC_SECT131R2,
+ SEC_OID_SECG_EC_SECT163R1,
+ SEC_OID_SECG_EC_SECT193R1,
+ SEC_OID_SECG_EC_SECT193R2,
+ SEC_OID_SECG_EC_SECT239K1,
+ SEC_OID_UNKNOWN, /* ECCurve_WTLS_1 */
+ SEC_OID_UNKNOWN, /* ECCurve_WTLS_8 */
+ SEC_OID_UNKNOWN, /* ECCurve_WTLS_9 */
+ SEC_OID_CURVE25519,
+ SEC_OID_UNKNOWN /* ECCurve_pastLastCurve */
+};
+
+typedef SECStatus (*op_func)(void *, void *, void *);
+typedef SECStatus (*pk11_op_func)(CK_SESSION_HANDLE, void *, void *, void *);
+
+typedef struct ThreadDataStr {
+ op_func op;
+ void *p1;
+ void *p2;
+ void *p3;
+ int iters;
+ PRLock *lock;
+ int count;
+ SECStatus status;
+ int isSign;
+} ThreadData;
+
+typedef SECItem SECKEYECParams;
+
+void
+PKCS11Thread(void *data)
+{
+ ThreadData *threadData = (ThreadData *)data;
+ pk11_op_func op = (pk11_op_func)threadData->op;
+ int iters = threadData->iters;
+ unsigned char sigData[256];
+ SECItem sig;
+ CK_SESSION_HANDLE session;
+ CK_RV crv;
+
+ threadData->status = SECSuccess;
+ threadData->count = 0;
+
+ /* get our thread's session */
+ PR_Lock(threadData->lock);
+ crv = NSC_OpenSession(1, CKF_SERIAL_SESSION, NULL, 0, &session);
+ PR_Unlock(threadData->lock);
+ if (crv != CKR_OK) {
+ return;
+ }
+
+ if (threadData->isSign) {
+ sig.data = sigData;
+ sig.len = sizeof(sigData);
+ threadData->p2 = (void *)&sig;
+ }
+
+ while (iters--) {
+ threadData->status = (*op)(session, threadData->p1,
+ threadData->p2, threadData->p3);
+ if (threadData->status != SECSuccess) {
+ break;
+ }
+ threadData->count++;
+ }
+ return;
+}
+
+void
+genericThread(void *data)
+{
+ ThreadData *threadData = (ThreadData *)data;
+ int iters = threadData->iters;
+ unsigned char sigData[256];
+ SECItem sig;
+
+ threadData->status = SECSuccess;
+ threadData->count = 0;
+
+ if (threadData->isSign) {
+ sig.data = sigData;
+ sig.len = sizeof(sigData);
+ threadData->p2 = (void *)&sig;
+ }
+
+ while (iters--) {
+ threadData->status = (*threadData->op)(threadData->p1,
+ threadData->p2, threadData->p3);
+ if (threadData->status != SECSuccess) {
+ break;
+ }
+ threadData->count++;
+ }
+ return;
+}
+
+/* Time iter repetitions of operation op. */
+SECStatus
+M_TimeOperation(void (*threadFunc)(void *),
+ op_func opfunc, char *op, void *param1, void *param2,
+ void *param3, int iters, int numThreads, PRLock *lock,
+ CK_SESSION_HANDLE session, int isSign, double *rate)
+{
+ double dUserTime;
+ int i, total;
+ PRIntervalTime startTime, totalTime;
+ PRThread **threadIDs;
+ ThreadData *threadData;
+ pk11_op_func pk11_op = (pk11_op_func)opfunc;
+ SECStatus rv;
+
+ /* verify operation works before testing performance */
+ if (session) {
+ rv = (*pk11_op)(session, param1, param2, param3);
+ } else {
+ rv = (*opfunc)(param1, param2, param3);
+ }
+ if (rv != SECSuccess) {
+ SECU_PrintError("Error:", op);
+ return rv;
+ }
+
+ /* get Data structures */
+ threadIDs = (PRThread **)PORT_Alloc(numThreads * sizeof(PRThread *));
+ threadData = (ThreadData *)PORT_Alloc(numThreads * sizeof(ThreadData));
+
+ startTime = PR_Now();
+ if (numThreads == 1) {
+ for (i = 0; i < iters; i++) {
+ if (session) {
+ rv = (*pk11_op)(session, param1, param2, param3);
+ } else {
+ rv = (*opfunc)(param1, param2, param3);
+ }
+ if (rv != SECSuccess) {
+ PORT_Free(threadIDs);
+ PORT_Free(threadData);
+ SECU_PrintError("Error:", op);
+ return rv;
+ }
+ }
+ total = iters;
+ } else {
+ for (i = 0; i < numThreads; i++) {
+ threadData[i].op = opfunc;
+ threadData[i].p1 = (void *)param1;
+ threadData[i].p2 = (void *)param2;
+ threadData[i].p3 = (void *)param3;
+ threadData[i].iters = iters;
+ threadData[i].lock = lock;
+ threadData[i].isSign = isSign;
+ threadIDs[i] = PR_CreateThread(PR_USER_THREAD, threadFunc,
+ (void *)&threadData[i], PR_PRIORITY_NORMAL,
+ PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+ }
+
+ total = 0;
+ for (i = 0; i < numThreads; i++) {
+ PR_JoinThread(threadIDs[i]);
+ /* check the status */
+ total += threadData[i].count;
+ }
+ }
+
+ totalTime = PR_Now() - startTime;
+ /* SecondsToInterval seems to be broken here ... */
+ dUserTime = (double)totalTime / (double)1000000;
+ if (dUserTime) {
+ printf(" %-15s count:%4d sec: %3.2f op/sec: %6.2f\n",
+ op, total, dUserTime, (double)total / dUserTime);
+ if (rate) {
+ *rate = ((double)total) / dUserTime;
+ }
+ }
+ PORT_Free(threadIDs);
+ PORT_Free(threadData);
+
+ return SECSuccess;
+}
+
+/* Test curve using specific field arithmetic. */
+#define ECTEST_NAMED_GFP(name_c, name_v) \
+ if (usefreebl) { \
+ printf("Testing %s using freebl implementation...\n", name_c); \
+ rv = ectest_curve_freebl(name_v, iterations, numThreads, ec_field_GFp); \
+ if (rv != SECSuccess) \
+ goto cleanup; \
+ printf("... okay.\n"); \
+ } \
+ if (usepkcs11) { \
+ printf("Testing %s using pkcs11 implementation...\n", name_c); \
+ rv = ectest_curve_pkcs11(name_v, iterations, numThreads); \
+ if (rv != SECSuccess) \
+ goto cleanup; \
+ printf("... okay.\n"); \
+ }
+
+/* Test curve using specific field arithmetic. */
+#define ECTEST_NAMED_CUSTOM(name_c, name_v) \
+ if (usefreebl) { \
+ printf("Testing %s using freebl implementation...\n", name_c); \
+ rv = ectest_curve_freebl(name_v, iterations, numThreads, ec_field_plain); \
+ if (rv != SECSuccess) \
+ goto cleanup; \
+ printf("... okay.\n"); \
+ } \
+ if (usepkcs11) { \
+ printf("Testing %s using pkcs11 implementation...\n", name_c); \
+ rv = ectest_curve_pkcs11(name_v, iterations, numThreads); \
+ if (rv != SECSuccess) \
+ goto cleanup; \
+ printf("... okay.\n"); \
+ }
+
+#define PK11_SETATTRS(x, id, v, l) \
+ (x)->type = (id); \
+ (x)->pValue = (v); \
+ (x)->ulValueLen = (l);
+
+SECStatus
+PKCS11_Derive(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hKey,
+ CK_MECHANISM *pMech, int *dummy)
+{
+ CK_RV crv;
+ CK_OBJECT_HANDLE newKey;
+ CK_BBOOL cktrue = CK_TRUE;
+ CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
+ CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
+ CK_ATTRIBUTE keyTemplate[3];
+ CK_ATTRIBUTE *attrs = keyTemplate;
+
+ PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass));
+ attrs++;
+ PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType));
+ attrs++;
+ PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, 1);
+ attrs++;
+
+ crv = NSC_DeriveKey(session, pMech, *hKey, keyTemplate, 3, &newKey);
+ if (crv != CKR_OK) {
+ printf("Derive Failed CK_RV=0x%x\n", (int)crv);
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+SECStatus
+PKCS11_Sign(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hKey,
+ SECItem *sig, SECItem *digest)
+{
+ CK_RV crv;
+ CK_MECHANISM mech;
+ CK_ULONG sigLen = sig->len;
+
+ mech.mechanism = CKM_ECDSA;
+ mech.pParameter = NULL;
+ mech.ulParameterLen = 0;
+
+ crv = NSC_SignInit(session, &mech, *hKey);
+ if (crv != CKR_OK) {
+ printf("Sign Failed CK_RV=0x%x\n", (int)crv);
+ return SECFailure;
+ }
+ crv = NSC_Sign(session, digest->data, digest->len, sig->data, &sigLen);
+ if (crv != CKR_OK) {
+ printf("Sign Failed CK_RV=0x%x\n", (int)crv);
+ return SECFailure;
+ }
+ sig->len = (unsigned int)sigLen;
+ return SECSuccess;
+}
+
+SECStatus
+PKCS11_Verify(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hKey,
+ SECItem *sig, SECItem *digest)
+{
+ CK_RV crv;
+ CK_MECHANISM mech;
+
+ mech.mechanism = CKM_ECDSA;
+ mech.pParameter = NULL;
+ mech.ulParameterLen = 0;
+
+ crv = NSC_VerifyInit(session, &mech, *hKey);
+ if (crv != CKR_OK) {
+ printf("Verify Failed CK_RV=0x%x\n", (int)crv);
+ return SECFailure;
+ }
+ crv = NSC_Verify(session, digest->data, digest->len, sig->data, sig->len);
+ if (crv != CKR_OK) {
+ printf("Verify Failed CK_RV=0x%x\n", (int)crv);
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+static SECStatus
+ecName2params(ECCurveName curve, SECKEYECParams *params)
+{
+ SECOidData *oidData = NULL;
+
+ if ((curve < ECCurve_noName) || (curve > ECCurve_pastLastCurve) ||
+ ((oidData = SECOID_FindOIDByTag(ecCurve_oid_map[curve])) == NULL)) {
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
+ return SECFailure;
+ }
+
+ SECITEM_AllocItem(NULL, params, (2 + oidData->oid.len));
+ /*
+ * params->data needs to contain the ASN encoding of an object ID (OID)
+ * representing the named curve. The actual OID is in
+ * oidData->oid.data so we simply prepend 0x06 and OID length
+ */
+ params->data[0] = SEC_ASN1_OBJECT_ID;
+ params->data[1] = oidData->oid.len;
+ memcpy(params->data + 2, oidData->oid.data, oidData->oid.len);
+
+ return SECSuccess;
+}
+
+/* Performs basic tests of elliptic curve cryptography over prime fields.
+ * If tests fail, then it prints an error message, aborts, and returns an
+ * error code. Otherwise, returns 0. */
+SECStatus
+ectest_curve_pkcs11(ECCurveName curve, int iterations, int numThreads)
+{
+ CK_OBJECT_HANDLE ecPriv;
+ CK_OBJECT_HANDLE ecPub;
+ CK_SESSION_HANDLE session;
+ SECItem sig;
+ SECItem digest;
+ SECKEYECParams ecParams;
+ CK_MECHANISM mech;
+ CK_ECDH1_DERIVE_PARAMS ecdh_params;
+ unsigned char sigData[256];
+ unsigned char digestData[20];
+ unsigned char pubKeyData[256];
+ PRLock *lock = NULL;
+ double signRate, deriveRate = 0;
+ CK_ATTRIBUTE template;
+ SECStatus rv;
+ CK_RV crv;
+
+ ecParams.data = NULL;
+ ecParams.len = 0;
+ rv = ecName2params(curve, &ecParams);
+ if (rv != SECSuccess) {
+ goto cleanup;
+ }
+
+ crv = NSC_OpenSession(1, CKF_SERIAL_SESSION, NULL, 0, &session);
+ if (crv != CKR_OK) {
+ printf("OpenSession Failed CK_RV=0x%x\n", (int)crv);
+ return SECFailure;
+ }
+
+ PORT_Memset(digestData, 0xa5, sizeof(digestData));
+ digest.data = digestData;
+ digest.len = sizeof(digestData);
+ sig.data = sigData;
+ sig.len = sizeof(sigData);
+
+ template.type = CKA_EC_PARAMS;
+ template.pValue = ecParams.data;
+ template.ulValueLen = ecParams.len;
+ mech.mechanism = CKM_EC_KEY_PAIR_GEN;
+ mech.pParameter = NULL;
+ mech.ulParameterLen = 0;
+ crv = NSC_GenerateKeyPair(session, &mech,
+ &template, 1, NULL, 0, &ecPub, &ecPriv);
+ if (crv != CKR_OK) {
+ printf("GenerateKeyPair Failed CK_RV=0x%x\n", (int)crv);
+ return SECFailure;
+ }
+
+ template.type = CKA_EC_POINT;
+ template.pValue = pubKeyData;
+ template.ulValueLen = sizeof(pubKeyData);
+ crv = NSC_GetAttributeValue(session, ecPub, &template, 1);
+ if (crv != CKR_OK) {
+ printf("GenerateKeyPair Failed CK_RV=0x%x\n", (int)crv);
+ return SECFailure;
+ }
+
+ ecdh_params.kdf = CKD_NULL;
+ ecdh_params.ulSharedDataLen = 0;
+ ecdh_params.pSharedData = NULL;
+ ecdh_params.ulPublicDataLen = template.ulValueLen;
+ ecdh_params.pPublicData = template.pValue;
+
+ mech.mechanism = CKM_ECDH1_DERIVE;
+ mech.pParameter = (void *)&ecdh_params;
+ mech.ulParameterLen = sizeof(ecdh_params);
+
+ lock = PR_NewLock();
+
+ if (ecCurve_map[curve]->usage & KU_KEY_AGREEMENT) {
+ rv = M_TimeOperation(PKCS11Thread, (op_func)PKCS11_Derive, "ECDH_Derive",
+ &ecPriv, &mech, NULL, iterations, numThreads,
+ lock, session, 0, &deriveRate);
+ if (rv != SECSuccess) {
+ goto cleanup;
+ }
+ }
+
+ if (ecCurve_map[curve]->usage & KU_DIGITAL_SIGNATURE) {
+ rv = M_TimeOperation(PKCS11Thread, (op_func)PKCS11_Sign, "ECDSA_Sign",
+ (void *)&ecPriv, &sig, &digest, iterations, numThreads,
+ lock, session, 1, &signRate);
+ if (rv != SECSuccess) {
+ goto cleanup;
+ }
+ printf(" ECDHE max rate = %.2f\n", (deriveRate + signRate) / 4.0);
+ /* get a signature */
+ rv = PKCS11_Sign(session, &ecPriv, &sig, &digest);
+ if (rv != SECSuccess) {
+ goto cleanup;
+ }
+ rv = M_TimeOperation(PKCS11Thread, (op_func)PKCS11_Verify, "ECDSA_Verify",
+ (void *)&ecPub, &sig, &digest, iterations, numThreads,
+ lock, session, 0, NULL);
+ if (rv != SECSuccess) {
+ goto cleanup;
+ }
+ }
+
+cleanup:
+ if (lock) {
+ PR_DestroyLock(lock);
+ }
+ return rv;
+}
+
+SECStatus
+ECDH_DeriveWrap(ECPrivateKey *priv, ECPublicKey *pub, int *dummy)
+{
+ SECItem secret;
+ unsigned char secretData[256];
+ SECStatus rv;
+
+ secret.data = secretData;
+ secret.len = sizeof(secretData);
+
+ rv = ECDH_Derive(&pub->publicValue, &pub->ecParams,
+ &priv->privateValue, 0, &secret);
+ SECITEM_FreeItem(&secret, PR_FALSE);
+ return rv;
+}
+
+/* Performs basic tests of elliptic curve cryptography over prime fields.
+ * If tests fail, then it prints an error message, aborts, and returns an
+ * error code. Otherwise, returns 0. */
+SECStatus
+ectest_curve_freebl(ECCurveName curve, int iterations, int numThreads,
+ ECFieldType fieldType)
+{
+ ECParams ecParams = { 0 };
+ ECPrivateKey *ecPriv = NULL;
+ ECPublicKey ecPub;
+ SECItem sig;
+ SECItem digest;
+ unsigned char sigData[256];
+ unsigned char digestData[20];
+ double signRate, deriveRate = 0;
+ char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];
+ SECStatus rv = SECFailure;
+ PLArenaPool *arena;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ return SECFailure;
+ }
+
+ if ((curve < ECCurve_noName) || (curve > ECCurve_pastLastCurve)) {
+ PORT_FreeArena(arena, PR_FALSE);
+ return SECFailure;
+ }
+
+ ecParams.name = curve;
+ ecParams.type = ec_params_named;
+ ecParams.curveOID.data = NULL;
+ ecParams.curveOID.len = 0;
+ ecParams.curve.seed.data = NULL;
+ ecParams.curve.seed.len = 0;
+ ecParams.DEREncoding.data = NULL;
+ ecParams.DEREncoding.len = 0;
+
+ ecParams.fieldID.size = ecCurve_map[curve]->size;
+ ecParams.fieldID.type = fieldType;
+ SECU_HexString2SECItem(arena, &ecParams.fieldID.u.prime, ecCurve_map[curve]->irr);
+ SECU_HexString2SECItem(arena, &ecParams.curve.a, ecCurve_map[curve]->curvea);
+ SECU_HexString2SECItem(arena, &ecParams.curve.b, ecCurve_map[curve]->curveb);
+ genenc[0] = '0';
+ genenc[1] = '4';
+ genenc[2] = '\0';
+ strcat(genenc, ecCurve_map[curve]->genx);
+ strcat(genenc, ecCurve_map[curve]->geny);
+ SECU_HexString2SECItem(arena, &ecParams.base, genenc);
+ SECU_HexString2SECItem(arena, &ecParams.order, ecCurve_map[curve]->order);
+ ecParams.cofactor = ecCurve_map[curve]->cofactor;
+
+ PORT_Memset(digestData, 0xa5, sizeof(digestData));
+ digest.data = digestData;
+ digest.len = sizeof(digestData);
+ sig.data = sigData;
+ sig.len = sizeof(sigData);
+
+ rv = EC_NewKey(&ecParams, &ecPriv);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ ecPub.ecParams = ecParams;
+ ecPub.publicValue = ecPriv->publicValue;
+
+ if (ecCurve_map[curve]->usage & KU_KEY_AGREEMENT) {
+ rv = M_TimeOperation(genericThread, (op_func)ECDH_DeriveWrap, "ECDH_Derive",
+ ecPriv, &ecPub, NULL, iterations, numThreads, 0, 0, 0, &deriveRate);
+ if (rv != SECSuccess) {
+ goto cleanup;
+ }
+ }
+
+ if (ecCurve_map[curve]->usage & KU_DIGITAL_SIGNATURE) {
+ rv = M_TimeOperation(genericThread, (op_func)ECDSA_SignDigest, "ECDSA_Sign",
+ ecPriv, &sig, &digest, iterations, numThreads, 0, 0, 1, &signRate);
+ if (rv != SECSuccess)
+ goto cleanup;
+ printf(" ECDHE max rate = %.2f\n", (deriveRate + signRate) / 4.0);
+ rv = ECDSA_SignDigest(ecPriv, &sig, &digest);
+ if (rv != SECSuccess) {
+ goto cleanup;
+ }
+ rv = M_TimeOperation(genericThread, (op_func)ECDSA_VerifyDigest, "ECDSA_Verify",
+ &ecPub, &sig, &digest, iterations, numThreads, 0, 0, 0, NULL);
+ if (rv != SECSuccess) {
+ goto cleanup;
+ }
+ }
+
+cleanup:
+ PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(ecPriv->ecParams.arena, PR_FALSE);
+ return rv;
+}
+
+/* Prints help information. */
+void
+printUsage(char *prog)
+{
+ printf("Usage: %s [-i iterations] [-t threads ] [-ans] [-fp] [-Al]\n"
+ "-a: ansi\n-n: nist\n-s: secp\n-f: usefreebl\n-p: usepkcs11\n-A: all\n",
+ prog);
+}
+
+/* Performs tests of elliptic curve cryptography over prime fields If
+ * tests fail, then it prints an error message, aborts, and returns an
+ * error code. Otherwise, returns 0. */
+int
+main(int argv, char **argc)
+{
+ int ansi = 0;
+ int nist = 0;
+ int secp = 0;
+ int usefreebl = 0;
+ int usepkcs11 = 0;
+ int i;
+ SECStatus rv = SECSuccess;
+ int iterations = 100;
+ int numThreads = 1;
+
+ const CK_C_INITIALIZE_ARGS pk11args = {
+ NULL, NULL, NULL, NULL, CKF_LIBRARY_CANT_CREATE_OS_THREADS,
+ (void *)"flags=readOnly,noCertDB,noModDB", NULL
+ };
+
+ /* read command-line arguments */
+ for (i = 1; i < argv; i++) {
+ if (PL_strcasecmp(argc[i], "-i") == 0) {
+ i++;
+ iterations = atoi(argc[i]);
+ } else if (PL_strcasecmp(argc[i], "-t") == 0) {
+ i++;
+ numThreads = atoi(argc[i]);
+ } else if (PL_strcasecmp(argc[i], "-A") == 0) {
+ ansi = nist = secp = 1;
+ usepkcs11 = usefreebl = 1;
+ } else if (PL_strcasecmp(argc[i], "-a") == 0) {
+ ansi = 1;
+ } else if (PL_strcasecmp(argc[i], "-n") == 0) {
+ nist = 1;
+ } else if (PL_strcasecmp(argc[i], "-s") == 0) {
+ secp = 1;
+ } else if (PL_strcasecmp(argc[i], "-p") == 0) {
+ usepkcs11 = 1;
+ } else if (PL_strcasecmp(argc[i], "-f") == 0) {
+ usefreebl = 1;
+ } else {
+ printUsage(argc[0]);
+ return 0;
+ }
+ }
+
+ if ((ansi | nist | secp) == 0) {
+ nist = 1;
+ }
+ if ((usepkcs11 | usefreebl) == 0) {
+ usefreebl = 1;
+ }
+
+ rv = RNG_RNGInit();
+ if (rv != SECSuccess) {
+ SECU_PrintError("Error:", "RNG_RNGInit");
+ return -1;
+ }
+ RNG_SystemInfoForRNG();
+
+ rv = SECOID_Init();
+ if (rv != SECSuccess) {
+ SECU_PrintError("Error:", "SECOID_Init");
+ goto cleanup;
+ }
+
+ if (usepkcs11) {
+ CK_RV crv = NSC_Initialize((CK_VOID_PTR)&pk11args);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_Initialize failed crv=0x%x\n", (unsigned int)crv);
+ return SECFailure;
+ }
+ }
+
+ /* specific arithmetic tests */
+ if (nist) {
+ ECTEST_NAMED_GFP("NIST-P256", ECCurve_NIST_P256);
+ ECTEST_NAMED_GFP("NIST-P384", ECCurve_NIST_P384);
+ ECTEST_NAMED_GFP("NIST-P521", ECCurve_NIST_P521);
+ ECTEST_NAMED_CUSTOM("Curve25519", ECCurve25519);
+ }
+
+cleanup:
+ rv |= SECOID_Shutdown();
+ RNG_RNGShutdown();
+
+ if (rv != SECSuccess) {
+ printf("Error: exiting with error value\n");
+ }
+ return rv;
+}
diff --git a/nss/cmd/ecperf/ecperf.gyp b/nss/cmd/ecperf/ecperf.gyp
new file mode 100644
index 0000000..c6e9944
--- /dev/null
+++ b/nss/cmd/ecperf/ecperf.gyp
@@ -0,0 +1,35 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi',
+ '../../cmd/platlibs.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'ecperf',
+ 'type': 'executable',
+ 'sources': [
+ 'ecperf.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:dbm_exports',
+ '<(DEPTH)/exports.gyp:nss_exports',
+ '<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3'
+ ]
+ }
+ ],
+ 'target_defaults': {
+ 'include_dirs': [
+ '<(DEPTH)/lib/softoken',
+ ],
+ 'defines': [
+ 'NSS_USE_STATIC_LIBS'
+ ]
+ },
+ 'variables': {
+ 'module': 'nss',
+ 'use_static_libs': 1
+ }
+}
\ No newline at end of file
diff --git a/nss/cmd/ecperf/manifest.mn b/nss/cmd/ecperf/manifest.mn
new file mode 100755
index 0000000..96cdc5a
--- /dev/null
+++ b/nss/cmd/ecperf/manifest.mn
@@ -0,0 +1,18 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEPTH = ../..
+CORE_DEPTH = ../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+INCLUDES += -I$(CORE_DEPTH)/nss/lib/softoken
+
+CSRCS = ecperf.c
+
+PROGRAM = ecperf
+
+USE_STATIC_LIBS = 1
diff --git a/nss/cmd/ectest/Makefile b/nss/cmd/ectest/Makefile
new file mode 100644
index 0000000..d20daa4
--- /dev/null
+++ b/nss/cmd/ectest/Makefile
@@ -0,0 +1,46 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+include ../platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+
+include ../platrules.mk
+
diff --git a/nss/cmd/ectest/ectest.c b/nss/cmd/ectest/ectest.c
new file mode 100644
index 0000000..545fbdd
--- /dev/null
+++ b/nss/cmd/ectest/ectest.c
@@ -0,0 +1,186 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "blapi.h"
+#include "ec.h"
+#include "ecl-curve.h"
+#include "prprf.h"
+#include "basicutil.h"
+#include "secder.h"
+#include "secitem.h"
+#include "nspr.h"
+#include
+
+typedef struct {
+ ECCurveName curve;
+ char *privhex;
+ char *our_pubhex;
+ char *their_pubhex;
+ char *common_key;
+ char *name;
+} ECDH_KAT;
+
+#include "testvecs.h"
+
+/*
+ * Initializes a SECItem from a hexadecimal string
+ *
+ */
+static SECItem *
+hexString2SECItem(PLArenaPool *arena, SECItem *item, const char *str)
+{
+ int i = 0;
+ int byteval = 0;
+ int tmp = PORT_Strlen(str);
+
+ PORT_Assert(arena);
+ PORT_Assert(item);
+
+ if ((tmp % 2) != 0) {
+ return NULL;
+ }
+
+ item = SECITEM_AllocItem(arena, item, tmp / 2);
+ if (item == NULL) {
+ return NULL;
+ }
+
+ while (str[i]) {
+ if ((str[i] >= '0') && (str[i] <= '9')) {
+ tmp = str[i] - '0';
+ } else if ((str[i] >= 'a') && (str[i] <= 'f')) {
+ tmp = str[i] - 'a' + 10;
+ } else if ((str[i] >= 'A') && (str[i] <= 'F')) {
+ tmp = str[i] - 'A' + 10;
+ } else {
+ /* item is in arena and gets freed by the caller */
+ return NULL;
+ }
+
+ byteval = byteval * 16 + tmp;
+ if ((i % 2) != 0) {
+ item->data[i / 2] = byteval;
+ byteval = 0;
+ }
+ i++;
+ }
+
+ return item;
+}
+
+SECStatus
+ectest_ecdh_kat(ECDH_KAT *kat)
+{
+ ECCurveName curve = kat->curve;
+ ECParams ecParams = { 0 };
+ ECPrivateKey *ecPriv = NULL;
+ SECItem theirKey = { siBuffer, NULL, 0 };
+ SECStatus rv = SECFailure;
+ PLArenaPool *arena;
+ SECItem seed = { siBuffer, NULL, 0 };
+ SECItem answer = { siBuffer, NULL, 0 };
+ SECItem answer2 = { siBuffer, NULL, 0 };
+ SECItem derived = { siBuffer, NULL, 0 };
+ char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ return SECFailure;
+ }
+
+ if ((curve < ECCurve_noName) || (curve > ECCurve_pastLastCurve)) {
+ PORT_FreeArena(arena, PR_FALSE);
+ return SECFailure;
+ }
+
+ ecParams.name = curve;
+ ecParams.type = ec_params_named;
+ ecParams.curveOID.data = NULL;
+ ecParams.curveOID.len = 0;
+ ecParams.curve.seed.data = NULL;
+ ecParams.curve.seed.len = 0;
+ ecParams.DEREncoding.data = NULL;
+ ecParams.DEREncoding.len = 0;
+
+ ecParams.fieldID.size = ecCurve_map[curve]->size;
+ ecParams.fieldID.type = ec_field_GFp;
+ hexString2SECItem(arena, &ecParams.fieldID.u.prime, ecCurve_map[curve]->irr);
+ hexString2SECItem(arena, &ecParams.curve.a, ecCurve_map[curve]->curvea);
+ hexString2SECItem(arena, &ecParams.curve.b, ecCurve_map[curve]->curveb);
+ genenc[0] = '0';
+ genenc[1] = '4';
+ genenc[2] = '\0';
+ strcat(genenc, ecCurve_map[curve]->genx);
+ strcat(genenc, ecCurve_map[curve]->geny);
+ hexString2SECItem(arena, &ecParams.base, genenc);
+ hexString2SECItem(arena, &ecParams.order, ecCurve_map[curve]->order);
+ ecParams.cofactor = ecCurve_map[curve]->cofactor;
+
+ hexString2SECItem(arena, &answer, kat->our_pubhex);
+ hexString2SECItem(arena, &seed, kat->privhex);
+ rv = EC_NewKeyFromSeed(&ecParams, &ecPriv, seed.data, seed.len);
+ if (rv != SECSuccess) {
+ rv = SECFailure;
+ goto cleanup;
+ }
+ if (SECITEM_CompareItem(&answer, &ecPriv->publicValue) != SECEqual) {
+ rv = SECFailure;
+ goto cleanup;
+ }
+
+ hexString2SECItem(arena, &theirKey, kat->their_pubhex);
+ hexString2SECItem(arena, &answer2, kat->common_key);
+ rv = ECDH_Derive(&theirKey, &ecParams, &ecPriv->privateValue, PR_TRUE, &derived);
+ if (rv != SECSuccess) {
+ rv = SECFailure;
+ goto cleanup;
+ }
+
+ if (SECITEM_CompareItem(&answer2, &derived) != SECEqual) {
+ rv = SECFailure;
+ goto cleanup;
+ }
+cleanup:
+ PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(ecPriv->ecParams.arena, PR_FALSE);
+ SECITEM_FreeItem(&derived, PR_FALSE);
+ return rv;
+}
+
+/* Performs tests of elliptic curve cryptography over prime fields If
+ * tests fail, then it prints an error message, aborts, and returns an
+ * error code. Otherwise, returns 0. */
+int
+main(int argv, char **argc)
+{
+ SECStatus rv = SECSuccess;
+ int numkats = 0;
+ int i = 0;
+
+ rv = SECOID_Init();
+ if (rv != SECSuccess) {
+ SECU_PrintError("Error:", "SECOID_Init");
+ goto cleanup;
+ }
+
+ while (ecdh_testvecs[numkats].curve != ECCurve_pastLastCurve) {
+ numkats++;
+ }
+ printf("1..%d\n", numkats);
+ for (i = 0; ecdh_testvecs[i].curve != ECCurve_pastLastCurve; i++) {
+ rv = ectest_ecdh_kat(&ecdh_testvecs[i]);
+ if (rv != SECSuccess) {
+ printf("not okay %d - %s\n", i + 1, ecdh_testvecs[i].name);
+ } else {
+ printf("okay %d - %s\n", i + 1, ecdh_testvecs[i].name);
+ }
+ }
+
+cleanup:
+ rv |= SECOID_Shutdown();
+
+ if (rv != SECSuccess) {
+ printf("Error: exiting with error value\n");
+ }
+ return rv;
+}
diff --git a/nss/cmd/ectest/manifest.mn b/nss/cmd/ectest/manifest.mn
new file mode 100644
index 0000000..6d6b77c
--- /dev/null
+++ b/nss/cmd/ectest/manifest.mn
@@ -0,0 +1,18 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEPTH = ../..
+CORE_DEPTH = ../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+INCLUDES += -I$(CORE_DEPTH)/nss/lib/softoken
+
+CSRCS = ectest.c
+
+PROGRAM = ectest
+
+USE_STATIC_LIBS = 1
diff --git a/nss/cmd/ectest/testvecs.h b/nss/cmd/ectest/testvecs.h
new file mode 100644
index 0000000..3f76440
--- /dev/null
+++ b/nss/cmd/ectest/testvecs.h
@@ -0,0 +1,728 @@
+static ECDH_KAT ecdh_testvecs[] = {
+ { ECCurve_NIST_P256,
+ "7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534",
+ "04ead218590119e8876b29146ff89ca61770c4edbbf97d38ce385ed281d8a6b23028af61281fd35e2fa7002523acc85a429cb06ee6648325389f59edfce1405141",
+ "04700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac",
+ "46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b",
+ "curve: P256 vector: 0" },
+
+ { ECCurve_NIST_P256,
+ "38f65d6dce47676044d58ce5139582d568f64bb16098d179dbab07741dd5caf5",
+ "04119f2f047902782ab0c9e27a54aff5eb9b964829ca99c06b02ddba95b0a3f6d08f52b726664cac366fc98ac7a012b2682cbd962e5acb544671d41b9445704d1d",
+ "04809f04289c64348c01515eb03d5ce7ac1a8cb9498f5caa50197e58d43a86a7aeb29d84e811197f25eba8f5194092cb6ff440e26d4421011372461f579271cda3",
+ "057d636096cb80b67a8c038c890e887d1adfa4195e9b3ce241c8a778c59cda67",
+ "curve: P256 vector: 1" },
+
+ { ECCurve_NIST_P256,
+ "1accfaf1b97712b85a6f54b148985a1bdc4c9bec0bd258cad4b3d603f49f32c8",
+ "04d9f2b79c172845bfdb560bbb01447ca5ecc0470a09513b6126902c6b4f8d1051f815ef5ec32128d3487834764678702e64e164ff7315185e23aff5facd96d7bc",
+ "04a2339c12d4a03c33546de533268b4ad667debf458b464d77443636440ee7fec3ef48a3ab26e20220bcda2c1851076839dae88eae962869a497bf73cb66faf536",
+ "2d457b78b4614132477618a5b077965ec90730a8c81a1c75d6d4ec68005d67ec",
+ "curve: P256 vector: 2" },
+
+ { ECCurve_NIST_P256,
+ "207c43a79bfee03db6f4b944f53d2fb76cc49ef1c9c4d34d51b6c65c4db6932d",
+ "0424277c33f450462dcb3d4801d57b9ced05188f16c28eda873258048cd1607e0dc4789753e2b1f63b32ff014ec42cd6a69fac81dfe6d0d6fd4af372ae27c46f88",
+ "04df3989b9fa55495719b3cf46dccd28b5153f7808191dd518eff0c3cff2b705ed422294ff46003429d739a33206c8752552c8ba54a270defc06e221e0feaf6ac4",
+ "96441259534b80f6aee3d287a6bb17b5094dd4277d9e294f8fe73e48bf2a0024",
+ "curve: P256 vector: 3" },
+
+ { ECCurve_NIST_P256,
+ "59137e38152350b195c9718d39673d519838055ad908dd4757152fd8255c09bf",
+ "04a8c5fdce8b62c5ada598f141adb3b26cf254c280b2857a63d2ad783a73115f6b806e1aafec4af80a0d786b3de45375b517a7e5b51ffb2c356537c9e6ef227d4a",
+ "0441192d2813e79561e6a1d6f53c8bc1a433a199c835e141b05a74a97b0faeb9221af98cc45e98a7e041b01cf35f462b7562281351c8ebf3ffa02e33a0722a1328",
+ "19d44c8d63e8e8dd12c22a87b8cd4ece27acdde04dbf47f7f27537a6999a8e62",
+ "curve: P256 vector: 4" },
+
+ { ECCurve_NIST_P256,
+ "f5f8e0174610a661277979b58ce5c90fee6c9b3bb346a90a7196255e40b132ef",
+ "047b861dcd2844a5a8363f6b8ef8d493640f55879217189d80326aad9480dfc149c4675b45eeb306405f6c33c38bc69eb2bdec9b75ad5af4706aab84543b9cc63a",
+ "0433e82092a0f1fb38f5649d5867fba28b503172b7035574bf8e5b7100a3052792f2cf6b601e0a05945e335550bf648d782f46186c772c0f20d3cd0d6b8ca14b2f",
+ "664e45d5bba4ac931cd65d52017e4be9b19a515f669bea4703542a2c525cd3d3",
+ "curve: P256 vector: 5" },
+
+ { ECCurve_NIST_P256,
+ "3b589af7db03459c23068b64f63f28d3c3c6bc25b5bf76ac05f35482888b5190",
+ "049fb38e2d58ea1baf7622e96720101cae3cde4ba6c1e9fa26d9b1de0899102863d5561b900406edf50802dd7d73e89395f8aed72fba0e1d1b61fe1d22302260f0",
+ "046a9e0c3f916e4e315c91147be571686d90464e8bf981d34a90b6353bca6eeba740f9bead39c2f2bcc2602f75b8a73ec7bdffcbcead159d0174c6c4d3c5357f05",
+ "ca342daa50dc09d61be7c196c85e60a80c5cb04931746820be548cdde055679d",
+ "curve: P256 vector: 6" },
+
+ { ECCurve_NIST_P256,
+ "d8bf929a20ea7436b2461b541a11c80e61d826c0a4c9d322b31dd54e7f58b9c8",
+ "0420f07631e4a6512a89ad487c4e9d63039e579cb0d7a556cb9e661cd59c1e7fa46de91846b3eee8a5ec09c2ab1f41e21bd83620ccdd1bdce3ab7ea6e02dd274f5",
+ "04a9c0acade55c2a73ead1a86fb0a9713223c82475791cd0e210b046412ce224bbf6de0afa20e93e078467c053d241903edad734c6b403ba758c2b5ff04c9d4229",
+ "35aa9b52536a461bfde4e85fc756be928c7de97923f0416c7a3ac8f88b3d4489",
+ "curve: P256 vector: 7" },
+
+ { ECCurve_NIST_P256,
+ "0f9883ba0ef32ee75ded0d8bda39a5146a29f1f2507b3bd458dbea0b2bb05b4d",
+ "04abb61b423be5d6c26e21c605832c9142dc1dfe5a5fff28726737936e6fbf516d733d2513ef58beab202090586fac91bf0fee31e80ab33473ab23a2d89e58fad6",
+ "0494e94f16a98255fff2b9ac0c9598aac35487b3232d3231bd93b7db7df36f9eb9d8049a43579cfa90b8093a94416cbefbf93386f15b3f6e190b6e3455fedfe69a",
+ "605c16178a9bc875dcbff54d63fe00df699c03e8a888e9e94dfbab90b25f39b4",
+ "curve: P256 vector: 8" },
+
+ { ECCurve_NIST_P256,
+ "2beedb04b05c6988f6a67500bb813faf2cae0d580c9253b6339e4a3337bb6c08",
+ "043d63e429cb5fa895a9247129bf4e48e89f35d7b11de8158efeb3e106a2a873950cae9e477ef41e7c8c1064379bb7b554ddcbcae79f9814281f1e50f0403c61f3",
+ "04e099bf2a4d557460b5544430bbf6da11004d127cb5d67f64ab07c94fcdf5274fd9c50dbe70d714edb5e221f4e020610eeb6270517e688ca64fb0e98c7ef8c1c5",
+ "f96e40a1b72840854bb62bc13c40cc2795e373d4e715980b261476835a092e0b",
+ "curve: P256 vector: 9" },
+
+ { ECCurve_NIST_P256,
+ "77c15dcf44610e41696bab758943eff1409333e4d5a11bbe72c8f6c395e9f848",
+ "04ad5d13c3db508ddcd38457e5991434a251bed49cf5ddcb59cdee73865f138c9f62cec1e70588aa4fdfc7b9a09daa678081c04e1208b9d662b8a2214bf8e81a21",
+ "04f75a5fe56bda34f3c1396296626ef012dc07e4825838778a645c8248cff0165833bbdf1b1772d8059df568b061f3f1122f28a8d819167c97be448e3dc3fb0c3c",
+ "8388fa79c4babdca02a8e8a34f9e43554976e420a4ad273c81b26e4228e9d3a3",
+ "curve: P256 vector: 10" },
+
+ { ECCurve_NIST_P256,
+ "42a83b985011d12303db1a800f2610f74aa71cdf19c67d54ce6c9ed951e9093e",
+ "04ab48caa61ea35f13f8ed07ffa6a13e8db224dfecfae1a7df8b1bb6ebaf0cb97d1274530ca2c385a3218bddfbcbf0b4024c9badd5243bff834ebff24a8618dccb",
+ "042db4540d50230756158abf61d9835712b6486c74312183ccefcaef2797b7674d62f57f314e3f3495dc4e099012f5e0ba71770f9660a1eada54104cdfde77243e",
+ "72877cea33ccc4715038d4bcbdfe0e43f42a9e2c0c3b017fc2370f4b9acbda4a",
+ "curve: P256 vector: 11" },
+
+ { ECCurve_NIST_P256,
+ "ceed35507b5c93ead5989119b9ba342cfe38e6e638ba6eea343a55475de2800b",
+ "049a8cd9bd72e71752df91440f77c547509a84df98114e7de4f26cdb39234a625dd07cfc84c8e144fab2839f5189bb1d7c88631d579bbc58012ed9a2327da52f62",
+ "04cd94fc9497e8990750309e9a8534fd114b0a6e54da89c4796101897041d14ecbc3def4b5fe04faee0a11932229fff563637bfdee0e79c6deeaf449f85401c5c4",
+ "e4e7408d85ff0e0e9c838003f28cdbd5247cdce31f32f62494b70e5f1bc36307",
+ "curve: P256 vector: 12" },
+
+ { ECCurve_NIST_P256,
+ "43e0e9d95af4dc36483cdd1968d2b7eeb8611fcce77f3a4e7d059ae43e509604",
+ "04f989cf8ee956a82e7ebd9881cdbfb2fd946189b08db53559bc8cfdd48071eb145eff28f1a18a616b04b7d337868679f6dd84f9a7b3d7b6f8af276c19611a541d",
+ "0415b9e467af4d290c417402e040426fe4cf236bae72baa392ed89780dfccdb471cdf4e9170fb904302b8fd93a820ba8cc7ed4efd3a6f2d6b05b80b2ff2aee4e77",
+ "ed56bcf695b734142c24ecb1fc1bb64d08f175eb243a31f37b3d9bb4407f3b96",
+ "curve: P256 vector: 13" },
+
+ { ECCurve_NIST_P256,
+ "b2f3600df3368ef8a0bb85ab22f41fc0e5f4fdd54be8167a5c3cd4b08db04903",
+ "0469c627625b36a429c398b45c38677cb35d8beb1cf78a571e40e99fe4eac1cd4e81690112b0a88f20f7136b28d7d47e5fbc2ada3c8edd87589bc19ec9590637bd",
+ "0449c503ba6c4fa605182e186b5e81113f075bc11dcfd51c932fb21e951eee2fa18af706ff0922d87b3f0c5e4e31d8b259aeb260a9269643ed520a13bb25da5924",
+ "bc5c7055089fc9d6c89f83c1ea1ada879d9934b2ea28fcf4e4a7e984b28ad2cf",
+ "curve: P256 vector: 14" },
+
+ { ECCurve_NIST_P256,
+ "4002534307f8b62a9bf67ff641ddc60fef593b17c3341239e95bdb3e579bfdc8",
+ "045fe964671315a18aa68a2a6e3dd1fde7e23b8ce7181471cfac43c99e1ae80262d5827be282e62c84de531b963884ba832db5d6b2c3a256f0e604fe7e6b8a7f72",
+ "0419b38de39fdd2f70f7091631a4f75d1993740ba9429162c2a45312401636b29c09aed7232b28e060941741b6828bcdfa2bc49cc844f3773611504f82a390a5ae",
+ "9a4e8e657f6b0e097f47954a63c75d74fcba71a30d83651e3e5a91aa7ccd8343",
+ "curve: P256 vector: 15" },
+
+ { ECCurve_NIST_P256,
+ "4dfa12defc60319021b681b3ff84a10a511958c850939ed45635934ba4979147",
+ "04c9b2b8496f1440bd4a2d1e52752fd372835b364885e154a7dac49295f281ec7cfbe6b926a8a4de26ccc83b802b1212400754be25d9f3eeaf008b09870ae76321",
+ "042c91c61f33adfe9311c942fdbff6ba47020feff416b7bb63cec13faf9b0999546cab31b06419e5221fca014fb84ec870622a1b12bab5ae43682aa7ea73ea08d0",
+ "3ca1fc7ad858fb1a6aba232542f3e2a749ffc7203a2374a3f3d3267f1fc97b78",
+ "curve: P256 vector: 16" },
+
+ { ECCurve_NIST_P256,
+ "1331f6d874a4ed3bc4a2c6e9c74331d3039796314beee3b7152fcdba5556304e",
+ "0459e1e101521046ad9cf1d082e9d2ec7dd22530cce064991f1e55c5bcf5fcb591482f4f673176c8fdaa0bb6e59b15a3e47454e3a04297d3863c9338d98add1f37",
+ "04a28a2edf58025668f724aaf83a50956b7ac1cfbbff79b08c3bf87dfd2828d767dfa7bfffd4c766b86abeaf5c99b6e50cb9ccc9d9d00b7ffc7804b0491b67bc03",
+ "1aaabe7ee6e4a6fa732291202433a237df1b49bc53866bfbe00db96a0f58224f",
+ "curve: P256 vector: 17" },
+
+ { ECCurve_NIST_P256,
+ "dd5e9f70ae740073ca0204df60763fb6036c45709bf4a7bb4e671412fad65da3",
+ "0430b9db2e2e977bcdc98cb87dd736cbd8e78552121925cf16e1933657c2fb23146a45028800b81291bce5c2e1fed7ded650620ebbe6050c6f3a7f0dfb4673ab5c",
+ "04a2ef857a081f9d6eb206a81c4cf78a802bdf598ae380c8886ecd85fdc1ed7644563c4c20419f07bc17d0539fade1855e34839515b892c0f5d26561f97fa04d1a",
+ "430e6a4fba4449d700d2733e557f66a3bf3d50517c1271b1ddae1161b7ac798c",
+ "curve: P256 vector: 18" },
+
+ { ECCurve_NIST_P256,
+ "5ae026cfc060d55600717e55b8a12e116d1d0df34af831979057607c2d9c2f76",
+ "0446c9ebd1a4a3c8c0b6d572b5dcfba12467603208a9cb5d2acfbb733c40cf639146c913a27d044185d38b467ace011e04d4d9bbbb8cb9ae25fa92aaf15a595e86",
+ "04ccd8a2d86bc92f2e01bce4d6922cf7fe1626aed044685e95e2eebd464505f01fe9ddd583a9635a667777d5b8a8f31b0f79eba12c75023410b54b8567dddc0f38",
+ "1ce9e6740529499f98d1f1d71329147a33df1d05e4765b539b11cf615d6974d3",
+ "curve: P256 vector: 19" },
+
+ { ECCurve_NIST_P256,
+ "b601ac425d5dbf9e1735c5e2d5bdb79ca98b3d5be4a2cfd6f2273f150e064d9d",
+ "047c9e950841d26c8dde8994398b8f5d475a022bc63de7773fcf8d552e01f1ba0acc42b9885c9b3bee0f8d8c57d3a8f6355016c019c4062fa22cff2f209b5cc2e1",
+ "04c188ffc8947f7301fb7b53e36746097c2134bf9cc981ba74b4e9c4361f595e4ebf7d2f2056e72421ef393f0c0f2b0e00130e3cac4abbcc00286168e85ec55051",
+ "4690e3743c07d643f1bc183636ab2a9cb936a60a802113c49bb1b3f2d0661660",
+ "curve: P256 vector: 20" },
+
+ { ECCurve_NIST_P256,
+ "fefb1dda1845312b5fce6b81b2be205af2f3a274f5a212f66c0d9fc33d7ae535",
+ "0438b54db85500cb20c61056edd3d88b6a9dc26780a047f213a6e1b900f76596eb6387e4e5781571e4eb8ae62991a33b5dc33301c5bc7e125d53794a39160d8fd0",
+ "04317e1020ff53fccef18bf47bb7f2dd7707fb7b7a7578e04f35b3beed222a0eb609420ce5a19d77c6fe1ee587e6a49fbaf8f280e8df033d75403302e5a27db2ae",
+ "30c2261bd0004e61feda2c16aa5e21ffa8d7e7f7dbf6ec379a43b48e4b36aeb0",
+ "curve: P256 vector: 21" },
+
+ { ECCurve_NIST_P256,
+ "334ae0c4693d23935a7e8e043ebbde21e168a7cba3fa507c9be41d7681e049ce",
+ "043f2bf1589abf3047bf3e54ac9a95379bff95f8f55405f64eca36a7eebe8ffca75212a94e66c5ae9a8991872f66a72723d80ec5b2e925745c456f5371943b3a06",
+ "0445fb02b2ceb9d7c79d9c2fa93e9c7967c2fa4df5789f9640b24264b1e524fcb15c6e8ecf1f7d3023893b7b1ca1e4d178972ee2a230757ddc564ffe37f5c5a321",
+ "2adae4a138a239dcd93c243a3803c3e4cf96e37fe14e6a9b717be9599959b11c",
+ "curve: P256 vector: 22" },
+
+ { ECCurve_NIST_P256,
+ "2c4bde40214fcc3bfc47d4cf434b629acbe9157f8fd0282540331de7942cf09d",
+ "0429c0807f10cbc42fb45c9989da50681eead716daa7b9e91fd32e062f5eb92ca0ff1d6d1955d7376b2da24fe1163a271659136341bc2eb1195fc706dc62e7f34d",
+ "04a19ef7bff98ada781842fbfc51a47aff39b5935a1c7d9625c8d323d511c92de6e9c184df75c955e02e02e400ffe45f78f339e1afe6d056fb3245f4700ce606ef",
+ "2e277ec30f5ea07d6ce513149b9479b96e07f4b6913b1b5c11305c1444a1bc0b",
+ "curve: P256 vector: 23" },
+
+ { ECCurve_NIST_P256,
+ "85a268f9d7772f990c36b42b0a331adc92b5941de0b862d5d89a347cbf8faab0",
+ "049cf4b98581ca1779453cc816ff28b4100af56cf1bf2e5bc312d83b6b1b21d3337a5504fcac5231a0d12d658218284868229c844a04a3450d6c7381abe080bf3b",
+ "04356c5a444c049a52fee0adeb7e5d82ae5aa83030bfff31bbf8ce2096cf161c4b57d128de8b2a57a094d1a001e572173f96e8866ae352bf29cddaf92fc85b2f92",
+ "1e51373bd2c6044c129c436e742a55be2a668a85ae08441b6756445df5493857",
+ "curve: P256 vector: 24" },
+
+ { ECCurve_NIST_P384,
+ "3cc3122a68f0d95027ad38c067916ba0eb8c38894d22e1b15618b6818a661774ad463b205da88cf699ab4d43c9cf98a1",
+ "049803807f2f6d2fd966cdd0290bd410c0190352fbec7ff6247de1302df86f25d34fe4a97bef60cff548355c015dbb3e5"
+ "fba26ca69ec2f5b5d9dad20cc9da711383a9dbe34ea3fa5a2af75b46502629ad54dd8b7d73a8abb06a3a3be47d650cc99",
+ "04a7c76b970c3b5fe8b05d2838ae04ab47697b9eaf52e764592efda27fe7513272734466b400091adbf2d68c58e0c5006"
+ "6ac68f19f2e1cb879aed43a9969b91a0839c4c38a49749b661efedf243451915ed0905a32b060992b468c64766fc8437a",
+ "5f9d29dc5e31a163060356213669c8ce132e22f57c9a04f40ba7fcead493b457e5621e766c40a2e3d4d6a04b25e533f1",
+ "curve: P384 vector: 0" },
+
+ { ECCurve_NIST_P384,
+ "92860c21bde06165f8e900c687f8ef0a05d14f290b3f07d8b3a8cc6404366e5d5119cd6d03fb12dc58e89f13df9cd783",
+ "04ea4018f5a307c379180bf6a62fd2ceceebeeb7d4df063a66fb838aa35243419791f7e2c9d4803c9319aa0eb03c416b"
+ "6668835a91484f05ef028284df6436fb88ffebabcdd69ab0133e6735a1bcfb37203d10d340a8328a7b68770ca75878a1a6",
+ "0430f43fcf2b6b00de53f624f1543090681839717d53c7c955d1d69efaf0349b7363acb447240101cbb3af6641ce4b88e0"
+ "25e46c0c54f0162a77efcc27b6ea792002ae2ba82714299c860857a68153ab62e525ec0530d81b5aa15897981e858757",
+ "a23742a2c267d7425fda94b93f93bbcc24791ac51cd8fd501a238d40812f4cbfc59aac9520d758cf789c76300c69d2ff",
+ "curve: P384 vector: 1" },
+
+ { ECCurve_NIST_P384,
+ "12cf6a223a72352543830f3f18530d5cb37f26880a0b294482c8a8ef8afad09aa78b7dc2f2789a78c66af5d1cc553853",
+ "04fcfcea085e8cf74d0dced1620ba8423694f903a219bbf901b0b59d6ac81baad316a242ba32bde85cb248119b852fab6"
+ "6972e3c68c7ab402c5836f2a16ed451a33120a7750a6039f3ff15388ee622b7065f7122bf6d51aefbc29b37b03404581b",
+ "041aefbfa2c6c8c855a1a216774550b79a24cda37607bb1f7cc906650ee4b3816d68f6a9c75da6e4242cebfb6652f65180"
+ "419d28b723ebadb7658fcebb9ad9b7adea674f1da3dc6b6397b55da0f61a3eddacb4acdb14441cb214b04a0844c02fa3",
+ "3d2e640f350805eed1ff43b40a72b2abed0a518bcebe8f2d15b111b6773223da3c3489121db173d414b5bd5ad7153435",
+ "curve: P384 vector: 2" },
+
+ { ECCurve_NIST_P384,
+ "8dd48063a3a058c334b5cc7a4ce07d02e5ee6d8f1f3c51a1600962cbab462690ae3cd974fb39e40b0e843daa0fd32de1",
+ "04e38c9846248123c3421861ea4d32669a7b5c3c08376ad28104399494c84ff5efa3894adb2c6cbe8c3c913ef2eec5bd3"
+ "c9fa84024a1028796df84021f7b6c9d02f0f4bd1a612a03cbf75a0beea43fef8ae84b48c60172aadf09c1ad016d0bf3ce",
+ "048bc089326ec55b9cf59b34f0eb754d93596ca290fcb3444c83d4de3a5607037ec397683f8cef07eab2fe357eae36c44"
+ "9d9d16ce8ac85b3f1e94568521aae534e67139e310ec72693526aa2e927b5b322c95a1a033c229cb6770c957cd3148dd7",
+ "6a42cfc392aba0bfd3d17b7ccf062b91fc09bbf3417612d02a90bdde62ae40c54bb2e56e167d6b70db670097eb8db854",
+ "curve: P384 vector: 3" },
+
+ { ECCurve_NIST_P384,
+ "84ece6cc3429309bd5b23e959793ed2b111ec5cb43b6c18085fcaea9efa0685d98a6262ee0d330ee250bc8a67d0e733f",
+ "043222063a2997b302ee60ee1961108ff4c7acf1c0ef1d5fb0d164b84bce71c431705cb9aea9a45f5d73806655a058bee"
+ "3e61fa9e7fbe7cd43abf99596a3d3a039e99fa9dc93b0bdd9cad81966d17eeaf557068afa7c78466bb5b22032d1100fa6",
+ "04eb952e2d9ac0c20c6cc48fb225c2ad154f53c8750b003fd3b4ed8ed1dc0defac61bcdde02a2bcfee7067d75d342ed2b"
+ "0f1828205baece82d1b267d0d7ff2f9c9e15b69a72df47058a97f3891005d1fb38858f5603de840e591dfa4f6e7d489e1",
+ "ce7ba454d4412729a32bb833a2d1fd2ae612d4667c3a900e069214818613447df8c611de66da200db7c375cf913e4405",
+ "curve: P384 vector: 4" },
+
+ { ECCurve_NIST_P384,
+ "68fce2121dc3a1e37b10f1dde309f9e2e18fac47cd1770951451c3484cdb77cb136d00e731260597cc2859601c01a25b",
+ "04868be0e694841830e424d913d8e7d86b84ee1021d82b0ecf523f09fe89a76c0c95c49f2dfbcf829c1e39709d55efbb"
+ "3b9195eb183675b40fd92f51f37713317e4a9b4f715c8ab22e0773b1bc71d3a219f05b8116074658ee86b52e36f3897116",
+ "04441d029e244eb7168d647d4df50db5f4e4974ab3fdaf022aff058b3695d0b8c814cc88da6285dc6df1ac55c55388500"
+ "3e8025ac23a41d4b1ea2aa46c50c6e479946b59b6d76497cd9249977e0bfe4a6262622f13d42a3c43d66bdbb30403c345",
+ "ba69f0acdf3e1ca95caaac4ecaf475bbe51b54777efce01ca381f45370e486fe87f9f419b150c61e329a286d1aa265ec",
+ "curve: P384 vector: 5" },
+
+ { ECCurve_NIST_P384,
+ "b1764c54897e7aae6de9e7751f2f37de849291f88f0f91093155b858d1cc32a3a87980f706b86cc83f927bdfdbeae0bd",
+ "04c371222feaa6770c6f3ea3e0dac9740def4fcf821378b7f91ff937c21e0470f70f3a31d5c6b2912195f10926942b48ae"
+ "047d6b4d765123563f81116bc665b7b8cc6207830d805fd84da7cb805a65baa7c12fd592d1b5b5e3e65d9672a9ef7662",
+ "043d4e6bf08a73404accc1629873468e4269e82d90d832e58ad72142639b5a056ad8d35c66c60e8149fac0c797bceb7c2"
+ "f9b0308dc7f0e6d29f8c277acbc65a21e5adb83d11e6873bc0a07fda0997f482504602f59e10bc5cb476b83d0a4f75e71",
+ "1a6688ee1d6e59865d8e3ada37781d36bb0c2717eef92e61964d3927cb765c2965ea80f7f63e58c322ba0397faeaf62b",
+ "curve: P384 vector: 6" },
+
+ { ECCurve_NIST_P384,
+ "f0f7a96e70d98fd5a30ad6406cf56eb5b72a510e9f192f50e1f84524dbf3d2439f7287bb36f5aa912a79deaab4adea82",
+ "0499c8c41cb1ab5e0854a346e4b08a537c1706a61553387c8d94943ab15196d40dbaa55b8210a77a5d00915f2c4ea69e"
+ "ab5531065bdcf17bfb3cb55a02e41a57c7f694c383ad289f900fbd656c2233a93c92e933e7a26f54cbb56f0ad875c51bb0",
+ "04f5f6bef1d110da03be0017eac760cc34b24d092f736f237bc7054b3865312a813bcb62d297fb10a4f7abf54708fe2d3d"
+ "06fdf8d7dc032f4e10010bf19cbf6159321252ff415fb91920d438f24e67e60c2eb0463204679fa356af44cea9c9ebf5",
+ "d06a568bf2336b90cbac325161be7695eacb2295f599500d787f072612aca313ee5d874f807ddef6c1f023fe2b6e7cd0",
+ "curve: P384 vector: 7" },
+
+ { ECCurve_NIST_P384,
+ "9efb87ddc61d43c482ba66e1b143aef678fbd0d1bebc2000941fabe677fe5b706bf78fce36d100b17cc787ead74bbca2",
+ "044c34efee8f0c95565d2065d1bbac2a2dd25ae964320eb6bccedc5f3a9b42a881a1afca1bb6b880584fa27b01c193cd9"
+ "2d8fb01dbf7cd0a3868c26b951f393c3c56c2858cee901f7793ff5d271925d13a41f8e52409f4eba1990f33acb0bac669",
+ "047cdec77e0737ea37c67b89b7137fe38818010f4464438ee4d1d35a0c488cad3fde2f37d00885d36d3b795b9f93d23a6"
+ "728c42ee8d6027c56cf979ba4c229fdb01d234944f8ac433650112c3cf0f02844e888a3569dfef7828a8a884589aa055e",
+ "bb3b1eda9c6560d82ff5bee403339f1e80342338a991344853b56b24f109a4d94b92f654f0425edd4c205903d7586104",
+ "curve: P384 vector: 8" },
+
+ { ECCurve_NIST_P384,
+ "d787a57fde22ec656a0a525cf3c738b30d73af61e743ea90893ecb2d7b622add2f94ee25c2171467afb093f3f84d0018",
+ "04171546923b87b2cbbad664f01ce932bf09d6a6118168678446bfa9f0938608cb4667a98f4ec8ac1462285c2508f7486"
+ "2fa41cb4db68ae71f1f8a3e8939dc52c2dec61a83c983beb2a02baf29ec49278088882ed0cf56c74b5c173b552ccf63cf",
+ "048eeea3a319c8df99fbc29cb55f243a720d95509515ee5cc587a5c5ae22fbbd009e626db3e911def0b99a4f7ae304b1b"
+ "a73877dc94db9adddc0d9a4b24e8976c22d73c844370e1ee857f8d1b129a3bd5f63f40caf3bd0533e38a5f5777074ff9e",
+ "1e97b60add7cb35c7403dd884c0a75795b7683fff8b49f9d8672a8206bfdcf0a106b8768f983258c74167422e44e4d14",
+ "curve: P384 vector: 9" },
+
+ { ECCurve_NIST_P384,
+ "83d70f7b164d9f4c227c767046b20eb34dfc778f5387e32e834b1e6daec20edb8ca5bb4192093f543b68e6aeb7ce788b",
+ "0457cd770f3bbcbe0c78c770eab0b169bc45e139f86378ffae1c2b16966727c2f2eb724572b8f3eb228d130db4ff862c"
+ "637ec5c8813b685558d83e924f14bc719f6eb7ae0cbb2c474227c5bda88637a4f26c64817929af999592da6f787490332f",
+ "04a721f6a2d4527411834b13d4d3a33c29beb83ab7682465c6cbaf6624aca6ea58c30eb0f29dd842886695400d7254f20f"
+ "14ba6e26355109ad35129366d5e3a640ae798505a7fa55a96a36b5dad33de00474f6670f522214dd7952140ab0a7eb68",
+ "1023478840e54775bfc69293a3cf97f5bc914726455c66538eb5623e218feef7df4befa23e09d77145ad577db32b41f9",
+ "curve: P384 vector: 10" },
+
+ { ECCurve_NIST_P384,
+ "8f558e05818b88ed383d5fca962e53413db1a0e4637eda194f761944cbea114ab9d5da175a7d57882550b0e432f395a9",
+ "049a2f57f4867ce753d72b0d95195df6f96c1fae934f602efd7b6a54582f556cfa539d89005ca2edac08ad9b72dd1f60b"
+ "ad9b94ee82da9cc601f346044998ba387aee56404dc6ecc8ab2b590443319d0b2b6176f9d0eac2d44678ed561607d09a9",
+ "04d882a8505c2d5cb9b8851fc676677bb0087681ad53faceba1738286b45827561e7da37b880276c656cfc38b32ade847"
+ "e34b314bdc134575654573cffaf40445da2e6aaf987f7e913cd4c3091523058984a25d8f21da8326192456c6a0fa5f60c",
+ "6ad6b9dc8a6cf0d3691c501cbb967867f6e4bbb764b60dbff8fcff3ed42dbba39d63cf325b4b4078858495ddee75f954",
+ "curve: P384 vector: 11" },
+
+ { ECCurve_NIST_P384,
+ "0f5dee0affa7bbf239d5dff32987ebb7cf84fcceed643e1d3c62d0b3352aec23b6e5ac7fa4105c8cb26126ad2d1892cb",
+ "0423346bdfbc9d7c7c736e02bdf607671ff6082fdd27334a8bc75f3b23681ebe614d0597dd614fae58677c835a9f0b273"
+ "b82ba36290d2f94db41479eb45ab4eaf67928a2315138d59eecc9b5285dfddd6714f77557216ea44cc6fc119d8243efaf",
+ "04815c9d773dbf5fb6a1b86799966247f4006a23c92e68c55e9eaa998b17d8832dd4d84d927d831d4f68dac67c6488219f"
+ "e79269948b2611484560fd490feec887cb55ef99a4b524880fa7499d6a07283aae2afa33feab97deca40bc606c4d8764",
+ "cc9e063566d46b357b3fcae21827377331e5e290a36e60cd7c39102b828ae0b918dc5a02216b07fe6f1958d834e42437",
+ "curve: P384 vector: 12" },
+
+ { ECCurve_NIST_P384,
+ "037b633b5b8ba857c0fc85656868232e2febf59578718391b81da8541a00bfe53c30ae04151847f27499f8d7abad8cf4",
+ "048878ac8a947f7d5cb2b47aad24fbb8210d86126585399a2871f84aa9c5fde3074ae540c6bf82275ca822d0feb862bc7"
+ "4632f5cd2f900c2711c32f8930728eb647d31edd8d650f9654e7d33e5ed1b475489d08daa30d8cbcba6bfc3b60d9b5a37",
+ "041c0eeda7a2be000c5bdcda0478aed4db733d2a9e341224379123ad847030f29e3b168fa18e89a3c0fba2a6ce1c28fc3"
+ "bec8c1c83c118c4dbea94271869f2d868eb65e8b44e21e6f14b0f4d9b38c068daefa27114255b9a41d084cc4a1ad85456",
+ "deff7f03bd09865baf945e73edff6d5122c03fb561db87dec8662e09bed4340b28a9efe118337bb7d3d4f7f568635ff9",
+ "curve: P384 vector: 13" },
+
+ { ECCurve_NIST_P384,
+ "e3d07106bedcc096e7d91630ffd3094df2c7859db8d7edbb2e37b4ac47f429a637d06a67d2fba33838764ef203464991",
+ "04e74a1a2b85f1cbf8dbbdf050cf1aff8acb02fda2fb6591f9d3cfe4e79d0ae938a9c1483e7b75f8db24505d65065cdb1"
+ "81773ee591822f7abaa856a1a60bc0a5203548dbd1cb5025466eff8481bd07614eaa04a16c3db76905913e972a5b6b59d",
+ "04c95c185e256bf997f30b311548ae7f768a38dee43eeeef43083f3077be70e2bf39ac1d4daf360c514c8c6be623443d1"
+ "a3e63a663eaf75d8a765ab2b9a35513d7933fa5e26420a5244550ec6c3b6f033b96db2aca3d6ac6aab052ce929595aea5",
+ "c8b1038f735ad3bb3e4637c3e47eab487637911a6b7950a4e461948329d3923b969e5db663675623611a457fcda35a71",
+ "curve: P384 vector: 14" },
+
+ { ECCurve_NIST_P384,
+ "f3f9b0c65a49a506632c8a45b10f66b5316f9eeb06fae218f2da62333f99905117b141c760e8974efc4af10570635791",
+ "04a4ad77aa7d86e5361118a6b921710c820721210712f4c347985fdee58aa4effa1e28be80a17b120b139f96300f89b4"
+ "9b1ddf22e07e03f1560d8f45a480094560dba9fae7f9531130c1b57ebb95982496524f31d3797793396fa823f22bdb4328",
+ "043497238a7e6ad166df2dac039aa4dac8d17aa925e7c7631eb3b56e3aaa1c545fcd54d2e5985807910fb202b1fc191d2a"
+ "a49e5c487dcc7aa40a8f234c979446040d9174e3ad357d404d7765183195aed3f913641b90c81a306ebf0d8913861316",
+ "d337eaa32b9f716b8747b005b97a553c59dab0c51df41a2d49039cdae705aa75c7b9e7bc0b6a0e8c578c902bc4fff23e",
+ "curve: P384 vector: 15" },
+
+ { ECCurve_NIST_P384,
+ "59fce7fad7de28bac0230690c95710c720e528f9a4e54d3a6a8cd5fc5c5f21637031ce1c5b4e3d39647d8dcb9b794664",
+ "049c43bf971edf09402876ee742095381f78b1bd3aa39b5132af75dbfe7e98bd78bde10fe2e903c2b6379e1deee175a1b"
+ "0a6c58ecea5a477bb01bd543b339f1cc49f1371a2cda4d46eb4e53e250597942351a99665a122ffea9bde0636c375daf2",
+ "0490a34737d45b1aa65f74e0bd0659bc118f8e4b774b761944ffa6573c6df4f41dec0d11b697abd934d390871d4b453240"
+ "9b590719bb3307c149a7817be355d684893a307764b512eeffe07cb699edb5a6ffbf8d6032e6c79d5e93e94212c2aa4e",
+ "32d292b695a4488e42a7b7922e1ae537d76a3d21a0b2e36875f60e9f6d3e8779c2afb3a413b9dd79ae18e70b47d337c1",
+ "curve: P384 vector: 16" },
+
+ { ECCurve_NIST_P384,
+ "3e49fbf950a424c5d80228dc4bc35e9f6c6c0c1d04440998da0a609a877575dbe437d6a5cedaa2ddd2a1a17fd112aded",
+ "045a949594228b1a3d6f599eb3db0d06070fbc551c657b58234ba164ce3fe415fa5f3eb823c08dc29b8c341219c77b6b3"
+ "d2baad447c8c290cfed25edd9031c41d0b76921457327f42db31122b81f337bbf0b1039ec830ce9061a3761953c75e4a8",
+ "04dda546acfc8f903d11e2e3920669636d44b2068aeb66ff07aa266f0030e1535b0ed0203cb8a460ac990f1394faf22f1"
+ "d15bbb2597913035faadf413476f4c70f7279769a40c986f470c427b4ee4962abdf8173bbad81874772925fd32f0b159f",
+ "1220e7e6cad7b25df98e5bbdcc6c0b65ca6c2a50c5ff6c41dca71e475646fd489615979ca92fb4389aeadefde79a24f1",
+ "curve: P384 vector: 17" },
+
+ { ECCurve_NIST_P384,
+ "50ccc1f7076e92f4638e85f2db98e0b483e6e2204c92bdd440a6deea04e37a07c6e72791c190ad4e4e86e01efba84269",
+ "04756c07df0ce32c839dac9fb4733c9c28b70113a676a7057c38d223f22a3a9095a8d564653af528e04c7e1824be4a651"
+ "217c2ce6962cbd2a2e066297b39d57dd9bb4680f0191d390f70b4e461419b2972ce68ad46127fdda6c39195774ea86df3",
+ "04788be2336c52f4454d63ee944b1e49bfb619a08371048e6da92e584eae70bde1f171c4df378bd1f3c0ab03048a237802"
+ "4673ebd8db604eaf41711748bab2968a23ca4476ce144e728247f08af752929157b5830f1e26067466bdfa8b65145a33",
+ "793bb9cd22a93cf468faf804a38d12b78cb12189ec679ddd2e9aa21fa9a5a0b049ab16a23574fe04c1c3c02343b91beb",
+ "curve: P384 vector: 18" },
+
+ { ECCurve_NIST_P384,
+ "06f132b71f74d87bf99857e1e4350a594e5fe35533b888552ceccbc0d8923c902e36141d7691e28631b8bc9bafe5e064",
+ "042a3cc6b8ff5cde926e7e3a189a1bd029c9b586351af8838f4f201cb8f4b70ef3b0da06d352c80fc26baf8f42b784459"
+ "ebf9985960176da6d23c7452a2954ffcbbcb24249b43019a2a023e0b3dabd461f19ad3e775c364f3f11ad49f3099400d3",
+ "04d09bb822eb99e38060954747c82bb3278cf96bbf36fece3400f4c873838a40c135eb3babb9293bd1001bf3ecdee7bf2"
+ "6d416db6e1b87bbb7427788a3b6c7a7ab2c165b1e366f9608df512037584f213a648d47f16ac326e19aae972f63fd76c9",
+ "012d191cf7404a523678c6fc075de8285b243720a903047708bb33e501e0dbee5bcc40d7c3ef6c6da39ea24d830da1e8",
+ "curve: P384 vector: 19" },
+
+ { ECCurve_NIST_P384,
+ "12048ebb4331ec19a1e23f1a2c773b664ccfe90a28bfb846fc12f81dff44b7443c77647164bf1e9e67fd2c07a6766241",
+ "04bc18836bc7a9fdf54b5352f37d7528ab8fa8ec544a8c6180511cbfdd49cce377c39e34c031b5240dc9980503ed2f26"
+ "2c8086cbe338191080f0b7a16c7afc4c7b0326f9ac66f58552ef4bb9d24de3429ed5d3277ed58fcf48f2b5f61326bec6c6",
+ "0413741262ede5861dad71063dfd204b91ea1d3b7c631df68eb949969527d79a1dc59295ef7d2bca6743e8cd77b04d1"
+ "b580baaeadc7e19d74a8a04451a135f1be1b02fe299f9dc00bfdf201e83d995c6950bcc1cb89d6f7b30bf54656b9a4da586",
+ "ad0fd3ddffe8884b9263f3c15fe1f07f2a5a22ffdc7e967085eea45f0cd959f20f18f522763e28bcc925e496a52dda98",
+ "curve: P384 vector: 20" },
+
+ { ECCurve_NIST_P384,
+ "34d61a699ca576169fcdc0cc7e44e4e1221db0fe63d16850c8104029f7d48449714b9884328cae189978754ab460b486",
+ "04867f81104ccd6b163a7902b670ef406042cb0cce7dcdc63d1dfc91b2c40e3cdf7595834bf9eceb79849f1636fc8462f"
+ "c9d4bde8e875ec49697d258d1d59465f8431c6f5531e1c59e9f9ebe3cf164a8d9ce10a12f1979283a959bad244dd83863",
+ "049e22cbc18657f516a864b37b783348b66f1aa9626cd631f4fa1bd32ad88cf11db52057c660860d39d11fbf024fabd44"
+ "46b0d53c79681c28116df71e9cee74fd56c8b7f04b39f1198cc72284e98be9562e35926fb4f48a9fbecafe729309e8b6f",
+ "dc4ca392dc15e20185f2c6a8ea5ec31dfc96f56153a47394b3072b13d0015f5d4ae13beb3bed54d65848f9b8383e6c95",
+ "curve: P384 vector: 21" },
+
+ { ECCurve_NIST_P384,
+ "dc60fa8736d702135ff16aab992bb88eac397f5972456c72ec447374d0d8ce61153831bfc86ad5a6eb5b60bfb96a862c",
+ "04b69beede85d0f829fec1b893ccb9c3e052ff692e13b974537bc5b0f9feaf7b22e84f03231629b24866bdb4b8cf9089"
+ "1466f85e2bfcaba2843285b0e14ebc07ef7dafff8b424416fee647b59897b619f20eed95a632e6a4206bf7da429c04c560",
+ "042db5da5f940eaa884f4db5ec2139b0469f38e4e6fbbcc52df15c0f7cf7fcb1808c749764b6be85d2fdc5b16f58ad5d"
+ "c022e8b02dcf33e1b5a083849545f84ad5e43f77cb71546dbbac0d11bdb2ee202e9d3872e8d028c08990746c5e1dde9989",
+ "d765b208112d2b9ed5ad10c4046e2e3b0dbf57c469329519e239ac28b25c7d852bf757d5de0ee271cadd021d86cfd347",
+ "curve: P384 vector: 22" },
+
+ { ECCurve_NIST_P384,
+ "6fa6a1c704730987aa634b0516a826aba8c6d6411d3a4c89772d7a62610256a2e2f289f5c3440b0ec1e70fa339e251ce",
+ "0453de1fc1328e8de14aecab29ad8a40d6b13768f86f7d298433d20fec791f86f8bc73f358098b256a298bb488de257bf"
+ "4ac28944fd27f17b82946c04c66c41f0053d3692f275da55cd8739a95bd8cd3af2f96e4de959ea8344d8945375905858b",
+ "04329647baa354224eb4414829c5368c82d7893b39804e08cbb2180f459befc4b347a389a70c91a23bd9d30c83be5295d"
+ "3cc8f61923fad2aa8e505d6cfa126b9fabd5af9dce290b75660ef06d1caa73681d06089c33bc4246b3aa30dbcd2435b12",
+ "d3778850aeb58804fbe9dfe6f38b9fa8e20c2ca4e0dec335aafceca0333e3f2490b53c0c1a14a831ba37c4b9d74be0f2",
+ "curve: P384 vector: 23" },
+
+ { ECCurve_NIST_P384,
+ "74ad8386c1cb2ca0fcdeb31e0869bb3f48c036afe2ef110ca302bc8b910f621c9fcc54cec32bb89ec7caa84c7b8e54a8",
+ "0427a3e83cfb9d5122e73129d801615857da7cc089cccc9c54ab3032a19e0a0a9f677346e37f08a0b3ed8da6e5dd69106"
+ "38d60e44aa5e0fd30c918456796af37f0e41957901645e5c596c6d989f5859b03a0bd7d1f4e77936fff3c74d204e5388e",
+ "0429d8a36d22200a75b7aea1bb47cdfcb1b7fd66de967041434728ab5d533a060df732130600fe6f75852a871fb2938e3"
+ "9e19b53db528395de897a45108967715eb8cb55c3fcbf23379372c0873a058d57544b102ecce722b2ccabb1a603774fd5",
+ "81e1e71575bb4505498de097350186430a6242fa6c57b85a5f984a23371123d2d1424eefbf804258392bc723e4ef1e35",
+ "curve: P384 vector: 24" },
+
+ { ECCurve_NIST_P521,
+ "017eecc07ab4b329068fba65e56a1f8890aa935e57134ae0ffcce802735151f4eac6564f6ee9974c5e6887a1fefee5743"
+ "ae2241bfeb95d5ce31ddcb6f9edb4d6fc47",
+ "0400602f9d0cf9e526b29e22381c203c48a886c2b0673033366314f1ffbcba240ba42f4ef38a76174635f91e6b4ed3427"
+ "5eb01c8467d05ca80315bf1a7bbd945f550a501b7c85f26f5d4b2d7355cf6b02117659943762b6d1db5ab4f1dbc44ce7b2"
+ "946eb6c7de342962893fd387d1b73d7a8672d1f236961170b7eb3579953ee5cdc88cd2d",
+ "0400685a48e86c79f0f0875f7bc18d25eb5fc8c0b07e5da4f4370f3a9490340854334b1e1b87fa395464c60626124a4e70"
+ "d0f785601d37c09870ebf176666877a2046d01ba52c56fc8776d9e8f5db4f0cc27636d0b741bbe05400697942e80b739884"
+ "a83bde99e0f6716939e632bc8986fa18dccd443a348b6c3e522497955a4f3c302f676",
+ "005fc70477c3e63bc3954bd0df3ea0d1f41ee21746ed95fc5e1fdf90930d5e136672d72cc770742d1711c3c3a4c334a0ad9"
+ "759436a4d3c5bf6e74b9578fac148c831",
+ "curve: P521 vector: 0" },
+
+ { ECCurve_NIST_P521,
+ "00816f19c1fb10ef94d4a1d81c156ec3d1de08b66761f03f06ee4bb9dcebbbfe1eaa1ed49a6a990838d8ed318c14d74cc"
+ "872f95d05d07ad50f621ceb620cd905cfb8",
+ "0400d45615ed5d37fde699610a62cd43ba76bedd8f85ed31005fe00d6450fbbd101291abd96d4945a8b57bc73b3fe9f46"
+ "71105309ec9b6879d0551d930dac8ba45d25501425332844e592b440c0027972ad1526431c06732df19cd46a242172d4d"
+ "d67c2c8c99dfc22e49949a56cf90c6473635ce82f25b33682fb19bc33bd910ed8ce3a7fa",
+ "0401df277c152108349bc34d539ee0cf06b24f5d3500677b4445453ccc21409453aafb8a72a0be9ebe54d12270aa51b3a"
+ "b7f316aa5e74a951c5e53f74cd95fc29aee7a013d52f33a9f3c14384d1587fa8abe7aed74bc33749ad9c570b471776422c"
+ "7d4505d9b0a96b3bfac041e4c6a6990ae7f700e5b4a6640229112deafa0cd8bb0d089b0",
+ "000b3920ac830ade812c8f96805da2236e002acbbf13596a9ab254d44d0e91b6255ebf1229f366fb5a05c5884ef46032c2"
+ "6d42189273ca4efa4c3db6bd12a6853759",
+ "curve: P521 vector: 1" },
+
+ { ECCurve_NIST_P521,
+ "012f2e0c6d9e9d117ceb9723bced02eb3d4eebf5feeaf8ee0113ccd8057b13ddd416e0b74280c2d0ba8ed291c443bc1b14"
+ "1caf8afb3a71f97f57c225c03e1e4d42b0",
+ "0400717fcb3d4a40d103871ede044dc803db508aaa4ae74b70b9fb8d8dfd84bfecfad17871879698c292d2fd5e17b4f9343"
+ "636c531a4fac68a35a93665546b9a87867900f3d96a8637036993ab5d244500fff9d2772112826f6436603d3eb234a44d5c"
+ "4e5c577234679c4f9df725ee5b9118f23d8a58d0cc01096daf70e8dfec0128bdc2e8",
+ "040092db3142564d27a5f0006f819908fba1b85038a5bc2509906a497daac67fd7aee0fc2daba4e4334eeaef0e0019204b4"
+ "71cd88024f82115d8149cc0cf4f7ce1a4d5016bad0623f517b158d9881841d2571efbad63f85cbe2e581960c5d670601a67"
+ "60272675a548996217e4ab2b8ebce31d71fca63fcc3c08e91c1d8edd91cf6fe845f8",
+ "006b380a6e95679277cfee4e8353bf96ef2a1ebdd060749f2f046fe571053740bbcc9a0b55790bc9ab56c3208aa05ddf746"
+ "a10a3ad694daae00d980d944aabc6a08f",
+ "curve: P521 vector: 2" },
+
+ { ECCurve_NIST_P521,
+ "00e548a79d8b05f923b9825d11b656f222e8cb98b0f89de1d317184dc5a698f7c71161ee7dc11cd31f4f4f8ae3a981e1a3e7"
+ "8bdebb97d7c204b9261b4ef92e0918e0",
+ "04000ce800217ed243dd10a79ad73df578aa8a3f9194af528cd1094bbfee27a3b5481ad5862c8876c0c3f91294c0ab3aa806"
+ "d9020cbaa2ed72b7fecdc5a09a6dad6f3201543c9ab45b12469232918e21d5a351f9a4b9cbf9efb2afcc402fa9b31650bec2d6"
+ "41a05c440d35331c0893d11fb13151335988b303341301a73dc5f61d574e67d9",
+ "0400fdd40d9e9d974027cb3bae682162eac1328ad61bc4353c45bf5afe76bf607d2894c8cce23695d920f2464fda4773d4693b"
+ "e4b3773584691bdb0329b7f4c86cc2990034ceac6a3fef1c3e1c494bfe8d872b183832219a7e14da414d4e3474573671ec19b03"
+ "3be831b915435905925b44947c592959945b4eb7c951c3b9c8cf52530ba23",
+ "00fbbcd0b8d05331fef6086f22a6cce4d35724ab7a2f49dd8458d0bfd57a0b8b70f246c17c4468c076874b0dff7a0336823b19e"
+ "98bf1cec05e4beffb0591f97713c6",
+ "curve: P521 vector: 3" },
+
+ { ECCurve_NIST_P521,
+ "01c8aae94bb10b8ca4f7be577b4fb32bb2381032c4942c24fc2d753e7cc5e47b483389d9f3b956d20ee9001b1eef9f23545f72"
+ "c5602140046839e963313c3decc864",
+ "040106a14e2ee8ff970aa8ab0c79b97a33bba2958e070b75b94736b77bbe3f777324fa52872771aa88a63a9e8490c3378df4dc"
+ "760cd14d62be700779dd1a4377943656002366ce3941e0b284b1aa81215d0d3b9778fce23c8cd1e4ed6fa0abf62156c91d4b3eb"
+ "55999c3471bed275e9e60e5aa9d690d310bfb15c9c5bbd6f5e9eb39682b74",
+ "040098d99dee0816550e84dbfced7e88137fddcf581a725a455021115fe49f8dc3cf233cd9ea0e6f039dc7919da973cdceaca20"
+ "5da39e0bd98c8062536c47f258f44b500cd225c8797371be0c4297d2b457740100c774141d8f214c23b61aa2b6cd4806b9b70722"
+ "aa4965fb622f42b7391e27e5ec21c5679c5b06b59127372997d421adc1e",
+ "0145cfa38f25943516c96a5fd4bfebb2f645d10520117aa51971eff442808a23b4e23c187e639ff928c3725fbd1c0c2ad0d4aeb2"
+ "07bc1a6fb6cb6d467888dc044b3c",
+ "curve: P521 vector: 4" },
+
+ { ECCurve_NIST_P521,
+ "009b0af137c9696c75b7e6df7b73156bb2d45f482e5a4217324f478b10ceb76af09724cf86afa316e7f89918d31d54824a5c33"
+ "107a483c15c15b96edc661340b1c0e",
+ "0400748cdbb875d35f4bccb62abe20e82d32e4c14dc2feb5b87da2d0ccb11c9b6d4b7737b6c46f0dfb4d896e2db92fcf53cdbb"
+ "ae2a404c0babd564ad7adeac6273efa301984acab8d8f173323de0bb60274b228871609373bb22a17287e9dec7495873abc09a"
+ "8915b54c8455c8e02f654f602e23a2bbd7a9ebb74f3009bd65ecc650814cc0",
+ "04007ae115adaaf041691ab6b7fb8c921f99d8ed32d283d67084e80b9ad9c40c56cd98389fb0a849d9ecf7268c297b6f934061"
+ "19f40e32b5773ed25a28a9a85c4a758801a28e004e37eeaefe1f4dbb71f1878696141af3a10a9691c4ed93487214643b761fa4b"
+ "0fbeeb247cf6d3fba7a60697536ad03f49b80a9d1cb079673654977c5fa94",
+ "005c5721e96c273319fd60ecc46b5962f698e974b429f28fe6962f4ac656be2eb8674c4aafc037eab48ece612953b1e8d86101"
+ "6b6ad0c79805784c67f73ada96f351",
+ "curve: P521 vector: 5" },
+
+ { ECCurve_NIST_P521,
+ "01e48faacee6dec83ffcde944cf6bdf4ce4bae72747888ebafee455b1e91584971efb49127976a52f4142952f7c207ec0265f2b"
+ "718cf3ead96ea4f62c752e4f7acd3",
+ "04010eb1b4d9172bcc23f4f20cc9560fc54928c3f34ea61c00391dc766c76ed9fa608449377d1e4fadd1236025417330b4b91086"
+ "704ace3e4e6484c606e2a943478c860149413864069825ee1d0828da9f4a97713005e9bd1adbc3b38c5b946900721a960fe96ad2c"
+ "1b3a44fe3de9156136d44cb17cbc2415729bb782e16bfe2deb3069e43",
+ "04012588115e6f7f7bdcfdf57f03b169b479758baafdaf569d04135987b2ce6164c02a57685eb5276b5dae6295d3fe90620f38b55"
+ "35c6d2260c173e61eb888ca92020301542c169cf97c2596fe2ddd848a222e367c5f7e6267ebc1bcd9ab5dcf49158f1a48e4af29a89"
+ "7b7e6a82091c2db874d8e7abf0f58064691344154f396dbaed188b6",
+ "01736d9717429b4f412e903febe2f9e0fffd81355d6ce2c06ff3f66a3be15ceec6e65e308347593f00d7f33591da4043c30763d72"
+ "749f72cdceebe825e4b34ecd570",
+ "curve: P521 vector: 6" },
+
+ { ECCurve_NIST_P521,
+ "00c29aa223ea8d64b4a1eda27f39d3bc98ea0148dd98c1cbe595f8fd2bfbde119c9e017a50f5d1fc121c08c1cef31b75885955"
+ "6eb3e0e042d8dd6aaac57a05ca61e3",
+ "04001511c848ef60d5419a98d10204db0fe58224124370061bcfa4e9249d50618c56bf3722471b259f38263bb7b280d23caf2a"
+ "1ee8737f9371cdb2732cdc958369930c01d461681ae6d8c49b4c5f4d6016143fb1bd7491573e3ed0e6c48b82e821644f87f82f0"
+ "e5f08fd16f1f98fa17586200ab02ed8c627b35c3f27617ec5fd92f456203f",
+ "040169491d55bd09049fdf4c2a53a660480fee4c03a0538675d1cd09b5bba78dac48543ef118a1173b3fbf8b20e39ce0e6b8"
+ "90a163c50f9645b3d21d1cbb3b60a6fff40083494b2eba76910fed33c761804515011fab50e3b377abd8a8a045d886d2238d2"
+ "c268ac1b6ec88bd71b7ba78e2c33c152e4bf7da5d565e4acbecf5e92c7ad662bb",
+ "018f2ae9476c771726a77780208dedfefa205488996b18fecc50bfd4c132753f5766b2cd744afa9918606de2e016effc63622"
+ "e9029e76dc6e3f0c69f7aeced565c2c",
+ "curve: P521 vector: 7" },
+
+ { ECCurve_NIST_P521,
+ "0028692be2bf5c4b48939846fb3d5bce74654bb2646e15f8389e23708a1afadf561511ea0d9957d0b53453819d60fba8f65a1"
+ "8f7b29df021b1bb01cd163293acc3cc",
+ "0401cfdc10c799f5c79cb6930a65fba351748e07567993e5e410ef4cacc4cd8a25784991eb4674e41050f930c7190ac812b92"
+ "45f48a7973b658daf408822fe5b85f6680180d9ddfc9af77b9c4a6f02a834db15e535e0b3845b2cce30388301b51cecbe32763"
+ "07ef439b5c9e6a72dc2d94d879bc395052dbb4a5787d06efb280210fb8be037",
+ "04008415f5bbd0eee387d6c09d0ef8acaf29c66db45d6ba101860ae45d3c60e1e0e3f7247a4626a60fdd404965c3566c79f644"
+ "9e856ce0bf94619f97da8da24bd2cfb600fdd7c59c58c361bc50a7a5d0d36f723b17c4f2ad2b03c24d42dc50f74a8c465a0afc"
+ "4683f10fab84652dfe9e928c2626b5456453e1573ff60be1507467d431fbb2",
+ "0105a346988b92ed8c7a25ce4d79d21bc86cfcc7f99c6cd19dbb4a39f48ab943b79e4f0647348da0b80bd864b85c6b8d92536"
+ "d6aa544dc7537a00c858f8b66319e25",
+ "curve: P521 vector: 8" },
+
+ { ECCurve_NIST_P521,
+ "01194d1ee613f5366cbc44b504d21a0cf6715e209cd358f2dd5f3e71cc0d67d0e964168c42a084ebda746f9863a86bacffc81"
+ "9f1edf1b8c727ccfb3047240a57c435",
+ "04016bd15c8a58d366f7f2b2f298cc87b7485e9ee70d11d12448b8377c0a82c7626f67aff7f97be7a3546bf417eeeddf75a93"
+ "c130191c84108042ea2fca17fd3f80d1401560502d04b74fce1743aab477a9d1eac93e5226981fdb97a7478ce4ce566ff72439"
+ "31284fad850b0c2bcae0ddd2d97790160c1a2e77c3ed6c95ecc44b89e2637fc",
+ "0401c721eea805a5cba29f34ba5758775be0cf6160e6c08723f5ab17bf96a1ff2bd9427961a4f34b07fc0b14ca4b2bf6845de"
+ "bd5a869f124ebfa7aa72fe565050b7f1800b6e89eb0e1dcf181236f7c548fd1a8c16b258b52c1a9bfd3fe8f22841b26763265"
+ "f074c4ccf2d634ae97b701956f67a11006c52d97197d92f585f5748bc2672eeb",
+ "004531b3d2c6cd12f21604c8610e6723dbf4daf80b5a459d6ba5814397d1c1f7a21d7c114be964e27376aaebe3a7bc3d6af7"
+ "a7f8c7befb611afe487ff032921f750f",
+ "curve: P521 vector: 9" },
+
+ { ECCurve_NIST_P521,
+ "01fd90e3e416e98aa3f2b6afa7f3bf368e451ad9ca5bd54b5b14aee2ed6723dde5181f5085b68169b09fbec721372ccf6b"
+ "284713f9a6356b8d560a8ff78ca3737c88",
+ "0401ebea1b10d3e3b971b7efb69fc878de11c7f472e4e4d384c31b8d6288d8071517acade9b39796c7af5163bcf71aeda7"
+ "77533f382c6cf0a4d9bbb938c85f44b78037016b0e3e19c2996b2cbd1ff64730e7ca90edca1984f9b2951333535e5748baa"
+ "34a99f61ff4d5f812079e0f01e87789f34efdad8098015ee74a4f846dd190d16dc6e1",
+ "0401c35823e440a9363ab98d9fc7a7bc0c0532dc7977a79165599bf1a9cc64c00fb387b42cca365286e8430360bfad3643"
+ "bc31354eda50dc936c329ecdb60905c40fcb00d9e7f433531e44df4f6d514201cbaabb06badd6783e01111726d815531d23"
+ "3c5cdb722893ffbb2027259d594de77438809738120c6f783934f926c3fb69b40c409",
+ "0100c8935969077bae0ba89ef0df8161d975ec5870ac811ae7e65ca5394efba4f0633d41bf79ea5e5b9496bbd7aae000b05"
+ "94baa82ef8f244e6984ae87ae1ed124b7",
+ "curve: P521 vector: 10" },
+
+ { ECCurve_NIST_P521,
+ "009012ecfdadc85ced630afea534cdc8e9d1ab8be5f3753dcf5f2b09b40eda66fc6858549bc36e6f8df55998cfa9a0703a"
+ "ecf6c42799c245011064f530c09db98369",
+ "0400234e32be0a907131d2d128a6477e0caceb86f02479745e0fe245cb332de631c078871160482eeef584e274df7fa412c"
+ "ea3e1e91f71ecba8781d9205d48386341ad01cf86455b09b1c005cffba8d76289a3759628c874beea462f51f30bd581e380"
+ "3134307dedbb771b3334ee15be2e242cd79c3407d2f58935456c6941dd9b6d155a46",
+ "0400093057fb862f2ad2e82e581baeb3324e7b32946f2ba845a9beeed87d6995f54918ec6619b9931955d5a89d4d74adf10"
+ "46bb362192f2ef6bd3e3d2d04dd1f87054a00aa3fb2448335f694e3cda4ae0cc71b1b2f2a206fa802d7262f19983c44674f"
+ "e15327acaac1fa40424c395a6556cb8167312527fae5865ecffc14bbdc17da78cdcf",
+ "017f36af19303841d13a389d95ec0b801c7f9a679a823146c75c17bc44256e9ad422a4f8b31f14647b2c7d317b933f7c294"
+ "6c4b8abd1d56d620fab1b5ff1a3adc71f",
+ "curve: P521 vector: 11" },
+
+ { ECCurve_NIST_P521,
+ "01b5ff847f8eff20b88cfad42c06e58c3742f2f8f1fdfd64b539ba48c25926926bd5e332b45649c0b184f77255e9d58fe8"
+ "afa1a6d968e2cb1d4637777120c765c128",
+ "0401de3dc9263bc8c4969dc684be0eec54befd9a9f3dba194d8658a789341bf0d78d84da6735227cafaf093519516911975"
+ "73c8c360a11e5285712b8bbdf5ac91b977c00812de58cd095ec2e5a9b247eb3ed41d8bef6aeace194a7a05b65aa5d289fbc9"
+ "b1770ec84bb6be0c2c64cc37c1d54a7f5d71377a9adbe20f26f6f2b544a821ea831",
+ "040083192ed0b1cb31f75817794937f66ad91cf74552cd510cedb9fd641310422af5d09f221cad249ee814d16dd7ac84ded"
+ "9eacdc28340fcfc9c0c06abe30a2fc28cd8002212ed868c9ba0fb2c91e2c39ba93996a3e4ebf45f2852d0928c48930e875c"
+ "c7b428d0e7f3f4d503e5d60c68cb49b13c2480cd486bed9200caddaddfe4ff8e3562",
+ "00062f9fc29ae1a68b2ee0dcf956cbd38c88ae5f645eaa546b00ebe87a7260bf724be20d34b9d02076655c933d056b21e30"
+ "4c24ddb1dedf1dd76de611fc4a2340336",
+ "curve: P521 vector: 12" },
+
+ { ECCurve_NIST_P521,
+ "011a6347d4e801c91923488354cc533e7e35fddf81ff0fb7f56bb0726e0c29ee5dcdc5f394ba54cf57269048aab6e055895c"
+ "8da24b8b0639a742314390cc04190ed6",
+ "0400fe30267f33ba5cdefc25cbb3c9320dad9ccb1d7d376644620ca4fadee5626a3cede25ad254624def727a7048f7145f761"
+ "62aa98042f9b123b2076f8e8cf59b3fdf001145dc6631953b6e2945e94301d6cbb098fe4b04f7ee9b09411df104dc82d7d79e"
+ "c46a01ed0f2d3e7db6eb680694bdeb107c1078aec6cabd9ebee3d342fe7e54df",
+ "0401a89b636a93e5d2ba6c2292bf23033a84f06a3ac1220ea71e806afbe097a804cc67e9baa514cfb6c12c9194be30212bf7a"
+ "ae7fdf6d376c212f0554e656463ffab7e0182efcaf70fc412d336602e014da47256a0b606f2addcce8053bf817ac8656bb4e4"
+ "2f14c8cbf2a68f488ab35dcdf64056271dee1f606a440ba4bd4e5a11b8b8e54f",
+ "0128ab09bfec5406799e610f772ba17e892249fa8e0e7b18a04b9197034b250b48294f1867fb9641518f92766066a07a8b917"
+ "b0e76879e1011e51ccbd9f540c54d4f",
+ "curve: P521 vector: 13" },
+
+ { ECCurve_NIST_P521,
+ "0022b6d2a22d71dfaa811d2d9f9f31fbed27f2e1f3d239538ddf3e4cc8c39a330266db25b7bc0a9704f17bde7f3592bf5f1f2d"
+ "4b56013aacc3d8d1bc02f00d3146cc",
+ "0400ba38cfbf9fd2518a3f61d43549e7a6a6d28b2be57ffd3e0faceb636b34ed17e044a9f249dae8fc132e937e2d9349cd2ed7"
+ "7bb1049ceb692a2ec5b17ad61502a64c001ec91d3058573fa6c0564a02a1a010160c313bc7c73510dc983e5461682b5be00dbc"
+ "e7e2c682ad73f29ca822cdc111f68fabe33a7b384a648342c3cdb9f050bcdb",
+ "04017200b3f16a68cbaed2bf78ba8cddfb6cffac262bba00fbc25f9dc72a07ce59372904899f364c44cb264c097b647d4412be"
+ "e3e519892d534d9129f8a28f7500fee700baba8d672a4f4a3b63de48b96f56e18df5d68f7d70d5109833f43770d6732e06b39ad"
+ "60d93e5b43db8789f1ec0aba47286a39ea584235acea757dbf13d53b58364",
+ "0101e462e9d9159968f6440e956f11dcf2227ae4aea81667122b6af9239a291eb5d6cf5a4087f358525fcacfa46bb2db01a75a"
+ "f1ba519b2d31da33eda87a9d565748",
+ "curve: P521 vector: 14" },
+
+ { ECCurve_NIST_P521,
+ "005bacfff268acf6553c3c583b464ea36a1d35e2b257a5d49eb3419d5a095087c2fb4d15cf5bf5af816d0f3ff7586490ccd3ddc1"
+ "a98b39ce63749c6288ce0dbdac7d",
+ "040036e488da7581472a9d8e628c58d6ad727311b7e6a3f6ae33a8544f34b09280249020be7196916fafd90e2ec54b66b5468d23"
+ "61b99b56fa00d7ac37abb8c6f16653011edb9fb8adb6a43f4f5f5fdc1421c9fe04fc8ba46c9b66334e3af927c8befb4307104f299"
+ "acec4e30f812d9345c9720d19869dbfffd4ca3e7d2713eb5fc3f42615",
+ "04004efd5dbd2f979e3831ce98f82355d6ca14a5757842875882990ab85ab9b7352dd6b9b2f4ea9a1e95c3880d65d1f3602f9ca6"
+ "53dc346fac858658d75626f4d4fb080061cf15dbdaa7f31589c98400373da284506d70c89f074ed262a9e28140796b7236c2eef99"
+ "016085e71552ff488c72b7339fefb7915c38459cb20ab85aec4e45052",
+ "0141d6a4b719ab67eaf04a92c0a41e2dda78f4354fb90bdc35202cc7699b9b04d49616f82255debf7bbec045ae58f982a66905fc"
+ "fae69d689785e38c868eb4a27e7b",
+ "curve: P521 vector: 15" },
+
+ { ECCurve_NIST_P521,
+ "008e2c93c5423876223a637cad367c8589da69a2d0fc68612f31923ae50219df2452e7cc92615b67f17b57ffd2f52b19154bb40"
+ "d7715336420fde2e89fee244f59dc",
+ "0400fa3b35118d6c422570f724a26f90b2833b19239174cea081c53133f64db60d6940ea1261299c04c1f4587cdb0c4c39616"
+ "479c1bb0c146799a118032dcf98f899c00069f040229006151fa32b51f679c8816f7c17506b403809dc77cd58a2aec430d94d"
+ "13b6c916de99f355aa45fcfbc6853d686c71be496a067d24bfaea4818fc51f75",
+ "040129891de0cf3cf82e8c2cf1bf90bb296fe00ab08ca45bb7892e0e227a504fdd05d2381a4448b68adff9c4153c87eacb783"
+ "30d8bd52515f9f9a0b58e85f446bb4e10009edd679696d3d1d0ef327f200383253f6413683d9e4fcc87bb35f112c2f110098d"
+ "15e5701d7ceee416291ff5fed85e687f727388b9afe26a4f6feed560b218e6bb",
+ "00345e26e0abb1aac12b75f3a9cf41efe1c336396dffa4a067a4c2cfeb878c68b2b045faa4e5b4e6fa4678f5b603c351903b1"
+ "4bf9a6a70c439257199a640890b61d1",
+ "curve: P521 vector: 16" },
+
+ { ECCurve_NIST_P521,
+ "0004d49d39d40d8111bf16d28c5936554326b197353eebbcf47545393bc8d3aaf98f14f5be7074bfb38e6cc97b989754074da"
+ "ddb3045f4e4ce745669fdb3ec0d5fa8",
+ "04012ec226d050ce07c79b3df4d0f0891f9f7adf462e8c98dbc1a2a14f5e53a3f5ad894433587cc429a8be9ea1d84fa33b180"
+ "3690dae04da7218d30026157fc995cf52004837dfbf3426f57b5c793269130abb9a38f618532211931154db4eeb9aede88e57"
+ "290f842ea0f2ea9a5f74c6203a3920fe4e305f6118f676b154e1d75b9cb5eb88",
+ "0401a3c20240e59f5b7a3e17c275d2314ba1741210ad58b71036f8c83cc1f6b0f409dfdd9113e94b67ec39c3291426c23ffc"
+ "c447054670d2908ff8fe67dc2306034c5c01d2825bfd3af8b1e13205780c137fe938f84fde40188e61ea02cead81badfdb425"
+ "c29f7d7fb0324debadc10bbb93de68f62c35069268283f5265865db57a79f7bf7",
+ "006fe9de6fb8e672e7fd150fdc5e617fabb0d43906354ccfd224757c7276f7a1010091b17ed072074f8d10a5ec971eb35a5c"
+ "b7076603b7bc38d432cbc059f80f9488",
+ "curve: P521 vector: 17" },
+
+ { ECCurve_NIST_P521,
+ "011a5d1cc79cd2bf73ea106f0e60a5ace220813b53e27b739864334a07c03367efda7a4619fa6eef3a9746492283b3c445610"
+ "a023a9cc49bf4591140384fca5c8bb5",
+ "0400eb07c7332eedb7d3036059d35f7d2288d4377d5f42337ad3964079fb120ccd4c8bd384b585621055217023acd9a94fcb3"
+ "b965bfb394675e788ade41a1de73e620c00491a835de2e6e7deb7e090f4a11f2c460c0b1f3d5e94ee8d751014dc720784fd3b"
+ "54500c86ebaef18429f09e8e876d5d1538968a030d7715dde99f0d8f06e29d59",
+ "04007e2d138f2832e345ae8ff65957e40e5ec7163f016bdf6d24a2243daa631d878a4a16783990c722382130f9e51f0c1bd6"
+ "ff5ac96780e48b68f5dec95f42e6144bb500b0de5c896791f52886b0f09913e26e78dd0b69798fc4df6d95e3ca708ecbcbcce1c1895f"
+ "5561bbabaae372e9e67e6e1a3be60e19b470cdf673ec1fc393d3426e20",
+ "01e4e759ecedce1013baf73e6fcc0b92451d03bdd50489b78871c333114990c9ba6a9b2fc7b1a2d9a1794c1b60d9279af6f"
+ "146f0bbfb0683140403bfa4ccdb524a29",
+ "curve: P521 vector: 18" },
+
+ { ECCurve_NIST_P521,
+ "010c908caf1be74c616b625fc8c1f514446a6aec83b5937141d6afbb0a8c7666a7746fa1f7a6664a2123e8cdf6cd8bf836c5"
+ "6d3c0ebdcc980e43a186f938f3a78ae7",
+ "040031890f4c7abec3f723362285d77d2636f876817db3bbc88b01e773597b969ff6f013ea470c854ab4a7739004eb8cbea6"
+ "9b82ddf36acadd406871798ecb2ac3aa7f00d8b429ae3250266b9643c0c765a60dc10155bc2531cf8627296f4978b6640a9e"
+ "600e19d0037d58503fa80799546a814d7478a550aa90e5ebeb052527faaeae5d08",
+ "0400118c36022209b1af8ebad1a12b566fc48744576e1199fe80de1cdf851cdf03e5b9091a8f7e079e83b7f827259b691d0"
+ "c22ee29d6bdf73ec7bbfd746f2cd97a357d00da5ff4904548a342e2e7ba6a1f4ee5f840411a96cf63e6fe622f22c13e614e"
+ "0a847c11a1ab3f1d12cc850c32e095614ca8f7e2721477b486e9ff40372977c3f65c",
+ "0163c9191d651039a5fe985a0eea1eba018a40ab1937fcd2b61220820ee8f2302e9799f6edfc3f5174f369d672d377ea895"
+ "4a8d0c8b851e81a56fda95212a6578f0e",
+ "curve: P521 vector: 19" },
+
+ { ECCurve_NIST_P521,
+ "01b37d6b7288de671360425d3e5ac1ccb21815079d8d73431e9b74a6f0e7ae004a357575b11ad66642ce8b775593eba9d98"
+ "bf25c75ef0b4d3a2098bbc641f59a2b77",
+ "0400189a5ee34de7e35aefeaeef9220c18071b4c29a4c3bd9d954458bd3e82a7a34da34cff5579b8101c065b1f2f527cf45"
+ "81501e28ef5671873e65267733d003520af01eb4bc50a7b4d4599d7e3fa773ddb9eb252c9b3422872e544bdf75c7bf60f51"
+ "66ddc11eb08fa7c30822dabaee373ab468eb2d922e484e2a527fff2ebb804b7d9a37",
+ "0401780edff1ca1c03cfbe593edc6c049bcb2860294a92c355489d9afb2e702075ade1c953895a456230a0cde905de4a3f"
+ "38573dbfcccd67ad6e7e93f0b5581e926a5d00a5481962c9162962e7f0ebdec936935d0eaa813e8226d40d7f6119bfd940"
+ "602380c86721e61db1830f51e139f210000bcec0d8edd39e54d73a9a129f95cd5fa979",
+ "015d613e267a36342e0d125cdad643d80d97ed0600afb9e6b9545c9e64a98cc6da7c5aaa3a8da0bdd9dd3b97e9788218a8"
+ "0abafc106ef065c8f1c4e1119ef58d298b",
+ "curve: P521 vector: 20" },
+
+ { ECCurve_NIST_P521,
+ "00f2661ac762f60c5fff23be5d969ccd4ec6f98e4e72618d12bdcdb9b4102162333788c0bae59f91cdfc172c7a1681ee44d9"
+ "6ab2135a6e5f3415ebbcd55165b1afb0",
+ "0400a8e25a6902d687b4787cdc94c364ac7cecc5c495483ed363dc0aa95ee2bd739c4c4d46b17006c728b076350d7d7e54c"
+ "6822f52f47162a25109aaaba690cab696ec0168d2f08fe19e4dc9ee7a195b03c9f7fe6676f9f520b6270557504e72ca4394"
+ "a2c6918625e15ac0c51b8f95cd560123653fb8e8ee6db961e2c4c62cc54e92e2a2a9",
+ "04016dacffa183e5303083a334f765de724ec5ec9402026d4797884a9828a0d321a8cfac74ab737fe20a7d6befcfc73b6a3"
+ "5c1c7b01d373e31abc192d48a4241a35803011e5327cac22d305e7156e559176e19bee7e4f2f59e86f1a9d0b6603b6a7df"
+ "1069bde6387feb71587b8ffce5b266e1bae86de29378a34e5c74b6724c4d40a719923",
+ "014d6082a3b5ced1ab8ca265a8106f302146c4acb8c30bb14a4c991e3c82a9731288bdb91e0e85bda313912d06384fc44"
+ "f2153fb13506fa9cf43c9aab5750988c943",
+ "curve: P521 vector: 21" },
+
+ { ECCurve_NIST_P521,
+ "00f430ca1261f09681a9282e9e970a9234227b1d5e58d558c3cc6eff44d1bdf53de16ad5ee2b18b92d62fc79586116b0e"
+ "fc15f79340fb7eaf5ce6c44341dcf8dde27",
+ "04006c1d9b5eca87de1fb871a0a32f807c725adccde9b3967453a71347d608f0c030cd09e338cdecbf4a02015bc8a6e8"
+ "d3e2595fe773ffc2fc4e4a55d0b1a2cc00323b01141b2109e7f4981c952aa818a2b9f6f5c41feccdb7a7a45b9b4b6729"
+ "37771b008cae5f934dfe3fed10d383ab1f38769c92ce88d9be5414817ecb073a31ab368ccb",
+ "0400a091421d3703e3b341e9f1e7d58f8cf7bdbd1798d001967b801d1cec27e605c580b2387c1cb464f55ce7ac803341"
+ "02ab03cfb86d88af76c9f4129c01bedd3bbfc4008c9c577a8e6fc446815e9d40baa66025f15dae285f19eb668ee60ae9"
+ "c98e7ecdbf2b2a68e22928059f67db188007161d3ecf397e0883f0c4eb7eaf7827a62205cc",
+ "0020c00747cb8d492fd497e0fec54644bf027d418ab686381f109712a99cabe328b9743d2225836f9ad66e5d7fed1de2"
+ "47e0da92f60d5b31f9e47672e57f710598f4",
+ "curve: P521 vector: 22" },
+
+ { ECCurve_NIST_P521,
+ "005dc33aeda03c2eb233014ee468dff753b72f73b00991043ea353828ae69d4cd0fadeda7bb278b535d7c57406ff2e6e"
+ "473a5a4ff98e90f90d6dadd25100e8d85666",
+ "0400c825ba307373cec8dd2498eef82e21fd9862168dbfeb83593980ca9f82875333899fe94f137daf1c4189eb502937"
+ "c3a367ea7951ed8b0f3377fcdf2922021d46a5016b8a2540d5e65493888bc337249e67c0a68774f3e8d81e3b4574a012"
+ "5165f0bd58b8af9de74b35832539f95c3cd9f1b759408560aa6851ae3ac7555347b0d3b13b",
+ "04004f38816681771289ce0cb83a5e29a1ab06fc91f786994b23708ff08a08a0f675b809ae99e9f9967eb1a49f196057"
+ "d69e50d6dedb4dd2d9a81c02bdcc8f7f518460009efb244c8b91087de1eed766500f0e81530752d469256ef79f6b965d"
+ "8a2232a0c2dbc4e8e1d09214bab38485be6e357c4200d073b52f04e4a16fc6f5247187aecb",
+ "00c2bfafcd7fbd3e2fd1c750fdea61e70bd4787a7e68468c574ee99ebc47eedef064e8944a73bcb7913dbab5d93dca6"
+ "60d216c553622362794f7a2acc71022bdb16f",
+ "curve: P521 vector: 23" },
+
+ { ECCurve_NIST_P521,
+ "00df14b1f1432a7b0fb053965fd8643afee26b2451ecb6a8a53a655d5fbe16e4c64ce8647225eb11e7fdcb23627471"
+ "dffc5c2523bd2ae89957cba3a57a23933e5a78",
+ "04004e8583bbbb2ecd93f0714c332dff5ab3bc6396e62f3c560229664329baa5138c3bb1c36428abd4e23d17fcb7"
+ "a2cfcc224b2e734c8941f6f121722d7b6b9415457601cf0874f204b0363f020864672fadbf87c8811eb147758b254b"
+ "74b14fae742159f0f671a018212bbf25b8519e126d4cad778cfff50d288fd39ceb0cac635b175ec0",
+ "0401a32099b02c0bd85371f60b0dd20890e6c7af048c8179890fda308b359dbbc2b7a832bb8c6526c4af99a7ea3f0"
+ "b3cb96ae1eb7684132795c478ad6f962e4a6f446d017627357b39e9d7632a1370b3e93c1afb5c851b910eb4ead0c9"
+ "d387df67cde85003e0e427552f1cd09059aad0262e235cce5fba8cedc4fdc1463da76dcd4b6d1a46",
+ "01aaf24e5d47e4080c18c55ea35581cd8da30f1a079565045d2008d51b12d0abb4411cda7a0785b15d149ed301a36"
+ "97062f42da237aa7f07e0af3fd00eb1800d9c41",
+ "curve: P521 vector: 24" },
+
+ { ECCurve_pastLastCurve, NULL, NULL, NULL, NULL, NULL }
+};
diff --git a/nss/cmd/fbectest/Makefile b/nss/cmd/fbectest/Makefile
new file mode 100644
index 0000000..d20daa4
--- /dev/null
+++ b/nss/cmd/fbectest/Makefile
@@ -0,0 +1,46 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+include ../platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+
+include ../platrules.mk
+
diff --git a/nss/cmd/fbectest/fbectest.c b/nss/cmd/fbectest/fbectest.c
new file mode 100644
index 0000000..2b65411
--- /dev/null
+++ b/nss/cmd/fbectest/fbectest.c
@@ -0,0 +1,281 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "blapi.h"
+#include "ec.h"
+#include "ecl-curve.h"
+#include "prprf.h"
+#include "basicutil.h"
+#include "secder.h"
+#include "secitem.h"
+#include "nspr.h"
+#include
+
+typedef struct {
+ ECCurveName curve;
+ int iterations;
+ char *privhex;
+ char *our_pubhex;
+ char *their_pubhex;
+ char *common_key;
+ char *name;
+ ECFieldType fieldType;
+} ECDH_KAT;
+
+typedef struct {
+ ECCurveName curve;
+ char *point;
+ char *name;
+ ECFieldType fieldType;
+} ECDH_BAD;
+
+#include "testvecs.h"
+
+void
+printBuf(const SECItem *item)
+{
+ int i;
+ if (!item || !item->len) {
+ printf("(null)\n");
+ return;
+ }
+
+ for (i = 0; i < item->len; i++) {
+ printf("%02x", item->data[i]);
+ }
+ printf("\n");
+}
+
+/* Initialise test with basic curve populate with only the necessary things */
+SECStatus
+init_params(ECParams *ecParams, ECCurveName curve, PLArenaPool **arena,
+ ECFieldType type)
+{
+ if ((curve < ECCurve_noName) || (curve > ECCurve_pastLastCurve)) {
+ return SECFailure;
+ }
+ *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!*arena) {
+ return SECFailure;
+ }
+ ecParams->name = curve;
+ ecParams->type = ec_params_named;
+ ecParams->curveOID.data = NULL;
+ ecParams->curveOID.len = 0;
+ ecParams->curve.seed.data = NULL;
+ ecParams->curve.seed.len = 0;
+ ecParams->DEREncoding.data = NULL;
+ ecParams->DEREncoding.len = 0;
+ ecParams->arena = *arena;
+ ecParams->fieldID.size = ecCurve_map[curve]->size;
+ ecParams->fieldID.type = type;
+ ecParams->cofactor = ecCurve_map[curve]->cofactor;
+
+ return SECSuccess;
+}
+
+SECStatus
+ectest_ecdh_kat(ECDH_KAT *kat)
+{
+ ECCurveName curve = kat->curve;
+ ECParams ecParams = { 0 };
+ ECPrivateKey *ecPriv = NULL;
+ SECItem theirKey = { siBuffer, NULL, 0 };
+ SECStatus rv = SECFailure;
+ PLArenaPool *arena = NULL;
+ SECItem seed = { siBuffer, NULL, 0 };
+ SECItem answer = { siBuffer, NULL, 0 };
+ SECItem answer2 = { siBuffer, NULL, 0 };
+ SECItem derived = { siBuffer, NULL, 0 };
+ char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];
+ int i;
+
+ rv = init_params(&ecParams, curve, &arena, kat->fieldType);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+
+ SECU_HexString2SECItem(arena, &ecParams.fieldID.u.prime, ecCurve_map[curve]->irr);
+ SECU_HexString2SECItem(arena, &ecParams.curve.a, ecCurve_map[curve]->curvea);
+ SECU_HexString2SECItem(arena, &ecParams.curve.b, ecCurve_map[curve]->curveb);
+ genenc[0] = '0';
+ genenc[1] = '4';
+ genenc[2] = '\0';
+ PORT_Assert(PR_ARRAY_SIZE(genenc) >= PORT_Strlen(ecCurve_map[curve]->genx));
+ PORT_Assert(PR_ARRAY_SIZE(genenc) >= PORT_Strlen(ecCurve_map[curve]->geny));
+ strcat(genenc, ecCurve_map[curve]->genx);
+ strcat(genenc, ecCurve_map[curve]->geny);
+ SECU_HexString2SECItem(arena, &ecParams.base, genenc);
+ SECU_HexString2SECItem(arena, &ecParams.order, ecCurve_map[curve]->order);
+
+ if (kat->our_pubhex) {
+ SECU_HexString2SECItem(arena, &answer, kat->our_pubhex);
+ }
+ SECU_HexString2SECItem(arena, &seed, kat->privhex);
+ rv = EC_NewKeyFromSeed(&ecParams, &ecPriv, seed.data, seed.len);
+ if (rv != SECSuccess) {
+ rv = SECFailure;
+ goto cleanup;
+ }
+ if (kat->our_pubhex) {
+ if (SECITEM_CompareItem(&answer, &ecPriv->publicValue) != SECEqual) {
+ rv = SECFailure;
+ goto cleanup;
+ }
+ }
+
+ SECU_HexString2SECItem(arena, &theirKey, kat->their_pubhex);
+ SECU_HexString2SECItem(arena, &answer2, kat->common_key);
+
+ rv = EC_ValidatePublicKey(&ecParams, &theirKey);
+ if (rv != SECSuccess) {
+ printf("EC_ValidatePublicKey failed\n");
+ goto cleanup;
+ }
+
+ for (i = 0; i < kat->iterations; ++i) {
+ rv = ECDH_Derive(&theirKey, &ecParams, &ecPriv->privateValue, PR_TRUE, &derived);
+ if (rv != SECSuccess) {
+ rv = SECFailure;
+ goto cleanup;
+ }
+ rv = SECITEM_CopyItem(ecParams.arena, &theirKey, &ecPriv->privateValue);
+ if (rv != SECSuccess) {
+ goto cleanup;
+ }
+ rv = SECITEM_CopyItem(ecParams.arena, &ecPriv->privateValue, &derived);
+ if (rv != SECSuccess) {
+ goto cleanup;
+ }
+ SECITEM_FreeItem(&derived, PR_FALSE);
+ }
+
+ if (SECITEM_CompareItem(&answer2, &ecPriv->privateValue) != SECEqual) {
+ printf("expected: ");
+ printBuf(&answer2);
+ printf("derived: ");
+ printBuf(&ecPriv->privateValue);
+ rv = SECFailure;
+ goto cleanup;
+ }
+
+cleanup:
+ PORT_FreeArena(arena, PR_FALSE);
+ if (ecPriv) {
+ PORT_FreeArena(ecPriv->ecParams.arena, PR_FALSE);
+ }
+ if (derived.data) {
+ SECITEM_FreeItem(&derived, PR_FALSE);
+ }
+ return rv;
+}
+
+SECStatus
+ectest_validate_point(ECDH_BAD *bad)
+{
+ ECParams ecParams = { 0 };
+ SECItem point = { siBuffer, NULL, 0 };
+ SECStatus rv = SECFailure;
+ PLArenaPool *arena = NULL;
+
+ rv = init_params(&ecParams, bad->curve, &arena, bad->fieldType);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+
+ SECU_HexString2SECItem(arena, &point, bad->point);
+ rv = EC_ValidatePublicKey(&ecParams, &point);
+
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+void
+printUsage(char *prog)
+{
+ printf("Usage: %s [-fp] [-nd]\n"
+ "\t-n: NIST curves\n"
+ "\t-d: non-NIST curves\n"
+ "You have to specify at at least one of n or d.\n"
+ "By default no tests are executed.\n",
+ prog);
+}
+
+/* Performs tests of elliptic curve cryptography over prime fields If
+ * tests fail, then it prints an error message, aborts, and returns an
+ * error code. Otherwise, returns 0. */
+int
+main(int argv, char **argc)
+{
+ SECStatus rv = SECSuccess;
+ int numkats = 0;
+ int i = 0;
+ int nist = 0;
+ int nonnist = 0;
+
+ for (i = 1; i < argv; i++) {
+ if (PL_strcasecmp(argc[i], "-n") == 0) {
+ nist = 1;
+ } else if (PL_strcasecmp(argc[i], "-d") == 0) {
+ nonnist = 1;
+ } else {
+ printUsage(argc[0]);
+ return 1;
+ }
+ }
+ if (!nist && !nonnist) {
+ printUsage(argc[0]);
+ return 1;
+ }
+
+ rv = SECOID_Init();
+ if (rv != SECSuccess) {
+ SECU_PrintError("Error:", "SECOID_Init");
+ goto cleanup;
+ }
+
+ /* Test P256, P384, P521 */
+ if (nist) {
+ while (ecdh_testvecs[numkats].curve != ECCurve_pastLastCurve) {
+ numkats++;
+ }
+ printf("1..%d\n", numkats);
+ for (i = 0; ecdh_testvecs[i].curve != ECCurve_pastLastCurve; i++) {
+ if (ectest_ecdh_kat(&ecdh_testvecs[i]) != SECSuccess) {
+ printf("not okay %d - %s\n", i + 1, ecdh_testvecs[i].name);
+ rv = SECFailure;
+ } else {
+ printf("okay %d - %s\n", i + 1, ecdh_testvecs[i].name);
+ }
+ }
+ }
+
+ /* Test KAT for non-NIST curves */
+ if (nonnist) {
+ for (i = 0; nonnist_testvecs[i].curve != ECCurve_pastLastCurve; i++) {
+ if (ectest_ecdh_kat(&nonnist_testvecs[i]) != SECSuccess) {
+ printf("not okay %d - %s\n", i + 1, nonnist_testvecs[i].name);
+ rv = SECFailure;
+ } else {
+ printf("okay %d - %s\n", i + 1, nonnist_testvecs[i].name);
+ }
+ }
+ for (i = 0; nonnist_testvecs_bad_values[i].curve != ECCurve_pastLastCurve; i++) {
+ if (ectest_validate_point(&nonnist_testvecs_bad_values[i]) == SECSuccess) {
+ printf("not okay %d - %s\n", i + 1, nonnist_testvecs_bad_values[i].name);
+ rv = SECFailure;
+ } else {
+ printf("okay %d - %s\n", i + 1, nonnist_testvecs_bad_values[i].name);
+ }
+ }
+ }
+
+cleanup:
+ rv |= SECOID_Shutdown();
+
+ if (rv != SECSuccess) {
+ printf("Error: exiting with error value\n");
+ }
+ return rv;
+}
diff --git a/nss/cmd/fbectest/fbectest.gyp b/nss/cmd/fbectest/fbectest.gyp
new file mode 100644
index 0000000..07357bc
--- /dev/null
+++ b/nss/cmd/fbectest/fbectest.gyp
@@ -0,0 +1,34 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi',
+ '../../cmd/platlibs.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'fbectest',
+ 'type': 'executable',
+ 'sources': [
+ 'fbectest.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports',
+ '<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3'
+ ]
+ }
+ ],
+ 'target_defaults': {
+ 'include_dirs': [
+ '<(DEPTH)/lib/softoken',
+ ],
+ 'defines': [
+ 'NSS_USE_STATIC_LIBS'
+ ]
+ },
+ 'variables': {
+ 'module': 'nss',
+ 'use_static_libs': 1
+ }
+}
\ No newline at end of file
diff --git a/nss/cmd/fbectest/manifest.mn b/nss/cmd/fbectest/manifest.mn
new file mode 100644
index 0000000..85d6aa5
--- /dev/null
+++ b/nss/cmd/fbectest/manifest.mn
@@ -0,0 +1,18 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEPTH = ../..
+CORE_DEPTH = ../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+INCLUDES += -I$(CORE_DEPTH)/nss/lib/softoken
+
+CSRCS = fbectest.c
+
+PROGRAM = fbectest
+
+USE_STATIC_LIBS = 1
diff --git a/nss/cmd/fbectest/testvecs.h b/nss/cmd/fbectest/testvecs.h
new file mode 100644
index 0000000..e66a2bf
--- /dev/null
+++ b/nss/cmd/fbectest/testvecs.h
@@ -0,0 +1,818 @@
+static ECDH_KAT ecdh_testvecs[] = {
+ { ECCurve_NIST_P256, 1,
+ "7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534",
+ "04ead218590119e8876b29146ff89ca61770c4edbbf97d38ce385ed281d8a6b23028af61281fd35e2fa7002523acc85a429cb06ee6648325389f59edfce1405141",
+ "04700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac",
+ "46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b",
+ "curve: P256 vector: 0", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "38f65d6dce47676044d58ce5139582d568f64bb16098d179dbab07741dd5caf5",
+ "04119f2f047902782ab0c9e27a54aff5eb9b964829ca99c06b02ddba95b0a3f6d08f52b726664cac366fc98ac7a012b2682cbd962e5acb544671d41b9445704d1d",
+ "04809f04289c64348c01515eb03d5ce7ac1a8cb9498f5caa50197e58d43a86a7aeb29d84e811197f25eba8f5194092cb6ff440e26d4421011372461f579271cda3",
+ "057d636096cb80b67a8c038c890e887d1adfa4195e9b3ce241c8a778c59cda67",
+ "curve: P256 vector: 1", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "1accfaf1b97712b85a6f54b148985a1bdc4c9bec0bd258cad4b3d603f49f32c8",
+ "04d9f2b79c172845bfdb560bbb01447ca5ecc0470a09513b6126902c6b4f8d1051f815ef5ec32128d3487834764678702e64e164ff7315185e23aff5facd96d7bc",
+ "04a2339c12d4a03c33546de533268b4ad667debf458b464d77443636440ee7fec3ef48a3ab26e20220bcda2c1851076839dae88eae962869a497bf73cb66faf536",
+ "2d457b78b4614132477618a5b077965ec90730a8c81a1c75d6d4ec68005d67ec",
+ "curve: P256 vector: 2", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "207c43a79bfee03db6f4b944f53d2fb76cc49ef1c9c4d34d51b6c65c4db6932d",
+ "0424277c33f450462dcb3d4801d57b9ced05188f16c28eda873258048cd1607e0dc4789753e2b1f63b32ff014ec42cd6a69fac81dfe6d0d6fd4af372ae27c46f88",
+ "04df3989b9fa55495719b3cf46dccd28b5153f7808191dd518eff0c3cff2b705ed422294ff46003429d739a33206c8752552c8ba54a270defc06e221e0feaf6ac4",
+ "96441259534b80f6aee3d287a6bb17b5094dd4277d9e294f8fe73e48bf2a0024",
+ "curve: P256 vector: 3", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "59137e38152350b195c9718d39673d519838055ad908dd4757152fd8255c09bf",
+ "04a8c5fdce8b62c5ada598f141adb3b26cf254c280b2857a63d2ad783a73115f6b806e1aafec4af80a0d786b3de45375b517a7e5b51ffb2c356537c9e6ef227d4a",
+ "0441192d2813e79561e6a1d6f53c8bc1a433a199c835e141b05a74a97b0faeb9221af98cc45e98a7e041b01cf35f462b7562281351c8ebf3ffa02e33a0722a1328",
+ "19d44c8d63e8e8dd12c22a87b8cd4ece27acdde04dbf47f7f27537a6999a8e62",
+ "curve: P256 vector: 4", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "f5f8e0174610a661277979b58ce5c90fee6c9b3bb346a90a7196255e40b132ef",
+ "047b861dcd2844a5a8363f6b8ef8d493640f55879217189d80326aad9480dfc149c4675b45eeb306405f6c33c38bc69eb2bdec9b75ad5af4706aab84543b9cc63a",
+ "0433e82092a0f1fb38f5649d5867fba28b503172b7035574bf8e5b7100a3052792f2cf6b601e0a05945e335550bf648d782f46186c772c0f20d3cd0d6b8ca14b2f",
+ "664e45d5bba4ac931cd65d52017e4be9b19a515f669bea4703542a2c525cd3d3",
+ "curve: P256 vector: 5", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "3b589af7db03459c23068b64f63f28d3c3c6bc25b5bf76ac05f35482888b5190",
+ "049fb38e2d58ea1baf7622e96720101cae3cde4ba6c1e9fa26d9b1de0899102863d5561b900406edf50802dd7d73e89395f8aed72fba0e1d1b61fe1d22302260f0",
+ "046a9e0c3f916e4e315c91147be571686d90464e8bf981d34a90b6353bca6eeba740f9bead39c2f2bcc2602f75b8a73ec7bdffcbcead159d0174c6c4d3c5357f05",
+ "ca342daa50dc09d61be7c196c85e60a80c5cb04931746820be548cdde055679d",
+ "curve: P256 vector: 6", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "d8bf929a20ea7436b2461b541a11c80e61d826c0a4c9d322b31dd54e7f58b9c8",
+ "0420f07631e4a6512a89ad487c4e9d63039e579cb0d7a556cb9e661cd59c1e7fa46de91846b3eee8a5ec09c2ab1f41e21bd83620ccdd1bdce3ab7ea6e02dd274f5",
+ "04a9c0acade55c2a73ead1a86fb0a9713223c82475791cd0e210b046412ce224bbf6de0afa20e93e078467c053d241903edad734c6b403ba758c2b5ff04c9d4229",
+ "35aa9b52536a461bfde4e85fc756be928c7de97923f0416c7a3ac8f88b3d4489",
+ "curve: P256 vector: 7", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "0f9883ba0ef32ee75ded0d8bda39a5146a29f1f2507b3bd458dbea0b2bb05b4d",
+ "04abb61b423be5d6c26e21c605832c9142dc1dfe5a5fff28726737936e6fbf516d733d2513ef58beab202090586fac91bf0fee31e80ab33473ab23a2d89e58fad6",
+ "0494e94f16a98255fff2b9ac0c9598aac35487b3232d3231bd93b7db7df36f9eb9d8049a43579cfa90b8093a94416cbefbf93386f15b3f6e190b6e3455fedfe69a",
+ "605c16178a9bc875dcbff54d63fe00df699c03e8a888e9e94dfbab90b25f39b4",
+ "curve: P256 vector: 8", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "2beedb04b05c6988f6a67500bb813faf2cae0d580c9253b6339e4a3337bb6c08",
+ "043d63e429cb5fa895a9247129bf4e48e89f35d7b11de8158efeb3e106a2a873950cae9e477ef41e7c8c1064379bb7b554ddcbcae79f9814281f1e50f0403c61f3",
+ "04e099bf2a4d557460b5544430bbf6da11004d127cb5d67f64ab07c94fcdf5274fd9c50dbe70d714edb5e221f4e020610eeb6270517e688ca64fb0e98c7ef8c1c5",
+ "f96e40a1b72840854bb62bc13c40cc2795e373d4e715980b261476835a092e0b",
+ "curve: P256 vector: 9", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "77c15dcf44610e41696bab758943eff1409333e4d5a11bbe72c8f6c395e9f848",
+ "04ad5d13c3db508ddcd38457e5991434a251bed49cf5ddcb59cdee73865f138c9f62cec1e70588aa4fdfc7b9a09daa678081c04e1208b9d662b8a2214bf8e81a21",
+ "04f75a5fe56bda34f3c1396296626ef012dc07e4825838778a645c8248cff0165833bbdf1b1772d8059df568b061f3f1122f28a8d819167c97be448e3dc3fb0c3c",
+ "8388fa79c4babdca02a8e8a34f9e43554976e420a4ad273c81b26e4228e9d3a3",
+ "curve: P256 vector: 10", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "42a83b985011d12303db1a800f2610f74aa71cdf19c67d54ce6c9ed951e9093e",
+ "04ab48caa61ea35f13f8ed07ffa6a13e8db224dfecfae1a7df8b1bb6ebaf0cb97d1274530ca2c385a3218bddfbcbf0b4024c9badd5243bff834ebff24a8618dccb",
+ "042db4540d50230756158abf61d9835712b6486c74312183ccefcaef2797b7674d62f57f314e3f3495dc4e099012f5e0ba71770f9660a1eada54104cdfde77243e",
+ "72877cea33ccc4715038d4bcbdfe0e43f42a9e2c0c3b017fc2370f4b9acbda4a",
+ "curve: P256 vector: 11", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "ceed35507b5c93ead5989119b9ba342cfe38e6e638ba6eea343a55475de2800b",
+ "049a8cd9bd72e71752df91440f77c547509a84df98114e7de4f26cdb39234a625dd07cfc84c8e144fab2839f5189bb1d7c88631d579bbc58012ed9a2327da52f62",
+ "04cd94fc9497e8990750309e9a8534fd114b0a6e54da89c4796101897041d14ecbc3def4b5fe04faee0a11932229fff563637bfdee0e79c6deeaf449f85401c5c4",
+ "e4e7408d85ff0e0e9c838003f28cdbd5247cdce31f32f62494b70e5f1bc36307",
+ "curve: P256 vector: 12", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "43e0e9d95af4dc36483cdd1968d2b7eeb8611fcce77f3a4e7d059ae43e509604",
+ "04f989cf8ee956a82e7ebd9881cdbfb2fd946189b08db53559bc8cfdd48071eb145eff28f1a18a616b04b7d337868679f6dd84f9a7b3d7b6f8af276c19611a541d",
+ "0415b9e467af4d290c417402e040426fe4cf236bae72baa392ed89780dfccdb471cdf4e9170fb904302b8fd93a820ba8cc7ed4efd3a6f2d6b05b80b2ff2aee4e77",
+ "ed56bcf695b734142c24ecb1fc1bb64d08f175eb243a31f37b3d9bb4407f3b96",
+ "curve: P256 vector: 13", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "b2f3600df3368ef8a0bb85ab22f41fc0e5f4fdd54be8167a5c3cd4b08db04903",
+ "0469c627625b36a429c398b45c38677cb35d8beb1cf78a571e40e99fe4eac1cd4e81690112b0a88f20f7136b28d7d47e5fbc2ada3c8edd87589bc19ec9590637bd",
+ "0449c503ba6c4fa605182e186b5e81113f075bc11dcfd51c932fb21e951eee2fa18af706ff0922d87b3f0c5e4e31d8b259aeb260a9269643ed520a13bb25da5924",
+ "bc5c7055089fc9d6c89f83c1ea1ada879d9934b2ea28fcf4e4a7e984b28ad2cf",
+ "curve: P256 vector: 14", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "4002534307f8b62a9bf67ff641ddc60fef593b17c3341239e95bdb3e579bfdc8",
+ "045fe964671315a18aa68a2a6e3dd1fde7e23b8ce7181471cfac43c99e1ae80262d5827be282e62c84de531b963884ba832db5d6b2c3a256f0e604fe7e6b8a7f72",
+ "0419b38de39fdd2f70f7091631a4f75d1993740ba9429162c2a45312401636b29c09aed7232b28e060941741b6828bcdfa2bc49cc844f3773611504f82a390a5ae",
+ "9a4e8e657f6b0e097f47954a63c75d74fcba71a30d83651e3e5a91aa7ccd8343",
+ "curve: P256 vector: 15", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "4dfa12defc60319021b681b3ff84a10a511958c850939ed45635934ba4979147",
+ "04c9b2b8496f1440bd4a2d1e52752fd372835b364885e154a7dac49295f281ec7cfbe6b926a8a4de26ccc83b802b1212400754be25d9f3eeaf008b09870ae76321",
+ "042c91c61f33adfe9311c942fdbff6ba47020feff416b7bb63cec13faf9b0999546cab31b06419e5221fca014fb84ec870622a1b12bab5ae43682aa7ea73ea08d0",
+ "3ca1fc7ad858fb1a6aba232542f3e2a749ffc7203a2374a3f3d3267f1fc97b78",
+ "curve: P256 vector: 16", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "1331f6d874a4ed3bc4a2c6e9c74331d3039796314beee3b7152fcdba5556304e",
+ "0459e1e101521046ad9cf1d082e9d2ec7dd22530cce064991f1e55c5bcf5fcb591482f4f673176c8fdaa0bb6e59b15a3e47454e3a04297d3863c9338d98add1f37",
+ "04a28a2edf58025668f724aaf83a50956b7ac1cfbbff79b08c3bf87dfd2828d767dfa7bfffd4c766b86abeaf5c99b6e50cb9ccc9d9d00b7ffc7804b0491b67bc03",
+ "1aaabe7ee6e4a6fa732291202433a237df1b49bc53866bfbe00db96a0f58224f",
+ "curve: P256 vector: 17", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "dd5e9f70ae740073ca0204df60763fb6036c45709bf4a7bb4e671412fad65da3",
+ "0430b9db2e2e977bcdc98cb87dd736cbd8e78552121925cf16e1933657c2fb23146a45028800b81291bce5c2e1fed7ded650620ebbe6050c6f3a7f0dfb4673ab5c",
+ "04a2ef857a081f9d6eb206a81c4cf78a802bdf598ae380c8886ecd85fdc1ed7644563c4c20419f07bc17d0539fade1855e34839515b892c0f5d26561f97fa04d1a",
+ "430e6a4fba4449d700d2733e557f66a3bf3d50517c1271b1ddae1161b7ac798c",
+ "curve: P256 vector: 18", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "5ae026cfc060d55600717e55b8a12e116d1d0df34af831979057607c2d9c2f76",
+ "0446c9ebd1a4a3c8c0b6d572b5dcfba12467603208a9cb5d2acfbb733c40cf639146c913a27d044185d38b467ace011e04d4d9bbbb8cb9ae25fa92aaf15a595e86",
+ "04ccd8a2d86bc92f2e01bce4d6922cf7fe1626aed044685e95e2eebd464505f01fe9ddd583a9635a667777d5b8a8f31b0f79eba12c75023410b54b8567dddc0f38",
+ "1ce9e6740529499f98d1f1d71329147a33df1d05e4765b539b11cf615d6974d3",
+ "curve: P256 vector: 19", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "b601ac425d5dbf9e1735c5e2d5bdb79ca98b3d5be4a2cfd6f2273f150e064d9d",
+ "047c9e950841d26c8dde8994398b8f5d475a022bc63de7773fcf8d552e01f1ba0acc42b9885c9b3bee0f8d8c57d3a8f6355016c019c4062fa22cff2f209b5cc2e1",
+ "04c188ffc8947f7301fb7b53e36746097c2134bf9cc981ba74b4e9c4361f595e4ebf7d2f2056e72421ef393f0c0f2b0e00130e3cac4abbcc00286168e85ec55051",
+ "4690e3743c07d643f1bc183636ab2a9cb936a60a802113c49bb1b3f2d0661660",
+ "curve: P256 vector: 20", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "fefb1dda1845312b5fce6b81b2be205af2f3a274f5a212f66c0d9fc33d7ae535",
+ "0438b54db85500cb20c61056edd3d88b6a9dc26780a047f213a6e1b900f76596eb6387e4e5781571e4eb8ae62991a33b5dc33301c5bc7e125d53794a39160d8fd0",
+ "04317e1020ff53fccef18bf47bb7f2dd7707fb7b7a7578e04f35b3beed222a0eb609420ce5a19d77c6fe1ee587e6a49fbaf8f280e8df033d75403302e5a27db2ae",
+ "30c2261bd0004e61feda2c16aa5e21ffa8d7e7f7dbf6ec379a43b48e4b36aeb0",
+ "curve: P256 vector: 21", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "334ae0c4693d23935a7e8e043ebbde21e168a7cba3fa507c9be41d7681e049ce",
+ "043f2bf1589abf3047bf3e54ac9a95379bff95f8f55405f64eca36a7eebe8ffca75212a94e66c5ae9a8991872f66a72723d80ec5b2e925745c456f5371943b3a06",
+ "0445fb02b2ceb9d7c79d9c2fa93e9c7967c2fa4df5789f9640b24264b1e524fcb15c6e8ecf1f7d3023893b7b1ca1e4d178972ee2a230757ddc564ffe37f5c5a321",
+ "2adae4a138a239dcd93c243a3803c3e4cf96e37fe14e6a9b717be9599959b11c",
+ "curve: P256 vector: 22", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "2c4bde40214fcc3bfc47d4cf434b629acbe9157f8fd0282540331de7942cf09d",
+ "0429c0807f10cbc42fb45c9989da50681eead716daa7b9e91fd32e062f5eb92ca0ff1d6d1955d7376b2da24fe1163a271659136341bc2eb1195fc706dc62e7f34d",
+ "04a19ef7bff98ada781842fbfc51a47aff39b5935a1c7d9625c8d323d511c92de6e9c184df75c955e02e02e400ffe45f78f339e1afe6d056fb3245f4700ce606ef",
+ "2e277ec30f5ea07d6ce513149b9479b96e07f4b6913b1b5c11305c1444a1bc0b",
+ "curve: P256 vector: 23", ec_field_GFp },
+
+ { ECCurve_NIST_P256, 1,
+ "85a268f9d7772f990c36b42b0a331adc92b5941de0b862d5d89a347cbf8faab0",
+ "049cf4b98581ca1779453cc816ff28b4100af56cf1bf2e5bc312d83b6b1b21d3337a5504fcac5231a0d12d658218284868229c844a04a3450d6c7381abe080bf3b",
+ "04356c5a444c049a52fee0adeb7e5d82ae5aa83030bfff31bbf8ce2096cf161c4b57d128de8b2a57a094d1a001e572173f96e8866ae352bf29cddaf92fc85b2f92",
+ "1e51373bd2c6044c129c436e742a55be2a668a85ae08441b6756445df5493857",
+ "curve: P256 vector: 24", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "3cc3122a68f0d95027ad38c067916ba0eb8c38894d22e1b15618b6818a661774ad463b205da88cf699ab4d43c9cf98a1",
+ "049803807f2f6d2fd966cdd0290bd410c0190352fbec7ff6247de1302df86f25d34fe4a97bef60cff548355c015dbb3e5"
+ "fba26ca69ec2f5b5d9dad20cc9da711383a9dbe34ea3fa5a2af75b46502629ad54dd8b7d73a8abb06a3a3be47d650cc99",
+ "04a7c76b970c3b5fe8b05d2838ae04ab47697b9eaf52e764592efda27fe7513272734466b400091adbf2d68c58e0c5006"
+ "6ac68f19f2e1cb879aed43a9969b91a0839c4c38a49749b661efedf243451915ed0905a32b060992b468c64766fc8437a",
+ "5f9d29dc5e31a163060356213669c8ce132e22f57c9a04f40ba7fcead493b457e5621e766c40a2e3d4d6a04b25e533f1",
+ "curve: P384 vector: 0", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "92860c21bde06165f8e900c687f8ef0a05d14f290b3f07d8b3a8cc6404366e5d5119cd6d03fb12dc58e89f13df9cd783",
+ "04ea4018f5a307c379180bf6a62fd2ceceebeeb7d4df063a66fb838aa35243419791f7e2c9d4803c9319aa0eb03c416b"
+ "6668835a91484f05ef028284df6436fb88ffebabcdd69ab0133e6735a1bcfb37203d10d340a8328a7b68770ca75878a1a6",
+ "0430f43fcf2b6b00de53f624f1543090681839717d53c7c955d1d69efaf0349b7363acb447240101cbb3af6641ce4b88e0"
+ "25e46c0c54f0162a77efcc27b6ea792002ae2ba82714299c860857a68153ab62e525ec0530d81b5aa15897981e858757",
+ "a23742a2c267d7425fda94b93f93bbcc24791ac51cd8fd501a238d40812f4cbfc59aac9520d758cf789c76300c69d2ff",
+ "curve: P384 vector: 1", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "12cf6a223a72352543830f3f18530d5cb37f26880a0b294482c8a8ef8afad09aa78b7dc2f2789a78c66af5d1cc553853",
+ "04fcfcea085e8cf74d0dced1620ba8423694f903a219bbf901b0b59d6ac81baad316a242ba32bde85cb248119b852fab6"
+ "6972e3c68c7ab402c5836f2a16ed451a33120a7750a6039f3ff15388ee622b7065f7122bf6d51aefbc29b37b03404581b",
+ "041aefbfa2c6c8c855a1a216774550b79a24cda37607bb1f7cc906650ee4b3816d68f6a9c75da6e4242cebfb6652f65180"
+ "419d28b723ebadb7658fcebb9ad9b7adea674f1da3dc6b6397b55da0f61a3eddacb4acdb14441cb214b04a0844c02fa3",
+ "3d2e640f350805eed1ff43b40a72b2abed0a518bcebe8f2d15b111b6773223da3c3489121db173d414b5bd5ad7153435",
+ "curve: P384 vector: 2", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "8dd48063a3a058c334b5cc7a4ce07d02e5ee6d8f1f3c51a1600962cbab462690ae3cd974fb39e40b0e843daa0fd32de1",
+ "04e38c9846248123c3421861ea4d32669a7b5c3c08376ad28104399494c84ff5efa3894adb2c6cbe8c3c913ef2eec5bd3"
+ "c9fa84024a1028796df84021f7b6c9d02f0f4bd1a612a03cbf75a0beea43fef8ae84b48c60172aadf09c1ad016d0bf3ce",
+ "048bc089326ec55b9cf59b34f0eb754d93596ca290fcb3444c83d4de3a5607037ec397683f8cef07eab2fe357eae36c44"
+ "9d9d16ce8ac85b3f1e94568521aae534e67139e310ec72693526aa2e927b5b322c95a1a033c229cb6770c957cd3148dd7",
+ "6a42cfc392aba0bfd3d17b7ccf062b91fc09bbf3417612d02a90bdde62ae40c54bb2e56e167d6b70db670097eb8db854",
+ "curve: P384 vector: 3", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "84ece6cc3429309bd5b23e959793ed2b111ec5cb43b6c18085fcaea9efa0685d98a6262ee0d330ee250bc8a67d0e733f",
+ "043222063a2997b302ee60ee1961108ff4c7acf1c0ef1d5fb0d164b84bce71c431705cb9aea9a45f5d73806655a058bee"
+ "3e61fa9e7fbe7cd43abf99596a3d3a039e99fa9dc93b0bdd9cad81966d17eeaf557068afa7c78466bb5b22032d1100fa6",
+ "04eb952e2d9ac0c20c6cc48fb225c2ad154f53c8750b003fd3b4ed8ed1dc0defac61bcdde02a2bcfee7067d75d342ed2b"
+ "0f1828205baece82d1b267d0d7ff2f9c9e15b69a72df47058a97f3891005d1fb38858f5603de840e591dfa4f6e7d489e1",
+ "ce7ba454d4412729a32bb833a2d1fd2ae612d4667c3a900e069214818613447df8c611de66da200db7c375cf913e4405",
+ "curve: P384 vector: 4", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "68fce2121dc3a1e37b10f1dde309f9e2e18fac47cd1770951451c3484cdb77cb136d00e731260597cc2859601c01a25b",
+ "04868be0e694841830e424d913d8e7d86b84ee1021d82b0ecf523f09fe89a76c0c95c49f2dfbcf829c1e39709d55efbb"
+ "3b9195eb183675b40fd92f51f37713317e4a9b4f715c8ab22e0773b1bc71d3a219f05b8116074658ee86b52e36f3897116",
+ "04441d029e244eb7168d647d4df50db5f4e4974ab3fdaf022aff058b3695d0b8c814cc88da6285dc6df1ac55c55388500"
+ "3e8025ac23a41d4b1ea2aa46c50c6e479946b59b6d76497cd9249977e0bfe4a6262622f13d42a3c43d66bdbb30403c345",
+ "ba69f0acdf3e1ca95caaac4ecaf475bbe51b54777efce01ca381f45370e486fe87f9f419b150c61e329a286d1aa265ec",
+ "curve: P384 vector: 5", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "b1764c54897e7aae6de9e7751f2f37de849291f88f0f91093155b858d1cc32a3a87980f706b86cc83f927bdfdbeae0bd",
+ "04c371222feaa6770c6f3ea3e0dac9740def4fcf821378b7f91ff937c21e0470f70f3a31d5c6b2912195f10926942b48ae"
+ "047d6b4d765123563f81116bc665b7b8cc6207830d805fd84da7cb805a65baa7c12fd592d1b5b5e3e65d9672a9ef7662",
+ "043d4e6bf08a73404accc1629873468e4269e82d90d832e58ad72142639b5a056ad8d35c66c60e8149fac0c797bceb7c2"
+ "f9b0308dc7f0e6d29f8c277acbc65a21e5adb83d11e6873bc0a07fda0997f482504602f59e10bc5cb476b83d0a4f75e71",
+ "1a6688ee1d6e59865d8e3ada37781d36bb0c2717eef92e61964d3927cb765c2965ea80f7f63e58c322ba0397faeaf62b",
+ "curve: P384 vector: 6", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "f0f7a96e70d98fd5a30ad6406cf56eb5b72a510e9f192f50e1f84524dbf3d2439f7287bb36f5aa912a79deaab4adea82",
+ "0499c8c41cb1ab5e0854a346e4b08a537c1706a61553387c8d94943ab15196d40dbaa55b8210a77a5d00915f2c4ea69e"
+ "ab5531065bdcf17bfb3cb55a02e41a57c7f694c383ad289f900fbd656c2233a93c92e933e7a26f54cbb56f0ad875c51bb0",
+ "04f5f6bef1d110da03be0017eac760cc34b24d092f736f237bc7054b3865312a813bcb62d297fb10a4f7abf54708fe2d3d"
+ "06fdf8d7dc032f4e10010bf19cbf6159321252ff415fb91920d438f24e67e60c2eb0463204679fa356af44cea9c9ebf5",
+ "d06a568bf2336b90cbac325161be7695eacb2295f599500d787f072612aca313ee5d874f807ddef6c1f023fe2b6e7cd0",
+ "curve: P384 vector: 7", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "9efb87ddc61d43c482ba66e1b143aef678fbd0d1bebc2000941fabe677fe5b706bf78fce36d100b17cc787ead74bbca2",
+ "044c34efee8f0c95565d2065d1bbac2a2dd25ae964320eb6bccedc5f3a9b42a881a1afca1bb6b880584fa27b01c193cd9"
+ "2d8fb01dbf7cd0a3868c26b951f393c3c56c2858cee901f7793ff5d271925d13a41f8e52409f4eba1990f33acb0bac669",
+ "047cdec77e0737ea37c67b89b7137fe38818010f4464438ee4d1d35a0c488cad3fde2f37d00885d36d3b795b9f93d23a6"
+ "728c42ee8d6027c56cf979ba4c229fdb01d234944f8ac433650112c3cf0f02844e888a3569dfef7828a8a884589aa055e",
+ "bb3b1eda9c6560d82ff5bee403339f1e80342338a991344853b56b24f109a4d94b92f654f0425edd4c205903d7586104",
+ "curve: P384 vector: 8", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "d787a57fde22ec656a0a525cf3c738b30d73af61e743ea90893ecb2d7b622add2f94ee25c2171467afb093f3f84d0018",
+ "04171546923b87b2cbbad664f01ce932bf09d6a6118168678446bfa9f0938608cb4667a98f4ec8ac1462285c2508f7486"
+ "2fa41cb4db68ae71f1f8a3e8939dc52c2dec61a83c983beb2a02baf29ec49278088882ed0cf56c74b5c173b552ccf63cf",
+ "048eeea3a319c8df99fbc29cb55f243a720d95509515ee5cc587a5c5ae22fbbd009e626db3e911def0b99a4f7ae304b1b"
+ "a73877dc94db9adddc0d9a4b24e8976c22d73c844370e1ee857f8d1b129a3bd5f63f40caf3bd0533e38a5f5777074ff9e",
+ "1e97b60add7cb35c7403dd884c0a75795b7683fff8b49f9d8672a8206bfdcf0a106b8768f983258c74167422e44e4d14",
+ "curve: P384 vector: 9", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "83d70f7b164d9f4c227c767046b20eb34dfc778f5387e32e834b1e6daec20edb8ca5bb4192093f543b68e6aeb7ce788b",
+ "0457cd770f3bbcbe0c78c770eab0b169bc45e139f86378ffae1c2b16966727c2f2eb724572b8f3eb228d130db4ff862c"
+ "637ec5c8813b685558d83e924f14bc719f6eb7ae0cbb2c474227c5bda88637a4f26c64817929af999592da6f787490332f",
+ "04a721f6a2d4527411834b13d4d3a33c29beb83ab7682465c6cbaf6624aca6ea58c30eb0f29dd842886695400d7254f20f"
+ "14ba6e26355109ad35129366d5e3a640ae798505a7fa55a96a36b5dad33de00474f6670f522214dd7952140ab0a7eb68",
+ "1023478840e54775bfc69293a3cf97f5bc914726455c66538eb5623e218feef7df4befa23e09d77145ad577db32b41f9",
+ "curve: P384 vector: 10", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "8f558e05818b88ed383d5fca962e53413db1a0e4637eda194f761944cbea114ab9d5da175a7d57882550b0e432f395a9",
+ "049a2f57f4867ce753d72b0d95195df6f96c1fae934f602efd7b6a54582f556cfa539d89005ca2edac08ad9b72dd1f60b"
+ "ad9b94ee82da9cc601f346044998ba387aee56404dc6ecc8ab2b590443319d0b2b6176f9d0eac2d44678ed561607d09a9",
+ "04d882a8505c2d5cb9b8851fc676677bb0087681ad53faceba1738286b45827561e7da37b880276c656cfc38b32ade847"
+ "e34b314bdc134575654573cffaf40445da2e6aaf987f7e913cd4c3091523058984a25d8f21da8326192456c6a0fa5f60c",
+ "6ad6b9dc8a6cf0d3691c501cbb967867f6e4bbb764b60dbff8fcff3ed42dbba39d63cf325b4b4078858495ddee75f954",
+ "curve: P384 vector: 11", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "0f5dee0affa7bbf239d5dff32987ebb7cf84fcceed643e1d3c62d0b3352aec23b6e5ac7fa4105c8cb26126ad2d1892cb",
+ "0423346bdfbc9d7c7c736e02bdf607671ff6082fdd27334a8bc75f3b23681ebe614d0597dd614fae58677c835a9f0b273"
+ "b82ba36290d2f94db41479eb45ab4eaf67928a2315138d59eecc9b5285dfddd6714f77557216ea44cc6fc119d8243efaf",
+ "04815c9d773dbf5fb6a1b86799966247f4006a23c92e68c55e9eaa998b17d8832dd4d84d927d831d4f68dac67c6488219f"
+ "e79269948b2611484560fd490feec887cb55ef99a4b524880fa7499d6a07283aae2afa33feab97deca40bc606c4d8764",
+ "cc9e063566d46b357b3fcae21827377331e5e290a36e60cd7c39102b828ae0b918dc5a02216b07fe6f1958d834e42437",
+ "curve: P384 vector: 12", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "037b633b5b8ba857c0fc85656868232e2febf59578718391b81da8541a00bfe53c30ae04151847f27499f8d7abad8cf4",
+ "048878ac8a947f7d5cb2b47aad24fbb8210d86126585399a2871f84aa9c5fde3074ae540c6bf82275ca822d0feb862bc7"
+ "4632f5cd2f900c2711c32f8930728eb647d31edd8d650f9654e7d33e5ed1b475489d08daa30d8cbcba6bfc3b60d9b5a37",
+ "041c0eeda7a2be000c5bdcda0478aed4db733d2a9e341224379123ad847030f29e3b168fa18e89a3c0fba2a6ce1c28fc3"
+ "bec8c1c83c118c4dbea94271869f2d868eb65e8b44e21e6f14b0f4d9b38c068daefa27114255b9a41d084cc4a1ad85456",
+ "deff7f03bd09865baf945e73edff6d5122c03fb561db87dec8662e09bed4340b28a9efe118337bb7d3d4f7f568635ff9",
+ "curve: P384 vector: 13", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "e3d07106bedcc096e7d91630ffd3094df2c7859db8d7edbb2e37b4ac47f429a637d06a67d2fba33838764ef203464991",
+ "04e74a1a2b85f1cbf8dbbdf050cf1aff8acb02fda2fb6591f9d3cfe4e79d0ae938a9c1483e7b75f8db24505d65065cdb1"
+ "81773ee591822f7abaa856a1a60bc0a5203548dbd1cb5025466eff8481bd07614eaa04a16c3db76905913e972a5b6b59d",
+ "04c95c185e256bf997f30b311548ae7f768a38dee43eeeef43083f3077be70e2bf39ac1d4daf360c514c8c6be623443d1"
+ "a3e63a663eaf75d8a765ab2b9a35513d7933fa5e26420a5244550ec6c3b6f033b96db2aca3d6ac6aab052ce929595aea5",
+ "c8b1038f735ad3bb3e4637c3e47eab487637911a6b7950a4e461948329d3923b969e5db663675623611a457fcda35a71",
+ "curve: P384 vector: 14", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "f3f9b0c65a49a506632c8a45b10f66b5316f9eeb06fae218f2da62333f99905117b141c760e8974efc4af10570635791",
+ "04a4ad77aa7d86e5361118a6b921710c820721210712f4c347985fdee58aa4effa1e28be80a17b120b139f96300f89b4"
+ "9b1ddf22e07e03f1560d8f45a480094560dba9fae7f9531130c1b57ebb95982496524f31d3797793396fa823f22bdb4328",
+ "043497238a7e6ad166df2dac039aa4dac8d17aa925e7c7631eb3b56e3aaa1c545fcd54d2e5985807910fb202b1fc191d2a"
+ "a49e5c487dcc7aa40a8f234c979446040d9174e3ad357d404d7765183195aed3f913641b90c81a306ebf0d8913861316",
+ "d337eaa32b9f716b8747b005b97a553c59dab0c51df41a2d49039cdae705aa75c7b9e7bc0b6a0e8c578c902bc4fff23e",
+ "curve: P384 vector: 15", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "59fce7fad7de28bac0230690c95710c720e528f9a4e54d3a6a8cd5fc5c5f21637031ce1c5b4e3d39647d8dcb9b794664",
+ "049c43bf971edf09402876ee742095381f78b1bd3aa39b5132af75dbfe7e98bd78bde10fe2e903c2b6379e1deee175a1b"
+ "0a6c58ecea5a477bb01bd543b339f1cc49f1371a2cda4d46eb4e53e250597942351a99665a122ffea9bde0636c375daf2",
+ "0490a34737d45b1aa65f74e0bd0659bc118f8e4b774b761944ffa6573c6df4f41dec0d11b697abd934d390871d4b453240"
+ "9b590719bb3307c149a7817be355d684893a307764b512eeffe07cb699edb5a6ffbf8d6032e6c79d5e93e94212c2aa4e",
+ "32d292b695a4488e42a7b7922e1ae537d76a3d21a0b2e36875f60e9f6d3e8779c2afb3a413b9dd79ae18e70b47d337c1",
+ "curve: P384 vector: 16", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "3e49fbf950a424c5d80228dc4bc35e9f6c6c0c1d04440998da0a609a877575dbe437d6a5cedaa2ddd2a1a17fd112aded",
+ "045a949594228b1a3d6f599eb3db0d06070fbc551c657b58234ba164ce3fe415fa5f3eb823c08dc29b8c341219c77b6b3"
+ "d2baad447c8c290cfed25edd9031c41d0b76921457327f42db31122b81f337bbf0b1039ec830ce9061a3761953c75e4a8",
+ "04dda546acfc8f903d11e2e3920669636d44b2068aeb66ff07aa266f0030e1535b0ed0203cb8a460ac990f1394faf22f1"
+ "d15bbb2597913035faadf413476f4c70f7279769a40c986f470c427b4ee4962abdf8173bbad81874772925fd32f0b159f",
+ "1220e7e6cad7b25df98e5bbdcc6c0b65ca6c2a50c5ff6c41dca71e475646fd489615979ca92fb4389aeadefde79a24f1",
+ "curve: P384 vector: 17", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "50ccc1f7076e92f4638e85f2db98e0b483e6e2204c92bdd440a6deea04e37a07c6e72791c190ad4e4e86e01efba84269",
+ "04756c07df0ce32c839dac9fb4733c9c28b70113a676a7057c38d223f22a3a9095a8d564653af528e04c7e1824be4a651"
+ "217c2ce6962cbd2a2e066297b39d57dd9bb4680f0191d390f70b4e461419b2972ce68ad46127fdda6c39195774ea86df3",
+ "04788be2336c52f4454d63ee944b1e49bfb619a08371048e6da92e584eae70bde1f171c4df378bd1f3c0ab03048a237802"
+ "4673ebd8db604eaf41711748bab2968a23ca4476ce144e728247f08af752929157b5830f1e26067466bdfa8b65145a33",
+ "793bb9cd22a93cf468faf804a38d12b78cb12189ec679ddd2e9aa21fa9a5a0b049ab16a23574fe04c1c3c02343b91beb",
+ "curve: P384 vector: 18", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "06f132b71f74d87bf99857e1e4350a594e5fe35533b888552ceccbc0d8923c902e36141d7691e28631b8bc9bafe5e064",
+ "042a3cc6b8ff5cde926e7e3a189a1bd029c9b586351af8838f4f201cb8f4b70ef3b0da06d352c80fc26baf8f42b784459"
+ "ebf9985960176da6d23c7452a2954ffcbbcb24249b43019a2a023e0b3dabd461f19ad3e775c364f3f11ad49f3099400d3",
+ "04d09bb822eb99e38060954747c82bb3278cf96bbf36fece3400f4c873838a40c135eb3babb9293bd1001bf3ecdee7bf2"
+ "6d416db6e1b87bbb7427788a3b6c7a7ab2c165b1e366f9608df512037584f213a648d47f16ac326e19aae972f63fd76c9",
+ "012d191cf7404a523678c6fc075de8285b243720a903047708bb33e501e0dbee5bcc40d7c3ef6c6da39ea24d830da1e8",
+ "curve: P384 vector: 19", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "12048ebb4331ec19a1e23f1a2c773b664ccfe90a28bfb846fc12f81dff44b7443c77647164bf1e9e67fd2c07a6766241",
+ "04bc18836bc7a9fdf54b5352f37d7528ab8fa8ec544a8c6180511cbfdd49cce377c39e34c031b5240dc9980503ed2f26"
+ "2c8086cbe338191080f0b7a16c7afc4c7b0326f9ac66f58552ef4bb9d24de3429ed5d3277ed58fcf48f2b5f61326bec6c6",
+ "0413741262ede5861dad71063dfd204b91ea1d3b7c631df68eb949969527d79a1dc59295ef7d2bca6743e8cd77b04d1"
+ "b580baaeadc7e19d74a8a04451a135f1be1b02fe299f9dc00bfdf201e83d995c6950bcc1cb89d6f7b30bf54656b9a4da586",
+ "ad0fd3ddffe8884b9263f3c15fe1f07f2a5a22ffdc7e967085eea45f0cd959f20f18f522763e28bcc925e496a52dda98",
+ "curve: P384 vector: 20", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "34d61a699ca576169fcdc0cc7e44e4e1221db0fe63d16850c8104029f7d48449714b9884328cae189978754ab460b486",
+ "04867f81104ccd6b163a7902b670ef406042cb0cce7dcdc63d1dfc91b2c40e3cdf7595834bf9eceb79849f1636fc8462f"
+ "c9d4bde8e875ec49697d258d1d59465f8431c6f5531e1c59e9f9ebe3cf164a8d9ce10a12f1979283a959bad244dd83863",
+ "049e22cbc18657f516a864b37b783348b66f1aa9626cd631f4fa1bd32ad88cf11db52057c660860d39d11fbf024fabd44"
+ "46b0d53c79681c28116df71e9cee74fd56c8b7f04b39f1198cc72284e98be9562e35926fb4f48a9fbecafe729309e8b6f",
+ "dc4ca392dc15e20185f2c6a8ea5ec31dfc96f56153a47394b3072b13d0015f5d4ae13beb3bed54d65848f9b8383e6c95",
+ "curve: P384 vector: 21", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "dc60fa8736d702135ff16aab992bb88eac397f5972456c72ec447374d0d8ce61153831bfc86ad5a6eb5b60bfb96a862c",
+ "04b69beede85d0f829fec1b893ccb9c3e052ff692e13b974537bc5b0f9feaf7b22e84f03231629b24866bdb4b8cf9089"
+ "1466f85e2bfcaba2843285b0e14ebc07ef7dafff8b424416fee647b59897b619f20eed95a632e6a4206bf7da429c04c560",
+ "042db5da5f940eaa884f4db5ec2139b0469f38e4e6fbbcc52df15c0f7cf7fcb1808c749764b6be85d2fdc5b16f58ad5d"
+ "c022e8b02dcf33e1b5a083849545f84ad5e43f77cb71546dbbac0d11bdb2ee202e9d3872e8d028c08990746c5e1dde9989",
+ "d765b208112d2b9ed5ad10c4046e2e3b0dbf57c469329519e239ac28b25c7d852bf757d5de0ee271cadd021d86cfd347",
+ "curve: P384 vector: 22", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "6fa6a1c704730987aa634b0516a826aba8c6d6411d3a4c89772d7a62610256a2e2f289f5c3440b0ec1e70fa339e251ce",
+ "0453de1fc1328e8de14aecab29ad8a40d6b13768f86f7d298433d20fec791f86f8bc73f358098b256a298bb488de257bf"
+ "4ac28944fd27f17b82946c04c66c41f0053d3692f275da55cd8739a95bd8cd3af2f96e4de959ea8344d8945375905858b",
+ "04329647baa354224eb4414829c5368c82d7893b39804e08cbb2180f459befc4b347a389a70c91a23bd9d30c83be5295d"
+ "3cc8f61923fad2aa8e505d6cfa126b9fabd5af9dce290b75660ef06d1caa73681d06089c33bc4246b3aa30dbcd2435b12",
+ "d3778850aeb58804fbe9dfe6f38b9fa8e20c2ca4e0dec335aafceca0333e3f2490b53c0c1a14a831ba37c4b9d74be0f2",
+ "curve: P384 vector: 23", ec_field_GFp },
+
+ { ECCurve_NIST_P384, 1,
+ "74ad8386c1cb2ca0fcdeb31e0869bb3f48c036afe2ef110ca302bc8b910f621c9fcc54cec32bb89ec7caa84c7b8e54a8",
+ "0427a3e83cfb9d5122e73129d801615857da7cc089cccc9c54ab3032a19e0a0a9f677346e37f08a0b3ed8da6e5dd69106"
+ "38d60e44aa5e0fd30c918456796af37f0e41957901645e5c596c6d989f5859b03a0bd7d1f4e77936fff3c74d204e5388e",
+ "0429d8a36d22200a75b7aea1bb47cdfcb1b7fd66de967041434728ab5d533a060df732130600fe6f75852a871fb2938e3"
+ "9e19b53db528395de897a45108967715eb8cb55c3fcbf23379372c0873a058d57544b102ecce722b2ccabb1a603774fd5",
+ "81e1e71575bb4505498de097350186430a6242fa6c57b85a5f984a23371123d2d1424eefbf804258392bc723e4ef1e35",
+ "curve: P384 vector: 24", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "017eecc07ab4b329068fba65e56a1f8890aa935e57134ae0ffcce802735151f4eac6564f6ee9974c5e6887a1fefee5743"
+ "ae2241bfeb95d5ce31ddcb6f9edb4d6fc47",
+ "0400602f9d0cf9e526b29e22381c203c48a886c2b0673033366314f1ffbcba240ba42f4ef38a76174635f91e6b4ed3427"
+ "5eb01c8467d05ca80315bf1a7bbd945f550a501b7c85f26f5d4b2d7355cf6b02117659943762b6d1db5ab4f1dbc44ce7b2"
+ "946eb6c7de342962893fd387d1b73d7a8672d1f236961170b7eb3579953ee5cdc88cd2d",
+ "0400685a48e86c79f0f0875f7bc18d25eb5fc8c0b07e5da4f4370f3a9490340854334b1e1b87fa395464c60626124a4e70"
+ "d0f785601d37c09870ebf176666877a2046d01ba52c56fc8776d9e8f5db4f0cc27636d0b741bbe05400697942e80b739884"
+ "a83bde99e0f6716939e632bc8986fa18dccd443a348b6c3e522497955a4f3c302f676",
+ "005fc70477c3e63bc3954bd0df3ea0d1f41ee21746ed95fc5e1fdf90930d5e136672d72cc770742d1711c3c3a4c334a0ad9"
+ "759436a4d3c5bf6e74b9578fac148c831",
+ "curve: P521 vector: 0", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "00816f19c1fb10ef94d4a1d81c156ec3d1de08b66761f03f06ee4bb9dcebbbfe1eaa1ed49a6a990838d8ed318c14d74cc"
+ "872f95d05d07ad50f621ceb620cd905cfb8",
+ "0400d45615ed5d37fde699610a62cd43ba76bedd8f85ed31005fe00d6450fbbd101291abd96d4945a8b57bc73b3fe9f46"
+ "71105309ec9b6879d0551d930dac8ba45d25501425332844e592b440c0027972ad1526431c06732df19cd46a242172d4d"
+ "d67c2c8c99dfc22e49949a56cf90c6473635ce82f25b33682fb19bc33bd910ed8ce3a7fa",
+ "0401df277c152108349bc34d539ee0cf06b24f5d3500677b4445453ccc21409453aafb8a72a0be9ebe54d12270aa51b3a"
+ "b7f316aa5e74a951c5e53f74cd95fc29aee7a013d52f33a9f3c14384d1587fa8abe7aed74bc33749ad9c570b471776422c"
+ "7d4505d9b0a96b3bfac041e4c6a6990ae7f700e5b4a6640229112deafa0cd8bb0d089b0",
+ "000b3920ac830ade812c8f96805da2236e002acbbf13596a9ab254d44d0e91b6255ebf1229f366fb5a05c5884ef46032c2"
+ "6d42189273ca4efa4c3db6bd12a6853759",
+ "curve: P521 vector: 1", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "012f2e0c6d9e9d117ceb9723bced02eb3d4eebf5feeaf8ee0113ccd8057b13ddd416e0b74280c2d0ba8ed291c443bc1b14"
+ "1caf8afb3a71f97f57c225c03e1e4d42b0",
+ "0400717fcb3d4a40d103871ede044dc803db508aaa4ae74b70b9fb8d8dfd84bfecfad17871879698c292d2fd5e17b4f9343"
+ "636c531a4fac68a35a93665546b9a87867900f3d96a8637036993ab5d244500fff9d2772112826f6436603d3eb234a44d5c"
+ "4e5c577234679c4f9df725ee5b9118f23d8a58d0cc01096daf70e8dfec0128bdc2e8",
+ "040092db3142564d27a5f0006f819908fba1b85038a5bc2509906a497daac67fd7aee0fc2daba4e4334eeaef0e0019204b4"
+ "71cd88024f82115d8149cc0cf4f7ce1a4d5016bad0623f517b158d9881841d2571efbad63f85cbe2e581960c5d670601a67"
+ "60272675a548996217e4ab2b8ebce31d71fca63fcc3c08e91c1d8edd91cf6fe845f8",
+ "006b380a6e95679277cfee4e8353bf96ef2a1ebdd060749f2f046fe571053740bbcc9a0b55790bc9ab56c3208aa05ddf746"
+ "a10a3ad694daae00d980d944aabc6a08f",
+ "curve: P521 vector: 2", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "00e548a79d8b05f923b9825d11b656f222e8cb98b0f89de1d317184dc5a698f7c71161ee7dc11cd31f4f4f8ae3a981e1a3e7"
+ "8bdebb97d7c204b9261b4ef92e0918e0",
+ "04000ce800217ed243dd10a79ad73df578aa8a3f9194af528cd1094bbfee27a3b5481ad5862c8876c0c3f91294c0ab3aa806"
+ "d9020cbaa2ed72b7fecdc5a09a6dad6f3201543c9ab45b12469232918e21d5a351f9a4b9cbf9efb2afcc402fa9b31650bec2d6"
+ "41a05c440d35331c0893d11fb13151335988b303341301a73dc5f61d574e67d9",
+ "0400fdd40d9e9d974027cb3bae682162eac1328ad61bc4353c45bf5afe76bf607d2894c8cce23695d920f2464fda4773d4693b"
+ "e4b3773584691bdb0329b7f4c86cc2990034ceac6a3fef1c3e1c494bfe8d872b183832219a7e14da414d4e3474573671ec19b03"
+ "3be831b915435905925b44947c592959945b4eb7c951c3b9c8cf52530ba23",
+ "00fbbcd0b8d05331fef6086f22a6cce4d35724ab7a2f49dd8458d0bfd57a0b8b70f246c17c4468c076874b0dff7a0336823b19e"
+ "98bf1cec05e4beffb0591f97713c6",
+ "curve: P521 vector: 3", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "01c8aae94bb10b8ca4f7be577b4fb32bb2381032c4942c24fc2d753e7cc5e47b483389d9f3b956d20ee9001b1eef9f23545f72"
+ "c5602140046839e963313c3decc864",
+ "040106a14e2ee8ff970aa8ab0c79b97a33bba2958e070b75b94736b77bbe3f777324fa52872771aa88a63a9e8490c3378df4dc"
+ "760cd14d62be700779dd1a4377943656002366ce3941e0b284b1aa81215d0d3b9778fce23c8cd1e4ed6fa0abf62156c91d4b3eb"
+ "55999c3471bed275e9e60e5aa9d690d310bfb15c9c5bbd6f5e9eb39682b74",
+ "040098d99dee0816550e84dbfced7e88137fddcf581a725a455021115fe49f8dc3cf233cd9ea0e6f039dc7919da973cdceaca20"
+ "5da39e0bd98c8062536c47f258f44b500cd225c8797371be0c4297d2b457740100c774141d8f214c23b61aa2b6cd4806b9b70722"
+ "aa4965fb622f42b7391e27e5ec21c5679c5b06b59127372997d421adc1e",
+ "0145cfa38f25943516c96a5fd4bfebb2f645d10520117aa51971eff442808a23b4e23c187e639ff928c3725fbd1c0c2ad0d4aeb2"
+ "07bc1a6fb6cb6d467888dc044b3c",
+ "curve: P521 vector: 4", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "009b0af137c9696c75b7e6df7b73156bb2d45f482e5a4217324f478b10ceb76af09724cf86afa316e7f89918d31d54824a5c33"
+ "107a483c15c15b96edc661340b1c0e",
+ "0400748cdbb875d35f4bccb62abe20e82d32e4c14dc2feb5b87da2d0ccb11c9b6d4b7737b6c46f0dfb4d896e2db92fcf53cdbb"
+ "ae2a404c0babd564ad7adeac6273efa301984acab8d8f173323de0bb60274b228871609373bb22a17287e9dec7495873abc09a"
+ "8915b54c8455c8e02f654f602e23a2bbd7a9ebb74f3009bd65ecc650814cc0",
+ "04007ae115adaaf041691ab6b7fb8c921f99d8ed32d283d67084e80b9ad9c40c56cd98389fb0a849d9ecf7268c297b6f934061"
+ "19f40e32b5773ed25a28a9a85c4a758801a28e004e37eeaefe1f4dbb71f1878696141af3a10a9691c4ed93487214643b761fa4b"
+ "0fbeeb247cf6d3fba7a60697536ad03f49b80a9d1cb079673654977c5fa94",
+ "005c5721e96c273319fd60ecc46b5962f698e974b429f28fe6962f4ac656be2eb8674c4aafc037eab48ece612953b1e8d86101"
+ "6b6ad0c79805784c67f73ada96f351",
+ "curve: P521 vector: 5", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "01e48faacee6dec83ffcde944cf6bdf4ce4bae72747888ebafee455b1e91584971efb49127976a52f4142952f7c207ec0265f2b"
+ "718cf3ead96ea4f62c752e4f7acd3",
+ "04010eb1b4d9172bcc23f4f20cc9560fc54928c3f34ea61c00391dc766c76ed9fa608449377d1e4fadd1236025417330b4b91086"
+ "704ace3e4e6484c606e2a943478c860149413864069825ee1d0828da9f4a97713005e9bd1adbc3b38c5b946900721a960fe96ad2c"
+ "1b3a44fe3de9156136d44cb17cbc2415729bb782e16bfe2deb3069e43",
+ "04012588115e6f7f7bdcfdf57f03b169b479758baafdaf569d04135987b2ce6164c02a57685eb5276b5dae6295d3fe90620f38b55"
+ "35c6d2260c173e61eb888ca92020301542c169cf97c2596fe2ddd848a222e367c5f7e6267ebc1bcd9ab5dcf49158f1a48e4af29a89"
+ "7b7e6a82091c2db874d8e7abf0f58064691344154f396dbaed188b6",
+ "01736d9717429b4f412e903febe2f9e0fffd81355d6ce2c06ff3f66a3be15ceec6e65e308347593f00d7f33591da4043c30763d72"
+ "749f72cdceebe825e4b34ecd570",
+ "curve: P521 vector: 6", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "00c29aa223ea8d64b4a1eda27f39d3bc98ea0148dd98c1cbe595f8fd2bfbde119c9e017a50f5d1fc121c08c1cef31b75885955"
+ "6eb3e0e042d8dd6aaac57a05ca61e3",
+ "04001511c848ef60d5419a98d10204db0fe58224124370061bcfa4e9249d50618c56bf3722471b259f38263bb7b280d23caf2a"
+ "1ee8737f9371cdb2732cdc958369930c01d461681ae6d8c49b4c5f4d6016143fb1bd7491573e3ed0e6c48b82e821644f87f82f0"
+ "e5f08fd16f1f98fa17586200ab02ed8c627b35c3f27617ec5fd92f456203f",
+ "040169491d55bd09049fdf4c2a53a660480fee4c03a0538675d1cd09b5bba78dac48543ef118a1173b3fbf8b20e39ce0e6b8"
+ "90a163c50f9645b3d21d1cbb3b60a6fff40083494b2eba76910fed33c761804515011fab50e3b377abd8a8a045d886d2238d2"
+ "c268ac1b6ec88bd71b7ba78e2c33c152e4bf7da5d565e4acbecf5e92c7ad662bb",
+ "018f2ae9476c771726a77780208dedfefa205488996b18fecc50bfd4c132753f5766b2cd744afa9918606de2e016effc63622"
+ "e9029e76dc6e3f0c69f7aeced565c2c",
+ "curve: P521 vector: 7", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "0028692be2bf5c4b48939846fb3d5bce74654bb2646e15f8389e23708a1afadf561511ea0d9957d0b53453819d60fba8f65a1"
+ "8f7b29df021b1bb01cd163293acc3cc",
+ "0401cfdc10c799f5c79cb6930a65fba351748e07567993e5e410ef4cacc4cd8a25784991eb4674e41050f930c7190ac812b92"
+ "45f48a7973b658daf408822fe5b85f6680180d9ddfc9af77b9c4a6f02a834db15e535e0b3845b2cce30388301b51cecbe32763"
+ "07ef439b5c9e6a72dc2d94d879bc395052dbb4a5787d06efb280210fb8be037",
+ "04008415f5bbd0eee387d6c09d0ef8acaf29c66db45d6ba101860ae45d3c60e1e0e3f7247a4626a60fdd404965c3566c79f644"
+ "9e856ce0bf94619f97da8da24bd2cfb600fdd7c59c58c361bc50a7a5d0d36f723b17c4f2ad2b03c24d42dc50f74a8c465a0afc"
+ "4683f10fab84652dfe9e928c2626b5456453e1573ff60be1507467d431fbb2",
+ "0105a346988b92ed8c7a25ce4d79d21bc86cfcc7f99c6cd19dbb4a39f48ab943b79e4f0647348da0b80bd864b85c6b8d92536"
+ "d6aa544dc7537a00c858f8b66319e25",
+ "curve: P521 vector: 8", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "01194d1ee613f5366cbc44b504d21a0cf6715e209cd358f2dd5f3e71cc0d67d0e964168c42a084ebda746f9863a86bacffc81"
+ "9f1edf1b8c727ccfb3047240a57c435",
+ "04016bd15c8a58d366f7f2b2f298cc87b7485e9ee70d11d12448b8377c0a82c7626f67aff7f97be7a3546bf417eeeddf75a93"
+ "c130191c84108042ea2fca17fd3f80d1401560502d04b74fce1743aab477a9d1eac93e5226981fdb97a7478ce4ce566ff72439"
+ "31284fad850b0c2bcae0ddd2d97790160c1a2e77c3ed6c95ecc44b89e2637fc",
+ "0401c721eea805a5cba29f34ba5758775be0cf6160e6c08723f5ab17bf96a1ff2bd9427961a4f34b07fc0b14ca4b2bf6845de"
+ "bd5a869f124ebfa7aa72fe565050b7f1800b6e89eb0e1dcf181236f7c548fd1a8c16b258b52c1a9bfd3fe8f22841b26763265"
+ "f074c4ccf2d634ae97b701956f67a11006c52d97197d92f585f5748bc2672eeb",
+ "004531b3d2c6cd12f21604c8610e6723dbf4daf80b5a459d6ba5814397d1c1f7a21d7c114be964e27376aaebe3a7bc3d6af7"
+ "a7f8c7befb611afe487ff032921f750f",
+ "curve: P521 vector: 9", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "01fd90e3e416e98aa3f2b6afa7f3bf368e451ad9ca5bd54b5b14aee2ed6723dde5181f5085b68169b09fbec721372ccf6b"
+ "284713f9a6356b8d560a8ff78ca3737c88",
+ "0401ebea1b10d3e3b971b7efb69fc878de11c7f472e4e4d384c31b8d6288d8071517acade9b39796c7af5163bcf71aeda7"
+ "77533f382c6cf0a4d9bbb938c85f44b78037016b0e3e19c2996b2cbd1ff64730e7ca90edca1984f9b2951333535e5748baa"
+ "34a99f61ff4d5f812079e0f01e87789f34efdad8098015ee74a4f846dd190d16dc6e1",
+ "0401c35823e440a9363ab98d9fc7a7bc0c0532dc7977a79165599bf1a9cc64c00fb387b42cca365286e8430360bfad3643"
+ "bc31354eda50dc936c329ecdb60905c40fcb00d9e7f433531e44df4f6d514201cbaabb06badd6783e01111726d815531d23"
+ "3c5cdb722893ffbb2027259d594de77438809738120c6f783934f926c3fb69b40c409",
+ "0100c8935969077bae0ba89ef0df8161d975ec5870ac811ae7e65ca5394efba4f0633d41bf79ea5e5b9496bbd7aae000b05"
+ "94baa82ef8f244e6984ae87ae1ed124b7",
+ "curve: P521 vector: 10", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "009012ecfdadc85ced630afea534cdc8e9d1ab8be5f3753dcf5f2b09b40eda66fc6858549bc36e6f8df55998cfa9a0703a"
+ "ecf6c42799c245011064f530c09db98369",
+ "0400234e32be0a907131d2d128a6477e0caceb86f02479745e0fe245cb332de631c078871160482eeef584e274df7fa412c"
+ "ea3e1e91f71ecba8781d9205d48386341ad01cf86455b09b1c005cffba8d76289a3759628c874beea462f51f30bd581e380"
+ "3134307dedbb771b3334ee15be2e242cd79c3407d2f58935456c6941dd9b6d155a46",
+ "0400093057fb862f2ad2e82e581baeb3324e7b32946f2ba845a9beeed87d6995f54918ec6619b9931955d5a89d4d74adf10"
+ "46bb362192f2ef6bd3e3d2d04dd1f87054a00aa3fb2448335f694e3cda4ae0cc71b1b2f2a206fa802d7262f19983c44674f"
+ "e15327acaac1fa40424c395a6556cb8167312527fae5865ecffc14bbdc17da78cdcf",
+ "017f36af19303841d13a389d95ec0b801c7f9a679a823146c75c17bc44256e9ad422a4f8b31f14647b2c7d317b933f7c294"
+ "6c4b8abd1d56d620fab1b5ff1a3adc71f",
+ "curve: P521 vector: 11", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "01b5ff847f8eff20b88cfad42c06e58c3742f2f8f1fdfd64b539ba48c25926926bd5e332b45649c0b184f77255e9d58fe8"
+ "afa1a6d968e2cb1d4637777120c765c128",
+ "0401de3dc9263bc8c4969dc684be0eec54befd9a9f3dba194d8658a789341bf0d78d84da6735227cafaf093519516911975"
+ "73c8c360a11e5285712b8bbdf5ac91b977c00812de58cd095ec2e5a9b247eb3ed41d8bef6aeace194a7a05b65aa5d289fbc9"
+ "b1770ec84bb6be0c2c64cc37c1d54a7f5d71377a9adbe20f26f6f2b544a821ea831",
+ "040083192ed0b1cb31f75817794937f66ad91cf74552cd510cedb9fd641310422af5d09f221cad249ee814d16dd7ac84ded"
+ "9eacdc28340fcfc9c0c06abe30a2fc28cd8002212ed868c9ba0fb2c91e2c39ba93996a3e4ebf45f2852d0928c48930e875c"
+ "c7b428d0e7f3f4d503e5d60c68cb49b13c2480cd486bed9200caddaddfe4ff8e3562",
+ "00062f9fc29ae1a68b2ee0dcf956cbd38c88ae5f645eaa546b00ebe87a7260bf724be20d34b9d02076655c933d056b21e30"
+ "4c24ddb1dedf1dd76de611fc4a2340336",
+ "curve: P521 vector: 12", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "011a6347d4e801c91923488354cc533e7e35fddf81ff0fb7f56bb0726e0c29ee5dcdc5f394ba54cf57269048aab6e055895c"
+ "8da24b8b0639a742314390cc04190ed6",
+ "0400fe30267f33ba5cdefc25cbb3c9320dad9ccb1d7d376644620ca4fadee5626a3cede25ad254624def727a7048f7145f761"
+ "62aa98042f9b123b2076f8e8cf59b3fdf001145dc6631953b6e2945e94301d6cbb098fe4b04f7ee9b09411df104dc82d7d79e"
+ "c46a01ed0f2d3e7db6eb680694bdeb107c1078aec6cabd9ebee3d342fe7e54df",
+ "0401a89b636a93e5d2ba6c2292bf23033a84f06a3ac1220ea71e806afbe097a804cc67e9baa514cfb6c12c9194be30212bf7a"
+ "ae7fdf6d376c212f0554e656463ffab7e0182efcaf70fc412d336602e014da47256a0b606f2addcce8053bf817ac8656bb4e4"
+ "2f14c8cbf2a68f488ab35dcdf64056271dee1f606a440ba4bd4e5a11b8b8e54f",
+ "0128ab09bfec5406799e610f772ba17e892249fa8e0e7b18a04b9197034b250b48294f1867fb9641518f92766066a07a8b917"
+ "b0e76879e1011e51ccbd9f540c54d4f",
+ "curve: P521 vector: 13", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "0022b6d2a22d71dfaa811d2d9f9f31fbed27f2e1f3d239538ddf3e4cc8c39a330266db25b7bc0a9704f17bde7f3592bf5f1f2d"
+ "4b56013aacc3d8d1bc02f00d3146cc",
+ "0400ba38cfbf9fd2518a3f61d43549e7a6a6d28b2be57ffd3e0faceb636b34ed17e044a9f249dae8fc132e937e2d9349cd2ed7"
+ "7bb1049ceb692a2ec5b17ad61502a64c001ec91d3058573fa6c0564a02a1a010160c313bc7c73510dc983e5461682b5be00dbc"
+ "e7e2c682ad73f29ca822cdc111f68fabe33a7b384a648342c3cdb9f050bcdb",
+ "04017200b3f16a68cbaed2bf78ba8cddfb6cffac262bba00fbc25f9dc72a07ce59372904899f364c44cb264c097b647d4412be"
+ "e3e519892d534d9129f8a28f7500fee700baba8d672a4f4a3b63de48b96f56e18df5d68f7d70d5109833f43770d6732e06b39ad"
+ "60d93e5b43db8789f1ec0aba47286a39ea584235acea757dbf13d53b58364",
+ "0101e462e9d9159968f6440e956f11dcf2227ae4aea81667122b6af9239a291eb5d6cf5a4087f358525fcacfa46bb2db01a75a"
+ "f1ba519b2d31da33eda87a9d565748",
+ "curve: P521 vector: 14", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "005bacfff268acf6553c3c583b464ea36a1d35e2b257a5d49eb3419d5a095087c2fb4d15cf5bf5af816d0f3ff7586490ccd3ddc1"
+ "a98b39ce63749c6288ce0dbdac7d",
+ "040036e488da7581472a9d8e628c58d6ad727311b7e6a3f6ae33a8544f34b09280249020be7196916fafd90e2ec54b66b5468d23"
+ "61b99b56fa00d7ac37abb8c6f16653011edb9fb8adb6a43f4f5f5fdc1421c9fe04fc8ba46c9b66334e3af927c8befb4307104f299"
+ "acec4e30f812d9345c9720d19869dbfffd4ca3e7d2713eb5fc3f42615",
+ "04004efd5dbd2f979e3831ce98f82355d6ca14a5757842875882990ab85ab9b7352dd6b9b2f4ea9a1e95c3880d65d1f3602f9ca6"
+ "53dc346fac858658d75626f4d4fb080061cf15dbdaa7f31589c98400373da284506d70c89f074ed262a9e28140796b7236c2eef99"
+ "016085e71552ff488c72b7339fefb7915c38459cb20ab85aec4e45052",
+ "0141d6a4b719ab67eaf04a92c0a41e2dda78f4354fb90bdc35202cc7699b9b04d49616f82255debf7bbec045ae58f982a66905fc"
+ "fae69d689785e38c868eb4a27e7b",
+ "curve: P521 vector: 15", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "008e2c93c5423876223a637cad367c8589da69a2d0fc68612f31923ae50219df2452e7cc92615b67f17b57ffd2f52b19154bb40"
+ "d7715336420fde2e89fee244f59dc",
+ "0400fa3b35118d6c422570f724a26f90b2833b19239174cea081c53133f64db60d6940ea1261299c04c1f4587cdb0c4c39616"
+ "479c1bb0c146799a118032dcf98f899c00069f040229006151fa32b51f679c8816f7c17506b403809dc77cd58a2aec430d94d"
+ "13b6c916de99f355aa45fcfbc6853d686c71be496a067d24bfaea4818fc51f75",
+ "040129891de0cf3cf82e8c2cf1bf90bb296fe00ab08ca45bb7892e0e227a504fdd05d2381a4448b68adff9c4153c87eacb783"
+ "30d8bd52515f9f9a0b58e85f446bb4e10009edd679696d3d1d0ef327f200383253f6413683d9e4fcc87bb35f112c2f110098d"
+ "15e5701d7ceee416291ff5fed85e687f727388b9afe26a4f6feed560b218e6bb",
+ "00345e26e0abb1aac12b75f3a9cf41efe1c336396dffa4a067a4c2cfeb878c68b2b045faa4e5b4e6fa4678f5b603c351903b1"
+ "4bf9a6a70c439257199a640890b61d1",
+ "curve: P521 vector: 16", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "0004d49d39d40d8111bf16d28c5936554326b197353eebbcf47545393bc8d3aaf98f14f5be7074bfb38e6cc97b989754074da"
+ "ddb3045f4e4ce745669fdb3ec0d5fa8",
+ "04012ec226d050ce07c79b3df4d0f0891f9f7adf462e8c98dbc1a2a14f5e53a3f5ad894433587cc429a8be9ea1d84fa33b180"
+ "3690dae04da7218d30026157fc995cf52004837dfbf3426f57b5c793269130abb9a38f618532211931154db4eeb9aede88e57"
+ "290f842ea0f2ea9a5f74c6203a3920fe4e305f6118f676b154e1d75b9cb5eb88",
+ "0401a3c20240e59f5b7a3e17c275d2314ba1741210ad58b71036f8c83cc1f6b0f409dfdd9113e94b67ec39c3291426c23ffc"
+ "c447054670d2908ff8fe67dc2306034c5c01d2825bfd3af8b1e13205780c137fe938f84fde40188e61ea02cead81badfdb425"
+ "c29f7d7fb0324debadc10bbb93de68f62c35069268283f5265865db57a79f7bf7",
+ "006fe9de6fb8e672e7fd150fdc5e617fabb0d43906354ccfd224757c7276f7a1010091b17ed072074f8d10a5ec971eb35a5c"
+ "b7076603b7bc38d432cbc059f80f9488",
+ "curve: P521 vector: 17", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "011a5d1cc79cd2bf73ea106f0e60a5ace220813b53e27b739864334a07c03367efda7a4619fa6eef3a9746492283b3c445610"
+ "a023a9cc49bf4591140384fca5c8bb5",
+ "0400eb07c7332eedb7d3036059d35f7d2288d4377d5f42337ad3964079fb120ccd4c8bd384b585621055217023acd9a94fcb3"
+ "b965bfb394675e788ade41a1de73e620c00491a835de2e6e7deb7e090f4a11f2c460c0b1f3d5e94ee8d751014dc720784fd3b"
+ "54500c86ebaef18429f09e8e876d5d1538968a030d7715dde99f0d8f06e29d59",
+ "04007e2d138f2832e345ae8ff65957e40e5ec7163f016bdf6d24a2243daa631d878a4a16783990c722382130f9e51f0c1bd6"
+ "ff5ac96780e48b68f5dec95f42e6144bb500b0de5c896791f52886b0f09913e26e78dd0b69798fc4df6d95e3ca708ecbcbcce1c1895f"
+ "5561bbabaae372e9e67e6e1a3be60e19b470cdf673ec1fc393d3426e20",
+ "01e4e759ecedce1013baf73e6fcc0b92451d03bdd50489b78871c333114990c9ba6a9b2fc7b1a2d9a1794c1b60d9279af6f"
+ "146f0bbfb0683140403bfa4ccdb524a29",
+ "curve: P521 vector: 18", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "010c908caf1be74c616b625fc8c1f514446a6aec83b5937141d6afbb0a8c7666a7746fa1f7a6664a2123e8cdf6cd8bf836c5"
+ "6d3c0ebdcc980e43a186f938f3a78ae7",
+ "040031890f4c7abec3f723362285d77d2636f876817db3bbc88b01e773597b969ff6f013ea470c854ab4a7739004eb8cbea6"
+ "9b82ddf36acadd406871798ecb2ac3aa7f00d8b429ae3250266b9643c0c765a60dc10155bc2531cf8627296f4978b6640a9e"
+ "600e19d0037d58503fa80799546a814d7478a550aa90e5ebeb052527faaeae5d08",
+ "0400118c36022209b1af8ebad1a12b566fc48744576e1199fe80de1cdf851cdf03e5b9091a8f7e079e83b7f827259b691d0"
+ "c22ee29d6bdf73ec7bbfd746f2cd97a357d00da5ff4904548a342e2e7ba6a1f4ee5f840411a96cf63e6fe622f22c13e614e"
+ "0a847c11a1ab3f1d12cc850c32e095614ca8f7e2721477b486e9ff40372977c3f65c",
+ "0163c9191d651039a5fe985a0eea1eba018a40ab1937fcd2b61220820ee8f2302e9799f6edfc3f5174f369d672d377ea895"
+ "4a8d0c8b851e81a56fda95212a6578f0e",
+ "curve: P521 vector: 19", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "01b37d6b7288de671360425d3e5ac1ccb21815079d8d73431e9b74a6f0e7ae004a357575b11ad66642ce8b775593eba9d98"
+ "bf25c75ef0b4d3a2098bbc641f59a2b77",
+ "0400189a5ee34de7e35aefeaeef9220c18071b4c29a4c3bd9d954458bd3e82a7a34da34cff5579b8101c065b1f2f527cf45"
+ "81501e28ef5671873e65267733d003520af01eb4bc50a7b4d4599d7e3fa773ddb9eb252c9b3422872e544bdf75c7bf60f51"
+ "66ddc11eb08fa7c30822dabaee373ab468eb2d922e484e2a527fff2ebb804b7d9a37",
+ "0401780edff1ca1c03cfbe593edc6c049bcb2860294a92c355489d9afb2e702075ade1c953895a456230a0cde905de4a3f"
+ "38573dbfcccd67ad6e7e93f0b5581e926a5d00a5481962c9162962e7f0ebdec936935d0eaa813e8226d40d7f6119bfd940"
+ "602380c86721e61db1830f51e139f210000bcec0d8edd39e54d73a9a129f95cd5fa979",
+ "015d613e267a36342e0d125cdad643d80d97ed0600afb9e6b9545c9e64a98cc6da7c5aaa3a8da0bdd9dd3b97e9788218a8"
+ "0abafc106ef065c8f1c4e1119ef58d298b",
+ "curve: P521 vector: 20", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "00f2661ac762f60c5fff23be5d969ccd4ec6f98e4e72618d12bdcdb9b4102162333788c0bae59f91cdfc172c7a1681ee44d9"
+ "6ab2135a6e5f3415ebbcd55165b1afb0",
+ "0400a8e25a6902d687b4787cdc94c364ac7cecc5c495483ed363dc0aa95ee2bd739c4c4d46b17006c728b076350d7d7e54c"
+ "6822f52f47162a25109aaaba690cab696ec0168d2f08fe19e4dc9ee7a195b03c9f7fe6676f9f520b6270557504e72ca4394"
+ "a2c6918625e15ac0c51b8f95cd560123653fb8e8ee6db961e2c4c62cc54e92e2a2a9",
+ "04016dacffa183e5303083a334f765de724ec5ec9402026d4797884a9828a0d321a8cfac74ab737fe20a7d6befcfc73b6a3"
+ "5c1c7b01d373e31abc192d48a4241a35803011e5327cac22d305e7156e559176e19bee7e4f2f59e86f1a9d0b6603b6a7df"
+ "1069bde6387feb71587b8ffce5b266e1bae86de29378a34e5c74b6724c4d40a719923",
+ "014d6082a3b5ced1ab8ca265a8106f302146c4acb8c30bb14a4c991e3c82a9731288bdb91e0e85bda313912d06384fc44"
+ "f2153fb13506fa9cf43c9aab5750988c943",
+ "curve: P521 vector: 21", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "00f430ca1261f09681a9282e9e970a9234227b1d5e58d558c3cc6eff44d1bdf53de16ad5ee2b18b92d62fc79586116b0e"
+ "fc15f79340fb7eaf5ce6c44341dcf8dde27",
+ "04006c1d9b5eca87de1fb871a0a32f807c725adccde9b3967453a71347d608f0c030cd09e338cdecbf4a02015bc8a6e8"
+ "d3e2595fe773ffc2fc4e4a55d0b1a2cc00323b01141b2109e7f4981c952aa818a2b9f6f5c41feccdb7a7a45b9b4b6729"
+ "37771b008cae5f934dfe3fed10d383ab1f38769c92ce88d9be5414817ecb073a31ab368ccb",
+ "0400a091421d3703e3b341e9f1e7d58f8cf7bdbd1798d001967b801d1cec27e605c580b2387c1cb464f55ce7ac803341"
+ "02ab03cfb86d88af76c9f4129c01bedd3bbfc4008c9c577a8e6fc446815e9d40baa66025f15dae285f19eb668ee60ae9"
+ "c98e7ecdbf2b2a68e22928059f67db188007161d3ecf397e0883f0c4eb7eaf7827a62205cc",
+ "0020c00747cb8d492fd497e0fec54644bf027d418ab686381f109712a99cabe328b9743d2225836f9ad66e5d7fed1de2"
+ "47e0da92f60d5b31f9e47672e57f710598f4",
+ "curve: P521 vector: 22", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "005dc33aeda03c2eb233014ee468dff753b72f73b00991043ea353828ae69d4cd0fadeda7bb278b535d7c57406ff2e6e"
+ "473a5a4ff98e90f90d6dadd25100e8d85666",
+ "0400c825ba307373cec8dd2498eef82e21fd9862168dbfeb83593980ca9f82875333899fe94f137daf1c4189eb502937"
+ "c3a367ea7951ed8b0f3377fcdf2922021d46a5016b8a2540d5e65493888bc337249e67c0a68774f3e8d81e3b4574a012"
+ "5165f0bd58b8af9de74b35832539f95c3cd9f1b759408560aa6851ae3ac7555347b0d3b13b",
+ "04004f38816681771289ce0cb83a5e29a1ab06fc91f786994b23708ff08a08a0f675b809ae99e9f9967eb1a49f196057"
+ "d69e50d6dedb4dd2d9a81c02bdcc8f7f518460009efb244c8b91087de1eed766500f0e81530752d469256ef79f6b965d"
+ "8a2232a0c2dbc4e8e1d09214bab38485be6e357c4200d073b52f04e4a16fc6f5247187aecb",
+ "00c2bfafcd7fbd3e2fd1c750fdea61e70bd4787a7e68468c574ee99ebc47eedef064e8944a73bcb7913dbab5d93dca6"
+ "60d216c553622362794f7a2acc71022bdb16f",
+ "curve: P521 vector: 23", ec_field_GFp },
+
+ { ECCurve_NIST_P521, 1,
+ "00df14b1f1432a7b0fb053965fd8643afee26b2451ecb6a8a53a655d5fbe16e4c64ce8647225eb11e7fdcb23627471"
+ "dffc5c2523bd2ae89957cba3a57a23933e5a78",
+ "04004e8583bbbb2ecd93f0714c332dff5ab3bc6396e62f3c560229664329baa5138c3bb1c36428abd4e23d17fcb7"
+ "a2cfcc224b2e734c8941f6f121722d7b6b9415457601cf0874f204b0363f020864672fadbf87c8811eb147758b254b"
+ "74b14fae742159f0f671a018212bbf25b8519e126d4cad778cfff50d288fd39ceb0cac635b175ec0",
+ "0401a32099b02c0bd85371f60b0dd20890e6c7af048c8179890fda308b359dbbc2b7a832bb8c6526c4af99a7ea3f0"
+ "b3cb96ae1eb7684132795c478ad6f962e4a6f446d017627357b39e9d7632a1370b3e93c1afb5c851b910eb4ead0c9"
+ "d387df67cde85003e0e427552f1cd09059aad0262e235cce5fba8cedc4fdc1463da76dcd4b6d1a46",
+ "01aaf24e5d47e4080c18c55ea35581cd8da30f1a079565045d2008d51b12d0abb4411cda7a0785b15d149ed301a36"
+ "97062f42da237aa7f07e0af3fd00eb1800d9c41",
+ "curve: P521 vector: 24", ec_field_GFp },
+
+ { ECCurve_pastLastCurve, 0, NULL, NULL, NULL, NULL, NULL, 0 }
+};
+
+static ECDH_KAT nonnist_testvecs[] = {
+ { ECCurve25519, 1,
+ "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+ NULL,
+ "e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c",
+ "c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552",
+ "curve: 25519 vector: 0", ec_field_plain },
+ { ECCurve25519, 1,
+ "4b66e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba0d",
+ NULL,
+ "e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a493",
+ "95cbde9476e8907d7aade45cb4b873f88b595a68799fa152e6f8f7647aac7957",
+ "curve: 25519 vector: 1", ec_field_plain },
+ { ECCurve25519, 1,
+ "0900000000000000000000000000000000000000000000000000000000000000",
+ NULL,
+ "0900000000000000000000000000000000000000000000000000000000000000",
+ "422c8e7a6227d7bca1350b3e2bb7279f7897b87bb6854b783c60e80311ae3079",
+ "curve: 25519 vector: 2", ec_field_plain },
+ { ECCurve25519, 1000,
+ "0900000000000000000000000000000000000000000000000000000000000000",
+ NULL,
+ "0900000000000000000000000000000000000000000000000000000000000000",
+ "684cf59ba83309552800ef566f2f4d3c1c3887c49360e3875f2eb94d99532c51",
+ "curve: 25519 vector: 1000 iterations", ec_field_plain },
+#ifdef NSS_ENABLE_EXPENSIVE_TESTS
+ /* This test is disabled by default because it takes a very long time
+ * to run. */
+ { ECCurve25519, 1000000,
+ "0900000000000000000000000000000000000000000000000000000000000000",
+ NULL,
+ "0900000000000000000000000000000000000000000000000000000000000000",
+ "7c3911e0ab2586fd864497297e575e6f3bc601c0883c30df5f4dd2d24f665424",
+ "curve: 25519 vector: 1000000 iterations", ec_field_plain },
+#endif
+ { ECCurve25519, 1,
+ "174a56a75017c029e0861044d3c57c291823cf477ae6e21065cc121578bfa893",
+ NULL,
+ "7bd8396462a5788951caf3d3a28cb0904e4d081e62e6ac2d9da7152eb1310f30",
+ "28c09f6be3666a6ab3bf8f5b03eec14e95505e32726ae887053ce6a2061a9656",
+ "curve: 25519 custom vector 1", ec_field_plain },
+ { ECCurve25519, 1,
+ "577a2a7fcdacd4ccf7d7f81ba93ec83ae4bda32bec00ff7d59c294b69404f688",
+ NULL,
+ "a43b5491cbd9273abf694115f383fabe3bdc5f2baa30d2e00e43b6937a75cc5d",
+ "4aed703c32552576ca0b30a3fab53242e1eea29ddec993219d3c2b3c3e59b735",
+ "curve: 25519 custom vector 1", ec_field_plain },
+
+ { ECCurve_pastLastCurve, 0, NULL, NULL, NULL, NULL, NULL, 0 }
+};
+
+static ECDH_BAD nonnist_testvecs_bad_values[] = {
+ { ECCurve25519, "00", "curve: 25519 vector: 0 bad point", ec_field_plain },
+ { ECCurve25519,
+ "0100000000000000000000000000000000000000000000000000000000000000",
+ "curve: 25519 vector: 1 bad point", ec_field_plain },
+ { ECCurve25519,
+ "e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b8",
+ "curve: 25519 vector: 2 bad point", ec_field_plain },
+ { ECCurve25519,
+ "5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f1157",
+ "curve: 25519 vector: 3 bad point", ec_field_plain },
+ { ECCurve25519,
+ "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
+ "curve: 25519 vector: 4 bad point", ec_field_plain },
+ { ECCurve25519,
+ "edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
+ "curve: 25519 vector: 5 bad point", ec_field_plain },
+ { ECCurve25519,
+ "eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
+ "curve: 25519 vector: 6 bad point", ec_field_plain },
+ { ECCurve25519,
+ "cdeb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b880",
+ "curve: 25519 vector: 7 bad point", ec_field_plain },
+ { ECCurve25519,
+ "4c9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f11d7",
+ "curve: 25519 vector: 8 bad point", ec_field_plain },
+ { ECCurve25519,
+ "d9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "curve: 25519 vector: 9 bad point", ec_field_plain },
+ { ECCurve25519,
+ "daffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "curve: 25519 vector: 10 bad point", ec_field_plain },
+ { ECCurve25519,
+ "dbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "curve: 25519 vector: 11 bad point", ec_field_plain },
+
+ { ECCurve_pastLastCurve, 0, NULL, 0 }
+};
diff --git a/nss/cmd/fipstest/Makefile b/nss/cmd/fipstest/Makefile
new file mode 100755
index 0000000..2cf5c05
--- /dev/null
+++ b/nss/cmd/fipstest/Makefile
@@ -0,0 +1,49 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+#MKPROG = purify -cache-dir=/u/mcgreer/pcache -best-effort \
+# -always-use-cache-dir $(CC)
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include ../platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+include ../platrules.mk
diff --git a/nss/cmd/fipstest/aes.sh b/nss/cmd/fipstest/aes.sh
new file mode 100644
index 0000000..7e25e60
--- /dev/null
+++ b/nss/cmd/fipstest/aes.sh
@@ -0,0 +1,112 @@
+#!/bin/sh
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+#
+# A Bourne shell script for running the NIST AES Algorithm Validation Suite
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/AES
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
+
+cbc_kat_requests="
+CBCGFSbox128.req
+CBCGFSbox192.req
+CBCGFSbox256.req
+CBCKeySbox128.req
+CBCKeySbox192.req
+CBCKeySbox256.req
+CBCVarKey128.req
+CBCVarKey192.req
+CBCVarKey256.req
+CBCVarTxt128.req
+CBCVarTxt192.req
+CBCVarTxt256.req
+"
+
+cbc_mct_requests="
+CBCMCT128.req
+CBCMCT192.req
+CBCMCT256.req
+"
+
+cbc_mmt_requests="
+CBCMMT128.req
+CBCMMT192.req
+CBCMMT256.req
+"
+
+ecb_kat_requests="
+ECBGFSbox128.req
+ECBGFSbox192.req
+ECBGFSbox256.req
+ECBKeySbox128.req
+ECBKeySbox192.req
+ECBKeySbox256.req
+ECBVarKey128.req
+ECBVarKey192.req
+ECBVarKey256.req
+ECBVarTxt128.req
+ECBVarTxt192.req
+ECBVarTxt256.req
+"
+
+ecb_mct_requests="
+ECBMCT128.req
+ECBMCT192.req
+ECBMCT256.req
+"
+
+ecb_mmt_requests="
+ECBMMT128.req
+ECBMMT192.req
+ECBMMT256.req
+"
+
+if [ ${COMMAND} = "verify" ]; then
+ for request in $cbc_kat_requests $cbc_mct_requests $cbc_mmt_requests $ecb_kat_requests $ecb_mct_requests $ecb_mmt_requests; do
+ sh ./validate1.sh ${TESTDIR} $request
+ done
+ exit 0
+fi
+
+for request in $cbc_kat_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest aes kat cbc ${REQDIR}/$request > ${RSPDIR}/$response
+done
+for request in $cbc_mct_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest aes mct cbc ${REQDIR}/$request > ${RSPDIR}/$response
+done
+for request in $cbc_mmt_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest aes mmt cbc ${REQDIR}/$request > ${RSPDIR}/$response
+done
+for request in $ecb_kat_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest aes kat ecb ${REQDIR}/$request > ${RSPDIR}/$response
+done
+for request in $ecb_mct_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest aes mct ecb ${REQDIR}/$request > ${RSPDIR}/$response
+done
+for request in $ecb_mmt_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest aes mmt ecb ${REQDIR}/$request > ${RSPDIR}/$response
+done
diff --git a/nss/cmd/fipstest/aesgcm.sh b/nss/cmd/fipstest/aesgcm.sh
new file mode 100644
index 0000000..3b4dcf5
--- /dev/null
+++ b/nss/cmd/fipstest/aesgcm.sh
@@ -0,0 +1,67 @@
+#!/bin/sh
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# A Bourne shell script for running the NIST AES Algorithm Validation Suite
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/AES_GCM
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
+
+gcm_decrypt_requests="
+gcmDecrypt128.req
+gcmDecrypt192.req
+gcmDecrypt256.req
+"
+
+gcm_encrypt_extiv_requests="
+gcmEncryptExtIV128.req
+gcmEncryptExtIV192.req
+gcmEncryptExtIV256.req
+"
+gcm_encrypt_intiv_requests="
+"
+
+#gcm_encrypt_intiv_requests="
+#gcmEncryptIntIV128.req
+#gcmEncryptIntIV192.req
+#gcmEncryptIntIV256.req
+#"
+
+if [ ${COMMAND} = "verify" ]; then
+ for request in $gcm_decrypt_requests $gcm_encrypt_extiv_requests; do
+ sh ./validate1.sh ${TESTDIR} $request ' ' '-e /Reason:/d'
+ done
+ for request in $gcm_encrypt_intiv_requests; do
+ name=`basename $request .req`
+ echo ">>>>> $name"
+ fipstest aes gcm decrypt ${RSPDIR}/$name.rsp | grep FAIL
+ done
+ exit 0
+fi
+
+for request in $gcm_decrypt_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest aes gcm decrypt ${REQDIR}/$request > ${RSPDIR}/$response
+done
+for request in $gcm_encrypt_intiv_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest aes gcm encrypt_intiv ${REQDIR}/$request > ${RSPDIR}/$response
+done
+for request in $gcm_encrypt_extiv_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest aes gcm encrypt_extiv ${REQDIR}/$request > ${RSPDIR}/$response
+done
diff --git a/nss/cmd/fipstest/dsa.sh b/nss/cmd/fipstest/dsa.sh
new file mode 100755
index 0000000..da18e1f
--- /dev/null
+++ b/nss/cmd/fipstest/dsa.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# A Bourne shell script for running the NIST DSA Validation System
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/DSA2
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
+
+
+#
+# several of the DSA tests do use known answer tests to verify the result.
+# in those cases, feed generated tests back into the fipstest tool and
+# see if we can verify those value. NOTE: th PQGVer and SigVer tests verify
+# the dsa pqgver and dsa sigver functions, so we know they can detect errors
+# in those PQGGen and SigGen. Only the KeyPair verify is potentially circular.
+#
+if [ ${COMMAND} = "verify" ]; then
+# verify generated keys
+ name=KeyPair
+ echo ">>>>> $name"
+ fipstest dsa keyver ${RSPDIR}/$name.rsp | grep ^Result.=.F
+# verify generated pqg values
+ name=PQGGen
+ echo ">>>>> $name"
+ fipstest dsa pqgver ${RSPDIR}/$name.rsp | grep ^Result.=.F
+# verify PQGVer with known answer
+# sh ./validate1.sh ${TESTDIR} PQGVer.req ' ' '-e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;'
+# verify signatures
+ name=SigGen
+ echo ">>>>> $name"
+ fipstest dsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F
+# verify SigVer with known answer
+ sh ./validate1.sh ${TESTDIR} SigVer.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);;'
+ exit 0
+fi
+
+request=KeyPair.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest dsa keypair ${REQDIR}/$request > ${RSPDIR}/$response
+
+request=PQGGen.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest dsa pqggen ${REQDIR}/$request > ${RSPDIR}/$response
+
+request=PQGVer1863.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest dsa pqgver ${REQDIR}/$request > ${RSPDIR}/$response
+
+request=SigGen.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest dsa siggen ${REQDIR}/$request > ${RSPDIR}/$response
+
+request=SigVer.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest dsa sigver ${REQDIR}/$request > ${RSPDIR}/$response
diff --git a/nss/cmd/fipstest/ecdsa.sh b/nss/cmd/fipstest/ecdsa.sh
new file mode 100644
index 0000000..9482160
--- /dev/null
+++ b/nss/cmd/fipstest/ecdsa.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# A Bourne shell script for running the NIST ECDSA Validation System
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/ECDSA2
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
+
+#
+# several of the ECDSA tests do not use known answer tests to verify the result.
+# In those cases, feed generated tests back into the fipstest tool and
+# see if we can verify those value. NOTE: PQGVer and SigVer tests verify
+# the dsa pqgver and dsa sigver functions, so we know they can detect errors
+# in those PQGGen and SigGen. Only the KeyPair verify is potentially circular.
+#
+if [ ${COMMAND} = "verify" ]; then
+# verify generated keys
+ name=KeyPair
+ echo ">>>>> $name"
+ fipstest ecdsa keyver ${RSPDIR}/$name.rsp | grep ^Result.=.F
+ sh ./validate1.sh ${TESTDIR} PKV.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;'
+# verify signatures
+ name=SigGen
+ echo ">>>>> $name"
+ fipstest ecdsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F
+# verify SigVer with known answer
+ sh ./validate1.sh ${TESTDIR} SigVer.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;'
+ exit 0
+fi
+
+request=KeyPair.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest ecdsa keypair ${REQDIR}/$request > ${RSPDIR}/$response
+
+request=PKV.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest ecdsa pkv ${REQDIR}/$request > ${RSPDIR}/$response
+
+request=SigGen.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest ecdsa siggen ${REQDIR}/$request > ${RSPDIR}/$response
+
+request=SigVer.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest ecdsa sigver ${REQDIR}/$request > ${RSPDIR}/$response
diff --git a/nss/cmd/fipstest/fipstest.c b/nss/cmd/fipstest/fipstest.c
new file mode 100644
index 0000000..ab73e42
--- /dev/null
+++ b/nss/cmd/fipstest/fipstest.c
@@ -0,0 +1,6137 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include
+#include
+#include
+
+#include "secitem.h"
+#include "blapi.h"
+#include "nssutil.h"
+#include "secerr.h"
+#include "secder.h"
+#include "secdig.h"
+#include "secoid.h"
+#include "ec.h"
+#include "hasht.h"
+#include "lowkeyi.h"
+#include "softoken.h"
+#include "pkcs11t.h"
+#define __PASTE(x, y) x##y
+#undef CK_PKCS11_FUNCTION_INFO
+#undef CK_NEED_ARG_LIST
+#define CK_EXTERN extern
+#define CK_PKCS11_FUNCTION_INFO(func) \
+ CK_RV __PASTE(NS, func)
+#define CK_NEED_ARG_LIST 1
+#include "pkcs11f.h"
+#undef CK_PKCS11_FUNCTION_INFO
+#undef CK_NEED_ARG_LIST
+#undef __PASTE
+#define SSL3_RANDOM_LENGTH 32
+
+#if 0
+#include "../../lib/freebl/mpi/mpi.h"
+#endif
+
+#ifndef NSS_DISABLE_ECC
+extern SECStatus
+EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams);
+extern SECStatus
+EC_CopyParams(PLArenaPool *arena, ECParams *dstParams,
+ const ECParams *srcParams);
+#endif
+
+#define ENCRYPT 1
+#define DECRYPT 0
+#define BYTE unsigned char
+#define DEFAULT_RSA_PUBLIC_EXPONENT 0x10001
+#define RSA_MAX_TEST_MODULUS_BITS 4096
+#define RSA_MAX_TEST_MODULUS_BYTES RSA_MAX_TEST_MODULUS_BITS / 8
+#define RSA_MAX_TEST_EXPONENT_BYTES 8
+#define PQG_TEST_SEED_BYTES 20
+
+SECStatus
+hex_to_byteval(const char *c2, unsigned char *byteval)
+{
+ int i;
+ unsigned char offset;
+ *byteval = 0;
+ for (i = 0; i < 2; i++) {
+ if (c2[i] >= '0' && c2[i] <= '9') {
+ offset = c2[i] - '0';
+ *byteval |= offset << 4 * (1 - i);
+ } else if (c2[i] >= 'a' && c2[i] <= 'f') {
+ offset = c2[i] - 'a';
+ *byteval |= (offset + 10) << 4 * (1 - i);
+ } else if (c2[i] >= 'A' && c2[i] <= 'F') {
+ offset = c2[i] - 'A';
+ *byteval |= (offset + 10) << 4 * (1 - i);
+ } else {
+ return SECFailure;
+ }
+ }
+ return SECSuccess;
+}
+
+SECStatus
+byteval_to_hex(unsigned char byteval, char *c2, char a)
+{
+ int i;
+ unsigned char offset;
+ for (i = 0; i < 2; i++) {
+ offset = (byteval >> 4 * (1 - i)) & 0x0f;
+ if (offset < 10) {
+ c2[i] = '0' + offset;
+ } else {
+ c2[i] = a + offset - 10;
+ }
+ }
+ return SECSuccess;
+}
+
+void
+to_hex_str(char *str, const unsigned char *buf, unsigned int len)
+{
+ unsigned int i;
+ for (i = 0; i < len; i++) {
+ byteval_to_hex(buf[i], &str[2 * i], 'a');
+ }
+ str[2 * len] = '\0';
+}
+
+void
+to_hex_str_cap(char *str, const unsigned char *buf, unsigned int len)
+{
+ unsigned int i;
+ for (i = 0; i < len; i++) {
+ byteval_to_hex(buf[i], &str[2 * i], 'A');
+ }
+ str[2 * len] = '\0';
+}
+
+/*
+ * Convert a string of hex digits (str) to an array (buf) of len bytes.
+ * Return PR_TRUE if the hex string can fit in the byte array. Return
+ * PR_FALSE if the hex string is empty or is too long.
+ */
+PRBool
+from_hex_str(unsigned char *buf, unsigned int len, const char *str)
+{
+ unsigned int nxdigit; /* number of hex digits in str */
+ unsigned int i; /* index into buf */
+ unsigned int j; /* index into str */
+
+ /* count the hex digits */
+ nxdigit = 0;
+ for (nxdigit = 0; isxdigit(str[nxdigit]); nxdigit++) {
+ /* empty body */
+ }
+ if (nxdigit == 0) {
+ return PR_FALSE;
+ }
+ if (nxdigit > 2 * len) {
+ /*
+ * The input hex string is too long, but we allow it if the
+ * extra digits are leading 0's.
+ */
+ for (j = 0; j < nxdigit - 2 * len; j++) {
+ if (str[j] != '0') {
+ return PR_FALSE;
+ }
+ }
+ /* skip leading 0's */
+ str += nxdigit - 2 * len;
+ nxdigit = 2 * len;
+ }
+ for (i = 0, j = 0; i < len; i++) {
+ if (2 * i < 2 * len - nxdigit) {
+ /* Handle a short input as if we padded it with leading 0's. */
+ if (2 * i + 1 < 2 * len - nxdigit) {
+ buf[i] = 0;
+ } else {
+ char tmp[2];
+ tmp[0] = '0';
+ tmp[1] = str[j];
+ hex_to_byteval(tmp, &buf[i]);
+ j++;
+ }
+ } else {
+ hex_to_byteval(&str[j], &buf[i]);
+ j += 2;
+ }
+ }
+ return PR_TRUE;
+}
+
+SECStatus
+tdea_encrypt_buf(
+ int mode,
+ const unsigned char *key,
+ const unsigned char *iv,
+ unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen,
+ const unsigned char *input, unsigned int inputlen)
+{
+ SECStatus rv = SECFailure;
+ DESContext *cx;
+ unsigned char doublecheck[8 * 20]; /* 1 to 20 blocks */
+ unsigned int doublechecklen = 0;
+
+ cx = DES_CreateContext(key, iv, mode, PR_TRUE);
+ if (cx == NULL) {
+ goto loser;
+ }
+ rv = DES_Encrypt(cx, output, outputlen, maxoutputlen, input, inputlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (*outputlen != inputlen) {
+ goto loser;
+ }
+ DES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+
+ /*
+ * Doublecheck our result by decrypting the ciphertext and
+ * compare the output with the input plaintext.
+ */
+ cx = DES_CreateContext(key, iv, mode, PR_FALSE);
+ if (cx == NULL) {
+ goto loser;
+ }
+ rv = DES_Decrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck,
+ output, *outputlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (doublechecklen != *outputlen) {
+ goto loser;
+ }
+ DES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+ if (memcmp(doublecheck, input, inputlen) != 0) {
+ goto loser;
+ }
+ rv = SECSuccess;
+
+loser:
+ if (cx != NULL) {
+ DES_DestroyContext(cx, PR_TRUE);
+ }
+ return rv;
+}
+
+SECStatus
+tdea_decrypt_buf(
+ int mode,
+ const unsigned char *key,
+ const unsigned char *iv,
+ unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen,
+ const unsigned char *input, unsigned int inputlen)
+{
+ SECStatus rv = SECFailure;
+ DESContext *cx;
+ unsigned char doublecheck[8 * 20]; /* 1 to 20 blocks */
+ unsigned int doublechecklen = 0;
+
+ cx = DES_CreateContext(key, iv, mode, PR_FALSE);
+ if (cx == NULL) {
+ goto loser;
+ }
+ rv = DES_Decrypt(cx, output, outputlen, maxoutputlen,
+ input, inputlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (*outputlen != inputlen) {
+ goto loser;
+ }
+ DES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+
+ /*
+ * Doublecheck our result by encrypting the plaintext and
+ * compare the output with the input ciphertext.
+ */
+ cx = DES_CreateContext(key, iv, mode, PR_TRUE);
+ if (cx == NULL) {
+ goto loser;
+ }
+ rv = DES_Encrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck,
+ output, *outputlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (doublechecklen != *outputlen) {
+ goto loser;
+ }
+ DES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+ if (memcmp(doublecheck, input, inputlen) != 0) {
+ goto loser;
+ }
+ rv = SECSuccess;
+
+loser:
+ if (cx != NULL) {
+ DES_DestroyContext(cx, PR_TRUE);
+ }
+ return rv;
+}
+
+/*
+ * Perform the TDEA Known Answer Test (KAT) or Multi-block Message
+ * Test (MMT) in ECB or CBC mode. The KAT (there are five types)
+ * and MMT have the same structure: given the key and IV (CBC mode
+ * only), encrypt the given plaintext or decrypt the given ciphertext.
+ * So we can handle them the same way.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+tdea_kat_mmt(char *reqfn)
+{
+ char buf[180]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "CIPHERTEXT = <180 hex digits>\n".
+ */
+ FILE *req; /* input stream from the REQUEST file */
+ FILE *resp; /* output stream to the RESPONSE file */
+ int i, j;
+ int mode = NSS_DES_EDE3; /* NSS_DES_EDE3 (ECB) or NSS_DES_EDE3_CBC */
+ int crypt = DECRYPT; /* 1 means encrypt, 0 means decrypt */
+ unsigned char key[24]; /* TDEA 3 key bundle */
+ unsigned int numKeys = 0;
+ unsigned char iv[8]; /* for all modes except ECB */
+ unsigned char plaintext[8 * 20]; /* 1 to 20 blocks */
+ unsigned int plaintextlen;
+ unsigned char ciphertext[8 * 20]; /* 1 to 20 blocks */
+ unsigned int ciphertextlen;
+ SECStatus rv;
+
+ req = fopen(reqfn, "r");
+ resp = stdout;
+ while (fgets(buf, sizeof buf, req) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, resp);
+ continue;
+ }
+ /* [ENCRYPT] or [DECRYPT] */
+ if (buf[0] == '[') {
+ if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
+ crypt = ENCRYPT;
+ } else {
+ crypt = DECRYPT;
+ }
+ fputs(buf, resp);
+ continue;
+ }
+ /* NumKeys */
+ if (strncmp(&buf[0], "NumKeys", 7) == 0) {
+ i = 7;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ numKeys = buf[i];
+ fputs(buf, resp);
+ continue;
+ }
+ /* "COUNT = x" begins a new data set */
+ if (strncmp(buf, "COUNT", 5) == 0) {
+ /* mode defaults to ECB, if dataset has IV mode will be set CBC */
+ mode = NSS_DES_EDE3;
+ /* zeroize the variables for the test with this data set */
+ memset(key, 0, sizeof key);
+ memset(iv, 0, sizeof iv);
+ memset(plaintext, 0, sizeof plaintext);
+ plaintextlen = 0;
+ memset(ciphertext, 0, sizeof ciphertext);
+ ciphertextlen = 0;
+ fputs(buf, resp);
+ continue;
+ }
+ if (numKeys == 0) {
+ if (strncmp(buf, "KEYs", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &key[j]);
+ key[j + 8] = key[j];
+ key[j + 16] = key[j];
+ }
+ fputs(buf, resp);
+ continue;
+ }
+ } else {
+ /* KEY1 = ... */
+ if (strncmp(buf, "KEY1", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &key[j]);
+ }
+ fputs(buf, resp);
+ continue;
+ }
+ /* KEY2 = ... */
+ if (strncmp(buf, "KEY2", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 8; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &key[j]);
+ }
+ fputs(buf, resp);
+ continue;
+ }
+ /* KEY3 = ... */
+ if (strncmp(buf, "KEY3", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 16; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &key[j]);
+ }
+ fputs(buf, resp);
+ continue;
+ }
+ }
+
+ /* IV = ... */
+ if (strncmp(buf, "IV", 2) == 0) {
+ mode = NSS_DES_EDE3_CBC;
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < sizeof iv; i += 2, j++) {
+ hex_to_byteval(&buf[i], &iv[j]);
+ }
+ fputs(buf, resp);
+ continue;
+ }
+
+ /* PLAINTEXT = ... */
+ if (strncmp(buf, "PLAINTEXT", 9) == 0) {
+ /* sanity check */
+ if (crypt != ENCRYPT) {
+ goto loser;
+ }
+ i = 9;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &plaintext[j]);
+ }
+ plaintextlen = j;
+ rv = tdea_encrypt_buf(mode, key,
+ (mode == NSS_DES_EDE3) ? NULL : iv,
+ ciphertext, &ciphertextlen, sizeof ciphertext,
+ plaintext, plaintextlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ fputs(buf, resp);
+ fputs("CIPHERTEXT = ", resp);
+ to_hex_str(buf, ciphertext, ciphertextlen);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ continue;
+ }
+ /* CIPHERTEXT = ... */
+ if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
+ /* sanity check */
+ if (crypt != DECRYPT) {
+ goto loser;
+ }
+
+ i = 10;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &ciphertext[j]);
+ }
+ ciphertextlen = j;
+
+ rv = tdea_decrypt_buf(mode, key,
+ (mode == NSS_DES_EDE3) ? NULL : iv,
+ plaintext, &plaintextlen, sizeof plaintext,
+ ciphertext, ciphertextlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ fputs(buf, resp);
+ fputs("PLAINTEXT = ", resp);
+ to_hex_str(buf, plaintext, plaintextlen);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ continue;
+ }
+ }
+
+loser:
+ fclose(req);
+}
+
+/*
+* Set the parity bit for the given byte
+*/
+BYTE
+odd_parity(BYTE in)
+{
+ BYTE out = in;
+ in ^= in >> 4;
+ in ^= in >> 2;
+ in ^= in >> 1;
+ return (BYTE)(out ^ !(in & 1));
+}
+
+/*
+ * Generate Keys [i+1] from Key[i], PT/CT[j-2], PT/CT[j-1], and PT/CT[j]
+ * for TDEA Monte Carlo Test (MCT) in ECB and CBC modes.
+ */
+void
+tdea_mct_next_keys(unsigned char *key,
+ const unsigned char *text_2, const unsigned char *text_1,
+ const unsigned char *text, unsigned int numKeys)
+{
+ int k;
+
+ /* key1[i+1] = key1[i] xor PT/CT[j] */
+ for (k = 0; k < 8; k++) {
+ key[k] ^= text[k];
+ }
+ /* key2 */
+ if (numKeys == 2 || numKeys == 3) {
+ /* key2 independent */
+ for (k = 8; k < 16; k++) {
+ /* key2[i+1] = KEY2[i] xor PT/CT[j-1] */
+ key[k] ^= text_1[k - 8];
+ }
+ } else {
+ /* key2 == key 1 */
+ for (k = 8; k < 16; k++) {
+ /* key2[i+1] = KEY2[i] xor PT/CT[j] */
+ key[k] = key[k - 8];
+ }
+ }
+ /* key3 */
+ if (numKeys == 1 || numKeys == 2) {
+ /* key3 == key 1 */
+ for (k = 16; k < 24; k++) {
+ /* key3[i+1] = KEY3[i] xor PT/CT[j] */
+ key[k] = key[k - 16];
+ }
+ } else {
+ /* key3 independent */
+ for (k = 16; k < 24; k++) {
+ /* key3[i+1] = KEY3[i] xor PT/CT[j-2] */
+ key[k] ^= text_2[k - 16];
+ }
+ }
+ /* set the parity bits */
+ for (k = 0; k < 24; k++) {
+ key[k] = odd_parity(key[k]);
+ }
+}
+
+/*
+ * Perform the Monte Carlo Test
+ *
+ * mode = NSS_DES_EDE3 or NSS_DES_EDE3_CBC
+ * crypt = ENCRYPT || DECRYPT
+ * inputtext = plaintext or Cyphertext depending on the value of crypt
+ * inputlength is expected to be size 8 bytes
+ * iv = needs to be set for NSS_DES_EDE3_CBC mode
+ * resp = is the output response file.
+ */
+void
+tdea_mct_test(int mode, unsigned char *key, unsigned int numKeys,
+ unsigned int crypt, unsigned char *inputtext,
+ unsigned int inputlength, unsigned char *iv, FILE *resp)
+{
+
+ int i, j;
+ unsigned char outputtext_1[8]; /* PT/CT[j-1] */
+ unsigned char outputtext_2[8]; /* PT/CT[j-2] */
+ char buf[80]; /* holds one line from the input REQUEST file. */
+ unsigned int outputlen;
+ unsigned char outputtext[8];
+
+ SECStatus rv;
+
+ if (mode == NSS_DES_EDE3 && iv != NULL) {
+ printf("IV must be NULL for NSS_DES_EDE3 mode");
+ goto loser;
+ } else if (mode == NSS_DES_EDE3_CBC && iv == NULL) {
+ printf("IV must not be NULL for NSS_DES_EDE3_CBC mode");
+ goto loser;
+ }
+
+ /* loop 400 times */
+ for (i = 0; i < 400; i++) {
+ /* if i == 0 CV[0] = IV not necessary */
+ /* record the count and key values and plainText */
+ sprintf(buf, "COUNT = %d\n", i);
+ fputs(buf, resp);
+ /* Output KEY1[i] */
+ fputs("KEY1 = ", resp);
+ to_hex_str(buf, key, 8);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ /* Output KEY2[i] */
+ fputs("KEY2 = ", resp);
+ to_hex_str(buf, &key[8], 8);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ /* Output KEY3[i] */
+ fputs("KEY3 = ", resp);
+ to_hex_str(buf, &key[16], 8);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ if (mode == NSS_DES_EDE3_CBC) {
+ /* Output CV[i] */
+ fputs("IV = ", resp);
+ to_hex_str(buf, iv, 8);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ }
+ if (crypt == ENCRYPT) {
+ /* Output PT[0] */
+ fputs("PLAINTEXT = ", resp);
+ } else {
+ /* Output CT[0] */
+ fputs("CIPHERTEXT = ", resp);
+ }
+
+ to_hex_str(buf, inputtext, inputlength);
+ fputs(buf, resp);
+ fputc('\n', resp);
+
+ /* loop 10,000 times */
+ for (j = 0; j < 10000; j++) {
+
+ outputlen = 0;
+ if (crypt == ENCRYPT) {
+ /* inputtext == ciphertext outputtext == plaintext*/
+ rv = tdea_encrypt_buf(mode, key,
+ (mode ==
+ NSS_DES_EDE3)
+ ? NULL
+ : iv,
+ outputtext, &outputlen, 8,
+ inputtext, 8);
+ } else {
+ /* inputtext == plaintext outputtext == ciphertext */
+ rv = tdea_decrypt_buf(mode, key,
+ (mode ==
+ NSS_DES_EDE3)
+ ? NULL
+ : iv,
+ outputtext, &outputlen, 8,
+ inputtext, 8);
+ }
+
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (outputlen != inputlength) {
+ goto loser;
+ }
+
+ if (mode == NSS_DES_EDE3_CBC) {
+ if (crypt == ENCRYPT) {
+ if (j == 0) {
+ /*P[j+1] = CV[0] */
+ memcpy(inputtext, iv, 8);
+ } else {
+ /* p[j+1] = C[j-1] */
+ memcpy(inputtext, outputtext_1, 8);
+ }
+ /* CV[j+1] = C[j] */
+ memcpy(iv, outputtext, 8);
+ if (j != 9999) {
+ /* save C[j-1] */
+ memcpy(outputtext_1, outputtext, 8);
+ }
+ } else { /* DECRYPT */
+ /* CV[j+1] = C[j] */
+ memcpy(iv, inputtext, 8);
+ /* C[j+1] = P[j] */
+ memcpy(inputtext, outputtext, 8);
+ }
+ } else {
+ /* ECB mode PT/CT[j+1] = CT/PT[j] */
+ memcpy(inputtext, outputtext, 8);
+ }
+
+ /* Save PT/CT[j-2] and PT/CT[j-1] */
+ if (j == 9997)
+ memcpy(outputtext_2, outputtext, 8);
+ if (j == 9998)
+ memcpy(outputtext_1, outputtext, 8);
+ /* done at the end of the for(j) loop */
+ }
+
+ if (crypt == ENCRYPT) {
+ /* Output CT[j] */
+ fputs("CIPHERTEXT = ", resp);
+ } else {
+ /* Output PT[j] */
+ fputs("PLAINTEXT = ", resp);
+ }
+ to_hex_str(buf, outputtext, 8);
+ fputs(buf, resp);
+ fputc('\n', resp);
+
+ /* Key[i+1] = Key[i] xor ... outputtext_2 == PT/CT[j-2]
+ * outputtext_1 == PT/CT[j-1] outputtext == PT/CT[j]
+ */
+ tdea_mct_next_keys(key, outputtext_2,
+ outputtext_1, outputtext, numKeys);
+
+ if (mode == NSS_DES_EDE3_CBC) {
+ /* taken care of in the j=9999 iteration */
+ if (crypt == ENCRYPT) {
+ /* P[i] = C[j-1] */
+ /* CV[i] = C[j] */
+ } else {
+ /* taken care of in the j=9999 iteration */
+ /* CV[i] = C[j] */
+ /* C[i] = P[j] */
+ }
+ } else {
+ /* ECB PT/CT[i] = PT/CT[j] */
+ memcpy(inputtext, outputtext, 8);
+ }
+ /* done at the end of the for(i) loop */
+ fputc('\n', resp);
+ }
+
+loser:
+ return;
+}
+
+/*
+ * Perform the TDEA Monte Carlo Test (MCT) in ECB/CBC modes.
+ * by gathering the input from the request file, and then
+ * calling tdea_mct_test.
+ *
+ * reqfn is the pathname of the input REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+tdea_mct(int mode, char *reqfn)
+{
+ int i, j;
+ char buf[80]; /* holds one line from the input REQUEST file. */
+ FILE *req; /* input stream from the REQUEST file */
+ FILE *resp; /* output stream to the RESPONSE file */
+ unsigned int crypt = 0; /* 1 means encrypt, 0 means decrypt */
+ unsigned char key[24]; /* TDEA 3 key bundle */
+ unsigned int numKeys = 0;
+ unsigned char plaintext[8]; /* PT[j] */
+ unsigned char ciphertext[8]; /* CT[j] */
+ unsigned char iv[8];
+
+ /* zeroize the variables for the test with this data set */
+ memset(key, 0, sizeof key);
+ memset(plaintext, 0, sizeof plaintext);
+ memset(ciphertext, 0, sizeof ciphertext);
+ memset(iv, 0, sizeof iv);
+
+ req = fopen(reqfn, "r");
+ resp = stdout;
+ while (fgets(buf, sizeof buf, req) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, resp);
+ continue;
+ }
+ /* [ENCRYPT] or [DECRYPT] */
+ if (buf[0] == '[') {
+ if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
+ crypt = ENCRYPT;
+ } else {
+ crypt = DECRYPT;
+ }
+ fputs(buf, resp);
+ continue;
+ }
+ /* NumKeys */
+ if (strncmp(&buf[0], "NumKeys", 7) == 0) {
+ i = 7;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ numKeys = atoi(&buf[i]);
+ continue;
+ }
+ /* KEY1 = ... */
+ if (strncmp(buf, "KEY1", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &key[j]);
+ }
+ continue;
+ }
+ /* KEY2 = ... */
+ if (strncmp(buf, "KEY2", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 8; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &key[j]);
+ }
+ continue;
+ }
+ /* KEY3 = ... */
+ if (strncmp(buf, "KEY3", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 16; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &key[j]);
+ }
+ continue;
+ }
+
+ /* IV = ... */
+ if (strncmp(buf, "IV", 2) == 0) {
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < sizeof iv; i += 2, j++) {
+ hex_to_byteval(&buf[i], &iv[j]);
+ }
+ continue;
+ }
+
+ /* PLAINTEXT = ... */
+ if (strncmp(buf, "PLAINTEXT", 9) == 0) {
+
+ /* sanity check */
+ if (crypt != ENCRYPT) {
+ goto loser;
+ }
+ /* PT[0] = PT */
+ i = 9;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < sizeof plaintext; i += 2, j++) {
+ hex_to_byteval(&buf[i], &plaintext[j]);
+ }
+
+ /* do the Monte Carlo test */
+ if (mode == NSS_DES_EDE3) {
+ tdea_mct_test(NSS_DES_EDE3, key, numKeys, crypt, plaintext, sizeof plaintext, NULL, resp);
+ } else {
+ tdea_mct_test(NSS_DES_EDE3_CBC, key, numKeys, crypt, plaintext, sizeof plaintext, iv, resp);
+ }
+ continue;
+ }
+ /* CIPHERTEXT = ... */
+ if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
+ /* sanity check */
+ if (crypt != DECRYPT) {
+ goto loser;
+ }
+ /* CT[0] = CT */
+ i = 10;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &ciphertext[j]);
+ }
+
+ /* do the Monte Carlo test */
+ if (mode == NSS_DES_EDE3) {
+ tdea_mct_test(NSS_DES_EDE3, key, numKeys, crypt, ciphertext, sizeof ciphertext, NULL, resp);
+ } else {
+ tdea_mct_test(NSS_DES_EDE3_CBC, key, numKeys, crypt, ciphertext, sizeof ciphertext, iv, resp);
+ }
+ continue;
+ }
+ }
+
+loser:
+ fclose(req);
+}
+
+SECStatus
+aes_encrypt_buf(
+ int mode,
+ const unsigned char *key, unsigned int keysize,
+ const unsigned char *iv,
+ unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen,
+ const unsigned char *input, unsigned int inputlen)
+{
+ SECStatus rv = SECFailure;
+ AESContext *cx;
+ unsigned char doublecheck[10 * 16]; /* 1 to 10 blocks */
+ unsigned int doublechecklen = 0;
+
+ cx = AES_CreateContext(key, iv, mode, PR_TRUE, keysize, 16);
+ if (cx == NULL) {
+ goto loser;
+ }
+ rv = AES_Encrypt(cx, output, outputlen, maxoutputlen, input, inputlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (*outputlen != inputlen) {
+ goto loser;
+ }
+ AES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+
+ /*
+ * Doublecheck our result by decrypting the ciphertext and
+ * compare the output with the input plaintext.
+ */
+ cx = AES_CreateContext(key, iv, mode, PR_FALSE, keysize, 16);
+ if (cx == NULL) {
+ goto loser;
+ }
+ rv = AES_Decrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck,
+ output, *outputlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (doublechecklen != *outputlen) {
+ goto loser;
+ }
+ AES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+ if (memcmp(doublecheck, input, inputlen) != 0) {
+ goto loser;
+ }
+ rv = SECSuccess;
+
+loser:
+ if (cx != NULL) {
+ AES_DestroyContext(cx, PR_TRUE);
+ }
+ return rv;
+}
+
+SECStatus
+aes_decrypt_buf(
+ int mode,
+ const unsigned char *key, unsigned int keysize,
+ const unsigned char *iv,
+ unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen,
+ const unsigned char *input, unsigned int inputlen)
+{
+ SECStatus rv = SECFailure;
+ AESContext *cx;
+ unsigned char doublecheck[10 * 16]; /* 1 to 10 blocks */
+ unsigned int doublechecklen = 0;
+
+ cx = AES_CreateContext(key, iv, mode, PR_FALSE, keysize, 16);
+ if (cx == NULL) {
+ goto loser;
+ }
+ rv = AES_Decrypt(cx, output, outputlen, maxoutputlen,
+ input, inputlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (*outputlen != inputlen) {
+ goto loser;
+ }
+ AES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+
+ /*
+ * Doublecheck our result by encrypting the plaintext and
+ * compare the output with the input ciphertext.
+ */
+ cx = AES_CreateContext(key, iv, mode, PR_TRUE, keysize, 16);
+ if (cx == NULL) {
+ goto loser;
+ }
+ rv = AES_Encrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck,
+ output, *outputlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (doublechecklen != *outputlen) {
+ goto loser;
+ }
+ AES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+ if (memcmp(doublecheck, input, inputlen) != 0) {
+ goto loser;
+ }
+ rv = SECSuccess;
+
+loser:
+ if (cx != NULL) {
+ AES_DestroyContext(cx, PR_TRUE);
+ }
+ return rv;
+}
+/*
+ * Perform the AES GCM tests.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+aes_gcm(char *reqfn, int encrypt)
+{
+ char buf[512]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "CIPHERTEXT = <320 hex digits>\n".
+ */
+ FILE *aesreq; /* input stream from the REQUEST file */
+ FILE *aesresp; /* output stream to the RESPONSE file */
+ int i, j;
+ unsigned char key[32]; /* 128, 192, or 256 bits */
+ unsigned int keysize = 0;
+ unsigned char iv[128]; /* handle large gcm IV's */
+ unsigned char plaintext[10 * 16]; /* 1 to 10 blocks */
+ unsigned int plaintextlen;
+ unsigned char ciphertext[11 * 16]; /* 1 to 10 blocks + tag */
+ unsigned int ciphertextlen;
+ unsigned char aad[11 * 16]; /* 1 to 10 blocks + tag */
+ unsigned int aadlen = 0;
+ unsigned int tagbits;
+ unsigned int taglen = 0;
+ unsigned int ivlen;
+ CK_GCM_PARAMS params;
+ SECStatus rv;
+
+ aesreq = fopen(reqfn, "r");
+ aesresp = stdout;
+ while (fgets(buf, sizeof buf, aesreq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, aesresp);
+ continue;
+ }
+ /* [ENCRYPT] or [DECRYPT] */
+ if (buf[0] == '[') {
+ if (strncmp(buf, "[Taglen", 7) == 0) {
+ if (sscanf(buf, "[Taglen = %d]", &tagbits) != 1) {
+ goto loser;
+ }
+ taglen = tagbits / 8;
+ }
+ if (strncmp(buf, "[IVlen", 6) == 0) {
+ if (sscanf(buf, "[IVlen = %d]", &ivlen) != 1) {
+ goto loser;
+ }
+ ivlen = ivlen / 8;
+ }
+ fputs(buf, aesresp);
+ continue;
+ }
+ /* "COUNT = x" begins a new data set */
+ if (strncmp(buf, "Count", 5) == 0) {
+ /* zeroize the variables for the test with this data set */
+ memset(key, 0, sizeof key);
+ keysize = 0;
+ memset(iv, 0, sizeof iv);
+ memset(plaintext, 0, sizeof plaintext);
+ plaintextlen = 0;
+ memset(ciphertext, 0, sizeof ciphertext);
+ ciphertextlen = 0;
+ fputs(buf, aesresp);
+ continue;
+ }
+ /* KEY = ... */
+ if (strncmp(buf, "Key", 3) == 0) {
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &key[j]);
+ }
+ keysize = j;
+ fputs(buf, aesresp);
+ continue;
+ }
+ /* IV = ... */
+ if (strncmp(buf, "IV", 2) == 0) {
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < sizeof iv; i += 2, j++) {
+ hex_to_byteval(&buf[i], &iv[j]);
+ }
+ fputs(buf, aesresp);
+ continue;
+ }
+ /* PLAINTEXT = ... */
+ if (strncmp(buf, "PT", 2) == 0) {
+ /* sanity check */
+ if (!encrypt) {
+ goto loser;
+ }
+
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &plaintext[j]);
+ }
+ plaintextlen = j;
+ fputs(buf, aesresp);
+ continue;
+ }
+ /* CIPHERTEXT = ... */
+ if (strncmp(buf, "CT", 2) == 0) {
+ /* sanity check */
+ if (encrypt) {
+ goto loser;
+ }
+
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &ciphertext[j]);
+ }
+ ciphertextlen = j;
+ fputs(buf, aesresp);
+ continue;
+ }
+ if (strncmp(buf, "AAD", 3) == 0) {
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &aad[j]);
+ }
+ aadlen = j;
+ fputs(buf, aesresp);
+ if (encrypt) {
+ if (encrypt == 2) {
+ rv = RNG_GenerateGlobalRandomBytes(iv, ivlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ }
+ params.pIv = iv;
+ params.ulIvLen = ivlen;
+ params.pAAD = aad;
+ params.ulAADLen = aadlen;
+ params.ulTagBits = tagbits;
+ rv = aes_encrypt_buf(NSS_AES_GCM, key, keysize,
+ (unsigned char *)¶ms,
+ ciphertext, &ciphertextlen, sizeof ciphertext,
+ plaintext, plaintextlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ if (encrypt == 2) {
+ fputs("IV = ", aesresp);
+ to_hex_str(buf, iv, ivlen);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+ }
+ fputs("CT = ", aesresp);
+ j = ciphertextlen - taglen;
+ to_hex_str(buf, ciphertext, j);
+ fputs(buf, aesresp);
+ fputs("\nTag = ", aesresp);
+ to_hex_str(buf, ciphertext + j, taglen);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+ }
+ continue;
+ }
+ if (strncmp(buf, "Tag", 3) == 0) {
+ /* sanity check */
+ if (encrypt) {
+ goto loser;
+ }
+
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &ciphertext[j + ciphertextlen]);
+ }
+ ciphertextlen += j;
+ params.pIv = iv;
+ params.ulIvLen = ivlen;
+ params.pAAD = aad;
+ params.ulAADLen = aadlen;
+ params.ulTagBits = tagbits;
+ rv = aes_decrypt_buf(NSS_AES_GCM, key, keysize,
+ (unsigned char *)¶ms,
+ plaintext, &plaintextlen, sizeof plaintext,
+ ciphertext, ciphertextlen);
+ fputs(buf, aesresp);
+ if (rv != SECSuccess) {
+ fprintf(aesresp, "FAIL\n");
+ } else {
+ fputs("PT = ", aesresp);
+ to_hex_str(buf, plaintext, plaintextlen);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+ }
+ continue;
+ }
+ }
+loser:
+ fclose(aesreq);
+}
+
+/*
+ * Perform the AES Known Answer Test (KAT) or Multi-block Message
+ * Test (MMT) in ECB or CBC mode. The KAT (there are four types)
+ * and MMT have the same structure: given the key and IV (CBC mode
+ * only), encrypt the given plaintext or decrypt the given ciphertext.
+ * So we can handle them the same way.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+aes_kat_mmt(char *reqfn)
+{
+ char buf[512]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "CIPHERTEXT = <320 hex digits>\n".
+ */
+ FILE *aesreq; /* input stream from the REQUEST file */
+ FILE *aesresp; /* output stream to the RESPONSE file */
+ int i, j;
+ int mode = NSS_AES; /* NSS_AES (ECB) or NSS_AES_CBC */
+ int encrypt = 0; /* 1 means encrypt, 0 means decrypt */
+ unsigned char key[32]; /* 128, 192, or 256 bits */
+ unsigned int keysize = 0;
+ unsigned char iv[16]; /* for all modes except ECB */
+ unsigned char plaintext[10 * 16]; /* 1 to 10 blocks */
+ unsigned int plaintextlen;
+ unsigned char ciphertext[10 * 16]; /* 1 to 10 blocks */
+ unsigned int ciphertextlen;
+ SECStatus rv;
+
+ aesreq = fopen(reqfn, "r");
+ aesresp = stdout;
+ while (fgets(buf, sizeof buf, aesreq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, aesresp);
+ continue;
+ }
+ /* [ENCRYPT] or [DECRYPT] */
+ if (buf[0] == '[') {
+ if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
+ encrypt = 1;
+ } else {
+ encrypt = 0;
+ }
+ fputs(buf, aesresp);
+ continue;
+ }
+ /* "COUNT = x" begins a new data set */
+ if (strncmp(buf, "COUNT", 5) == 0) {
+ mode = NSS_AES;
+ /* zeroize the variables for the test with this data set */
+ memset(key, 0, sizeof key);
+ keysize = 0;
+ memset(iv, 0, sizeof iv);
+ memset(plaintext, 0, sizeof plaintext);
+ plaintextlen = 0;
+ memset(ciphertext, 0, sizeof ciphertext);
+ ciphertextlen = 0;
+ fputs(buf, aesresp);
+ continue;
+ }
+ /* KEY = ... */
+ if (strncmp(buf, "KEY", 3) == 0) {
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &key[j]);
+ }
+ keysize = j;
+ fputs(buf, aesresp);
+ continue;
+ }
+ /* IV = ... */
+ if (strncmp(buf, "IV", 2) == 0) {
+ mode = NSS_AES_CBC;
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < sizeof iv; i += 2, j++) {
+ hex_to_byteval(&buf[i], &iv[j]);
+ }
+ fputs(buf, aesresp);
+ continue;
+ }
+ /* PLAINTEXT = ... */
+ if (strncmp(buf, "PLAINTEXT", 9) == 0) {
+ /* sanity check */
+ if (!encrypt) {
+ goto loser;
+ }
+
+ i = 9;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &plaintext[j]);
+ }
+ plaintextlen = j;
+
+ rv = aes_encrypt_buf(mode, key, keysize,
+ (mode ==
+ NSS_AES)
+ ? NULL
+ : iv,
+ ciphertext, &ciphertextlen, sizeof ciphertext,
+ plaintext, plaintextlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ fputs(buf, aesresp);
+ fputs("CIPHERTEXT = ", aesresp);
+ to_hex_str(buf, ciphertext, ciphertextlen);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+ continue;
+ }
+ /* CIPHERTEXT = ... */
+ if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
+ /* sanity check */
+ if (encrypt) {
+ goto loser;
+ }
+
+ i = 10;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &ciphertext[j]);
+ }
+ ciphertextlen = j;
+
+ rv = aes_decrypt_buf(mode, key, keysize,
+ (mode ==
+ NSS_AES)
+ ? NULL
+ : iv,
+ plaintext, &plaintextlen, sizeof plaintext,
+ ciphertext, ciphertextlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ fputs(buf, aesresp);
+ fputs("PLAINTEXT = ", aesresp);
+ to_hex_str(buf, plaintext, plaintextlen);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+ continue;
+ }
+ }
+loser:
+ fclose(aesreq);
+}
+
+/*
+ * Generate Key[i+1] from Key[i], CT[j-1], and CT[j] for AES Monte Carlo
+ * Test (MCT) in ECB and CBC modes.
+ */
+void
+aes_mct_next_key(unsigned char *key, unsigned int keysize,
+ const unsigned char *ciphertext_1, const unsigned char *ciphertext)
+{
+ int k;
+
+ switch (keysize) {
+ case 16: /* 128-bit key */
+ /* Key[i+1] = Key[i] xor CT[j] */
+ for (k = 0; k < 16; k++) {
+ key[k] ^= ciphertext[k];
+ }
+ break;
+ case 24: /* 192-bit key */
+ /*
+ * Key[i+1] = Key[i] xor (last 64-bits of
+ * CT[j-1] || CT[j])
+ */
+ for (k = 0; k < 8; k++) {
+ key[k] ^= ciphertext_1[k + 8];
+ }
+ for (k = 8; k < 24; k++) {
+ key[k] ^= ciphertext[k - 8];
+ }
+ break;
+ case 32: /* 256-bit key */
+ /* Key[i+1] = Key[i] xor (CT[j-1] || CT[j]) */
+ for (k = 0; k < 16; k++) {
+ key[k] ^= ciphertext_1[k];
+ }
+ for (k = 16; k < 32; k++) {
+ key[k] ^= ciphertext[k - 16];
+ }
+ break;
+ }
+}
+
+/*
+ * Perform the AES Monte Carlo Test (MCT) in ECB mode. MCT exercises
+ * our AES code in streaming mode because the plaintext or ciphertext
+ * is generated block by block as we go, so we can't collect all the
+ * plaintext or ciphertext in one buffer and encrypt or decrypt it in
+ * one shot.
+ *
+ * reqfn is the pathname of the input REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+aes_ecb_mct(char *reqfn)
+{
+ char buf[80]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "KEY = <64 hex digits>\n".
+ */
+ FILE *aesreq; /* input stream from the REQUEST file */
+ FILE *aesresp; /* output stream to the RESPONSE file */
+ int i, j;
+ int encrypt = 0; /* 1 means encrypt, 0 means decrypt */
+ unsigned char key[32]; /* 128, 192, or 256 bits */
+ unsigned int keysize = 0;
+ unsigned char plaintext[16]; /* PT[j] */
+ unsigned char plaintext_1[16]; /* PT[j-1] */
+ unsigned char ciphertext[16]; /* CT[j] */
+ unsigned char ciphertext_1[16]; /* CT[j-1] */
+ unsigned char doublecheck[16];
+ unsigned int outputlen;
+ AESContext *cx = NULL; /* the operation being tested */
+ AESContext *cx2 = NULL; /* the inverse operation done in parallel
+ * to doublecheck our result.
+ */
+ SECStatus rv;
+
+ aesreq = fopen(reqfn, "r");
+ aesresp = stdout;
+ while (fgets(buf, sizeof buf, aesreq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, aesresp);
+ continue;
+ }
+ /* [ENCRYPT] or [DECRYPT] */
+ if (buf[0] == '[') {
+ if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
+ encrypt = 1;
+ } else {
+ encrypt = 0;
+ }
+ fputs(buf, aesresp);
+ continue;
+ }
+ /* "COUNT = x" begins a new data set */
+ if (strncmp(buf, "COUNT", 5) == 0) {
+ /* zeroize the variables for the test with this data set */
+ memset(key, 0, sizeof key);
+ keysize = 0;
+ memset(plaintext, 0, sizeof plaintext);
+ memset(ciphertext, 0, sizeof ciphertext);
+ continue;
+ }
+ /* KEY = ... */
+ if (strncmp(buf, "KEY", 3) == 0) {
+ /* Key[0] = Key */
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &key[j]);
+ }
+ keysize = j;
+ continue;
+ }
+ /* PLAINTEXT = ... */
+ if (strncmp(buf, "PLAINTEXT", 9) == 0) {
+ /* sanity check */
+ if (!encrypt) {
+ goto loser;
+ }
+ /* PT[0] = PT */
+ i = 9;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < sizeof plaintext; i += 2, j++) {
+ hex_to_byteval(&buf[i], &plaintext[j]);
+ }
+
+ for (i = 0; i < 100; i++) {
+ sprintf(buf, "COUNT = %d\n", i);
+ fputs(buf, aesresp);
+ /* Output Key[i] */
+ fputs("KEY = ", aesresp);
+ to_hex_str(buf, key, keysize);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+ /* Output PT[0] */
+ fputs("PLAINTEXT = ", aesresp);
+ to_hex_str(buf, plaintext, sizeof plaintext);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+
+ cx = AES_CreateContext(key, NULL, NSS_AES,
+ PR_TRUE, keysize, 16);
+ if (cx == NULL) {
+ goto loser;
+ }
+ /*
+ * doublecheck our result by decrypting the result
+ * and comparing the output with the plaintext.
+ */
+ cx2 = AES_CreateContext(key, NULL, NSS_AES,
+ PR_FALSE, keysize, 16);
+ if (cx2 == NULL) {
+ goto loser;
+ }
+ for (j = 0; j < 1000; j++) {
+ /* Save CT[j-1] */
+ memcpy(ciphertext_1, ciphertext, sizeof ciphertext);
+
+ /* CT[j] = AES(Key[i], PT[j]) */
+ outputlen = 0;
+ rv = AES_Encrypt(cx,
+ ciphertext, &outputlen, sizeof ciphertext,
+ plaintext, sizeof plaintext);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (outputlen != sizeof plaintext) {
+ goto loser;
+ }
+
+ /* doublecheck our result */
+ outputlen = 0;
+ rv = AES_Decrypt(cx2,
+ doublecheck, &outputlen, sizeof doublecheck,
+ ciphertext, sizeof ciphertext);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (outputlen != sizeof ciphertext) {
+ goto loser;
+ }
+ if (memcmp(doublecheck, plaintext, sizeof plaintext)) {
+ goto loser;
+ }
+
+ /* PT[j+1] = CT[j] */
+ memcpy(plaintext, ciphertext, sizeof plaintext);
+ }
+ AES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+ AES_DestroyContext(cx2, PR_TRUE);
+ cx2 = NULL;
+
+ /* Output CT[j] */
+ fputs("CIPHERTEXT = ", aesresp);
+ to_hex_str(buf, ciphertext, sizeof ciphertext);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+
+ /* Key[i+1] = Key[i] xor ... */
+ aes_mct_next_key(key, keysize, ciphertext_1, ciphertext);
+ /* PT[0] = CT[j] */
+ /* done at the end of the for(j) loop */
+
+ fputc('\n', aesresp);
+ }
+
+ continue;
+ }
+ /* CIPHERTEXT = ... */
+ if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
+ /* sanity check */
+ if (encrypt) {
+ goto loser;
+ }
+ /* CT[0] = CT */
+ i = 10;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &ciphertext[j]);
+ }
+
+ for (i = 0; i < 100; i++) {
+ sprintf(buf, "COUNT = %d\n", i);
+ fputs(buf, aesresp);
+ /* Output Key[i] */
+ fputs("KEY = ", aesresp);
+ to_hex_str(buf, key, keysize);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+ /* Output CT[0] */
+ fputs("CIPHERTEXT = ", aesresp);
+ to_hex_str(buf, ciphertext, sizeof ciphertext);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+
+ cx = AES_CreateContext(key, NULL, NSS_AES,
+ PR_FALSE, keysize, 16);
+ if (cx == NULL) {
+ goto loser;
+ }
+ /*
+ * doublecheck our result by encrypting the result
+ * and comparing the output with the ciphertext.
+ */
+ cx2 = AES_CreateContext(key, NULL, NSS_AES,
+ PR_TRUE, keysize, 16);
+ if (cx2 == NULL) {
+ goto loser;
+ }
+ for (j = 0; j < 1000; j++) {
+ /* Save PT[j-1] */
+ memcpy(plaintext_1, plaintext, sizeof plaintext);
+
+ /* PT[j] = AES(Key[i], CT[j]) */
+ outputlen = 0;
+ rv = AES_Decrypt(cx,
+ plaintext, &outputlen, sizeof plaintext,
+ ciphertext, sizeof ciphertext);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (outputlen != sizeof ciphertext) {
+ goto loser;
+ }
+
+ /* doublecheck our result */
+ outputlen = 0;
+ rv = AES_Encrypt(cx2,
+ doublecheck, &outputlen, sizeof doublecheck,
+ plaintext, sizeof plaintext);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (outputlen != sizeof plaintext) {
+ goto loser;
+ }
+ if (memcmp(doublecheck, ciphertext, sizeof ciphertext)) {
+ goto loser;
+ }
+
+ /* CT[j+1] = PT[j] */
+ memcpy(ciphertext, plaintext, sizeof ciphertext);
+ }
+ AES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+ AES_DestroyContext(cx2, PR_TRUE);
+ cx2 = NULL;
+
+ /* Output PT[j] */
+ fputs("PLAINTEXT = ", aesresp);
+ to_hex_str(buf, plaintext, sizeof plaintext);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+
+ /* Key[i+1] = Key[i] xor ... */
+ aes_mct_next_key(key, keysize, plaintext_1, plaintext);
+ /* CT[0] = PT[j] */
+ /* done at the end of the for(j) loop */
+
+ fputc('\n', aesresp);
+ }
+
+ continue;
+ }
+ }
+loser:
+ if (cx != NULL) {
+ AES_DestroyContext(cx, PR_TRUE);
+ }
+ if (cx2 != NULL) {
+ AES_DestroyContext(cx2, PR_TRUE);
+ }
+ fclose(aesreq);
+}
+
+/*
+ * Perform the AES Monte Carlo Test (MCT) in CBC mode. MCT exercises
+ * our AES code in streaming mode because the plaintext or ciphertext
+ * is generated block by block as we go, so we can't collect all the
+ * plaintext or ciphertext in one buffer and encrypt or decrypt it in
+ * one shot.
+ *
+ * reqfn is the pathname of the input REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+aes_cbc_mct(char *reqfn)
+{
+ char buf[80]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "KEY = <64 hex digits>\n".
+ */
+ FILE *aesreq; /* input stream from the REQUEST file */
+ FILE *aesresp; /* output stream to the RESPONSE file */
+ int i, j;
+ int encrypt = 0; /* 1 means encrypt, 0 means decrypt */
+ unsigned char key[32]; /* 128, 192, or 256 bits */
+ unsigned int keysize = 0;
+ unsigned char iv[16];
+ unsigned char plaintext[16]; /* PT[j] */
+ unsigned char plaintext_1[16]; /* PT[j-1] */
+ unsigned char ciphertext[16]; /* CT[j] */
+ unsigned char ciphertext_1[16]; /* CT[j-1] */
+ unsigned char doublecheck[16];
+ unsigned int outputlen;
+ AESContext *cx = NULL; /* the operation being tested */
+ AESContext *cx2 = NULL; /* the inverse operation done in parallel
+ * to doublecheck our result.
+ */
+ SECStatus rv;
+
+ aesreq = fopen(reqfn, "r");
+ aesresp = stdout;
+ while (fgets(buf, sizeof buf, aesreq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, aesresp);
+ continue;
+ }
+ /* [ENCRYPT] or [DECRYPT] */
+ if (buf[0] == '[') {
+ if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
+ encrypt = 1;
+ } else {
+ encrypt = 0;
+ }
+ fputs(buf, aesresp);
+ continue;
+ }
+ /* "COUNT = x" begins a new data set */
+ if (strncmp(buf, "COUNT", 5) == 0) {
+ /* zeroize the variables for the test with this data set */
+ memset(key, 0, sizeof key);
+ keysize = 0;
+ memset(iv, 0, sizeof iv);
+ memset(plaintext, 0, sizeof plaintext);
+ memset(ciphertext, 0, sizeof ciphertext);
+ continue;
+ }
+ /* KEY = ... */
+ if (strncmp(buf, "KEY", 3) == 0) {
+ /* Key[0] = Key */
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &key[j]);
+ }
+ keysize = j;
+ continue;
+ }
+ /* IV = ... */
+ if (strncmp(buf, "IV", 2) == 0) {
+ /* IV[0] = IV */
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < sizeof iv; i += 2, j++) {
+ hex_to_byteval(&buf[i], &iv[j]);
+ }
+ continue;
+ }
+ /* PLAINTEXT = ... */
+ if (strncmp(buf, "PLAINTEXT", 9) == 0) {
+ /* sanity check */
+ if (!encrypt) {
+ goto loser;
+ }
+ /* PT[0] = PT */
+ i = 9;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < sizeof plaintext; i += 2, j++) {
+ hex_to_byteval(&buf[i], &plaintext[j]);
+ }
+
+ for (i = 0; i < 100; i++) {
+ sprintf(buf, "COUNT = %d\n", i);
+ fputs(buf, aesresp);
+ /* Output Key[i] */
+ fputs("KEY = ", aesresp);
+ to_hex_str(buf, key, keysize);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+ /* Output IV[i] */
+ fputs("IV = ", aesresp);
+ to_hex_str(buf, iv, sizeof iv);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+ /* Output PT[0] */
+ fputs("PLAINTEXT = ", aesresp);
+ to_hex_str(buf, plaintext, sizeof plaintext);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+
+ cx = AES_CreateContext(key, iv, NSS_AES_CBC,
+ PR_TRUE, keysize, 16);
+ if (cx == NULL) {
+ goto loser;
+ }
+ /*
+ * doublecheck our result by decrypting the result
+ * and comparing the output with the plaintext.
+ */
+ cx2 = AES_CreateContext(key, iv, NSS_AES_CBC,
+ PR_FALSE, keysize, 16);
+ if (cx2 == NULL) {
+ goto loser;
+ }
+ /* CT[-1] = IV[i] */
+ memcpy(ciphertext, iv, sizeof ciphertext);
+ for (j = 0; j < 1000; j++) {
+ /* Save CT[j-1] */
+ memcpy(ciphertext_1, ciphertext, sizeof ciphertext);
+ /*
+ * If ( j=0 )
+ * CT[j] = AES(Key[i], IV[i], PT[j])
+ * PT[j+1] = IV[i] (= CT[j-1])
+ * Else
+ * CT[j] = AES(Key[i], PT[j])
+ * PT[j+1] = CT[j-1]
+ */
+ outputlen = 0;
+ rv = AES_Encrypt(cx,
+ ciphertext, &outputlen, sizeof ciphertext,
+ plaintext, sizeof plaintext);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (outputlen != sizeof plaintext) {
+ goto loser;
+ }
+
+ /* doublecheck our result */
+ outputlen = 0;
+ rv = AES_Decrypt(cx2,
+ doublecheck, &outputlen, sizeof doublecheck,
+ ciphertext, sizeof ciphertext);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (outputlen != sizeof ciphertext) {
+ goto loser;
+ }
+ if (memcmp(doublecheck, plaintext, sizeof plaintext)) {
+ goto loser;
+ }
+
+ memcpy(plaintext, ciphertext_1, sizeof plaintext);
+ }
+ AES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+ AES_DestroyContext(cx2, PR_TRUE);
+ cx2 = NULL;
+
+ /* Output CT[j] */
+ fputs("CIPHERTEXT = ", aesresp);
+ to_hex_str(buf, ciphertext, sizeof ciphertext);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+
+ /* Key[i+1] = Key[i] xor ... */
+ aes_mct_next_key(key, keysize, ciphertext_1, ciphertext);
+ /* IV[i+1] = CT[j] */
+ memcpy(iv, ciphertext, sizeof iv);
+ /* PT[0] = CT[j-1] */
+ /* done at the end of the for(j) loop */
+
+ fputc('\n', aesresp);
+ }
+
+ continue;
+ }
+ /* CIPHERTEXT = ... */
+ if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
+ /* sanity check */
+ if (encrypt) {
+ goto loser;
+ }
+ /* CT[0] = CT */
+ i = 10;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &ciphertext[j]);
+ }
+
+ for (i = 0; i < 100; i++) {
+ sprintf(buf, "COUNT = %d\n", i);
+ fputs(buf, aesresp);
+ /* Output Key[i] */
+ fputs("KEY = ", aesresp);
+ to_hex_str(buf, key, keysize);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+ /* Output IV[i] */
+ fputs("IV = ", aesresp);
+ to_hex_str(buf, iv, sizeof iv);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+ /* Output CT[0] */
+ fputs("CIPHERTEXT = ", aesresp);
+ to_hex_str(buf, ciphertext, sizeof ciphertext);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+
+ cx = AES_CreateContext(key, iv, NSS_AES_CBC,
+ PR_FALSE, keysize, 16);
+ if (cx == NULL) {
+ goto loser;
+ }
+ /*
+ * doublecheck our result by encrypting the result
+ * and comparing the output with the ciphertext.
+ */
+ cx2 = AES_CreateContext(key, iv, NSS_AES_CBC,
+ PR_TRUE, keysize, 16);
+ if (cx2 == NULL) {
+ goto loser;
+ }
+ /* PT[-1] = IV[i] */
+ memcpy(plaintext, iv, sizeof plaintext);
+ for (j = 0; j < 1000; j++) {
+ /* Save PT[j-1] */
+ memcpy(plaintext_1, plaintext, sizeof plaintext);
+ /*
+ * If ( j=0 )
+ * PT[j] = AES(Key[i], IV[i], CT[j])
+ * CT[j+1] = IV[i] (= PT[j-1])
+ * Else
+ * PT[j] = AES(Key[i], CT[j])
+ * CT[j+1] = PT[j-1]
+ */
+ outputlen = 0;
+ rv = AES_Decrypt(cx,
+ plaintext, &outputlen, sizeof plaintext,
+ ciphertext, sizeof ciphertext);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (outputlen != sizeof ciphertext) {
+ goto loser;
+ }
+
+ /* doublecheck our result */
+ outputlen = 0;
+ rv = AES_Encrypt(cx2,
+ doublecheck, &outputlen, sizeof doublecheck,
+ plaintext, sizeof plaintext);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (outputlen != sizeof plaintext) {
+ goto loser;
+ }
+ if (memcmp(doublecheck, ciphertext, sizeof ciphertext)) {
+ goto loser;
+ }
+
+ memcpy(ciphertext, plaintext_1, sizeof ciphertext);
+ }
+ AES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+ AES_DestroyContext(cx2, PR_TRUE);
+ cx2 = NULL;
+
+ /* Output PT[j] */
+ fputs("PLAINTEXT = ", aesresp);
+ to_hex_str(buf, plaintext, sizeof plaintext);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+
+ /* Key[i+1] = Key[i] xor ... */
+ aes_mct_next_key(key, keysize, plaintext_1, plaintext);
+ /* IV[i+1] = PT[j] */
+ memcpy(iv, plaintext, sizeof iv);
+ /* CT[0] = PT[j-1] */
+ /* done at the end of the for(j) loop */
+
+ fputc('\n', aesresp);
+ }
+
+ continue;
+ }
+ }
+loser:
+ if (cx != NULL) {
+ AES_DestroyContext(cx, PR_TRUE);
+ }
+ if (cx2 != NULL) {
+ AES_DestroyContext(cx2, PR_TRUE);
+ }
+ fclose(aesreq);
+}
+
+void
+write_compact_string(FILE *out, unsigned char *hash, unsigned int len)
+{
+ unsigned int i;
+ int j, count = 0, last = -1, z = 0;
+ long start = ftell(out);
+ for (i = 0; i < len; i++) {
+ for (j = 7; j >= 0; j--) {
+ if (last < 0) {
+ last = (hash[i] & (1 << j)) ? 1 : 0;
+ fprintf(out, "%d ", last);
+ count = 1;
+ } else if (hash[i] & (1 << j)) {
+ if (last) {
+ count++;
+ } else {
+ last = 0;
+ fprintf(out, "%d ", count);
+ count = 1;
+ z++;
+ }
+ } else {
+ if (!last) {
+ count++;
+ } else {
+ last = 1;
+ fprintf(out, "%d ", count);
+ count = 1;
+ z++;
+ }
+ }
+ }
+ }
+ fprintf(out, "^\n");
+ fseek(out, start, SEEK_SET);
+ fprintf(out, "%d ", z);
+ fseek(out, 0, SEEK_END);
+}
+
+int
+get_next_line(FILE *req, char *key, char *val, FILE *rsp)
+{
+ int ignore = 0;
+ char *writeto = key;
+ int w = 0;
+ int c;
+ while ((c = fgetc(req)) != EOF) {
+ if (ignore) {
+ fprintf(rsp, "%c", c);
+ if (c == '\n')
+ return ignore;
+ } else if (c == '\n') {
+ break;
+ } else if (c == '#') {
+ ignore = 1;
+ fprintf(rsp, "%c", c);
+ } else if (c == '=') {
+ writeto[w] = '\0';
+ w = 0;
+ writeto = val;
+ } else if (c == ' ' || c == '[' || c == ']') {
+ continue;
+ } else {
+ writeto[w++] = c;
+ }
+ }
+ writeto[w] = '\0';
+ return (c == EOF) ? -1 : ignore;
+}
+
+#ifndef NSS_DISABLE_ECC
+typedef struct curveNameTagPairStr {
+ char *curveName;
+ SECOidTag curveOidTag;
+} CurveNameTagPair;
+
+#define DEFAULT_CURVE_OID_TAG SEC_OID_SECG_EC_SECP192R1
+/* #define DEFAULT_CURVE_OID_TAG SEC_OID_SECG_EC_SECP160R1 */
+
+static CurveNameTagPair nameTagPair[] =
+ {
+ { "sect163k1", SEC_OID_SECG_EC_SECT163K1 },
+ { "nistk163", SEC_OID_SECG_EC_SECT163K1 },
+ { "sect163r1", SEC_OID_SECG_EC_SECT163R1 },
+ { "sect163r2", SEC_OID_SECG_EC_SECT163R2 },
+ { "nistb163", SEC_OID_SECG_EC_SECT163R2 },
+ { "sect193r1", SEC_OID_SECG_EC_SECT193R1 },
+ { "sect193r2", SEC_OID_SECG_EC_SECT193R2 },
+ { "sect233k1", SEC_OID_SECG_EC_SECT233K1 },
+ { "nistk233", SEC_OID_SECG_EC_SECT233K1 },
+ { "sect233r1", SEC_OID_SECG_EC_SECT233R1 },
+ { "nistb233", SEC_OID_SECG_EC_SECT233R1 },
+ { "sect239k1", SEC_OID_SECG_EC_SECT239K1 },
+ { "sect283k1", SEC_OID_SECG_EC_SECT283K1 },
+ { "nistk283", SEC_OID_SECG_EC_SECT283K1 },
+ { "sect283r1", SEC_OID_SECG_EC_SECT283R1 },
+ { "nistb283", SEC_OID_SECG_EC_SECT283R1 },
+ { "sect409k1", SEC_OID_SECG_EC_SECT409K1 },
+ { "nistk409", SEC_OID_SECG_EC_SECT409K1 },
+ { "sect409r1", SEC_OID_SECG_EC_SECT409R1 },
+ { "nistb409", SEC_OID_SECG_EC_SECT409R1 },
+ { "sect571k1", SEC_OID_SECG_EC_SECT571K1 },
+ { "nistk571", SEC_OID_SECG_EC_SECT571K1 },
+ { "sect571r1", SEC_OID_SECG_EC_SECT571R1 },
+ { "nistb571", SEC_OID_SECG_EC_SECT571R1 },
+ { "secp160k1", SEC_OID_SECG_EC_SECP160K1 },
+ { "secp160r1", SEC_OID_SECG_EC_SECP160R1 },
+ { "secp160r2", SEC_OID_SECG_EC_SECP160R2 },
+ { "secp192k1", SEC_OID_SECG_EC_SECP192K1 },
+ { "secp192r1", SEC_OID_SECG_EC_SECP192R1 },
+ { "nistp192", SEC_OID_SECG_EC_SECP192R1 },
+ { "secp224k1", SEC_OID_SECG_EC_SECP224K1 },
+ { "secp224r1", SEC_OID_SECG_EC_SECP224R1 },
+ { "nistp224", SEC_OID_SECG_EC_SECP224R1 },
+ { "secp256k1", SEC_OID_SECG_EC_SECP256K1 },
+ { "secp256r1", SEC_OID_SECG_EC_SECP256R1 },
+ { "nistp256", SEC_OID_SECG_EC_SECP256R1 },
+ { "secp384r1", SEC_OID_SECG_EC_SECP384R1 },
+ { "nistp384", SEC_OID_SECG_EC_SECP384R1 },
+ { "secp521r1", SEC_OID_SECG_EC_SECP521R1 },
+ { "nistp521", SEC_OID_SECG_EC_SECP521R1 },
+
+ { "prime192v1", SEC_OID_ANSIX962_EC_PRIME192V1 },
+ { "prime192v2", SEC_OID_ANSIX962_EC_PRIME192V2 },
+ { "prime192v3", SEC_OID_ANSIX962_EC_PRIME192V3 },
+ { "prime239v1", SEC_OID_ANSIX962_EC_PRIME239V1 },
+ { "prime239v2", SEC_OID_ANSIX962_EC_PRIME239V2 },
+ { "prime239v3", SEC_OID_ANSIX962_EC_PRIME239V3 },
+
+ { "c2pnb163v1", SEC_OID_ANSIX962_EC_C2PNB163V1 },
+ { "c2pnb163v2", SEC_OID_ANSIX962_EC_C2PNB163V2 },
+ { "c2pnb163v3", SEC_OID_ANSIX962_EC_C2PNB163V3 },
+ { "c2pnb176v1", SEC_OID_ANSIX962_EC_C2PNB176V1 },
+ { "c2tnb191v1", SEC_OID_ANSIX962_EC_C2TNB191V1 },
+ { "c2tnb191v2", SEC_OID_ANSIX962_EC_C2TNB191V2 },
+ { "c2tnb191v3", SEC_OID_ANSIX962_EC_C2TNB191V3 },
+ { "c2onb191v4", SEC_OID_ANSIX962_EC_C2ONB191V4 },
+ { "c2onb191v5", SEC_OID_ANSIX962_EC_C2ONB191V5 },
+ { "c2pnb208w1", SEC_OID_ANSIX962_EC_C2PNB208W1 },
+ { "c2tnb239v1", SEC_OID_ANSIX962_EC_C2TNB239V1 },
+ { "c2tnb239v2", SEC_OID_ANSIX962_EC_C2TNB239V2 },
+ { "c2tnb239v3", SEC_OID_ANSIX962_EC_C2TNB239V3 },
+ { "c2onb239v4", SEC_OID_ANSIX962_EC_C2ONB239V4 },
+ { "c2onb239v5", SEC_OID_ANSIX962_EC_C2ONB239V5 },
+ { "c2pnb272w1", SEC_OID_ANSIX962_EC_C2PNB272W1 },
+ { "c2pnb304w1", SEC_OID_ANSIX962_EC_C2PNB304W1 },
+ { "c2tnb359v1", SEC_OID_ANSIX962_EC_C2TNB359V1 },
+ { "c2pnb368w1", SEC_OID_ANSIX962_EC_C2PNB368W1 },
+ { "c2tnb431r1", SEC_OID_ANSIX962_EC_C2TNB431R1 },
+
+ { "secp112r1", SEC_OID_SECG_EC_SECP112R1 },
+ { "secp112r2", SEC_OID_SECG_EC_SECP112R2 },
+ { "secp128r1", SEC_OID_SECG_EC_SECP128R1 },
+ { "secp128r2", SEC_OID_SECG_EC_SECP128R2 },
+
+ { "sect113r1", SEC_OID_SECG_EC_SECT113R1 },
+ { "sect113r2", SEC_OID_SECG_EC_SECT113R2 },
+ { "sect131r1", SEC_OID_SECG_EC_SECT131R1 },
+ { "sect131r2", SEC_OID_SECG_EC_SECT131R2 },
+ };
+
+static SECItem *
+getECParams(const char *curve)
+{
+ SECItem *ecparams;
+ SECOidData *oidData = NULL;
+ SECOidTag curveOidTag = SEC_OID_UNKNOWN; /* default */
+ int i, numCurves;
+
+ if (curve != NULL) {
+ numCurves = sizeof(nameTagPair) / sizeof(CurveNameTagPair);
+ for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN));
+ i++) {
+ if (PL_strcmp(curve, nameTagPair[i].curveName) == 0)
+ curveOidTag = nameTagPair[i].curveOidTag;
+ }
+ }
+
+ /* Return NULL if curve name is not recognized */
+ if ((curveOidTag == SEC_OID_UNKNOWN) ||
+ (oidData = SECOID_FindOIDByTag(curveOidTag)) == NULL) {
+ fprintf(stderr, "Unrecognized elliptic curve %s\n", curve);
+ return NULL;
+ }
+
+ ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len));
+
+ /*
+ * ecparams->data needs to contain the ASN encoding of an object ID (OID)
+ * representing the named curve. The actual OID is in
+ * oidData->oid.data so we simply prepend 0x06 and OID length
+ */
+ ecparams->data[0] = SEC_ASN1_OBJECT_ID;
+ ecparams->data[1] = oidData->oid.len;
+ memcpy(ecparams->data + 2, oidData->oid.data, oidData->oid.len);
+
+ return ecparams;
+}
+
+/*
+ * HASH_ functions are available to full NSS apps and internally inside
+ * freebl, but not exported to users of freebl. Create short stubs to
+ * replace the functionality for fipstest.
+ */
+SECStatus
+fips_hashBuf(HASH_HashType type, unsigned char *hashBuf,
+ unsigned char *msg, int len)
+{
+ SECStatus rv = SECFailure;
+
+ switch (type) {
+ case HASH_AlgSHA1:
+ rv = SHA1_HashBuf(hashBuf, msg, len);
+ break;
+ case HASH_AlgSHA224:
+ rv = SHA224_HashBuf(hashBuf, msg, len);
+ break;
+ case HASH_AlgSHA256:
+ rv = SHA256_HashBuf(hashBuf, msg, len);
+ break;
+ case HASH_AlgSHA384:
+ rv = SHA384_HashBuf(hashBuf, msg, len);
+ break;
+ case HASH_AlgSHA512:
+ rv = SHA512_HashBuf(hashBuf, msg, len);
+ break;
+ default:
+ break;
+ }
+ return rv;
+}
+
+int
+fips_hashLen(HASH_HashType type)
+{
+ int len = 0;
+
+ switch (type) {
+ case HASH_AlgSHA1:
+ len = SHA1_LENGTH;
+ break;
+ case HASH_AlgSHA224:
+ len = SHA224_LENGTH;
+ break;
+ case HASH_AlgSHA256:
+ len = SHA256_LENGTH;
+ break;
+ case HASH_AlgSHA384:
+ len = SHA384_LENGTH;
+ break;
+ case HASH_AlgSHA512:
+ len = SHA512_LENGTH;
+ break;
+ default:
+ break;
+ }
+ return len;
+}
+
+SECOidTag
+fips_hashOid(HASH_HashType type)
+{
+ SECOidTag oid = SEC_OID_UNKNOWN;
+
+ switch (type) {
+ case HASH_AlgSHA1:
+ oid = SEC_OID_SHA1;
+ break;
+ case HASH_AlgSHA224:
+ oid = SEC_OID_SHA224;
+ break;
+ case HASH_AlgSHA256:
+ oid = SEC_OID_SHA256;
+ break;
+ case HASH_AlgSHA384:
+ oid = SEC_OID_SHA384;
+ break;
+ case HASH_AlgSHA512:
+ oid = SEC_OID_SHA512;
+ break;
+ default:
+ break;
+ }
+ return oid;
+}
+
+HASH_HashType
+sha_get_hashType(int hashbits)
+{
+ HASH_HashType hashType = HASH_AlgNULL;
+
+ switch (hashbits) {
+ case 1:
+ case (SHA1_LENGTH * PR_BITS_PER_BYTE):
+ hashType = HASH_AlgSHA1;
+ break;
+ case (SHA224_LENGTH * PR_BITS_PER_BYTE):
+ hashType = HASH_AlgSHA224;
+ break;
+ case (SHA256_LENGTH * PR_BITS_PER_BYTE):
+ hashType = HASH_AlgSHA256;
+ break;
+ case (SHA384_LENGTH * PR_BITS_PER_BYTE):
+ hashType = HASH_AlgSHA384;
+ break;
+ case (SHA512_LENGTH * PR_BITS_PER_BYTE):
+ hashType = HASH_AlgSHA512;
+ break;
+ default:
+ break;
+ }
+ return hashType;
+}
+
+/*
+ * Perform the ECDSA Key Pair Generation Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+ecdsa_keypair_test(char *reqfn)
+{
+ char buf[256]; /* holds one line from the input REQUEST file
+ * or to the output RESPONSE file.
+ * needs to be large enough to hold the longest
+ * line "Qx = <144 hex digits>\n".
+ */
+ FILE *ecdsareq; /* input stream from the REQUEST file */
+ FILE *ecdsaresp; /* output stream to the RESPONSE file */
+ char curve[16]; /* "nistxddd" */
+ ECParams *ecparams = NULL;
+ int N;
+ int i;
+ unsigned int len;
+
+ ecdsareq = fopen(reqfn, "r");
+ ecdsaresp = stdout;
+ strcpy(curve, "nist");
+ while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* [X-ddd] */
+ if (buf[0] == '[') {
+ const char *src;
+ char *dst;
+ SECItem *encodedparams;
+
+ if (buf[1] == 'B') {
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ if (ecparams) {
+ PORT_FreeArena(ecparams->arena, PR_FALSE);
+ ecparams = NULL;
+ }
+
+ src = &buf[1];
+ dst = &curve[4];
+ *dst++ = tolower(*src);
+ src += 2; /* skip the hyphen */
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst = '\0';
+ encodedparams = getECParams(curve);
+ if (encodedparams == NULL) {
+ fprintf(stderr, "Unknown curve %s.", curve);
+ goto loser;
+ }
+ if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
+ fprintf(stderr, "Curve %s not supported.\n", curve);
+ goto loser;
+ }
+ SECITEM_FreeItem(encodedparams, PR_TRUE);
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* N = x */
+ if (buf[0] == 'N') {
+ if (sscanf(buf, "N = %d", &N) != 1) {
+ goto loser;
+ }
+ for (i = 0; i < N; i++) {
+ ECPrivateKey *ecpriv;
+
+ if (EC_NewKey(ecparams, &ecpriv) != SECSuccess) {
+ goto loser;
+ }
+ fputs("d = ", ecdsaresp);
+ to_hex_str(buf, ecpriv->privateValue.data,
+ ecpriv->privateValue.len);
+ fputs(buf, ecdsaresp);
+ fputc('\n', ecdsaresp);
+ if (EC_ValidatePublicKey(ecparams, &ecpriv->publicValue) !=
+ SECSuccess) {
+ goto loser;
+ }
+ len = ecpriv->publicValue.len;
+ if (len % 2 == 0) {
+ goto loser;
+ }
+ len = (len - 1) / 2;
+ if (ecpriv->publicValue.data[0] !=
+ EC_POINT_FORM_UNCOMPRESSED) {
+ goto loser;
+ }
+ fputs("Qx = ", ecdsaresp);
+ to_hex_str(buf, &ecpriv->publicValue.data[1], len);
+ fputs(buf, ecdsaresp);
+ fputc('\n', ecdsaresp);
+ fputs("Qy = ", ecdsaresp);
+ to_hex_str(buf, &ecpriv->publicValue.data[1 + len], len);
+ fputs(buf, ecdsaresp);
+ fputc('\n', ecdsaresp);
+ fputc('\n', ecdsaresp);
+ PORT_FreeArena(ecpriv->ecParams.arena, PR_TRUE);
+ }
+ continue;
+ }
+ }
+loser:
+ if (ecparams) {
+ PORT_FreeArena(ecparams->arena, PR_FALSE);
+ ecparams = NULL;
+ }
+ fclose(ecdsareq);
+}
+
+/*
+ * Perform the ECDSA Public Key Validation Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+ecdsa_pkv_test(char *reqfn)
+{
+ char buf[256]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "Qx = <144 hex digits>\n".
+ */
+ FILE *ecdsareq; /* input stream from the REQUEST file */
+ FILE *ecdsaresp; /* output stream to the RESPONSE file */
+ char curve[16]; /* "nistxddd" */
+ ECParams *ecparams = NULL;
+ SECItem pubkey;
+ unsigned int i;
+ unsigned int len = 0;
+ PRBool keyvalid = PR_TRUE;
+
+ ecdsareq = fopen(reqfn, "r");
+ ecdsaresp = stdout;
+ strcpy(curve, "nist");
+ pubkey.data = NULL;
+ while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* [X-ddd] */
+ if (buf[0] == '[') {
+ const char *src;
+ char *dst;
+ SECItem *encodedparams;
+
+ src = &buf[1];
+ dst = &curve[4];
+ *dst++ = tolower(*src);
+ src += 2; /* skip the hyphen */
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst = '\0';
+ if (ecparams != NULL) {
+ PORT_FreeArena(ecparams->arena, PR_FALSE);
+ ecparams = NULL;
+ }
+ encodedparams = getECParams(curve);
+ if (encodedparams == NULL) {
+ fprintf(stderr, "Unknown curve %s.", curve);
+ goto loser;
+ }
+ if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
+ fprintf(stderr, "Curve %s not supported.\n", curve);
+ goto loser;
+ }
+ SECITEM_FreeItem(encodedparams, PR_TRUE);
+ len = (ecparams->fieldID.size + 7) >> 3;
+ if (pubkey.data != NULL) {
+ PORT_Free(pubkey.data);
+ pubkey.data = NULL;
+ }
+ SECITEM_AllocItem(NULL, &pubkey, EC_GetPointSize(ecparams));
+ if (pubkey.data == NULL) {
+ goto loser;
+ }
+ pubkey.data[0] = EC_POINT_FORM_UNCOMPRESSED;
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* Qx = ... */
+ if (strncmp(buf, "Qx", 2) == 0) {
+ fputs(buf, ecdsaresp);
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ keyvalid = from_hex_str(&pubkey.data[1], len, &buf[i]);
+ continue;
+ }
+ /* Qy = ... */
+ if (strncmp(buf, "Qy", 2) == 0) {
+ fputs(buf, ecdsaresp);
+ if (!keyvalid) {
+ fputs("Result = F\n", ecdsaresp);
+ continue;
+ }
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ keyvalid = from_hex_str(&pubkey.data[1 + len], len, &buf[i]);
+ if (!keyvalid) {
+ fputs("Result = F\n", ecdsaresp);
+ continue;
+ }
+ if (EC_ValidatePublicKey(ecparams, &pubkey) == SECSuccess) {
+ fputs("Result = P\n", ecdsaresp);
+ } else if (PORT_GetError() == SEC_ERROR_BAD_KEY) {
+ fputs("Result = F\n", ecdsaresp);
+ } else {
+ goto loser;
+ }
+ continue;
+ }
+ }
+loser:
+ if (ecparams != NULL) {
+ PORT_FreeArena(ecparams->arena, PR_FALSE);
+ }
+ if (pubkey.data != NULL) {
+ PORT_Free(pubkey.data);
+ }
+ fclose(ecdsareq);
+}
+
+/*
+ * Perform the ECDSA Signature Generation Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+ecdsa_siggen_test(char *reqfn)
+{
+ char buf[1024]; /* holds one line from the input REQUEST file
+ * or to the output RESPONSE file.
+ * needs to be large enough to hold the longest
+ * line "Msg = <256 hex digits>\n".
+ */
+ FILE *ecdsareq; /* input stream from the REQUEST file */
+ FILE *ecdsaresp; /* output stream to the RESPONSE file */
+ char curve[16]; /* "nistxddd" */
+ ECParams *ecparams = NULL;
+ int i, j;
+ unsigned int len;
+ unsigned char msg[512]; /* message to be signed (<= 128 bytes) */
+ unsigned int msglen;
+ unsigned char sha[HASH_LENGTH_MAX]; /* SHA digest */
+ unsigned int shaLength = 0; /* length of SHA */
+ HASH_HashType shaAlg = HASH_AlgNULL; /* type of SHA Alg */
+ unsigned char sig[2 * MAX_ECKEY_LEN];
+ SECItem signature, digest;
+
+ ecdsareq = fopen(reqfn, "r");
+ ecdsaresp = stdout;
+ strcpy(curve, "nist");
+ while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* [X-ddd] */
+ if (buf[0] == '[') {
+ const char *src;
+ char *dst;
+ SECItem *encodedparams;
+
+ src = &buf[1];
+ dst = &curve[4];
+ *dst++ = tolower(*src);
+ src += 2; /* skip the hyphen */
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst = '\0';
+ src++; /* skip the comma */
+ /* set the SHA Algorithm */
+ if (strncmp(src, "SHA-1", 5) == 0) {
+ shaAlg = HASH_AlgSHA1;
+ } else if (strncmp(src, "SHA-224", 7) == 0) {
+ shaAlg = HASH_AlgSHA224;
+ } else if (strncmp(src, "SHA-256", 7) == 0) {
+ shaAlg = HASH_AlgSHA256;
+ } else if (strncmp(src, "SHA-384", 7) == 0) {
+ shaAlg = HASH_AlgSHA384;
+ } else if (strncmp(src, "SHA-512", 7) == 0) {
+ shaAlg = HASH_AlgSHA512;
+ } else {
+ fprintf(ecdsaresp, "ERROR: Unable to find SHAAlg type");
+ goto loser;
+ }
+ if (ecparams != NULL) {
+ PORT_FreeArena(ecparams->arena, PR_FALSE);
+ ecparams = NULL;
+ }
+ encodedparams = getECParams(curve);
+ if (encodedparams == NULL) {
+ fprintf(stderr, "Unknown curve %s.", curve);
+ goto loser;
+ }
+ if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
+ fprintf(stderr, "Curve %s not supported.\n", curve);
+ goto loser;
+ }
+ SECITEM_FreeItem(encodedparams, PR_TRUE);
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* Msg = ... */
+ if (strncmp(buf, "Msg", 3) == 0) {
+ ECPrivateKey *ecpriv;
+
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &msg[j]);
+ }
+ msglen = j;
+ shaLength = fips_hashLen(shaAlg);
+ if (fips_hashBuf(shaAlg, sha, msg, msglen) != SECSuccess) {
+ if (shaLength == 0) {
+ fprintf(ecdsaresp, "ERROR: SHAAlg not defined.");
+ }
+ fprintf(ecdsaresp, "ERROR: Unable to generate SHA%x",
+ shaLength == 160 ? 1 : shaLength);
+ goto loser;
+ }
+ fputs(buf, ecdsaresp);
+
+ if (EC_NewKey(ecparams, &ecpriv) != SECSuccess) {
+ goto loser;
+ }
+ if (EC_ValidatePublicKey(ecparams, &ecpriv->publicValue) !=
+ SECSuccess) {
+ goto loser;
+ }
+ len = ecpriv->publicValue.len;
+ if (len % 2 == 0) {
+ goto loser;
+ }
+ len = (len - 1) / 2;
+ if (ecpriv->publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
+ goto loser;
+ }
+ fputs("Qx = ", ecdsaresp);
+ to_hex_str(buf, &ecpriv->publicValue.data[1], len);
+ fputs(buf, ecdsaresp);
+ fputc('\n', ecdsaresp);
+ fputs("Qy = ", ecdsaresp);
+ to_hex_str(buf, &ecpriv->publicValue.data[1 + len], len);
+ fputs(buf, ecdsaresp);
+ fputc('\n', ecdsaresp);
+
+ digest.type = siBuffer;
+ digest.data = sha;
+ digest.len = shaLength;
+ signature.type = siBuffer;
+ signature.data = sig;
+ signature.len = sizeof sig;
+ if (ECDSA_SignDigest(ecpriv, &signature, &digest) != SECSuccess) {
+ goto loser;
+ }
+ len = signature.len;
+ if (len % 2 != 0) {
+ goto loser;
+ }
+ len = len / 2;
+ fputs("R = ", ecdsaresp);
+ to_hex_str(buf, &signature.data[0], len);
+ fputs(buf, ecdsaresp);
+ fputc('\n', ecdsaresp);
+ fputs("S = ", ecdsaresp);
+ to_hex_str(buf, &signature.data[len], len);
+ fputs(buf, ecdsaresp);
+ fputc('\n', ecdsaresp);
+
+ PORT_FreeArena(ecpriv->ecParams.arena, PR_TRUE);
+ continue;
+ }
+ }
+loser:
+ if (ecparams != NULL) {
+ PORT_FreeArena(ecparams->arena, PR_FALSE);
+ }
+ fclose(ecdsareq);
+}
+
+/*
+ * Perform the ECDSA Signature Verification Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+ecdsa_sigver_test(char *reqfn)
+{
+ char buf[1024]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "Msg = <256 hex digits>\n".
+ */
+ FILE *ecdsareq; /* input stream from the REQUEST file */
+ FILE *ecdsaresp; /* output stream to the RESPONSE file */
+ char curve[16]; /* "nistxddd" */
+ ECPublicKey ecpub;
+ unsigned int i, j;
+ unsigned int flen = 0; /* length in bytes of the field size */
+ unsigned int olen = 0; /* length in bytes of the base point order */
+ unsigned char msg[512]; /* message that was signed (<= 128 bytes) */
+ unsigned int msglen = 0;
+ unsigned char sha[HASH_LENGTH_MAX]; /* SHA digest */
+ unsigned int shaLength = 0; /* length of SHA */
+ HASH_HashType shaAlg = HASH_AlgNULL; /* type of SHA Alg */
+ unsigned char sig[2 * MAX_ECKEY_LEN];
+ SECItem signature, digest;
+ PRBool keyvalid = PR_TRUE;
+ PRBool sigvalid = PR_TRUE;
+
+ ecdsareq = fopen(reqfn, "r");
+ ecdsaresp = stdout;
+ ecpub.ecParams.arena = NULL;
+ strcpy(curve, "nist");
+ while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* [X-ddd] */
+ if (buf[0] == '[') {
+ const char *src;
+ char *dst;
+ SECItem *encodedparams;
+ ECParams *ecparams;
+
+ src = &buf[1];
+ dst = &curve[4];
+ *dst++ = tolower(*src);
+ src += 2; /* skip the hyphen */
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst = '\0';
+ src++; /* skip the comma */
+ /* set the SHA Algorithm */
+ if (strncmp(src, "SHA-1", 5) == 0) {
+ shaAlg = HASH_AlgSHA1;
+ } else if (strncmp(src, "SHA-224", 7) == 0) {
+ shaAlg = HASH_AlgSHA224;
+ } else if (strncmp(src, "SHA-256", 7) == 0) {
+ shaAlg = HASH_AlgSHA256;
+ } else if (strncmp(src, "SHA-384", 7) == 0) {
+ shaAlg = HASH_AlgSHA384;
+ } else if (strncmp(src, "SHA-512", 7) == 0) {
+ shaAlg = HASH_AlgSHA512;
+ } else {
+ fprintf(ecdsaresp, "ERROR: Unable to find SHAAlg type");
+ goto loser;
+ }
+ encodedparams = getECParams(curve);
+ if (encodedparams == NULL) {
+ fprintf(stderr, "Unknown curve %s.", curve);
+ goto loser;
+ }
+ if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
+ fprintf(stderr, "Curve %s not supported.\n", curve);
+ goto loser;
+ }
+ SECITEM_FreeItem(encodedparams, PR_TRUE);
+ if (ecpub.ecParams.arena != NULL) {
+ PORT_FreeArena(ecpub.ecParams.arena, PR_FALSE);
+ }
+ ecpub.ecParams.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (ecpub.ecParams.arena == NULL) {
+ goto loser;
+ }
+ if (EC_CopyParams(ecpub.ecParams.arena, &ecpub.ecParams, ecparams) !=
+ SECSuccess) {
+ goto loser;
+ }
+ PORT_FreeArena(ecparams->arena, PR_FALSE);
+ flen = (ecpub.ecParams.fieldID.size + 7) >> 3;
+ olen = ecpub.ecParams.order.len;
+ if (2 * olen > sizeof sig) {
+ goto loser;
+ }
+ ecpub.publicValue.type = siBuffer;
+ ecpub.publicValue.data = NULL;
+ ecpub.publicValue.len = 0;
+ SECITEM_AllocItem(ecpub.ecParams.arena,
+ &ecpub.publicValue, 2 * flen + 1);
+ if (ecpub.publicValue.data == NULL) {
+ goto loser;
+ }
+ ecpub.publicValue.data[0] = EC_POINT_FORM_UNCOMPRESSED;
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* Msg = ... */
+ if (strncmp(buf, "Msg", 3) == 0) {
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &msg[j]);
+ }
+ msglen = j;
+ shaLength = fips_hashLen(shaAlg);
+ if (fips_hashBuf(shaAlg, sha, msg, msglen) != SECSuccess) {
+ if (shaLength == 0) {
+ fprintf(ecdsaresp, "ERROR: SHAAlg not defined.");
+ }
+ fprintf(ecdsaresp, "ERROR: Unable to generate SHA%x",
+ shaLength == 160 ? 1 : shaLength);
+ goto loser;
+ }
+ fputs(buf, ecdsaresp);
+
+ digest.type = siBuffer;
+ digest.data = sha;
+ digest.len = shaLength;
+
+ continue;
+ }
+ /* Qx = ... */
+ if (strncmp(buf, "Qx", 2) == 0) {
+ fputs(buf, ecdsaresp);
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ keyvalid = from_hex_str(&ecpub.publicValue.data[1], flen,
+ &buf[i]);
+ continue;
+ }
+ /* Qy = ... */
+ if (strncmp(buf, "Qy", 2) == 0) {
+ fputs(buf, ecdsaresp);
+ if (!keyvalid) {
+ continue;
+ }
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ keyvalid = from_hex_str(&ecpub.publicValue.data[1 + flen], flen,
+ &buf[i]);
+ if (!keyvalid) {
+ continue;
+ }
+ if (EC_ValidatePublicKey(&ecpub.ecParams, &ecpub.publicValue) !=
+ SECSuccess) {
+ if (PORT_GetError() == SEC_ERROR_BAD_KEY) {
+ keyvalid = PR_FALSE;
+ } else {
+ goto loser;
+ }
+ }
+ continue;
+ }
+ /* R = ... */
+ if (buf[0] == 'R') {
+ fputs(buf, ecdsaresp);
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ sigvalid = from_hex_str(sig, olen, &buf[i]);
+ continue;
+ }
+ /* S = ... */
+ if (buf[0] == 'S') {
+ fputs(buf, ecdsaresp);
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ if (sigvalid) {
+ sigvalid = from_hex_str(&sig[olen], olen, &buf[i]);
+ }
+ signature.type = siBuffer;
+ signature.data = sig;
+ signature.len = 2 * olen;
+
+ if (!keyvalid || !sigvalid) {
+ fputs("Result = F\n", ecdsaresp);
+ } else if (ECDSA_VerifyDigest(&ecpub, &signature, &digest) ==
+ SECSuccess) {
+ fputs("Result = P\n", ecdsaresp);
+ } else {
+ fputs("Result = F\n", ecdsaresp);
+ }
+ continue;
+ }
+ }
+loser:
+ if (ecpub.ecParams.arena != NULL) {
+ PORT_FreeArena(ecpub.ecParams.arena, PR_FALSE);
+ }
+ fclose(ecdsareq);
+}
+#endif /* NSS_DISABLE_ECC */
+
+PRBool
+isblankline(char *b)
+{
+ while (isspace(*b))
+ b++;
+ if ((*b == '\n') || (*b == 0)) {
+ return PR_TRUE;
+ }
+ return PR_FALSE;
+}
+
+static int debug = 0;
+
+/*
+ * Perform the Hash_DRBG (CAVS) for the RNG algorithm
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+drbg(char *reqfn)
+{
+ char buf[2000]; /* test case has some very long lines, returned bits
+ * as high as 800 bytes (6400 bits). That 1600 byte
+ * plus a tag */
+ char buf2[2000];
+ FILE *rngreq; /* input stream from the REQUEST file */
+ FILE *rngresp; /* output stream to the RESPONSE file */
+
+ unsigned int i, j;
+#ifdef HANDLE_PREDICTION_RESISTANCE
+ PRBool predictionResistance = PR_FALSE;
+#endif
+ unsigned char *nonce = NULL;
+ int nonceLen = 0;
+ unsigned char *personalizationString = NULL;
+ int personalizationStringLen = 0;
+ unsigned char *additionalInput = NULL;
+ int additionalInputLen = 0;
+ unsigned char *entropyInput = NULL;
+ int entropyInputLen = 0;
+ unsigned char *predictedreturn_bytes = NULL;
+ unsigned char *return_bytes = NULL;
+ int return_bytes_len = 0;
+ enum { NONE,
+ INSTANTIATE,
+ GENERATE,
+ RESEED,
+ RESULT } command =
+ NONE;
+ PRBool genResult = PR_FALSE;
+ SECStatus rv;
+
+ rngreq = fopen(reqfn, "r");
+ rngresp = stdout;
+ while (fgets(buf, sizeof buf, rngreq) != NULL) {
+ switch (command) {
+ case INSTANTIATE:
+ if (debug) {
+ fputs("# PRNGTEST_Instantiate(", rngresp);
+ to_hex_str(buf2, entropyInput, entropyInputLen);
+ fputs(buf2, rngresp);
+ fprintf(rngresp, ",%d,", entropyInputLen);
+ to_hex_str(buf2, nonce, nonceLen);
+ fputs(buf2, rngresp);
+ fprintf(rngresp, ",%d,", nonceLen);
+ to_hex_str(buf2, personalizationString,
+ personalizationStringLen);
+ fputs(buf2, rngresp);
+ fprintf(rngresp, ",%d)\n", personalizationStringLen);
+ }
+ rv = PRNGTEST_Instantiate(entropyInput, entropyInputLen,
+ nonce, nonceLen,
+ personalizationString,
+ personalizationStringLen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ break;
+
+ case GENERATE:
+ case RESULT:
+ memset(return_bytes, 0, return_bytes_len);
+ if (debug) {
+ fputs("# PRNGTEST_Generate(returnbytes", rngresp);
+ fprintf(rngresp, ",%d,", return_bytes_len);
+ to_hex_str(buf2, additionalInput, additionalInputLen);
+ fputs(buf2, rngresp);
+ fprintf(rngresp, ",%d)\n", additionalInputLen);
+ }
+ rv = PRNGTEST_Generate((PRUint8 *)return_bytes,
+ return_bytes_len,
+ (PRUint8 *)additionalInput,
+ additionalInputLen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ if (command == RESULT) {
+ fputs("ReturnedBits = ", rngresp);
+ to_hex_str(buf2, return_bytes, return_bytes_len);
+ fputs(buf2, rngresp);
+ fputc('\n', rngresp);
+ if (debug) {
+ fputs("# PRNGTEST_Uninstantiate()\n", rngresp);
+ }
+ rv = PRNGTEST_Uninstantiate();
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ } else if (debug) {
+ fputs("#ReturnedBits = ", rngresp);
+ to_hex_str(buf2, return_bytes, return_bytes_len);
+ fputs(buf2, rngresp);
+ fputc('\n', rngresp);
+ }
+
+ memset(additionalInput, 0, additionalInputLen);
+ break;
+
+ case RESEED:
+ if (entropyInput || additionalInput) {
+ if (debug) {
+ fputs("# PRNGTEST_Reseed(", rngresp);
+ fprintf(rngresp, ",%d,", return_bytes_len);
+ to_hex_str(buf2, entropyInput, entropyInputLen);
+ fputs(buf2, rngresp);
+ fprintf(rngresp, ",%d,", entropyInputLen);
+ to_hex_str(buf2, additionalInput, additionalInputLen);
+ fputs(buf2, rngresp);
+ fprintf(rngresp, ",%d)\n", additionalInputLen);
+ }
+ rv = PRNGTEST_Reseed(entropyInput, entropyInputLen,
+ additionalInput, additionalInputLen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ }
+ memset(entropyInput, 0, entropyInputLen);
+ memset(additionalInput, 0, additionalInputLen);
+ break;
+ case NONE:
+ break;
+ }
+ command = NONE;
+
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r') {
+ fputs(buf, rngresp);
+ continue;
+ }
+
+ /* [Hash - SHA256] */
+ if (strncmp(buf, "[SHA-256]", 9) == 0) {
+ fputs(buf, rngresp);
+ continue;
+ }
+
+ if (strncmp(buf, "[PredictionResistance", 21) == 0) {
+#ifdef HANDLE_PREDICTION_RESISTANCE
+ i = 21;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ if (strncmp(buf, "False", 5) == 0) {
+ predictionResistance = PR_FALSE;
+ } else {
+ predictionResistance = PR_TRUE;
+ }
+#endif
+
+ fputs(buf, rngresp);
+ continue;
+ }
+
+ if (strncmp(buf, "[ReturnedBitsLen", 16) == 0) {
+ if (return_bytes) {
+ PORT_ZFree(return_bytes, return_bytes_len);
+ return_bytes = NULL;
+ }
+ if (predictedreturn_bytes) {
+ PORT_ZFree(predictedreturn_bytes, return_bytes_len);
+ predictedreturn_bytes = NULL;
+ }
+ return_bytes_len = 0;
+ if (sscanf(buf, "[ReturnedBitsLen = %d]", &return_bytes_len) != 1) {
+ goto loser;
+ }
+ return_bytes_len = return_bytes_len / 8;
+ if (return_bytes_len > 0) {
+ return_bytes = PORT_Alloc(return_bytes_len);
+ predictedreturn_bytes = PORT_Alloc(return_bytes_len);
+ }
+ fputs(buf, rngresp);
+ continue;
+ }
+
+ if (strncmp(buf, "[EntropyInputLen", 16) == 0) {
+ if (entropyInput) {
+ PORT_ZFree(entropyInput, entropyInputLen);
+ entropyInput = NULL;
+ entropyInputLen = 0;
+ }
+ if (sscanf(buf, "[EntropyInputLen = %d]", &entropyInputLen) != 1) {
+ goto loser;
+ }
+ entropyInputLen = entropyInputLen / 8;
+ if (entropyInputLen > 0) {
+ entropyInput = PORT_Alloc(entropyInputLen);
+ }
+ fputs(buf, rngresp);
+ continue;
+ }
+
+ if (strncmp(buf, "[NonceLen", 9) == 0) {
+ if (nonce) {
+ PORT_ZFree(nonce, nonceLen);
+ nonce = NULL;
+ nonceLen = 0;
+ }
+
+ if (sscanf(buf, "[NonceLen = %d]", &nonceLen) != 1) {
+ goto loser;
+ }
+ nonceLen = nonceLen / 8;
+ if (nonceLen > 0) {
+ nonce = PORT_Alloc(nonceLen);
+ }
+ fputs(buf, rngresp);
+ continue;
+ }
+
+ if (strncmp(buf, "[PersonalizationStringLen", 16) == 0) {
+ if (personalizationString) {
+ PORT_ZFree(personalizationString, personalizationStringLen);
+ personalizationString = NULL;
+ personalizationStringLen = 0;
+ }
+
+ if (sscanf(buf, "[PersonalizationStringLen = %d]", &personalizationStringLen) != 1) {
+ goto loser;
+ }
+ personalizationStringLen = personalizationStringLen / 8;
+ if (personalizationStringLen > 0) {
+ personalizationString = PORT_Alloc(personalizationStringLen);
+ }
+ fputs(buf, rngresp);
+
+ continue;
+ }
+
+ if (strncmp(buf, "[AdditionalInputLen", 16) == 0) {
+ if (additionalInput) {
+ PORT_ZFree(additionalInput, additionalInputLen);
+ additionalInput = NULL;
+ additionalInputLen = 0;
+ }
+
+ if (sscanf(buf, "[AdditionalInputLen = %d]", &additionalInputLen) != 1) {
+ goto loser;
+ }
+ additionalInputLen = additionalInputLen / 8;
+ if (additionalInputLen > 0) {
+ additionalInput = PORT_Alloc(additionalInputLen);
+ }
+ fputs(buf, rngresp);
+ continue;
+ }
+
+ if (strncmp(buf, "COUNT", 5) == 0) {
+ /* zeroize the variables for the test with this data set */
+ if (entropyInput) {
+ memset(entropyInput, 0, entropyInputLen);
+ }
+ if (nonce) {
+ memset(nonce, 0, nonceLen);
+ }
+ if (personalizationString) {
+ memset(personalizationString, 0, personalizationStringLen);
+ }
+ if (additionalInput) {
+ memset(additionalInput, 0, additionalInputLen);
+ }
+ genResult = PR_FALSE;
+
+ fputs(buf, rngresp);
+ continue;
+ }
+
+ /* EntropyInputReseed = ... */
+ if (strncmp(buf, "EntropyInputReseed", 18) == 0) {
+ if (entropyInput) {
+ memset(entropyInput, 0, entropyInputLen);
+ i = 18;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) { /*j\n".
+ */
+ FILE *rngreq; /* input stream from the REQUEST file */
+ FILE *rngresp; /* output stream to the RESPONSE file */
+ unsigned int i, j;
+ unsigned char Q[DSA1_SUBPRIME_LEN];
+ PRBool hasQ = PR_FALSE;
+ unsigned int b = 0; /* 160 <= b <= 512, b is a multiple of 8 */
+ unsigned char XKey[512 / 8];
+ unsigned char XSeed[512 / 8];
+ unsigned char GENX[DSA1_SIGNATURE_LEN];
+ unsigned char DSAX[DSA1_SUBPRIME_LEN];
+ SECStatus rv;
+
+ rngreq = fopen(reqfn, "r");
+ rngresp = stdout;
+ while (fgets(buf, sizeof buf, rngreq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, rngresp);
+ continue;
+ }
+ /* [Xchange - SHA1] */
+ if (buf[0] == '[') {
+ fputs(buf, rngresp);
+ continue;
+ }
+ /* Q = ... */
+ if (buf[0] == 'Q') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < sizeof Q; i += 2, j++) {
+ hex_to_byteval(&buf[i], &Q[j]);
+ }
+ fputs(buf, rngresp);
+ hasQ = PR_TRUE;
+ continue;
+ }
+ /* "COUNT = x" begins a new data set */
+ if (strncmp(buf, "COUNT", 5) == 0) {
+ /* zeroize the variables for the test with this data set */
+ b = 0;
+ memset(XKey, 0, sizeof XKey);
+ memset(XSeed, 0, sizeof XSeed);
+ fputs(buf, rngresp);
+ continue;
+ }
+ /* b = ... */
+ if (buf[0] == 'b') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ b = atoi(&buf[i]);
+ if (b < 160 || b > 512 || b % 8 != 0) {
+ goto loser;
+ }
+ fputs(buf, rngresp);
+ continue;
+ }
+ /* XKey = ... */
+ if (strncmp(buf, "XKey", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < b / 8; i += 2, j++) {
+ hex_to_byteval(&buf[i], &XKey[j]);
+ }
+ fputs(buf, rngresp);
+ continue;
+ }
+ /* XSeed = ... */
+ if (strncmp(buf, "XSeed", 5) == 0) {
+ i = 5;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < b / 8; i += 2, j++) {
+ hex_to_byteval(&buf[i], &XSeed[j]);
+ }
+ fputs(buf, rngresp);
+
+ rv = FIPS186Change_GenerateX(XKey, XSeed, GENX);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ fputs("X = ", rngresp);
+ if (hasQ) {
+ rv = FIPS186Change_ReduceModQForDSA(GENX, Q, DSAX);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ to_hex_str(buf, DSAX, sizeof DSAX);
+ } else {
+ to_hex_str(buf, GENX, sizeof GENX);
+ }
+ fputs(buf, rngresp);
+ fputc('\n', rngresp);
+ continue;
+ }
+ }
+loser:
+ fclose(rngreq);
+}
+
+/*
+ * Perform the RNG Monte Carlo Test (MCT) for the RNG algorithm
+ * "DSA - Generation of X", used both as specified and as a generic
+ * purpose RNG. The presence of "Q = ..." in the REQUEST file
+ * indicates we are using the algorithm as specified.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+rng_mct(char *reqfn)
+{
+ char buf[256]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "XSeed = <128 hex digits>\n".
+ */
+ FILE *rngreq; /* input stream from the REQUEST file */
+ FILE *rngresp; /* output stream to the RESPONSE file */
+ unsigned int i, j;
+ unsigned char Q[DSA1_SUBPRIME_LEN];
+ PRBool hasQ = PR_FALSE;
+ unsigned int b = 0; /* 160 <= b <= 512, b is a multiple of 8 */
+ unsigned char XKey[512 / 8];
+ unsigned char XSeed[512 / 8];
+ unsigned char GENX[2 * SHA1_LENGTH];
+ unsigned char DSAX[DSA1_SUBPRIME_LEN];
+ SECStatus rv;
+
+ rngreq = fopen(reqfn, "r");
+ rngresp = stdout;
+ while (fgets(buf, sizeof buf, rngreq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, rngresp);
+ continue;
+ }
+ /* [Xchange - SHA1] */
+ if (buf[0] == '[') {
+ fputs(buf, rngresp);
+ continue;
+ }
+ /* Q = ... */
+ if (buf[0] == 'Q') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < sizeof Q; i += 2, j++) {
+ hex_to_byteval(&buf[i], &Q[j]);
+ }
+ fputs(buf, rngresp);
+ hasQ = PR_TRUE;
+ continue;
+ }
+ /* "COUNT = x" begins a new data set */
+ if (strncmp(buf, "COUNT", 5) == 0) {
+ /* zeroize the variables for the test with this data set */
+ b = 0;
+ memset(XKey, 0, sizeof XKey);
+ memset(XSeed, 0, sizeof XSeed);
+ fputs(buf, rngresp);
+ continue;
+ }
+ /* b = ... */
+ if (buf[0] == 'b') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ b = atoi(&buf[i]);
+ if (b < 160 || b > 512 || b % 8 != 0) {
+ goto loser;
+ }
+ fputs(buf, rngresp);
+ continue;
+ }
+ /* XKey = ... */
+ if (strncmp(buf, "XKey", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < b / 8; i += 2, j++) {
+ hex_to_byteval(&buf[i], &XKey[j]);
+ }
+ fputs(buf, rngresp);
+ continue;
+ }
+ /* XSeed = ... */
+ if (strncmp(buf, "XSeed", 5) == 0) {
+ unsigned int k;
+ i = 5;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < b / 8; i += 2, j++) {
+ hex_to_byteval(&buf[i], &XSeed[j]);
+ }
+ fputs(buf, rngresp);
+
+ for (k = 0; k < 10000; k++) {
+ rv = FIPS186Change_GenerateX(XKey, XSeed, GENX);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ }
+ fputs("X = ", rngresp);
+ if (hasQ) {
+ rv = FIPS186Change_ReduceModQForDSA(GENX, Q, DSAX);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ to_hex_str(buf, DSAX, sizeof DSAX);
+ } else {
+ to_hex_str(buf, GENX, sizeof GENX);
+ }
+ fputs(buf, rngresp);
+ fputc('\n', rngresp);
+ continue;
+ }
+ }
+loser:
+ fclose(rngreq);
+}
+
+/*
+ * Calculate the SHA Message Digest
+ *
+ * MD = Message digest
+ * MDLen = length of Message Digest and SHA_Type
+ * msg = message to digest
+ * msgLen = length of message to digest
+ */
+SECStatus
+sha_calcMD(unsigned char *MD, unsigned int MDLen, unsigned char *msg, unsigned int msgLen)
+{
+ HASH_HashType hashType = sha_get_hashType(MDLen * PR_BITS_PER_BYTE);
+
+ return fips_hashBuf(hashType, MD, msg, msgLen);
+}
+
+/*
+ * Perform the SHA Monte Carlo Test
+ *
+ * MDLen = length of Message Digest and SHA_Type
+ * seed = input seed value
+ * resp = is the output response file.
+ */
+SECStatus
+sha_mct_test(unsigned int MDLen, unsigned char *seed, FILE *resp)
+{
+ int i, j;
+ unsigned int msgLen = MDLen * 3;
+ unsigned char MD_i3[HASH_LENGTH_MAX]; /* MD[i-3] */
+ unsigned char MD_i2[HASH_LENGTH_MAX]; /* MD[i-2] */
+ unsigned char MD_i1[HASH_LENGTH_MAX]; /* MD[i-1] */
+ unsigned char MD_i[HASH_LENGTH_MAX]; /* MD[i] */
+ unsigned char msg[HASH_LENGTH_MAX * 3];
+ char buf[HASH_LENGTH_MAX * 2 + 1]; /* MAX buf MD_i as a hex string */
+
+ for (j = 0; j < 100; j++) {
+ /* MD_0 = MD_1 = MD_2 = seed */
+ memcpy(MD_i3, seed, MDLen);
+ memcpy(MD_i2, seed, MDLen);
+ memcpy(MD_i1, seed, MDLen);
+
+ for (i = 3; i < 1003; i++) {
+ /* Mi = MD[i-3] || MD [i-2] || MD [i-1] */
+ memcpy(msg, MD_i3, MDLen);
+ memcpy(&msg[MDLen], MD_i2, MDLen);
+ memcpy(&msg[MDLen * 2], MD_i1, MDLen);
+
+ /* MDi = SHA(Msg) */
+ if (sha_calcMD(MD_i, MDLen,
+ msg, msgLen) != SECSuccess) {
+ return SECFailure;
+ }
+
+ /* save MD[i-3] MD[i-2] MD[i-1] */
+ memcpy(MD_i3, MD_i2, MDLen);
+ memcpy(MD_i2, MD_i1, MDLen);
+ memcpy(MD_i1, MD_i, MDLen);
+ }
+
+ /* seed = MD_i */
+ memcpy(seed, MD_i, MDLen);
+
+ sprintf(buf, "COUNT = %d\n", j);
+ fputs(buf, resp);
+
+ /* output MD_i */
+ fputs("MD = ", resp);
+ to_hex_str(buf, MD_i, MDLen);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ }
+
+ return SECSuccess;
+}
+
+/*
+ * Perform the SHA Tests.
+ *
+ * reqfn is the pathname of the input REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+sha_test(char *reqfn)
+{
+ unsigned int i, j;
+ unsigned int MDlen = 0; /* the length of the Message Digest in Bytes */
+ unsigned int msgLen = 0; /* the length of the input Message in Bytes */
+ unsigned char *msg = NULL; /* holds the message to digest.*/
+ size_t bufSize = 256 * 128; /*MAX buffer size */
+ char *buf = NULL; /* holds one line from the input REQUEST file.*/
+ unsigned char seed[HASH_LENGTH_MAX]; /* max size of seed 64 bytes */
+ unsigned char MD[HASH_LENGTH_MAX]; /* message digest */
+
+ FILE *req = NULL; /* input stream from the REQUEST file */
+ FILE *resp; /* output stream to the RESPONSE file */
+
+ buf = PORT_ZAlloc(bufSize);
+ if (buf == NULL) {
+ goto loser;
+ }
+
+ /* zeroize the variables for the test with this data set */
+ memset(seed, 0, sizeof seed);
+
+ req = fopen(reqfn, "r");
+ resp = stdout;
+ while (fgets(buf, bufSize, req) != NULL) {
+
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, resp);
+ continue;
+ }
+ /* [L = Length of the Message Digest and sha_type */
+ if (buf[0] == '[') {
+ if (strncmp(&buf[1], "L ", 1) == 0) {
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ MDlen = atoi(&buf[i]);
+ fputs(buf, resp);
+ continue;
+ }
+ }
+ /* Len = Length of the Input Message Length ... */
+ if (strncmp(buf, "Len", 3) == 0) {
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ if (msg) {
+ PORT_ZFree(msg, msgLen);
+ msg = NULL;
+ }
+ msgLen = atoi(&buf[i]); /* in bits */
+ if (msgLen % 8 != 0) {
+ fprintf(stderr, "SHA tests are incorrectly configured for "
+ "BIT oriented implementations\n");
+ goto loser;
+ }
+ msgLen = msgLen / 8; /* convert to bytes */
+ fputs(buf, resp);
+ msg = PORT_ZAlloc(msgLen);
+ if (msg == NULL && msgLen != 0) {
+ goto loser;
+ }
+ continue;
+ }
+ /* MSG = ... */
+ if (strncmp(buf, "Msg", 3) == 0) {
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < msgLen; i += 2, j++) {
+ hex_to_byteval(&buf[i], &msg[j]);
+ }
+ fputs(buf, resp);
+ /* calculate the Message Digest */
+ memset(MD, 0, sizeof MD);
+ if (sha_calcMD(MD, MDlen,
+ msg, msgLen) != SECSuccess) {
+ goto loser;
+ }
+
+ fputs("MD = ", resp);
+ to_hex_str(buf, MD, MDlen);
+ fputs(buf, resp);
+ fputc('\n', resp);
+
+ continue;
+ }
+ /* Seed = ... */
+ if (strncmp(buf, "Seed", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < sizeof seed; i += 2, j++) {
+ hex_to_byteval(&buf[i], &seed[j]);
+ }
+
+ fputs(buf, resp);
+ fputc('\n', resp);
+
+ /* do the Monte Carlo test */
+ if (sha_mct_test(MDlen, seed, resp) != SECSuccess) {
+ goto loser;
+ }
+
+ continue;
+ }
+ }
+loser:
+ if (req) {
+ fclose(req);
+ }
+ if (buf) {
+ PORT_ZFree(buf, bufSize);
+ }
+ if (msg) {
+ PORT_ZFree(msg, msgLen);
+ }
+}
+
+/****************************************************/
+/* HMAC SHA-X calc */
+/* hmac_computed - the computed HMAC */
+/* hmac_length - the length of the computed HMAC */
+/* secret_key - secret key to HMAC */
+/* secret_key_length - length of secret key, */
+/* message - message to HMAC */
+/* message_length - length ofthe message */
+/****************************************************/
+static SECStatus
+hmac_calc(unsigned char *hmac_computed,
+ const unsigned int hmac_length,
+ const unsigned char *secret_key,
+ const unsigned int secret_key_length,
+ const unsigned char *message,
+ const unsigned int message_length,
+ const HASH_HashType hashAlg)
+{
+ SECStatus hmac_status = SECFailure;
+ HMACContext *cx = NULL;
+ SECHashObject *hashObj = NULL;
+ unsigned int bytes_hashed = 0;
+
+ hashObj = (SECHashObject *)HASH_GetRawHashObject(hashAlg);
+
+ if (!hashObj)
+ return (SECFailure);
+
+ cx = HMAC_Create(hashObj, secret_key,
+ secret_key_length,
+ PR_TRUE); /* PR_TRUE for in FIPS mode */
+
+ if (cx == NULL)
+ return (SECFailure);
+
+ HMAC_Begin(cx);
+ HMAC_Update(cx, message, message_length);
+ hmac_status = HMAC_Finish(cx, hmac_computed, &bytes_hashed,
+ hmac_length);
+
+ HMAC_Destroy(cx, PR_TRUE);
+
+ return (hmac_status);
+}
+
+/*
+ * Perform the HMAC Tests.
+ *
+ * reqfn is the pathname of the input REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+hmac_test(char *reqfn)
+{
+ unsigned int i, j;
+ size_t bufSize = 400; /* MAX buffer size */
+ char *buf = NULL; /* holds one line from the input REQUEST file.*/
+ unsigned int keyLen = 0; /* Key Length */
+ unsigned char key[200]; /* key MAX size = 184 */
+ unsigned int msgLen = 128; /* the length of the input */
+ /* Message is always 128 Bytes */
+ unsigned char *msg = NULL; /* holds the message to digest.*/
+ unsigned int HMACLen = 0; /* the length of the HMAC Bytes */
+ unsigned int TLen = 0; /* the length of the requested */
+ /* truncated HMAC Bytes */
+ unsigned char HMAC[HASH_LENGTH_MAX]; /* computed HMAC */
+ unsigned char expectedHMAC[HASH_LENGTH_MAX]; /* for .fax files that have */
+ /* supplied known answer */
+ HASH_HashType hash_alg = HASH_AlgNULL; /* HMAC type */
+
+ FILE *req = NULL; /* input stream from the REQUEST file */
+ FILE *resp; /* output stream to the RESPONSE file */
+
+ buf = PORT_ZAlloc(bufSize);
+ if (buf == NULL) {
+ goto loser;
+ }
+ msg = PORT_ZAlloc(msgLen);
+ if (msg == NULL) {
+ goto loser;
+ }
+
+ req = fopen(reqfn, "r");
+ resp = stdout;
+ while (fgets(buf, bufSize, req) != NULL) {
+ if (strncmp(buf, "Mac", 3) == 0) {
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ memset(expectedHMAC, 0, HASH_LENGTH_MAX);
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &expectedHMAC[j]);
+ }
+ if (memcmp(HMAC, expectedHMAC, TLen) != 0) {
+ fprintf(stderr, "Generate failed:\n");
+ fputs(" expected=", stderr);
+ to_hex_str(buf, expectedHMAC,
+ TLen);
+ fputs(buf, stderr);
+ fputs("\n generated=", stderr);
+ to_hex_str(buf, HMAC,
+ TLen);
+ fputs(buf, stderr);
+ fputc('\n', stderr);
+ }
+ }
+
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, resp);
+ continue;
+ }
+ /* [L = Length of the MAC and HASH_type */
+ if (buf[0] == '[') {
+ if (strncmp(&buf[1], "L ", 1) == 0) {
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ /* HMACLen will get reused for Tlen */
+ HMACLen = atoi(&buf[i]);
+ hash_alg = sha_get_hashType(HMACLen * PR_BITS_PER_BYTE);
+ if (hash_alg == HASH_AlgNULL) {
+ goto loser;
+ }
+ fputs(buf, resp);
+ continue;
+ }
+ }
+ /* Count = test iteration number*/
+ if (strncmp(buf, "Count ", 5) == 0) {
+ /* count can just be put into resp file */
+ fputs(buf, resp);
+ /* zeroize the variables for the test with this data set */
+ keyLen = 0;
+ TLen = 0;
+ memset(key, 0, sizeof key);
+ memset(msg, 0, msgLen);
+ memset(HMAC, 0, sizeof HMAC);
+ continue;
+ }
+ /* KLen = Length of the Input Secret Key ... */
+ if (strncmp(buf, "Klen", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ keyLen = atoi(&buf[i]); /* in bytes */
+ fputs(buf, resp);
+ continue;
+ }
+ /* key = the secret key for the key to MAC */
+ if (strncmp(buf, "Key", 3) == 0) {
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < keyLen; i += 2, j++) {
+ hex_to_byteval(&buf[i], &key[j]);
+ }
+ fputs(buf, resp);
+ }
+ /* TLen = Length of the calculated HMAC */
+ if (strncmp(buf, "Tlen", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ TLen = atoi(&buf[i]); /* in bytes */
+ fputs(buf, resp);
+ continue;
+ }
+ /* MSG = to HMAC always 128 bytes for these tests */
+ if (strncmp(buf, "Msg", 3) == 0) {
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < msgLen; i += 2, j++) {
+ hex_to_byteval(&buf[i], &msg[j]);
+ }
+ fputs(buf, resp);
+ /* calculate the HMAC and output */
+ if (hmac_calc(HMAC, HMACLen, key, keyLen,
+ msg, msgLen, hash_alg) != SECSuccess) {
+ goto loser;
+ }
+ fputs("Mac = ", resp);
+ to_hex_str(buf, HMAC, TLen);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ continue;
+ }
+ }
+loser:
+ if (req) {
+ fclose(req);
+ }
+ if (buf) {
+ PORT_ZFree(buf, bufSize);
+ }
+ if (msg) {
+ PORT_ZFree(msg, msgLen);
+ }
+}
+
+/*
+ * Perform the DSA Key Pair Generation Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+dsa_keypair_test(char *reqfn)
+{
+ char buf[800]; /* holds one line from the input REQUEST file
+ * or to the output RESPONSE file.
+ * 800 to hold (384 public key (x2 for HEX) + 1'\n'
+ */
+ FILE *dsareq; /* input stream from the REQUEST file */
+ FILE *dsaresp; /* output stream to the RESPONSE file */
+ int count;
+ int N;
+ int L;
+ int i;
+ PQGParams *pqg = NULL;
+ PQGVerify *vfy = NULL;
+ PRBool use_dsa1 = PR_FALSE;
+ int keySizeIndex; /* index for valid key sizes */
+
+ dsareq = fopen(reqfn, "r");
+ dsaresp = stdout;
+ while (fgets(buf, sizeof buf, dsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* [Mod = x] */
+ if (buf[0] == '[') {
+ if (pqg != NULL) {
+ PQG_DestroyParams(pqg);
+ pqg = NULL;
+ }
+ if (vfy != NULL) {
+ PQG_DestroyVerify(vfy);
+ vfy = NULL;
+ }
+
+ if (sscanf(buf, "[mod = L=%d, N=%d]", &L, &N) != 2) {
+ use_dsa1 = PR_TRUE;
+ if (sscanf(buf, "[mod = %d]", &L) != 1) {
+ goto loser;
+ }
+ }
+ fputs(buf, dsaresp);
+ fputc('\n', dsaresp);
+
+ if (use_dsa1) {
+ /*************************************************************
+ * PQG_ParamGenSeedLen doesn't take a key size, it takes an
+ * index that points to a valid key size.
+ */
+ keySizeIndex = PQG_PBITS_TO_INDEX(L);
+ if (keySizeIndex == -1 || L < 512 || L > 1024) {
+ fprintf(dsaresp,
+ "DSA key size must be a multiple of 64 between 512 "
+ "and 1024, inclusive");
+ goto loser;
+ }
+
+ /* Generate the parameters P, Q, and G */
+ if (PQG_ParamGenSeedLen(keySizeIndex, PQG_TEST_SEED_BYTES,
+ &pqg, &vfy) !=
+ SECSuccess) {
+ fprintf(dsaresp,
+ "ERROR: Unable to generate PQG parameters");
+ goto loser;
+ }
+ } else {
+ if (PQG_ParamGenV2(L, N, N, &pqg, &vfy) != SECSuccess) {
+ fprintf(dsaresp,
+ "ERROR: Unable to generate PQG parameters");
+ goto loser;
+ }
+ }
+
+ /* output P, Q, and G */
+ to_hex_str(buf, pqg->prime.data, pqg->prime.len);
+ fprintf(dsaresp, "P = %s\n", buf);
+ to_hex_str(buf, pqg->subPrime.data, pqg->subPrime.len);
+ fprintf(dsaresp, "Q = %s\n", buf);
+ to_hex_str(buf, pqg->base.data, pqg->base.len);
+ fprintf(dsaresp, "G = %s\n\n", buf);
+ continue;
+ }
+ /* N = ...*/
+ if (buf[0] == 'N') {
+
+ if (sscanf(buf, "N = %d", &count) != 1) {
+ goto loser;
+ }
+ /* Generate a DSA key, and output the key pair for N times */
+ for (i = 0; i < count; i++) {
+ DSAPrivateKey *dsakey = NULL;
+ if (DSA_NewKey(pqg, &dsakey) != SECSuccess) {
+ fprintf(dsaresp, "ERROR: Unable to generate DSA key");
+ goto loser;
+ }
+ to_hex_str(buf, dsakey->privateValue.data,
+ dsakey->privateValue.len);
+ fprintf(dsaresp, "X = %s\n", buf);
+ to_hex_str(buf, dsakey->publicValue.data,
+ dsakey->publicValue.len);
+ fprintf(dsaresp, "Y = %s\n\n", buf);
+ PORT_FreeArena(dsakey->params.arena, PR_TRUE);
+ dsakey = NULL;
+ }
+ continue;
+ }
+ }
+loser:
+ fclose(dsareq);
+}
+
+/*
+ * pqg generation type
+ */
+typedef enum {
+ FIPS186_1, /* Generate/Verify P,Q & G according to FIPS 186-1 */
+ A_1_2_1, /* Generate Provable P & Q */
+ A_1_1_3, /* Verify Probable P & Q */
+ A_1_2_2, /* Verify Provable P & Q */
+ A_2_1, /* Generate Unverifiable G */
+ A_2_2, /* Assure Unverifiable G */
+ A_2_3, /* Generate Verifiable G */
+ A_2_4 /* Verify Verifiable G */
+} dsa_pqg_type;
+
+/*
+ * Perform the DSA Domain Parameter Validation Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+dsa_pqgver_test(char *reqfn)
+{
+ char buf[800]; /* holds one line from the input REQUEST file
+ * or to the output RESPONSE file.
+ * 800 to hold (384 public key (x2 for HEX) + P = ...
+ */
+ FILE *dsareq; /* input stream from the REQUEST file */
+ FILE *dsaresp; /* output stream to the RESPONSE file */
+ int N;
+ int L;
+ unsigned int i, j;
+ PQGParams pqg;
+ PQGVerify vfy;
+ unsigned int pghSize = 0; /* size for p, g, and h */
+ dsa_pqg_type type = FIPS186_1;
+
+ dsareq = fopen(reqfn, "r");
+ dsaresp = stdout;
+ memset(&pqg, 0, sizeof(pqg));
+ memset(&vfy, 0, sizeof(vfy));
+
+ while (fgets(buf, sizeof buf, dsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* [A.xxxxx ] */
+ if (buf[0] == '[' && buf[1] == 'A') {
+
+ if (strncmp(&buf[1], "A.1.1.3", 7) == 0) {
+ type = A_1_1_3;
+ } else if (strncmp(&buf[1], "A.2.2", 5) == 0) {
+ type = A_2_2;
+ } else if (strncmp(&buf[1], "A.2.4", 5) == 0) {
+ type = A_2_4;
+ } else if (strncmp(&buf[1], "A.1.2.2", 7) == 0) {
+ type = A_1_2_2;
+ /* validate our output from PQGGEN */
+ } else if (strncmp(&buf[1], "A.1.1.2", 7) == 0) {
+ type = A_2_4; /* validate PQ and G together */
+ } else {
+ fprintf(stderr, "Unknown dsa ver test %s\n", &buf[1]);
+ exit(1);
+ }
+
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* [Mod = x] */
+ if (buf[0] == '[') {
+
+ if (type == FIPS186_1) {
+ N = 160;
+ if (sscanf(buf, "[mod = %d]", &L) != 1) {
+ goto loser;
+ }
+ } else if (sscanf(buf, "[mod = L=%d, N=%d", &L, &N) != 2) {
+ goto loser;
+ }
+
+ if (pqg.prime.data) { /* P */
+ SECITEM_ZfreeItem(&pqg.prime, PR_FALSE);
+ }
+ if (pqg.subPrime.data) { /* Q */
+ SECITEM_ZfreeItem(&pqg.subPrime, PR_FALSE);
+ }
+ if (pqg.base.data) { /* G */
+ SECITEM_ZfreeItem(&pqg.base, PR_FALSE);
+ }
+ if (vfy.seed.data) { /* seed */
+ SECITEM_ZfreeItem(&vfy.seed, PR_FALSE);
+ }
+ if (vfy.h.data) { /* H */
+ SECITEM_ZfreeItem(&vfy.h, PR_FALSE);
+ }
+
+ fputs(buf, dsaresp);
+
+ /*calculate the size of p, g, and h then allocate items */
+ pghSize = L / 8;
+
+ pqg.base.data = vfy.h.data = NULL;
+ vfy.seed.len = pqg.base.len = vfy.h.len = 0;
+ SECITEM_AllocItem(NULL, &pqg.prime, pghSize);
+ SECITEM_AllocItem(NULL, &vfy.seed, pghSize * 3);
+ if (type == A_2_2) {
+ SECITEM_AllocItem(NULL, &vfy.h, pghSize);
+ vfy.h.len = pghSize;
+ } else if (type == A_2_4) {
+ SECITEM_AllocItem(NULL, &vfy.h, 1);
+ vfy.h.len = 1;
+ }
+ pqg.prime.len = pghSize;
+ /* q is always N bits */
+ SECITEM_AllocItem(NULL, &pqg.subPrime, N / 8);
+ pqg.subPrime.len = N / 8;
+ vfy.counter = -1;
+
+ continue;
+ }
+ /* P = ... */
+ if (buf[0] == 'P') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < pqg.prime.len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &pqg.prime.data[j]);
+ }
+
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* Q = ... */
+ if (buf[0] == 'Q') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < pqg.subPrime.len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &pqg.subPrime.data[j]);
+ }
+
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* G = ... */
+ if (buf[0] == 'G') {
+ i = 1;
+ if (pqg.base.data) {
+ SECITEM_ZfreeItem(&pqg.base, PR_FALSE);
+ }
+ SECITEM_AllocItem(NULL, &pqg.base, pghSize);
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < pqg.base.len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &pqg.base.data[j]);
+ }
+
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* Seed = ... or domain_parameter_seed = ... */
+ if (strncmp(buf, "Seed", 4) == 0) {
+ i = 4;
+ } else if (strncmp(buf, "domain_parameter_seed", 21) == 0) {
+ i = 21;
+ } else if (strncmp(buf, "firstseed", 9) == 0) {
+ i = 9;
+ } else {
+ i = 0;
+ }
+ if (i) {
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &vfy.seed.data[j]);
+ }
+ vfy.seed.len = j;
+
+ fputs(buf, dsaresp);
+ if (type == A_2_4) {
+ SECStatus result;
+
+ /* Verify the Parameters */
+ SECStatus rv = PQG_VerifyParams(&pqg, &vfy, &result);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (result == SECSuccess) {
+ fprintf(dsaresp, "Result = P\n");
+ } else {
+ fprintf(dsaresp, "Result = F\n");
+ }
+ }
+ continue;
+ }
+ if ((strncmp(buf, "pseed", 5) == 0) ||
+ (strncmp(buf, "qseed", 5) == 0)) {
+ i = 5;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = vfy.seed.len; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &vfy.seed.data[j]);
+ }
+ vfy.seed.len = j;
+ fputs(buf, dsaresp);
+
+ continue;
+ }
+ if (strncmp(buf, "index", 4) == 0) {
+ i = 5;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ hex_to_byteval(&buf[i], &vfy.h.data[0]);
+ vfy.h.len = 1;
+ fputs(buf, dsaresp);
+ }
+
+ /* c = ... or counter=*/
+ if (buf[0] == 'c') {
+ if (strncmp(buf, "counter", 7) == 0) {
+ if (sscanf(buf, "counter = %u", &vfy.counter) != 1) {
+ goto loser;
+ }
+ } else {
+ if (sscanf(buf, "c = %u", &vfy.counter) != 1) {
+ goto loser;
+ }
+ }
+
+ fputs(buf, dsaresp);
+ if (type == A_1_1_3) {
+ SECStatus result;
+ /* only verify P and Q, we have everything now. do it */
+ SECStatus rv = PQG_VerifyParams(&pqg, &vfy, &result);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (result == SECSuccess) {
+ fprintf(dsaresp, "Result = P\n");
+ } else {
+ fprintf(dsaresp, "Result = F\n");
+ }
+ fprintf(dsaresp, "\n");
+ }
+ continue;
+ }
+ if (strncmp(buf, "pgen_counter", 12) == 0) {
+ if (sscanf(buf, "pgen_counter = %u", &vfy.counter) != 1) {
+ goto loser;
+ }
+ fputs(buf, dsaresp);
+ continue;
+ }
+ if (strncmp(buf, "qgen_counter", 12) == 0) {
+ fputs(buf, dsaresp);
+ if (type == A_1_2_2) {
+ SECStatus result;
+ /* only verify P and Q, we have everything now. do it */
+ SECStatus rv = PQG_VerifyParams(&pqg, &vfy, &result);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (result == SECSuccess) {
+ fprintf(dsaresp, "Result = P\n");
+ } else {
+ fprintf(dsaresp, "Result = F\n");
+ }
+ fprintf(dsaresp, "\n");
+ }
+ continue;
+ }
+ /* H = ... */
+ if (buf[0] == 'H') {
+ SECStatus rv, result = SECFailure;
+
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &vfy.h.data[j]);
+ }
+ vfy.h.len = j;
+ fputs(buf, dsaresp);
+
+ /* this should be a byte value. Remove the leading zeros. If
+ * it doesn't reduce to a byte, PQG_VerifyParams will catch it
+ if (type == A_2_2) {
+ data_save = vfy.h.data;
+ while(vfy.h.data[0] && (vfy.h.len > 1)) {
+ vfy.h.data++;
+ vfy.h.len--;
+ }
+ } */
+
+ /* Verify the Parameters */
+ rv = PQG_VerifyParams(&pqg, &vfy, &result);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (result == SECSuccess) {
+ fprintf(dsaresp, "Result = P\n");
+ } else {
+ fprintf(dsaresp, "Result = F\n");
+ }
+ fprintf(dsaresp, "\n");
+ continue;
+ }
+ }
+loser:
+ fclose(dsareq);
+ if (pqg.prime.data) { /* P */
+ SECITEM_ZfreeItem(&pqg.prime, PR_FALSE);
+ }
+ if (pqg.subPrime.data) { /* Q */
+ SECITEM_ZfreeItem(&pqg.subPrime, PR_FALSE);
+ }
+ if (pqg.base.data) { /* G */
+ SECITEM_ZfreeItem(&pqg.base, PR_FALSE);
+ }
+ if (vfy.seed.data) { /* seed */
+ SECITEM_ZfreeItem(&vfy.seed, PR_FALSE);
+ }
+ if (vfy.h.data) { /* H */
+ SECITEM_ZfreeItem(&vfy.h, PR_FALSE);
+ }
+}
+
+/*
+ * Perform the DSA Public Key Validation Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+dsa_pqggen_test(char *reqfn)
+{
+ char buf[800]; /* holds one line from the input REQUEST file
+ * or to the output RESPONSE file.
+ * 800 to hold seed = (384 public key (x2 for HEX)
+ */
+ FILE *dsareq; /* input stream from the REQUEST file */
+ FILE *dsaresp; /* output stream to the RESPONSE file */
+ int count; /* number of times to generate parameters */
+ int N;
+ int L;
+ int i;
+ unsigned int j;
+ int output_g = 1;
+ PQGParams *pqg = NULL;
+ PQGVerify *vfy = NULL;
+ unsigned int keySizeIndex = 0;
+ dsa_pqg_type type = FIPS186_1;
+
+ dsareq = fopen(reqfn, "r");
+ dsaresp = stdout;
+ while (fgets(buf, sizeof buf, dsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* [A.xxxxx ] */
+ if (buf[0] == '[' && buf[1] == 'A') {
+ if (strncmp(&buf[1], "A.1.1.2", 7) == 0) {
+ fprintf(stderr, "NSS does Generate Probablistic Primes\n");
+ exit(1);
+ } else if (strncmp(&buf[1], "A.2.1", 5) == 0) {
+ type = A_1_2_1;
+ output_g = 1;
+ exit(1);
+ } else if (strncmp(&buf[1], "A.2.3", 5) == 0) {
+ fprintf(stderr, "NSS only Generates G with P&Q\n");
+ exit(1);
+ } else if (strncmp(&buf[1], "A.1.2.1", 7) == 0) {
+ type = A_1_2_1;
+ output_g = 0;
+ } else {
+ fprintf(stderr, "Unknown dsa pqggen test %s\n", &buf[1]);
+ exit(1);
+ }
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* [Mod = ... ] */
+ if (buf[0] == '[') {
+
+ if (type == FIPS186_1) {
+ N = 160;
+ if (sscanf(buf, "[mod = %d]", &L) != 1) {
+ goto loser;
+ }
+ } else if (sscanf(buf, "[mod = L=%d, N=%d", &L, &N) != 2) {
+ goto loser;
+ }
+
+ fputs(buf, dsaresp);
+ fputc('\n', dsaresp);
+
+ if (type == FIPS186_1) {
+ /************************************************************
+ * PQG_ParamGenSeedLen doesn't take a key size, it takes an
+ * index that points to a valid key size.
+ */
+ keySizeIndex = PQG_PBITS_TO_INDEX(L);
+ if (keySizeIndex == -1 || L < 512 || L > 1024) {
+ fprintf(dsaresp,
+ "DSA key size must be a multiple of 64 between 512 "
+ "and 1024, inclusive");
+ goto loser;
+ }
+ }
+ continue;
+ }
+ /* N = ... */
+ if (buf[0] == 'N') {
+ if (strncmp(buf, "Num", 3) == 0) {
+ if (sscanf(buf, "Num = %d", &count) != 1) {
+ goto loser;
+ }
+ } else if (sscanf(buf, "N = %d", &count) != 1) {
+ goto loser;
+ }
+ for (i = 0; i < count; i++) {
+ SECStatus rv;
+
+ if (type == FIPS186_1) {
+ rv = PQG_ParamGenSeedLen(keySizeIndex, PQG_TEST_SEED_BYTES,
+ &pqg, &vfy);
+ } else {
+ rv = PQG_ParamGenV2(L, N, N, &pqg, &vfy);
+ }
+ if (rv != SECSuccess) {
+ fprintf(dsaresp,
+ "ERROR: Unable to generate PQG parameters");
+ goto loser;
+ }
+ to_hex_str(buf, pqg->prime.data, pqg->prime.len);
+ fprintf(dsaresp, "P = %s\n", buf);
+ to_hex_str(buf, pqg->subPrime.data, pqg->subPrime.len);
+ fprintf(dsaresp, "Q = %s\n", buf);
+ if (output_g) {
+ to_hex_str(buf, pqg->base.data, pqg->base.len);
+ fprintf(dsaresp, "G = %s\n", buf);
+ }
+ if (type == FIPS186_1) {
+ to_hex_str(buf, vfy->seed.data, vfy->seed.len);
+ fprintf(dsaresp, "Seed = %s\n", buf);
+ fprintf(dsaresp, "c = %d\n", vfy->counter);
+ to_hex_str(buf, vfy->h.data, vfy->h.len);
+ fputs("H = ", dsaresp);
+ for (j = vfy->h.len; j < pqg->prime.len; j++) {
+ fprintf(dsaresp, "00");
+ }
+ fprintf(dsaresp, "%s\n", buf);
+ } else {
+ unsigned int seedlen = vfy->seed.len / 2;
+ unsigned int pgen_counter = vfy->counter >> 16;
+ unsigned int qgen_counter = vfy->counter & 0xffff;
+ /*fprintf(dsaresp, "index = %02x\n", vfy->h.data[0]); */
+ to_hex_str(buf, vfy->seed.data, seedlen);
+ fprintf(dsaresp, "pseed = %s\n", buf);
+ to_hex_str(buf, vfy->seed.data + seedlen, seedlen);
+ fprintf(dsaresp, "qseed = %s\n", buf);
+ fprintf(dsaresp, "pgen_counter = %d\n", pgen_counter);
+ fprintf(dsaresp, "qgen_counter = %d\n", qgen_counter);
+ if (output_g) {
+ to_hex_str(buf, vfy->seed.data, vfy->seed.len);
+ fprintf(dsaresp, "domain_parameter_seed = %s\n", buf);
+ fprintf(dsaresp, "index = %02x\n", vfy->h.data[0]);
+ }
+ }
+ fputc('\n', dsaresp);
+ if (pqg != NULL) {
+ PQG_DestroyParams(pqg);
+ pqg = NULL;
+ }
+ if (vfy != NULL) {
+ PQG_DestroyVerify(vfy);
+ vfy = NULL;
+ }
+ }
+
+ continue;
+ }
+ }
+loser:
+ fclose(dsareq);
+ if (pqg != NULL) {
+ PQG_DestroyParams(pqg);
+ }
+ if (vfy != NULL) {
+ PQG_DestroyVerify(vfy);
+ }
+}
+
+/*
+ * Perform the DSA Signature Generation Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+dsa_siggen_test(char *reqfn)
+{
+ char buf[800]; /* holds one line from the input REQUEST file
+ * or to the output RESPONSE file.
+ * max for Msg = ....
+ */
+ FILE *dsareq; /* input stream from the REQUEST file */
+ FILE *dsaresp; /* output stream to the RESPONSE file */
+ int modulus;
+ int L;
+ int N;
+ int i, j;
+ PRBool use_dsa1 = PR_FALSE;
+ PQGParams *pqg = NULL;
+ PQGVerify *vfy = NULL;
+ DSAPrivateKey *dsakey = NULL;
+ int keySizeIndex; /* index for valid key sizes */
+ unsigned char hashBuf[HASH_LENGTH_MAX]; /* SHA-x hash (160-512 bits) */
+ unsigned char sig[DSA_MAX_SIGNATURE_LEN];
+ SECItem digest, signature;
+ HASH_HashType hashType = HASH_AlgNULL;
+ int hashNum = 0;
+
+ dsareq = fopen(reqfn, "r");
+ dsaresp = stdout;
+
+ while (fgets(buf, sizeof buf, dsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* [Mod = x] */
+ if (buf[0] == '[') {
+ if (pqg != NULL) {
+ PQG_DestroyParams(pqg);
+ pqg = NULL;
+ }
+ if (vfy != NULL) {
+ PQG_DestroyVerify(vfy);
+ vfy = NULL;
+ }
+ if (dsakey != NULL) {
+ PORT_FreeArena(dsakey->params.arena, PR_TRUE);
+ dsakey = NULL;
+ }
+
+ if (sscanf(buf, "[mod = L=%d, N=%d, SHA-%d]", &L, &N,
+ &hashNum) != 3) {
+ use_dsa1 = PR_TRUE;
+ hashNum = 1;
+ if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
+ goto loser;
+ }
+ }
+ fputs(buf, dsaresp);
+ fputc('\n', dsaresp);
+
+ /****************************************************************
+ * PQG_ParamGenSeedLen doesn't take a key size, it takes an index
+ * that points to a valid key size.
+ */
+ if (use_dsa1) {
+ keySizeIndex = PQG_PBITS_TO_INDEX(modulus);
+ if (keySizeIndex == -1 || modulus < 512 || modulus > 1024) {
+ fprintf(dsaresp,
+ "DSA key size must be a multiple of 64 between 512 "
+ "and 1024, inclusive");
+ goto loser;
+ }
+ /* Generate PQG and output PQG */
+ if (PQG_ParamGenSeedLen(keySizeIndex, PQG_TEST_SEED_BYTES,
+ &pqg, &vfy) !=
+ SECSuccess) {
+ fprintf(dsaresp,
+ "ERROR: Unable to generate PQG parameters");
+ goto loser;
+ }
+ } else {
+ if (PQG_ParamGenV2(L, N, N, &pqg, &vfy) != SECSuccess) {
+ fprintf(dsaresp,
+ "ERROR: Unable to generate PQG parameters");
+ goto loser;
+ }
+ }
+ to_hex_str(buf, pqg->prime.data, pqg->prime.len);
+ fprintf(dsaresp, "P = %s\n", buf);
+ to_hex_str(buf, pqg->subPrime.data, pqg->subPrime.len);
+ fprintf(dsaresp, "Q = %s\n", buf);
+ to_hex_str(buf, pqg->base.data, pqg->base.len);
+ fprintf(dsaresp, "G = %s\n", buf);
+
+ /* create DSA Key */
+ if (DSA_NewKey(pqg, &dsakey) != SECSuccess) {
+ fprintf(dsaresp, "ERROR: Unable to generate DSA key");
+ goto loser;
+ }
+
+ hashType = sha_get_hashType(hashNum);
+ if (hashType == HASH_AlgNULL) {
+ fprintf(dsaresp, "ERROR: invalid hash (SHA-%d)", hashNum);
+ goto loser;
+ }
+ continue;
+ }
+
+ /* Msg = ... */
+ if (strncmp(buf, "Msg", 3) == 0) {
+ unsigned char msg[128]; /* MAX msg 128 */
+ unsigned int len = 0;
+
+ if (hashType == HASH_AlgNULL) {
+ fprintf(dsaresp, "ERROR: Hash Alg not set");
+ goto loser;
+ }
+
+ memset(hashBuf, 0, sizeof hashBuf);
+ memset(sig, 0, sizeof sig);
+
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &msg[j]);
+ }
+ if (fips_hashBuf(hashType, hashBuf, msg, j) != SECSuccess) {
+ fprintf(dsaresp, "ERROR: Unable to generate SHA% digest",
+ hashNum);
+ goto loser;
+ }
+
+ digest.type = siBuffer;
+ digest.data = hashBuf;
+ digest.len = fips_hashLen(hashType);
+ signature.type = siBuffer;
+ signature.data = sig;
+ signature.len = sizeof sig;
+
+ if (DSA_SignDigest(dsakey, &signature, &digest) != SECSuccess) {
+ fprintf(dsaresp, "ERROR: Unable to generate DSA signature");
+ goto loser;
+ }
+ len = signature.len;
+ if (len % 2 != 0) {
+ goto loser;
+ }
+ len = len / 2;
+
+ /* output the orginal Msg, and generated Y, R, and S */
+ fputs(buf, dsaresp);
+ to_hex_str(buf, dsakey->publicValue.data,
+ dsakey->publicValue.len);
+ fprintf(dsaresp, "Y = %s\n", buf);
+ to_hex_str(buf, &signature.data[0], len);
+ fprintf(dsaresp, "R = %s\n", buf);
+ to_hex_str(buf, &signature.data[len], len);
+ fprintf(dsaresp, "S = %s\n", buf);
+ fputc('\n', dsaresp);
+ continue;
+ }
+ }
+loser:
+ fclose(dsareq);
+ if (pqg != NULL) {
+ PQG_DestroyParams(pqg);
+ pqg = NULL;
+ }
+ if (vfy != NULL) {
+ PQG_DestroyVerify(vfy);
+ vfy = NULL;
+ }
+ if (dsakey) {
+ PORT_FreeArena(dsakey->params.arena, PR_TRUE);
+ dsakey = NULL;
+ }
+}
+
+/*
+ * Perform the DSA Signature Verification Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+dsa_sigver_test(char *reqfn)
+{
+ char buf[800]; /* holds one line from the input REQUEST file
+ * or to the output RESPONSE file.
+ * max for Msg = ....
+ */
+ FILE *dsareq; /* input stream from the REQUEST file */
+ FILE *dsaresp; /* output stream to the RESPONSE file */
+ int L;
+ int N;
+ unsigned int i, j;
+ SECItem digest, signature;
+ DSAPublicKey pubkey;
+ unsigned int pgySize; /* size for p, g, and y */
+ unsigned char hashBuf[HASH_LENGTH_MAX]; /* SHA-x hash (160-512 bits) */
+ unsigned char sig[DSA_MAX_SIGNATURE_LEN];
+ HASH_HashType hashType = HASH_AlgNULL;
+ int hashNum = 0;
+
+ dsareq = fopen(reqfn, "r");
+ dsaresp = stdout;
+ memset(&pubkey, 0, sizeof(pubkey));
+
+ while (fgets(buf, sizeof buf, dsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* [Mod = x] */
+ if (buf[0] == '[') {
+
+ if (sscanf(buf, "[mod = L=%d, N=%d, SHA-%d]", &L, &N,
+ &hashNum) != 3) {
+ N = 160;
+ hashNum = 1;
+ if (sscanf(buf, "[mod = %d]", &L) != 1) {
+ goto loser;
+ }
+ }
+
+ if (pubkey.params.prime.data) { /* P */
+ SECITEM_ZfreeItem(&pubkey.params.prime, PR_FALSE);
+ }
+ if (pubkey.params.subPrime.data) { /* Q */
+ SECITEM_ZfreeItem(&pubkey.params.subPrime, PR_FALSE);
+ }
+ if (pubkey.params.base.data) { /* G */
+ SECITEM_ZfreeItem(&pubkey.params.base, PR_FALSE);
+ }
+ if (pubkey.publicValue.data) { /* Y */
+ SECITEM_ZfreeItem(&pubkey.publicValue, PR_FALSE);
+ }
+ fputs(buf, dsaresp);
+
+ /* calculate the size of p, g, and y then allocate items */
+ pgySize = L / 8;
+ SECITEM_AllocItem(NULL, &pubkey.params.prime, pgySize);
+ SECITEM_AllocItem(NULL, &pubkey.params.base, pgySize);
+ SECITEM_AllocItem(NULL, &pubkey.publicValue, pgySize);
+ pubkey.params.prime.len = pubkey.params.base.len = pgySize;
+ pubkey.publicValue.len = pgySize;
+
+ /* q always N/8 bytes */
+ SECITEM_AllocItem(NULL, &pubkey.params.subPrime, N / 8);
+ pubkey.params.subPrime.len = N / 8;
+
+ hashType = sha_get_hashType(hashNum);
+ if (hashType == HASH_AlgNULL) {
+ fprintf(dsaresp, "ERROR: invalid hash (SHA-%d)", hashNum);
+ goto loser;
+ }
+
+ continue;
+ }
+ /* P = ... */
+ if (buf[0] == 'P') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ memset(pubkey.params.prime.data, 0, pubkey.params.prime.len);
+ for (j = 0; j < pubkey.params.prime.len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &pubkey.params.prime.data[j]);
+ }
+
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* Q = ... */
+ if (buf[0] == 'Q') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ memset(pubkey.params.subPrime.data, 0, pubkey.params.subPrime.len);
+ for (j = 0; j < pubkey.params.subPrime.len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &pubkey.params.subPrime.data[j]);
+ }
+
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* G = ... */
+ if (buf[0] == 'G') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ memset(pubkey.params.base.data, 0, pubkey.params.base.len);
+ for (j = 0; j < pubkey.params.base.len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &pubkey.params.base.data[j]);
+ }
+
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* Msg = ... */
+ if (strncmp(buf, "Msg", 3) == 0) {
+ unsigned char msg[128]; /* MAX msg 128 */
+ memset(hashBuf, 0, sizeof hashBuf);
+
+ if (hashType == HASH_AlgNULL) {
+ fprintf(dsaresp, "ERROR: Hash Alg not set");
+ goto loser;
+ }
+
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]); i += 2, j++) {
+ hex_to_byteval(&buf[i], &msg[j]);
+ }
+ if (fips_hashBuf(hashType, hashBuf, msg, j) != SECSuccess) {
+ fprintf(dsaresp, "ERROR: Unable to generate SHA-%d digest",
+ hashNum);
+ goto loser;
+ }
+
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* Y = ... */
+ if (buf[0] == 'Y') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ memset(pubkey.publicValue.data, 0, pubkey.params.subPrime.len);
+ for (j = 0; j < pubkey.publicValue.len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &pubkey.publicValue.data[j]);
+ }
+
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* R = ... */
+ if (buf[0] == 'R') {
+ memset(sig, 0, sizeof sig);
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < pubkey.params.subPrime.len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &sig[j]);
+ }
+
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* S = ... */
+ if (buf[0] == 'S') {
+ if (hashType == HASH_AlgNULL) {
+ fprintf(dsaresp, "ERROR: Hash Alg not set");
+ goto loser;
+ }
+
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = pubkey.params.subPrime.len;
+ j < pubkey.params.subPrime.len * 2; i += 2, j++) {
+ hex_to_byteval(&buf[i], &sig[j]);
+ }
+ fputs(buf, dsaresp);
+
+ digest.type = siBuffer;
+ digest.data = hashBuf;
+ digest.len = fips_hashLen(hashType);
+ signature.type = siBuffer;
+ signature.data = sig;
+ signature.len = pubkey.params.subPrime.len * 2;
+
+ if (DSA_VerifyDigest(&pubkey, &signature, &digest) == SECSuccess) {
+ fprintf(dsaresp, "Result = P\n");
+ } else {
+ fprintf(dsaresp, "Result = F\n");
+ }
+ fprintf(dsaresp, "\n");
+ continue;
+ }
+ }
+loser:
+ fclose(dsareq);
+ if (pubkey.params.prime.data) { /* P */
+ SECITEM_ZfreeItem(&pubkey.params.prime, PR_FALSE);
+ }
+ if (pubkey.params.subPrime.data) { /* Q */
+ SECITEM_ZfreeItem(&pubkey.params.subPrime, PR_FALSE);
+ }
+ if (pubkey.params.base.data) { /* G */
+ SECITEM_ZfreeItem(&pubkey.params.base, PR_FALSE);
+ }
+ if (pubkey.publicValue.data) { /* Y */
+ SECITEM_ZfreeItem(&pubkey.publicValue, PR_FALSE);
+ }
+}
+
+static void
+pad(unsigned char *buf, int pad_len, unsigned char *src, int src_len)
+{
+ int offset = 0;
+ /* this shouldn't happen, fail right away rather than produce bad output */
+ if (pad_len < src_len) {
+ fprintf(stderr, "data bigger than expected! %d > %d\n", src_len, pad_len);
+ exit(1);
+ }
+
+ offset = pad_len - src_len;
+ memset(buf, 0, offset);
+ memcpy(buf + offset, src, src_len);
+ return;
+}
+
+/*
+ * Perform the DSA Key Pair Generation Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+rsa_keypair_test(char *reqfn)
+{
+ char buf[800]; /* holds one line from the input REQUEST file
+ * or to the output RESPONSE file.
+ * 800 to hold (384 public key (x2 for HEX) + 1'\n'
+ */
+ unsigned char buf2[400]; /* can't need more then 1/2 buf length */
+ FILE *rsareq; /* input stream from the REQUEST file */
+ FILE *rsaresp; /* output stream to the RESPONSE file */
+ int count;
+ int i;
+ int keySize = 1; /* key size in bits*/
+ int len = 0; /* key size in bytes */
+ int len2 = 0; /* key size in bytes/2 (prime size) */
+ SECItem e;
+ unsigned char default_e[] = { 0x1, 0x0, 0x1 };
+
+ e.data = default_e;
+ e.len = sizeof(default_e);
+
+ rsareq = fopen(reqfn, "r");
+ rsaresp = stdout;
+ while (fgets(buf, sizeof buf, rsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, rsaresp);
+ continue;
+ }
+
+ /* [Mod = x] */
+ if (buf[0] == '[') {
+ if (buf[1] == 'm') {
+ if (sscanf(buf, "[mod = %d]", &keySize) != 1) {
+ goto loser;
+ }
+ len = keySize / 8;
+ len2 = keySize / 16;
+ }
+ fputs(buf, rsaresp);
+ continue;
+ }
+ /* N = ...*/
+ if (buf[0] == 'N') {
+
+ if (sscanf(buf, "N = %d", &count) != 1) {
+ goto loser;
+ }
+
+ /* Generate a DSA key, and output the key pair for N times */
+ for (i = 0; i < count; i++) {
+ RSAPrivateKey *rsakey = NULL;
+ if ((rsakey = RSA_NewKey(keySize, &e)) == NULL) {
+ fprintf(rsaresp, "ERROR: Unable to generate RSA key");
+ goto loser;
+ }
+ pad(buf2, len, rsakey->publicExponent.data,
+ rsakey->publicExponent.len);
+ to_hex_str(buf, buf2, len);
+ fprintf(rsaresp, "e = %s\n", buf);
+ pad(buf2, len2, rsakey->prime1.data,
+ rsakey->prime1.len);
+ to_hex_str(buf, buf2, len2);
+ fprintf(rsaresp, "p = %s\n", buf);
+ pad(buf2, len2, rsakey->prime2.data,
+ rsakey->prime2.len);
+ to_hex_str(buf, buf2, len2);
+ fprintf(rsaresp, "q = %s\n", buf);
+ pad(buf2, len, rsakey->modulus.data,
+ rsakey->modulus.len);
+ to_hex_str(buf, buf2, len);
+ fprintf(rsaresp, "n = %s\n", buf);
+ pad(buf2, len, rsakey->privateExponent.data,
+ rsakey->privateExponent.len);
+ to_hex_str(buf, buf2, len);
+ fprintf(rsaresp, "d = %s\n", buf);
+ fprintf(rsaresp, "\n");
+ PORT_FreeArena(rsakey->arena, PR_TRUE);
+ rsakey = NULL;
+ }
+ continue;
+ }
+ }
+loser:
+ fclose(rsareq);
+}
+
+/*
+ * Perform the RSA Signature Generation Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+rsa_siggen_test(char *reqfn)
+{
+ char buf[2 * RSA_MAX_TEST_MODULUS_BYTES + 1];
+ /* buf holds one line from the input REQUEST file
+ * or to the output RESPONSE file.
+ * 2x for HEX output + 1 for \n
+ */
+ FILE *rsareq; /* input stream from the REQUEST file */
+ FILE *rsaresp; /* output stream to the RESPONSE file */
+ int i, j;
+ unsigned char sha[HASH_LENGTH_MAX]; /* SHA digest */
+ unsigned int shaLength = 0; /* length of SHA */
+ HASH_HashType shaAlg = HASH_AlgNULL; /* type of SHA Alg */
+ SECOidTag shaOid = SEC_OID_UNKNOWN;
+ int modulus; /* the Modulus size */
+ int publicExponent = DEFAULT_RSA_PUBLIC_EXPONENT;
+ SECItem pe = { 0, 0, 0 };
+ unsigned char pubEx[4];
+ int peCount = 0;
+
+ RSAPrivateKey *rsaBlapiPrivKey = NULL; /* holds RSA private and
+ * public keys */
+ RSAPublicKey *rsaBlapiPublicKey = NULL; /* hold RSA public key */
+
+ rsareq = fopen(reqfn, "r");
+ rsaresp = stdout;
+
+ /* calculate the exponent */
+ for (i = 0; i < 4; i++) {
+ if (peCount || (publicExponent &
+ ((unsigned long)0xff000000L >> (i *
+ 8)))) {
+ pubEx[peCount] =
+ (unsigned char)((publicExponent >> (3 - i) * 8) & 0xff);
+ peCount++;
+ }
+ }
+ pe.len = peCount;
+ pe.data = &pubEx[0];
+ pe.type = siBuffer;
+
+ while (fgets(buf, sizeof buf, rsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, rsaresp);
+ continue;
+ }
+
+ /* [mod = ...] */
+ if (buf[0] == '[') {
+
+ if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
+ goto loser;
+ }
+ if (modulus > RSA_MAX_TEST_MODULUS_BITS) {
+ fprintf(rsaresp, "ERROR: modulus greater than test maximum\n");
+ goto loser;
+ }
+
+ fputs(buf, rsaresp);
+
+ if (rsaBlapiPrivKey != NULL) {
+ PORT_FreeArena(rsaBlapiPrivKey->arena, PR_TRUE);
+ rsaBlapiPrivKey = NULL;
+ rsaBlapiPublicKey = NULL;
+ }
+
+ rsaBlapiPrivKey = RSA_NewKey(modulus, &pe);
+ if (rsaBlapiPrivKey == NULL) {
+ fprintf(rsaresp, "Error unable to create RSA key\n");
+ goto loser;
+ }
+
+ to_hex_str(buf, rsaBlapiPrivKey->modulus.data,
+ rsaBlapiPrivKey->modulus.len);
+ fprintf(rsaresp, "\nn = %s\n\n", buf);
+ to_hex_str(buf, rsaBlapiPrivKey->publicExponent.data,
+ rsaBlapiPrivKey->publicExponent.len);
+ fprintf(rsaresp, "e = %s\n", buf);
+ /* convert private key to public key. Memory
+ * is freed with private key's arena */
+ rsaBlapiPublicKey = (RSAPublicKey *)PORT_ArenaAlloc(
+ rsaBlapiPrivKey->arena,
+ sizeof(RSAPublicKey));
+
+ rsaBlapiPublicKey->modulus.len = rsaBlapiPrivKey->modulus.len;
+ rsaBlapiPublicKey->modulus.data = rsaBlapiPrivKey->modulus.data;
+ rsaBlapiPublicKey->publicExponent.len =
+ rsaBlapiPrivKey->publicExponent.len;
+ rsaBlapiPublicKey->publicExponent.data =
+ rsaBlapiPrivKey->publicExponent.data;
+ continue;
+ }
+
+ /* SHAAlg = ... */
+ if (strncmp(buf, "SHAAlg", 6) == 0) {
+ i = 6;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ /* set the SHA Algorithm */
+ if (strncmp(&buf[i], "SHA1", 4) == 0) {
+ shaAlg = HASH_AlgSHA1;
+ } else if (strncmp(&buf[i], "SHA224", 6) == 0) {
+ shaAlg = HASH_AlgSHA224;
+ } else if (strncmp(&buf[i], "SHA256", 6) == 0) {
+ shaAlg = HASH_AlgSHA256;
+ } else if (strncmp(&buf[i], "SHA384", 6) == 0) {
+ shaAlg = HASH_AlgSHA384;
+ } else if (strncmp(&buf[i], "SHA512", 6) == 0) {
+ shaAlg = HASH_AlgSHA512;
+ } else {
+ fprintf(rsaresp, "ERROR: Unable to find SHAAlg type");
+ goto loser;
+ }
+ fputs(buf, rsaresp);
+ continue;
+ }
+ /* Msg = ... */
+ if (strncmp(buf, "Msg", 3) == 0) {
+
+ unsigned char msg[128]; /* MAX msg 128 */
+ unsigned int rsa_bytes_signed;
+ unsigned char rsa_computed_signature[RSA_MAX_TEST_MODULUS_BYTES];
+ SECStatus rv = SECFailure;
+ NSSLOWKEYPublicKey *rsa_public_key;
+ NSSLOWKEYPrivateKey *rsa_private_key;
+ NSSLOWKEYPrivateKey low_RSA_private_key = { NULL,
+ NSSLOWKEYRSAKey };
+ NSSLOWKEYPublicKey low_RSA_public_key = { NULL,
+ NSSLOWKEYRSAKey };
+
+ low_RSA_private_key.u.rsa = *rsaBlapiPrivKey;
+ low_RSA_public_key.u.rsa = *rsaBlapiPublicKey;
+
+ rsa_private_key = &low_RSA_private_key;
+ rsa_public_key = &low_RSA_public_key;
+
+ memset(sha, 0, sizeof sha);
+ memset(msg, 0, sizeof msg);
+ rsa_bytes_signed = 0;
+ memset(rsa_computed_signature, 0, sizeof rsa_computed_signature);
+
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; isxdigit(buf[i]) && j < sizeof(msg); i += 2, j++) {
+ hex_to_byteval(&buf[i], &msg[j]);
+ }
+ shaLength = fips_hashLen(shaAlg);
+ if (fips_hashBuf(shaAlg, sha, msg, j) != SECSuccess) {
+ if (shaLength == 0) {
+ fprintf(rsaresp, "ERROR: SHAAlg not defined.");
+ }
+ fprintf(rsaresp, "ERROR: Unable to generate SHA%x",
+ shaLength == 160 ? 1 : shaLength);
+ goto loser;
+ }
+ shaOid = fips_hashOid(shaAlg);
+
+ /* Perform RSA signature with the RSA private key. */
+ rv = RSA_HashSign(shaOid,
+ rsa_private_key,
+ rsa_computed_signature,
+ &rsa_bytes_signed,
+ nsslowkey_PrivateModulusLen(rsa_private_key),
+ sha,
+ shaLength);
+
+ if (rv != SECSuccess) {
+ fprintf(rsaresp, "ERROR: RSA_HashSign failed");
+ goto loser;
+ }
+
+ /* Output the signature */
+ fputs(buf, rsaresp);
+ to_hex_str(buf, rsa_computed_signature, rsa_bytes_signed);
+ fprintf(rsaresp, "S = %s\n", buf);
+
+ /* Perform RSA verification with the RSA public key. */
+ rv = RSA_HashCheckSign(shaOid,
+ rsa_public_key,
+ rsa_computed_signature,
+ rsa_bytes_signed,
+ sha,
+ shaLength);
+ if (rv != SECSuccess) {
+ fprintf(rsaresp, "ERROR: RSA_HashCheckSign failed");
+ goto loser;
+ }
+ continue;
+ }
+ }
+loser:
+ fclose(rsareq);
+
+ if (rsaBlapiPrivKey != NULL) {
+ /* frees private and public key */
+ PORT_FreeArena(rsaBlapiPrivKey->arena, PR_TRUE);
+ rsaBlapiPrivKey = NULL;
+ rsaBlapiPublicKey = NULL;
+ }
+}
+/*
+ * Perform the RSA Signature Verification Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+rsa_sigver_test(char *reqfn)
+{
+ char buf[2 * RSA_MAX_TEST_MODULUS_BYTES + 7];
+ /* buf holds one line from the input REQUEST file
+ * or to the output RESPONSE file.
+ * s = 2x for HEX output + 1 for \n
+ */
+ FILE *rsareq; /* input stream from the REQUEST file */
+ FILE *rsaresp; /* output stream to the RESPONSE file */
+ int i, j;
+ unsigned char sha[HASH_LENGTH_MAX]; /* SHA digest */
+ unsigned int shaLength = 0; /* actual length of the digest */
+ HASH_HashType shaAlg = HASH_AlgNULL;
+ SECOidTag shaOid = SEC_OID_UNKNOWN;
+ int modulus = 0; /* the Modulus size */
+ unsigned char signature[513]; /* largest signature size + '\n' */
+ unsigned int signatureLength = 0; /* actual length of the signature */
+ PRBool keyvalid = PR_TRUE;
+
+ RSAPublicKey rsaBlapiPublicKey; /* hold RSA public key */
+
+ rsareq = fopen(reqfn, "r");
+ rsaresp = stdout;
+ memset(&rsaBlapiPublicKey, 0, sizeof(RSAPublicKey));
+
+ while (fgets(buf, sizeof buf, rsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, rsaresp);
+ continue;
+ }
+
+ /* [Mod = ...] */
+ if (buf[0] == '[') {
+ unsigned int flen; /* length in bytes of the field size */
+
+ if (rsaBlapiPublicKey.modulus.data) { /* n */
+ SECITEM_ZfreeItem(&rsaBlapiPublicKey.modulus, PR_FALSE);
+ }
+ if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
+ goto loser;
+ }
+
+ if (modulus > RSA_MAX_TEST_MODULUS_BITS) {
+ fprintf(rsaresp, "ERROR: modulus greater than test maximum\n");
+ goto loser;
+ }
+
+ fputs(buf, rsaresp);
+
+ signatureLength = flen = modulus / 8;
+
+ SECITEM_AllocItem(NULL, &rsaBlapiPublicKey.modulus, flen);
+ if (rsaBlapiPublicKey.modulus.data == NULL) {
+ goto loser;
+ }
+ continue;
+ }
+
+ /* n = ... modulus */
+ if (buf[0] == 'n') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ keyvalid = from_hex_str(&rsaBlapiPublicKey.modulus.data[0],
+ rsaBlapiPublicKey.modulus.len,
+ &buf[i]);
+
+ if (!keyvalid) {
+ fprintf(rsaresp, "ERROR: rsa_sigver n not valid.\n");
+ goto loser;
+ }
+ fputs(buf, rsaresp);
+ continue;
+ }
+
+ /* SHAAlg = ... */
+ if (strncmp(buf, "SHAAlg", 6) == 0) {
+ i = 6;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ /* set the SHA Algorithm */
+ if (strncmp(&buf[i], "SHA1", 4) == 0) {
+ shaAlg = HASH_AlgSHA1;
+ } else if (strncmp(&buf[i], "SHA224", 6) == 0) {
+ shaAlg = HASH_AlgSHA224;
+ } else if (strncmp(&buf[i], "SHA256", 6) == 0) {
+ shaAlg = HASH_AlgSHA256;
+ } else if (strncmp(&buf[i], "SHA384", 6) == 0) {
+ shaAlg = HASH_AlgSHA384;
+ } else if (strncmp(&buf[i], "SHA512", 6) == 0) {
+ shaAlg = HASH_AlgSHA512;
+ } else {
+ fprintf(rsaresp, "ERROR: Unable to find SHAAlg type");
+ goto loser;
+ }
+ fputs(buf, rsaresp);
+ continue;
+ }
+
+ /* e = ... public Key */
+ if (buf[0] == 'e') {
+ unsigned char data[RSA_MAX_TEST_EXPONENT_BYTES];
+ unsigned char t;
+
+ memset(data, 0, sizeof data);
+
+ if (rsaBlapiPublicKey.publicExponent.data) { /* e */
+ SECITEM_ZfreeItem(&rsaBlapiPublicKey.publicExponent, PR_FALSE);
+ }
+
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ /* skip leading zero's */
+ while (isxdigit(buf[i])) {
+ hex_to_byteval(&buf[i], &t);
+ if (t == 0) {
+ i += 2;
+ } else
+ break;
+ }
+
+ /* get the exponent */
+ for (j = 0; isxdigit(buf[i]) && j < sizeof data; i += 2, j++) {
+ hex_to_byteval(&buf[i], &data[j]);
+ }
+
+ if (j == 0) {
+ j = 1;
+ } /* to handle 1 byte length exponents */
+
+ SECITEM_AllocItem(NULL, &rsaBlapiPublicKey.publicExponent, j);
+ if (rsaBlapiPublicKey.publicExponent.data == NULL) {
+ goto loser;
+ }
+
+ for (i = 0; i < j; i++) {
+ rsaBlapiPublicKey.publicExponent.data[i] = data[i];
+ }
+
+ fputs(buf, rsaresp);
+ continue;
+ }
+
+ /* Msg = ... */
+ if (strncmp(buf, "Msg", 3) == 0) {
+ unsigned char msg[128]; /* MAX msg 128 */
+
+ memset(sha, 0, sizeof sha);
+ memset(msg, 0, sizeof msg);
+
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+
+ for (j = 0; isxdigit(buf[i]) && j < sizeof msg; i += 2, j++) {
+ hex_to_byteval(&buf[i], &msg[j]);
+ }
+
+ shaLength = fips_hashLen(shaAlg);
+ if (fips_hashBuf(shaAlg, sha, msg, j) != SECSuccess) {
+ if (shaLength == 0) {
+ fprintf(rsaresp, "ERROR: SHAAlg not defined.");
+ }
+ fprintf(rsaresp, "ERROR: Unable to generate SHA%x",
+ shaLength == 160 ? 1 : shaLength);
+ goto loser;
+ }
+
+ fputs(buf, rsaresp);
+ continue;
+ }
+
+ /* S = ... */
+ if (buf[0] == 'S') {
+ SECStatus rv = SECFailure;
+ NSSLOWKEYPublicKey *rsa_public_key;
+ NSSLOWKEYPublicKey low_RSA_public_key = { NULL,
+ NSSLOWKEYRSAKey };
+
+ /* convert to a low RSA public key */
+ low_RSA_public_key.u.rsa = rsaBlapiPublicKey;
+ rsa_public_key = &low_RSA_public_key;
+
+ memset(signature, 0, sizeof(signature));
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+
+ for (j = 0; isxdigit(buf[i]) && j < sizeof signature; i += 2, j++) {
+ hex_to_byteval(&buf[i], &signature[j]);
+ }
+
+ signatureLength = j;
+ fputs(buf, rsaresp);
+
+ shaOid = fips_hashOid(shaAlg);
+
+ /* Perform RSA verification with the RSA public key. */
+ rv = RSA_HashCheckSign(shaOid,
+ rsa_public_key,
+ signature,
+ signatureLength,
+ sha,
+ shaLength);
+ if (rv == SECSuccess) {
+ fputs("Result = P\n", rsaresp);
+ } else {
+ fputs("Result = F\n", rsaresp);
+ }
+ continue;
+ }
+ }
+loser:
+ fclose(rsareq);
+ if (rsaBlapiPublicKey.modulus.data) { /* n */
+ SECITEM_ZfreeItem(&rsaBlapiPublicKey.modulus, PR_FALSE);
+ }
+ if (rsaBlapiPublicKey.publicExponent.data) { /* e */
+ SECITEM_ZfreeItem(&rsaBlapiPublicKey.publicExponent, PR_FALSE);
+ }
+}
+
+void
+tls(char *reqfn)
+{
+ char buf[256]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "XSeed = <128 hex digits>\n".
+ */
+ unsigned char *pms = NULL;
+ int pms_len;
+ unsigned char *master_secret = NULL;
+ unsigned char *key_block = NULL;
+ int key_block_len;
+ unsigned char serverHello_random[SSL3_RANDOM_LENGTH];
+ unsigned char clientHello_random[SSL3_RANDOM_LENGTH];
+ unsigned char server_random[SSL3_RANDOM_LENGTH];
+ unsigned char client_random[SSL3_RANDOM_LENGTH];
+ FILE *tlsreq = NULL; /* input stream from the REQUEST file */
+ FILE *tlsresp; /* output stream to the RESPONSE file */
+ unsigned int i, j;
+ CK_SLOT_ID slotList[10];
+ CK_SLOT_ID slotID;
+ CK_ULONG slotListCount = sizeof(slotList) / sizeof(slotList[0]);
+ CK_ULONG count;
+ static const CK_C_INITIALIZE_ARGS pk11args = {
+ NULL, NULL, NULL, NULL, CKF_LIBRARY_CANT_CREATE_OS_THREADS,
+ (void *)"flags=readOnly,noCertDB,noModDB", NULL
+ };
+ static CK_OBJECT_CLASS ck_secret = CKO_SECRET_KEY;
+ static CK_KEY_TYPE ck_generic = CKK_GENERIC_SECRET;
+ static CK_BBOOL ck_true = CK_TRUE;
+ static CK_ULONG one = 1;
+ CK_ATTRIBUTE create_template[] = {
+ { CKA_VALUE, NULL, 0 },
+ { CKA_CLASS, &ck_secret, sizeof(ck_secret) },
+ { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) },
+ { CKA_DERIVE, &ck_true, sizeof(ck_true) },
+ };
+ CK_ULONG create_template_count =
+ sizeof(create_template) / sizeof(create_template[0]);
+ CK_ATTRIBUTE derive_template[] = {
+ { CKA_CLASS, &ck_secret, sizeof(ck_secret) },
+ { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) },
+ { CKA_DERIVE, &ck_true, sizeof(ck_true) },
+ { CKA_VALUE_LEN, &one, sizeof(one) },
+ };
+ CK_ULONG derive_template_count =
+ sizeof(derive_template) / sizeof(derive_template[0]);
+ CK_ATTRIBUTE master_template =
+ { CKA_VALUE, NULL, 0 };
+ CK_ATTRIBUTE kb1_template =
+ { CKA_VALUE, NULL, 0 };
+ CK_ATTRIBUTE kb2_template =
+ { CKA_VALUE, NULL, 0 };
+
+ CK_MECHANISM master_mech = { CKM_TLS_MASTER_KEY_DERIVE, NULL, 0 };
+ CK_MECHANISM key_block_mech = { CKM_TLS_KEY_AND_MAC_DERIVE, NULL, 0 };
+ CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params;
+ CK_SSL3_KEY_MAT_PARAMS key_block_params;
+ CK_SSL3_KEY_MAT_OUT key_material;
+ CK_RV crv;
+
+ /* set up PKCS #11 parameters */
+ master_params.pVersion = NULL;
+ master_params.RandomInfo.pClientRandom = clientHello_random;
+ master_params.RandomInfo.ulClientRandomLen = sizeof(clientHello_random);
+ master_params.RandomInfo.pServerRandom = serverHello_random;
+ master_params.RandomInfo.ulServerRandomLen = sizeof(serverHello_random);
+ master_mech.pParameter = (void *)&master_params;
+ master_mech.ulParameterLen = sizeof(master_params);
+ key_block_params.ulMacSizeInBits = 0;
+ key_block_params.ulKeySizeInBits = 0;
+ key_block_params.ulIVSizeInBits = 0;
+ key_block_params.bIsExport = PR_FALSE; /* ignored anyway for TLS mech */
+ key_block_params.RandomInfo.pClientRandom = client_random;
+ key_block_params.RandomInfo.ulClientRandomLen = sizeof(client_random);
+ key_block_params.RandomInfo.pServerRandom = server_random;
+ key_block_params.RandomInfo.ulServerRandomLen = sizeof(server_random);
+ key_block_params.pReturnedKeyMaterial = &key_material;
+ key_block_mech.pParameter = (void *)&key_block_params;
+ key_block_mech.ulParameterLen = sizeof(key_block_params);
+
+ crv = NSC_Initialize((CK_VOID_PTR)&pk11args);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_Initialize failed crv=0x%x\n", (unsigned int)crv);
+ goto loser;
+ }
+ count = slotListCount;
+ crv = NSC_GetSlotList(PR_TRUE, slotList, &count);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_GetSlotList failed crv=0x%x\n", (unsigned int)crv);
+ goto loser;
+ }
+ if ((count > slotListCount) || count < 1) {
+ fprintf(stderr,
+ "NSC_GetSlotList returned too many or too few slots: %d slots max=%d min=1\n",
+ (int)count, (int)slotListCount);
+ goto loser;
+ }
+ slotID = slotList[0];
+ tlsreq = fopen(reqfn, "r");
+ tlsresp = stdout;
+ while (fgets(buf, sizeof buf, tlsreq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, tlsresp);
+ continue;
+ }
+ /* [Xchange - SHA1] */
+ if (buf[0] == '[') {
+ if (strncmp(buf, "[TLS", 4) == 0) {
+ if (buf[7] == '0') {
+ master_mech.mechanism = CKM_TLS_MASTER_KEY_DERIVE;
+ key_block_mech.mechanism = CKM_TLS_KEY_AND_MAC_DERIVE;
+ } else if (buf[7] == '2') {
+ master_mech.mechanism =
+ CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256;
+ key_block_mech.mechanism =
+ CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256;
+ } else {
+ fprintf(stderr, "Unknown TLS type %x\n",
+ (unsigned int)buf[0]);
+ goto loser;
+ }
+ }
+ if (strncmp(buf, "[pre-master", 11) == 0) {
+ if (sscanf(buf, "[pre-master secret length = %d]",
+ &pms_len) != 1) {
+ goto loser;
+ }
+ pms_len = pms_len / 8;
+ pms = malloc(pms_len);
+ master_secret = malloc(pms_len);
+ create_template[0].pValue = pms;
+ create_template[0].ulValueLen = pms_len;
+ master_template.pValue = master_secret;
+ master_template.ulValueLen = pms_len;
+ }
+ if (strncmp(buf, "[key", 4) == 0) {
+ if (sscanf(buf, "[key block length = %d]", &key_block_len) != 1) {
+ goto loser;
+ }
+ key_block_params.ulKeySizeInBits = 8;
+ key_block_params.ulIVSizeInBits = key_block_len / 2 - 8;
+ key_block_len = key_block_len / 8;
+ key_block = malloc(key_block_len);
+ kb1_template.pValue = &key_block[0];
+ kb1_template.ulValueLen = 1;
+ kb2_template.pValue = &key_block[1];
+ kb2_template.ulValueLen = 1;
+ key_material.pIVClient = &key_block[2];
+ key_material.pIVServer = &key_block[2 + key_block_len / 2 - 1];
+ }
+ fputs(buf, tlsresp);
+ continue;
+ }
+ /* "COUNT = x" begins a new data set */
+ if (strncmp(buf, "COUNT", 5) == 0) {
+ /* zeroize the variables for the test with this data set */
+ memset(pms, 0, pms_len);
+ memset(master_secret, 0, pms_len);
+ memset(key_block, 0, key_block_len);
+ fputs(buf, tlsresp);
+ continue;
+ }
+ /* pre_master_secret = ... */
+ if (strncmp(buf, "pre_master_secret", 17) == 0) {
+ i = 17;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < pms_len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &pms[j]);
+ }
+ fputs(buf, tlsresp);
+ continue;
+ }
+ /* serverHello_random = ... */
+ if (strncmp(buf, "serverHello_random", 18) == 0) {
+ i = 18;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < SSL3_RANDOM_LENGTH; i += 2, j++) {
+ hex_to_byteval(&buf[i], &serverHello_random[j]);
+ }
+ fputs(buf, tlsresp);
+ continue;
+ }
+ /* clientHello_random = ... */
+ if (strncmp(buf, "clientHello_random", 18) == 0) {
+ i = 18;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < SSL3_RANDOM_LENGTH; i += 2, j++) {
+ hex_to_byteval(&buf[i], &clientHello_random[j]);
+ }
+ fputs(buf, tlsresp);
+ continue;
+ }
+ /* server_random = ... */
+ if (strncmp(buf, "server_random", 13) == 0) {
+ i = 13;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < SSL3_RANDOM_LENGTH; i += 2, j++) {
+ hex_to_byteval(&buf[i], &server_random[j]);
+ }
+ fputs(buf, tlsresp);
+ continue;
+ }
+ /* client_random = ... */
+ if (strncmp(buf, "client_random", 13) == 0) {
+ CK_SESSION_HANDLE session;
+ CK_OBJECT_HANDLE pms_handle;
+ CK_OBJECT_HANDLE master_handle;
+ CK_OBJECT_HANDLE fake_handle;
+ i = 13;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j = 0; j < SSL3_RANDOM_LENGTH; i += 2, j++) {
+ hex_to_byteval(&buf[i], &client_random[j]);
+ }
+ fputs(buf, tlsresp);
+ crv = NSC_OpenSession(slotID, 0, NULL, NULL, &session);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_OpenSession failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ crv = NSC_CreateObject(session, create_template,
+ create_template_count, &pms_handle);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_CreateObject failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ crv = NSC_DeriveKey(session, &master_mech, pms_handle,
+ derive_template, derive_template_count -
+ 1,
+ &master_handle);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_DeriveKey(master) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ crv = NSC_GetAttributeValue(session, master_handle,
+ &master_template, 1);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_GetAttribute failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ fputs("master_secret = ", tlsresp);
+ to_hex_str(buf, master_secret, pms_len);
+ fputs(buf, tlsresp);
+ fputc('\n', tlsresp);
+ crv = NSC_DeriveKey(session, &key_block_mech, master_handle,
+ derive_template, derive_template_count, &fake_handle);
+ if (crv != CKR_OK) {
+ fprintf(stderr,
+ "NSC_DeriveKey(keyblock) failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ crv = NSC_GetAttributeValue(session, key_material.hClientKey,
+ &kb1_template, 1);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_GetAttribute failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ crv = NSC_GetAttributeValue(session, key_material.hServerKey,
+ &kb2_template, 1);
+ if (crv != CKR_OK) {
+ fprintf(stderr, "NSC_GetAttribute failed crv=0x%x\n",
+ (unsigned int)crv);
+ goto loser;
+ }
+ fputs("key_block = ", tlsresp);
+ to_hex_str(buf, key_block, key_block_len);
+ fputs(buf, tlsresp);
+ fputc('\n', tlsresp);
+ crv = NSC_CloseSession(session);
+ continue;
+ }
+ }
+loser:
+ NSC_Finalize(NULL);
+ if (pms)
+ free(pms);
+ if (master_secret)
+ free(master_secret);
+ if (key_block)
+ free(key_block);
+ if (tlsreq)
+ fclose(tlsreq);
+}
+
+int
+main(int argc, char **argv)
+{
+ if (argc < 2)
+ exit(-1);
+
+ RNG_RNGInit();
+ SECOID_Init();
+
+ /*************/
+ /* TDEA */
+ /*************/
+ if (strcmp(argv[1], "tdea") == 0) {
+ /* argv[2]=kat|mmt|mct argv[3]=ecb|cbc argv[4]=.req */
+ if (strcmp(argv[2], "kat") == 0) {
+ /* Known Answer Test (KAT) */
+ tdea_kat_mmt(argv[4]);
+ } else if (strcmp(argv[2], "mmt") == 0) {
+ /* Multi-block Message Test (MMT) */
+ tdea_kat_mmt(argv[4]);
+ } else if (strcmp(argv[2], "mct") == 0) {
+ /* Monte Carlo Test (MCT) */
+ if (strcmp(argv[3], "ecb") == 0) {
+ /* ECB mode */
+ tdea_mct(NSS_DES_EDE3, argv[4]);
+ } else if (strcmp(argv[3], "cbc") == 0) {
+ /* CBC mode */
+ tdea_mct(NSS_DES_EDE3_CBC, argv[4]);
+ }
+ }
+ /*************/
+ /* AES */
+ /*************/
+ } else if (strcmp(argv[1], "aes") == 0) {
+ /* argv[2]=kat|mmt|mct argv[3]=ecb|cbc argv[4]=.req */
+ if (strcmp(argv[2], "kat") == 0) {
+ /* Known Answer Test (KAT) */
+ aes_kat_mmt(argv[4]);
+ } else if (strcmp(argv[2], "mmt") == 0) {
+ /* Multi-block Message Test (MMT) */
+ aes_kat_mmt(argv[4]);
+ } else if (strcmp(argv[2], "gcm") == 0) {
+ if (strcmp(argv[3], "decrypt") == 0) {
+ aes_gcm(argv[4], 0);
+ } else if (strcmp(argv[3], "encrypt_extiv") == 0) {
+ aes_gcm(argv[4], 1);
+ } else if (strcmp(argv[3], "encrypt_intiv") == 0) {
+ aes_gcm(argv[4], 2);
+ }
+ } else if (strcmp(argv[2], "mct") == 0) {
+ /* Monte Carlo Test (MCT) */
+ if (strcmp(argv[3], "ecb") == 0) {
+ /* ECB mode */
+ aes_ecb_mct(argv[4]);
+ } else if (strcmp(argv[3], "cbc") == 0) {
+ /* CBC mode */
+ aes_cbc_mct(argv[4]);
+ }
+ }
+ /*************/
+ /* SHA */
+ /*************/
+ } else if (strcmp(argv[1], "sha") == 0) {
+ sha_test(argv[2]);
+ /*************/
+ /* RSA */
+ /*************/
+ } else if (strcmp(argv[1], "rsa") == 0) {
+ /* argv[2]=siggen|sigver */
+ /* argv[3]=.req */
+ if (strcmp(argv[2], "siggen") == 0) {
+ /* Signature Generation Test */
+ rsa_siggen_test(argv[3]);
+ } else if (strcmp(argv[2], "sigver") == 0) {
+ /* Signature Verification Test */
+ rsa_sigver_test(argv[3]);
+ } else if (strcmp(argv[2], "keypair") == 0) {
+ /* Key Pair Generation Test */
+ rsa_keypair_test(argv[3]);
+ }
+ /*************/
+ /* HMAC */
+ /*************/
+ } else if (strcmp(argv[1], "hmac") == 0) {
+ hmac_test(argv[2]);
+ /*************/
+ /* DSA */
+ /*************/
+ } else if (strcmp(argv[1], "dsa") == 0) {
+ /* argv[2]=keypair|pqggen|pqgver|siggen|sigver */
+ /* argv[3]=.req */
+ if (strcmp(argv[2], "keypair") == 0) {
+ /* Key Pair Generation Test */
+ dsa_keypair_test(argv[3]);
+ } else if (strcmp(argv[2], "pqggen") == 0) {
+ /* Domain Parameter Generation Test */
+ dsa_pqggen_test(argv[3]);
+ } else if (strcmp(argv[2], "pqgver") == 0) {
+ /* Domain Parameter Validation Test */
+ dsa_pqgver_test(argv[3]);
+ } else if (strcmp(argv[2], "siggen") == 0) {
+ /* Signature Generation Test */
+ dsa_siggen_test(argv[3]);
+ } else if (strcmp(argv[2], "sigver") == 0) {
+ /* Signature Verification Test */
+ dsa_sigver_test(argv[3]);
+ }
+#ifndef NSS_DISABLE_ECC
+ /*************/
+ /* ECDSA */
+ /*************/
+ } else if (strcmp(argv[1], "ecdsa") == 0) {
+ /* argv[2]=keypair|pkv|siggen|sigver argv[3]=.req */
+ if (strcmp(argv[2], "keypair") == 0) {
+ /* Key Pair Generation Test */
+ ecdsa_keypair_test(argv[3]);
+ } else if (strcmp(argv[2], "pkv") == 0) {
+ /* Public Key Validation Test */
+ ecdsa_pkv_test(argv[3]);
+ } else if (strcmp(argv[2], "siggen") == 0) {
+ /* Signature Generation Test */
+ ecdsa_siggen_test(argv[3]);
+ } else if (strcmp(argv[2], "sigver") == 0) {
+ /* Signature Verification Test */
+ ecdsa_sigver_test(argv[3]);
+ }
+#endif /* NSS_DISABLE_ECC */
+ /*************/
+ /* RNG */
+ /*************/
+ } else if (strcmp(argv[1], "rng") == 0) {
+ /* argv[2]=vst|mct argv[3]=.req */
+ if (strcmp(argv[2], "vst") == 0) {
+ /* Variable Seed Test */
+ rng_vst(argv[3]);
+ } else if (strcmp(argv[2], "mct") == 0) {
+ /* Monte Carlo Test */
+ rng_mct(argv[3]);
+ }
+ } else if (strcmp(argv[1], "drbg") == 0) {
+ /* Variable Seed Test */
+ drbg(argv[2]);
+ } else if (strcmp(argv[1], "ddrbg") == 0) {
+ debug = 1;
+ drbg(argv[2]);
+ }
+ return 0;
+}
diff --git a/nss/cmd/fipstest/fipstest.gyp b/nss/cmd/fipstest/fipstest.gyp
new file mode 100644
index 0000000..41024ca
--- /dev/null
+++ b/nss/cmd/fipstest/fipstest.gyp
@@ -0,0 +1,31 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi',
+ '../../cmd/platlibs.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'fipstest',
+ 'type': 'executable',
+ 'sources': [
+ 'fipstest.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports',
+ '<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3'
+ ]
+ }
+ ],
+ 'target_defaults': {
+ 'defines': [
+ 'NSS_USE_STATIC_LIBS'
+ ]
+ },
+ 'variables': {
+ 'module': 'nss',
+ 'use_static_libs': 1
+ }
+}
\ No newline at end of file
diff --git a/nss/cmd/fipstest/hmac.sh b/nss/cmd/fipstest/hmac.sh
new file mode 100755
index 0000000..d29dbc2
--- /dev/null
+++ b/nss/cmd/fipstest/hmac.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# A Bourne shell script for running the NIST HMAC Algorithm Validation Suite
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/HMAC
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
+
+hmac_requests="
+HMAC.req
+"
+
+if [ ${COMMAND} = "verify" ]; then
+ for request in $hmac_requests; do
+ sh ./validate1.sh ${TESTDIR} $request
+ done
+ exit 0
+fi
+for request in $hmac_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest hmac ${REQDIR}/$request > ${RSPDIR}/$response
+done
+
diff --git a/nss/cmd/fipstest/manifest.mn b/nss/cmd/fipstest/manifest.mn
new file mode 100644
index 0000000..1cebd79
--- /dev/null
+++ b/nss/cmd/fipstest/manifest.mn
@@ -0,0 +1,23 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+CORE_DEPTH = ../..
+
+MODULE = nss
+
+PROGRAM = fipstest
+
+USE_STATIC_LIBS = 1
+
+EXPORTS = \
+ $(NULL)
+
+PRIVATE_EXPORTS = \
+ $(NULL)
+
+CSRCS = \
+ fipstest.c \
+ $(NULL)
+
diff --git a/nss/cmd/fipstest/rng.sh b/nss/cmd/fipstest/rng.sh
new file mode 100644
index 0000000..1a313b4
--- /dev/null
+++ b/nss/cmd/fipstest/rng.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# A Bourne shell script for running the NIST RNG Validation Suite
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/DRBG800-90A
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
+
+drbg_requests="
+Hash_DRBG.req
+"
+
+if [ ${COMMAND} = "verify" ]; then
+ for request in $drbg_requests; do
+ sh ./validate1.sh ${TESTDIR} $request
+ done
+ exit 0
+fi
+for request in $drbg_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest drbg ${REQDIR}/$request > ${RSPDIR}/$response
+done
diff --git a/nss/cmd/fipstest/rsa.sh b/nss/cmd/fipstest/rsa.sh
new file mode 100644
index 0000000..b86a739
--- /dev/null
+++ b/nss/cmd/fipstest/rsa.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# A Bourne shell script for running the NIST RSA Validation System
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/RSA2
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
+
+if [ ${COMMAND} = "verify" ]; then
+#verify the signatures. The fax file does not have any known answers, so
+#use our own verify function.
+ name=SigGen15_186-3
+ echo ">>>>> $name"
+ fipstest rsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F
+# fipstest rsa sigver ${REQDIR}/SigVer15_186-3.req | grep ^Result.=.F
+#The Fax file has the private exponent and the salt value, remove it
+#also remove the false reason
+ sh ./validate1.sh ${TESTDIR} SigVer15_186-3.req ' ' '-e /^SaltVal/d -e/^d.=/d -e /^p.=/d -e /^q.=/d -e /^EM.with/d -e /^Result.=.F/s;.(.*);;'
+#
+# currently don't have a way to verify the RSA keygen
+#
+ exit 0
+fi
+
+request=SigGen15_186-3.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest rsa siggen ${REQDIR}/$request > ${RSPDIR}/$response
+
+request=SigVer15_186-3.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest rsa sigver ${REQDIR}/$request > ${RSPDIR}/$response
+
+#request=KeyGen_186-3.req
+request=KeyGen_RandomProbablyPrime3_3.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest rsa keypair ${REQDIR}/$request > ${RSPDIR}/$response
diff --git a/nss/cmd/fipstest/runtest.sh b/nss/cmd/fipstest/runtest.sh
new file mode 100644
index 0000000..99cefed
--- /dev/null
+++ b/nss/cmd/fipstest/runtest.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+TESTDIR=${1-.}
+COMMAND=${2-run}
+TESTS="aes aesgcm dsa ecdsa hmac tls rng rsa sha tdea"
+if [ ${NSS_ENABLE_ECC}x = 1x ]; then
+ TESTS=${TESTS} ecdsa
+fi
+for i in $TESTS
+do
+ echo "********************Running $i tests"
+ sh ./${i}.sh ${TESTDIR} ${COMMAND}
+done
diff --git a/nss/cmd/fipstest/sha.sh b/nss/cmd/fipstest/sha.sh
new file mode 100644
index 0000000..ccc52d2
--- /dev/null
+++ b/nss/cmd/fipstest/sha.sh
@@ -0,0 +1,66 @@
+#!/bin/sh
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# A Bourne shell script for running the NIST SHA Algorithm Validation Suite
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/SHA
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
+
+sha_ShortMsg_requests="
+SHA1ShortMsg.req
+SHA224ShortMsg.req
+SHA256ShortMsg.req
+SHA384ShortMsg.req
+SHA512ShortMsg.req
+"
+
+sha_LongMsg_requests="
+SHA1LongMsg.req
+SHA224LongMsg.req
+SHA256LongMsg.req
+SHA384LongMsg.req
+SHA512LongMsg.req
+"
+
+sha_Monte_requests="
+SHA1Monte.req
+SHA224Monte.req
+SHA256Monte.req
+SHA384Monte.req
+SHA512Monte.req
+"
+
+if [ ${COMMAND} = "verify" ]; then
+ for request in $sha_ShortMsg_requests $sha_LongMsg_requests $sha_Monte_requests; do
+ sh ./validate1.sh ${TESTDIR} $request
+ done
+ exit 0
+fi
+
+for request in $sha_ShortMsg_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest sha ${REQDIR}/$request > ${RSPDIR}/$response
+done
+for request in $sha_LongMsg_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest sha ${REQDIR}/$request > ${RSPDIR}/$response
+done
+for request in $sha_Monte_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest sha ${REQDIR}/$request > ${RSPDIR}/$response
+done
+
diff --git a/nss/cmd/fipstest/tdea.sh b/nss/cmd/fipstest/tdea.sh
new file mode 100644
index 0000000..cbddad7
--- /dev/null
+++ b/nss/cmd/fipstest/tdea.sh
@@ -0,0 +1,106 @@
+#!/bin/sh
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# A Bourne shell script for running the NIST tdea Algorithm Validation Suite
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/TDES
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
+
+#CBC_Known_Answer_tests
+#Initial Permutation KAT
+#Permutation Operation KAT
+#Subsitution Table KAT
+#Variable Key KAT
+#Variable PlainText KAT
+cbc_kat_requests="
+TCBCinvperm.req
+TCBCpermop.req
+TCBCsubtab.req
+TCBCvarkey.req
+TCBCvartext.req
+"
+
+#CBC Monte Carlo KATs
+cbc_monte_requests="
+TCBCMonte1.req
+TCBCMonte2.req
+TCBCMonte3.req
+"
+#Multi-block Message KATs
+cbc_mmt_requests="
+TCBCMMT1.req
+TCBCMMT2.req
+TCBCMMT3.req
+"
+
+ecb_kat_requests="
+TECBinvperm.req
+TECBpermop.req
+TECBsubtab.req
+TECBvarkey.req
+TECBvartext.req
+"
+
+ecb_monte_requests="
+TECBMonte1.req
+TECBMonte2.req
+TECBMonte3.req
+"
+
+ecb_mmt_requests="
+TECBMMT1.req
+TECBMMT2.req
+TECBMMT3.req
+"
+
+
+if [ ${COMMAND} = "verify" ]; then
+ for request in $cbc_kat_requests $cbc_monte_requests $cbc_mmt_requests $ecb_kat_requests $ecb_monte_requests $ecb_mmt_requests
+ do
+ sh ./validate1.sh ${TESTDIR} $request "-e /^NumKeys/d"
+ done
+ exit 0
+fi
+
+for request in $cbc_kat_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest tdea kat cbc ${REQDIR}/$request > ${RSPDIR}/$response
+done
+for request in $cbc_mmt_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest tdea mmt cbc ${REQDIR}/$request > ${RSPDIR}/$response
+done
+for request in $cbc_monte_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest tdea mct cbc ${REQDIR}/$request > ${RSPDIR}/$response
+done
+for request in $ecb_kat_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest tdea kat ecb ${REQDIR}/$request > ${RSPDIR}/$response
+done
+for request in $ecb_mmt_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest tdea mmt ecb ${REQDIR}/$request > ${RSPDIR}/$response
+done
+for request in $ecb_monte_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest tdea mct ecb ${REQDIR}/$request > ${RSPDIR}/$response
+done
diff --git a/nss/cmd/fipstest/tls.sh b/nss/cmd/fipstest/tls.sh
new file mode 100644
index 0000000..1c28245
--- /dev/null
+++ b/nss/cmd/fipstest/tls.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# A Bourne shell script for running the NIST RNG Validation Suite
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/KDF135
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
+
+drbg_requests="
+tls.req
+"
+
+if [ ${COMMAND} = "verify" ]; then
+ for request in $drbg_requests; do
+ sh ./validate1.sh ${TESTDIR} $request
+ done
+ exit 0
+fi
+for request in $drbg_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest tls ${REQDIR}/$request > ${RSPDIR}/$response
+done
diff --git a/nss/cmd/fipstest/validate.sh b/nss/cmd/fipstest/validate.sh
new file mode 100644
index 0000000..d446dd5
--- /dev/null
+++ b/nss/cmd/fipstest/validate.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+sh ./runtest.sh ${1-.} verify
diff --git a/nss/cmd/fipstest/validate1.sh b/nss/cmd/fipstest/validate1.sh
new file mode 100644
index 0000000..1440af8
--- /dev/null
+++ b/nss/cmd/fipstest/validate1.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# Validate1.sh is a helper shell script that each of the base test shell
+# scripts call to help validate that the generated response (response)
+# matches the known answer response (fax). Sometimes (depending on the
+# individual tests) there are extraneous output in either or both response
+# and fax files. These allow the caller to pass in additional sed commands
+# to clear out those extraneous outputs before we compare the two files.
+# The sed line always clears out Windows line endings, replaces tabs with
+# spaces, and removed comments.
+#
+TESTDIR=${1-.}
+request=${2}
+extraneous_response=${3}
+extraneous_fax=${4}
+name=`basename $request .req`
+echo ">>>>> $name"
+sed -e 's;
;;g' -e 's; ; ;g' -e '/^#/d' $extraneous_response ${TESTDIR}/resp/${name}.rsp > /tmp/y1
+# if we didn't generate any output, flag that as an error
+size=`sum /tmp/y1 | awk '{ print $NF }'`
+if [ $size -eq 0 ]; then
+ echo "${TESTDIR}/resp/${name}.rsp: empty"
+ exit 1;
+fi
+sed -e 's;
;;g' -e 's; ; ;g' -e '/^#/d' $extraneous_fax ${TESTDIR}/fax/${name}.fax > /tmp/y2
+diff -i -w -B /tmp/y1 /tmp/y2
diff --git a/nss/cmd/httpserv/Makefile b/nss/cmd/httpserv/Makefile
new file mode 100644
index 0000000..7b74b36
--- /dev/null
+++ b/nss/cmd/httpserv/Makefile
@@ -0,0 +1,46 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+include ../platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+
+include ../platrules.mk
+
diff --git a/nss/cmd/httpserv/httpserv.c b/nss/cmd/httpserv/httpserv.c
new file mode 100644
index 0000000..7cf28c6
--- /dev/null
+++ b/nss/cmd/httpserv/httpserv.c
@@ -0,0 +1,1453 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include
+#include
+
+#include "secutil.h"
+
+#if defined(XP_UNIX)
+#include
+#endif
+
+#if defined(_WINDOWS)
+#include /* for getpid() */
+#endif
+
+#include
+#include
+#include
+#include
+#include
+
+#include "nspr.h"
+#include "prio.h"
+#include "prerror.h"
+#include "prnetdb.h"
+#include "prclist.h"
+#include "plgetopt.h"
+#include "pk11func.h"
+#include "nss.h"
+#include "nssb64.h"
+#include "sechash.h"
+#include "cert.h"
+#include "certdb.h"
+#include "ocsp.h"
+#include "ocspti.h"
+#include "ocspi.h"
+
+#ifndef PORT_Sprintf
+#define PORT_Sprintf sprintf
+#endif
+
+#ifndef PORT_Strstr
+#define PORT_Strstr strstr
+#endif
+
+#ifndef PORT_Malloc
+#define PORT_Malloc PR_Malloc
+#endif
+
+static int handle_connection(PRFileDesc *, PRFileDesc *, int);
+
+/* data and structures for shutdown */
+static int stopping;
+
+static PRBool noDelay;
+static int verbose;
+
+static PRThread *acceptorThread;
+
+static PRLogModuleInfo *lm;
+
+#define PRINTF \
+ if (verbose) \
+ printf
+#define FPRINTF \
+ if (verbose) \
+ fprintf
+#define FLUSH \
+ if (verbose) { \
+ fflush(stdout); \
+ fflush(stderr); \
+ }
+#define VLOG(arg) PR_LOG(lm, PR_LOG_DEBUG, arg)
+
+static void
+Usage(const char *progName)
+{
+ fprintf(stderr,
+
+ "Usage: %s -p port [-Dbv]\n"
+ " [-t threads] [-i pid_file]\n"
+ " [-A nickname -C crl-filename]... [-O method]\n"
+ " [-d dbdir] [-f password_file] [-w password] [-P dbprefix]\n"
+ "-D means disable Nagle delays in TCP\n"
+ "-b means try binding to the port and exit\n"
+ "-v means verbose output\n"
+ "-t threads -- specify the number of threads to use for connections.\n"
+ "-i pid_file file to write the process id of httpserv\n"
+ "Parameters -A, -C and -O are used to provide an OCSP server at /ocsp?\n"
+ "-A a nickname of a CA certificate\n"
+ "-C a CRL filename corresponding to the preceding CA nickname\n"
+ "-O allowed HTTP methods for OCSP requests: get, post, all, random, get-unknown\n"
+ " random means: randomly fail if request method is GET, POST always works\n"
+ " get-unknown means: status unknown for GET, correct status for POST\n"
+ "Multiple pairs of parameters -A and -C are allowed.\n"
+ "If status for a cert from an unknown CA is requested, the cert from the\n"
+ "first -A parameter will be used to sign the unknown status response.\n"
+ "NSS database parameters are used only if OCSP parameters are used.\n",
+ progName);
+}
+
+static const char *
+errWarn(char *funcString)
+{
+ PRErrorCode perr = PR_GetError();
+ const char *errString = SECU_Strerror(perr);
+
+ fprintf(stderr, "httpserv: %s returned error %d:\n%s\n",
+ funcString, perr, errString);
+ return errString;
+}
+
+static void
+errExit(char *funcString)
+{
+ errWarn(funcString);
+ exit(3);
+}
+
+#define MAX_VIRT_SERVER_NAME_ARRAY_INDEX 10
+
+/**************************************************************************
+** Begin thread management routines and data.
+**************************************************************************/
+#define MIN_THREADS 3
+#define DEFAULT_THREADS 8
+#define MAX_THREADS 4096
+#define MAX_PROCS 25
+static int maxThreads = DEFAULT_THREADS;
+
+typedef struct jobStr {
+ PRCList link;
+ PRFileDesc *tcp_sock;
+ PRFileDesc *model_sock;
+ int requestCert;
+} JOB;
+
+static PZLock *qLock; /* this lock protects all data immediately below */
+static PRLock *lastLoadedCrlLock; /* this lock protects lastLoadedCrl variable */
+static PZCondVar *jobQNotEmptyCv;
+static PZCondVar *freeListNotEmptyCv;
+static PZCondVar *threadCountChangeCv;
+static int threadCount;
+static PRCList jobQ;
+static PRCList freeJobs;
+static JOB *jobTable;
+
+SECStatus
+setupJobs(int maxJobs)
+{
+ int i;
+
+ jobTable = (JOB *)PR_Calloc(maxJobs, sizeof(JOB));
+ if (!jobTable)
+ return SECFailure;
+
+ PR_INIT_CLIST(&jobQ);
+ PR_INIT_CLIST(&freeJobs);
+
+ for (i = 0; i < maxJobs; ++i) {
+ JOB *pJob = jobTable + i;
+ PR_APPEND_LINK(&pJob->link, &freeJobs);
+ }
+ return SECSuccess;
+}
+
+typedef int startFn(PRFileDesc *a, PRFileDesc *b, int c);
+
+typedef enum { rs_idle = 0,
+ rs_running = 1,
+ rs_zombie = 2 } runState;
+
+typedef struct perThreadStr {
+ PRFileDesc *a;
+ PRFileDesc *b;
+ int c;
+ int rv;
+ startFn *startFunc;
+ PRThread *prThread;
+ runState state;
+} perThread;
+
+static perThread *threads;
+
+void
+thread_wrapper(void *arg)
+{
+ perThread *slot = (perThread *)arg;
+
+ slot->rv = (*slot->startFunc)(slot->a, slot->b, slot->c);
+
+ /* notify the thread exit handler. */
+ PZ_Lock(qLock);
+ slot->state = rs_zombie;
+ --threadCount;
+ PZ_NotifyAllCondVar(threadCountChangeCv);
+ PZ_Unlock(qLock);
+}
+
+int
+jobLoop(PRFileDesc *a, PRFileDesc *b, int c)
+{
+ PRCList *myLink = 0;
+ JOB *myJob;
+
+ PZ_Lock(qLock);
+ do {
+ myLink = 0;
+ while (PR_CLIST_IS_EMPTY(&jobQ) && !stopping) {
+ PZ_WaitCondVar(jobQNotEmptyCv, PR_INTERVAL_NO_TIMEOUT);
+ }
+ if (!PR_CLIST_IS_EMPTY(&jobQ)) {
+ myLink = PR_LIST_HEAD(&jobQ);
+ PR_REMOVE_AND_INIT_LINK(myLink);
+ }
+ PZ_Unlock(qLock);
+ myJob = (JOB *)myLink;
+ /* myJob will be null when stopping is true and jobQ is empty */
+ if (!myJob)
+ break;
+ handle_connection(myJob->tcp_sock, myJob->model_sock,
+ myJob->requestCert);
+ PZ_Lock(qLock);
+ PR_APPEND_LINK(myLink, &freeJobs);
+ PZ_NotifyCondVar(freeListNotEmptyCv);
+ } while (PR_TRUE);
+ return 0;
+}
+
+SECStatus
+launch_threads(
+ startFn *startFunc,
+ PRFileDesc *a,
+ PRFileDesc *b,
+ int c,
+ PRBool local)
+{
+ int i;
+ SECStatus rv = SECSuccess;
+
+ /* create the thread management serialization structs */
+ qLock = PZ_NewLock(nssILockSelfServ);
+ jobQNotEmptyCv = PZ_NewCondVar(qLock);
+ freeListNotEmptyCv = PZ_NewCondVar(qLock);
+ threadCountChangeCv = PZ_NewCondVar(qLock);
+
+ /* create monitor for crl reload procedure */
+ lastLoadedCrlLock = PR_NewLock();
+
+ /* allocate the array of thread slots */
+ threads = PR_Calloc(maxThreads, sizeof(perThread));
+ if (NULL == threads) {
+ fprintf(stderr, "Oh Drat! Can't allocate the perThread array\n");
+ return SECFailure;
+ }
+ /* 5 is a little extra, intended to keep the jobQ from underflowing.
+ ** That is, from going empty while not stopping and clients are still
+ ** trying to contact us.
+ */
+ rv = setupJobs(maxThreads + 5);
+ if (rv != SECSuccess)
+ return rv;
+
+ PZ_Lock(qLock);
+ for (i = 0; i < maxThreads; ++i) {
+ perThread *slot = threads + i;
+
+ slot->state = rs_running;
+ slot->a = a;
+ slot->b = b;
+ slot->c = c;
+ slot->startFunc = startFunc;
+ slot->prThread = PR_CreateThread(PR_USER_THREAD,
+ thread_wrapper, slot, PR_PRIORITY_NORMAL,
+ (PR_TRUE ==
+ local)
+ ? PR_LOCAL_THREAD
+ : PR_GLOBAL_THREAD,
+ PR_JOINABLE_THREAD, 0);
+ if (slot->prThread == NULL) {
+ printf("httpserv: Failed to launch thread!\n");
+ slot->state = rs_idle;
+ rv = SECFailure;
+ break;
+ }
+
+ ++threadCount;
+ }
+ PZ_Unlock(qLock);
+
+ return rv;
+}
+
+#define DESTROY_CONDVAR(name) \
+ if (name) { \
+ PZ_DestroyCondVar(name); \
+ name = NULL; \
+ }
+#define DESTROY_LOCK(name) \
+ if (name) { \
+ PZ_DestroyLock(name); \
+ name = NULL; \
+ }
+
+void
+terminateWorkerThreads(void)
+{
+ int i;
+
+ VLOG(("httpserv: server_thread: waiting on stopping"));
+ PZ_Lock(qLock);
+ PZ_NotifyAllCondVar(jobQNotEmptyCv);
+ PZ_Unlock(qLock);
+
+ /* Wait for worker threads to terminate. */
+ for (i = 0; i < maxThreads; ++i) {
+ perThread *slot = threads + i;
+ if (slot->prThread) {
+ PR_JoinThread(slot->prThread);
+ }
+ }
+
+ /* The worker threads empty the jobQ before they terminate. */
+ PZ_Lock(qLock);
+ PORT_Assert(threadCount == 0);
+ PORT_Assert(PR_CLIST_IS_EMPTY(&jobQ));
+ PZ_Unlock(qLock);
+
+ DESTROY_CONDVAR(jobQNotEmptyCv);
+ DESTROY_CONDVAR(freeListNotEmptyCv);
+ DESTROY_CONDVAR(threadCountChangeCv);
+
+ PR_DestroyLock(lastLoadedCrlLock);
+ DESTROY_LOCK(qLock);
+ PR_Free(jobTable);
+ PR_Free(threads);
+}
+
+/**************************************************************************
+** End thread management routines.
+**************************************************************************/
+
+PRBool NoReuse = PR_FALSE;
+PRBool disableLocking = PR_FALSE;
+static secuPWData pwdata = { PW_NONE, 0 };
+
+struct caRevoInfoStr {
+ PRCList link;
+ char *nickname;
+ char *crlFilename;
+ CERTCertificate *cert;
+ CERTOCSPCertID *id;
+ CERTSignedCrl *crl;
+};
+typedef struct caRevoInfoStr caRevoInfo;
+/* Created during app init. No locks necessary,
+ * because later on, only read access will occur. */
+static caRevoInfo *caRevoInfos = NULL;
+
+static enum {
+ ocspGetOnly,
+ ocspPostOnly,
+ ocspGetAndPost,
+ ocspRandomGetFailure,
+ ocspGetUnknown
+} ocspMethodsAllowed = ocspGetAndPost;
+
+static const char stopCmd[] = { "GET /stop " };
+static const char getCmd[] = { "GET " };
+static const char outHeader[] = {
+ "HTTP/1.0 200 OK\r\n"
+ "Server: Generic Web Server\r\n"
+ "Date: Tue, 26 Aug 1997 22:10:05 GMT\r\n"
+ "Content-type: text/plain\r\n"
+ "\r\n"
+};
+static const char outOcspHeader[] = {
+ "HTTP/1.0 200 OK\r\n"
+ "Server: Generic OCSP Server\r\n"
+ "Content-type: application/ocsp-response\r\n"
+ "\r\n"
+};
+static const char outBadRequestHeader[] = {
+ "HTTP/1.0 400 Bad Request\r\n"
+ "Server: Generic OCSP Server\r\n"
+ "\r\n"
+};
+
+void
+stop_server()
+{
+ stopping = 1;
+ PR_Interrupt(acceptorThread);
+ PZ_TraceFlush();
+}
+
+/* Will only work if the original input to url encoding was
+ * a base64 encoded buffer. Will only decode the sequences used
+ * for encoding the special base64 characters, and fail if any
+ * other encoded chars are found.
+ * Will return SECSuccess if input could be processed.
+ * Coversion is done in place.
+ */
+static SECStatus
+urldecode_base64chars_inplace(char *buf)
+{
+ char *walk;
+ size_t remaining_bytes;
+
+ if (!buf || !*buf)
+ return SECFailure;
+
+ walk = buf;
+ remaining_bytes = strlen(buf) + 1; /* include terminator */
+
+ while (*walk) {
+ if (*walk == '%') {
+ if (!PL_strncasecmp(walk, "%2B", 3)) {
+ *walk = '+';
+ } else if (!PL_strncasecmp(walk, "%2F", 3)) {
+ *walk = '/';
+ } else if (!PL_strncasecmp(walk, "%3D", 3)) {
+ *walk = '=';
+ } else {
+ return SECFailure;
+ }
+ remaining_bytes -= 3;
+ ++walk;
+ memmove(walk, walk + 2, remaining_bytes);
+ } else {
+ ++walk;
+ --remaining_bytes;
+ }
+ }
+ return SECSuccess;
+}
+
+int
+handle_connection(
+ PRFileDesc *tcp_sock,
+ PRFileDesc *model_sock,
+ int requestCert)
+{
+ PRFileDesc *ssl_sock = NULL;
+ PRFileDesc *local_file_fd = NULL;
+ char *pBuf; /* unused space at end of buf */
+ const char *errString;
+ PRStatus status;
+ int bufRem; /* unused bytes at end of buf */
+ int bufDat; /* characters received in buf */
+ int newln = 0; /* # of consecutive newlns */
+ int firstTime = 1;
+ int reqLen;
+ int rv;
+ int numIOVs;
+ PRSocketOptionData opt;
+ PRIOVec iovs[16];
+ char msgBuf[160];
+ char buf[10240];
+ char fileName[513];
+ char *getData = NULL; /* inplace conversion */
+ SECItem postData;
+ PRBool isOcspRequest = PR_FALSE;
+ PRBool isPost;
+
+ postData.data = NULL;
+ postData.len = 0;
+
+ pBuf = buf;
+ bufRem = sizeof buf;
+
+ VLOG(("httpserv: handle_connection: starting"));
+ opt.option = PR_SockOpt_Nonblocking;
+ opt.value.non_blocking = PR_FALSE;
+ PR_SetSocketOption(tcp_sock, &opt);
+
+ VLOG(("httpserv: handle_connection: starting\n"));
+ ssl_sock = tcp_sock;
+
+ if (noDelay) {
+ opt.option = PR_SockOpt_NoDelay;
+ opt.value.no_delay = PR_TRUE;
+ status = PR_SetSocketOption(ssl_sock, &opt);
+ if (status != PR_SUCCESS) {
+ errWarn("PR_SetSocketOption(PR_SockOpt_NoDelay, PR_TRUE)");
+ if (ssl_sock) {
+ PR_Close(ssl_sock);
+ }
+ return SECFailure;
+ }
+ }
+
+ while (1) {
+ const char *post;
+ const char *foundStr = NULL;
+ const char *tmp = NULL;
+
+ newln = 0;
+ reqLen = 0;
+
+ rv = PR_Read(ssl_sock, pBuf, bufRem - 1);
+ if (rv == 0 ||
+ (rv < 0 && PR_END_OF_FILE_ERROR == PR_GetError())) {
+ if (verbose)
+ errWarn("HDX PR_Read hit EOF");
+ break;
+ }
+ if (rv < 0) {
+ errWarn("HDX PR_Read");
+ goto cleanup;
+ }
+ /* NULL termination */
+ pBuf[rv] = 0;
+ if (firstTime) {
+ firstTime = 0;
+ }
+
+ pBuf += rv;
+ bufRem -= rv;
+ bufDat = pBuf - buf;
+ /* Parse the input, starting at the beginning of the buffer.
+ * Stop when we detect two consecutive \n's (or \r\n's)
+ * as this signifies the end of the GET or POST portion.
+ * The posted data follows.
+ */
+ while (reqLen < bufDat && newln < 2) {
+ int octet = buf[reqLen++];
+ if (octet == '\n') {
+ newln++;
+ } else if (octet != '\r') {
+ newln = 0;
+ }
+ }
+
+ /* came to the end of the buffer, or second newln
+ * If we didn't get an empty line (CRLFCRLF) then keep on reading.
+ */
+ if (newln < 2)
+ continue;
+
+ /* we're at the end of the HTTP request.
+ * If the request is a POST, then there will be one more
+ * line of data.
+ * This parsing is a hack, but ok for SSL test purposes.
+ */
+ post = PORT_Strstr(buf, "POST ");
+ if (!post || *post != 'P')
+ break;
+
+ postData.data = (void *)(buf + reqLen);
+
+ tmp = "content-length: ";
+ foundStr = PL_strcasestr(buf, tmp);
+ if (foundStr) {
+ int expectedPostLen;
+ int havePostLen;
+
+ expectedPostLen = atoi(foundStr + strlen(tmp));
+ havePostLen = bufDat - reqLen;
+ if (havePostLen >= expectedPostLen) {
+ postData.len = expectedPostLen;
+ break;
+ }
+ } else {
+ /* use legacy hack */
+ /* It's a post, so look for the next and final CR/LF. */
+ while (reqLen < bufDat && newln < 3) {
+ int octet = buf[reqLen++];
+ if (octet == '\n') {
+ newln++;
+ }
+ }
+ if (newln == 3)
+ break;
+ }
+ } /* read loop */
+
+ bufDat = pBuf - buf;
+ if (bufDat)
+ do { /* just close if no data */
+ /* Have either (a) a complete get, (b) a complete post, (c) EOF */
+ if (reqLen > 0) {
+ PRBool isGetOrPost = PR_FALSE;
+ unsigned skipChars = 0;
+ isPost = PR_FALSE;
+
+ if (!strncmp(buf, getCmd, sizeof getCmd - 1)) {
+ isGetOrPost = PR_TRUE;
+ skipChars = 4;
+ } else if (!strncmp(buf, "POST ", 5)) {
+ isGetOrPost = PR_TRUE;
+ isPost = PR_TRUE;
+ skipChars = 5;
+ }
+
+ if (isGetOrPost) {
+ char *fnBegin = buf;
+ char *fnEnd;
+ char *fnstart = NULL;
+ PRFileInfo info;
+
+ fnBegin += skipChars;
+
+ fnEnd = strpbrk(fnBegin, " \r\n");
+ if (fnEnd) {
+ int fnLen = fnEnd - fnBegin;
+ if (fnLen < sizeof fileName) {
+ strncpy(fileName, fnBegin, fnLen);
+ fileName[fnLen] = 0; /* null terminate */
+ fnstart = fileName;
+ /* strip initial / because our root is the current directory*/
+ while (*fnstart && *fnstart == '/')
+ ++fnstart;
+ }
+ }
+ if (fnstart) {
+ if (!strncmp(fnstart, "ocsp", 4)) {
+ if (isPost) {
+ if (postData.data) {
+ isOcspRequest = PR_TRUE;
+ }
+ } else {
+ if (!strncmp(fnstart, "ocsp/", 5)) {
+ isOcspRequest = PR_TRUE;
+ getData = fnstart + 5;
+ }
+ }
+ } else {
+ /* try to open the file named.
+ * If successful, then write it to the client.
+ */
+ status = PR_GetFileInfo(fnstart, &info);
+ if (status == PR_SUCCESS &&
+ info.type == PR_FILE_FILE &&
+ info.size >= 0) {
+ local_file_fd = PR_Open(fnstart, PR_RDONLY, 0);
+ }
+ }
+ }
+ }
+ }
+
+ numIOVs = 0;
+
+ iovs[numIOVs].iov_base = (char *)outHeader;
+ iovs[numIOVs].iov_len = (sizeof(outHeader)) - 1;
+ numIOVs++;
+
+ if (isOcspRequest && caRevoInfos) {
+ CERTOCSPRequest *request = NULL;
+ PRBool failThisRequest = PR_FALSE;
+ PLArenaPool *arena = NULL;
+
+ if (ocspMethodsAllowed == ocspGetOnly && postData.len) {
+ failThisRequest = PR_TRUE;
+ } else if (ocspMethodsAllowed == ocspPostOnly && getData) {
+ failThisRequest = PR_TRUE;
+ } else if (ocspMethodsAllowed == ocspRandomGetFailure && getData) {
+ if (!(rand() % 2)) {
+ failThisRequest = PR_TRUE;
+ }
+ }
+
+ if (failThisRequest) {
+ PR_Write(ssl_sock, outBadRequestHeader, strlen(outBadRequestHeader));
+ break;
+ }
+ /* get is base64, post is binary.
+ * If we have base64, convert into the (empty) postData array.
+ */
+ if (getData) {
+ if (urldecode_base64chars_inplace(getData) == SECSuccess) {
+ /* The code below can handle a NULL arena */
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ NSSBase64_DecodeBuffer(arena, &postData, getData, strlen(getData));
+ }
+ }
+ if (postData.len) {
+ request = CERT_DecodeOCSPRequest(&postData);
+ }
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+ if (!request || !request->tbsRequest ||
+ !request->tbsRequest->requestList ||
+ !request->tbsRequest->requestList[0]) {
+ PORT_Sprintf(msgBuf, "Cannot decode OCSP request.\r\n");
+
+ iovs[numIOVs].iov_base = msgBuf;
+ iovs[numIOVs].iov_len = PORT_Strlen(msgBuf);
+ numIOVs++;
+ } else {
+ /* TODO: support more than one request entry */
+ CERTOCSPCertID *reqid = request->tbsRequest->requestList[0]->reqCert;
+ const caRevoInfo *revoInfo = NULL;
+ PRBool unknown = PR_FALSE;
+ PRBool revoked = PR_FALSE;
+ PRTime nextUpdate = 0;
+ PRTime revoDate = 0;
+ PRCList *caRevoIter;
+
+ caRevoIter = &caRevoInfos->link;
+ do {
+ CERTOCSPCertID *caid;
+
+ revoInfo = (caRevoInfo *)caRevoIter;
+ caid = revoInfo->id;
+
+ if (SECOID_CompareAlgorithmID(&reqid->hashAlgorithm,
+ &caid->hashAlgorithm) == SECEqual &&
+ SECITEM_CompareItem(&reqid->issuerNameHash,
+ &caid->issuerNameHash) == SECEqual &&
+ SECITEM_CompareItem(&reqid->issuerKeyHash,
+ &caid->issuerKeyHash) == SECEqual) {
+ break;
+ }
+ revoInfo = NULL;
+ caRevoIter = PR_NEXT_LINK(caRevoIter);
+ } while (caRevoIter != &caRevoInfos->link);
+
+ if (!revoInfo) {
+ unknown = PR_TRUE;
+ revoInfo = caRevoInfos;
+ } else {
+ CERTCrl *crl = &revoInfo->crl->crl;
+ CERTCrlEntry *entry = NULL;
+ DER_DecodeTimeChoice(&nextUpdate, &crl->nextUpdate);
+ if (crl->entries) {
+ int iv = 0;
+ /* assign, not compare */
+ while ((entry = crl->entries[iv++])) {
+ if (SECITEM_CompareItem(&reqid->serialNumber,
+ &entry->serialNumber) == SECEqual) {
+ break;
+ }
+ }
+ }
+ if (entry) {
+ /* revoked status response */
+ revoked = PR_TRUE;
+ DER_DecodeTimeChoice(&revoDate, &entry->revocationDate);
+ } else {
+ /* else good status response */
+ if (!isPost && ocspMethodsAllowed == ocspGetUnknown) {
+ unknown = PR_TRUE;
+ nextUpdate = PR_Now() + (PRTime)60 * 60 * 24 * PR_USEC_PER_SEC; /*tomorrow*/
+ revoDate = PR_Now() - (PRTime)60 * 60 * 24 * PR_USEC_PER_SEC; /*yesterday*/
+ }
+ }
+ }
+
+ {
+ PRTime now = PR_Now();
+ PLArenaPool *arena = NULL;
+ CERTOCSPSingleResponse *sr;
+ CERTOCSPSingleResponse **singleResponses;
+ SECItem *ocspResponse;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if (unknown) {
+ sr = CERT_CreateOCSPSingleResponseUnknown(arena, reqid, now,
+ &nextUpdate);
+ } else if (revoked) {
+ sr = CERT_CreateOCSPSingleResponseRevoked(arena, reqid, now,
+ &nextUpdate, revoDate, NULL);
+ } else {
+ sr = CERT_CreateOCSPSingleResponseGood(arena, reqid, now,
+ &nextUpdate);
+ }
+
+ /* meaning of value 2: one entry + one end marker */
+ singleResponses = PORT_ArenaNewArray(arena, CERTOCSPSingleResponse *, 2);
+ singleResponses[0] = sr;
+ singleResponses[1] = NULL;
+ ocspResponse = CERT_CreateEncodedOCSPSuccessResponse(arena,
+ revoInfo->cert, ocspResponderID_byName, now,
+ singleResponses, &pwdata);
+
+ if (!ocspResponse) {
+ PORT_Sprintf(msgBuf, "Failed to encode response\r\n");
+ iovs[numIOVs].iov_base = msgBuf;
+ iovs[numIOVs].iov_len = PORT_Strlen(msgBuf);
+ numIOVs++;
+ } else {
+ PR_Write(ssl_sock, outOcspHeader, strlen(outOcspHeader));
+ PR_Write(ssl_sock, ocspResponse->data, ocspResponse->len);
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+ }
+ CERT_DestroyOCSPRequest(request);
+ break;
+ }
+ } else if (local_file_fd) {
+ PRInt32 bytes;
+ int errLen;
+ bytes = PR_TransmitFile(ssl_sock, local_file_fd, outHeader,
+ sizeof outHeader - 1,
+ PR_TRANSMITFILE_KEEP_OPEN,
+ PR_INTERVAL_NO_TIMEOUT);
+ if (bytes >= 0) {
+ bytes -= sizeof outHeader - 1;
+ FPRINTF(stderr,
+ "httpserv: PR_TransmitFile wrote %d bytes from %s\n",
+ bytes, fileName);
+ break;
+ }
+ errString = errWarn("PR_TransmitFile");
+ errLen = PORT_Strlen(errString);
+ errLen = PR_MIN(errLen, sizeof msgBuf - 1);
+ PORT_Memcpy(msgBuf, errString, errLen);
+ msgBuf[errLen] = 0;
+
+ iovs[numIOVs].iov_base = msgBuf;
+ iovs[numIOVs].iov_len = PORT_Strlen(msgBuf);
+ numIOVs++;
+ } else if (reqLen <= 0) { /* hit eof */
+ PORT_Sprintf(msgBuf, "Get or Post incomplete after %d bytes.\r\n",
+ bufDat);
+
+ iovs[numIOVs].iov_base = msgBuf;
+ iovs[numIOVs].iov_len = PORT_Strlen(msgBuf);
+ numIOVs++;
+ } else if (reqLen < bufDat) {
+ PORT_Sprintf(msgBuf, "Discarded %d characters.\r\n",
+ bufDat - reqLen);
+
+ iovs[numIOVs].iov_base = msgBuf;
+ iovs[numIOVs].iov_len = PORT_Strlen(msgBuf);
+ numIOVs++;
+ }
+
+ if (reqLen > 0) {
+ if (verbose > 1)
+ fwrite(buf, 1, reqLen, stdout); /* display it */
+
+ iovs[numIOVs].iov_base = buf;
+ iovs[numIOVs].iov_len = reqLen;
+ numIOVs++;
+ }
+
+ rv = PR_Writev(ssl_sock, iovs, numIOVs, PR_INTERVAL_NO_TIMEOUT);
+ if (rv < 0) {
+ errWarn("PR_Writev");
+ break;
+ }
+
+ } while (0);
+
+cleanup:
+ if (ssl_sock) {
+ PR_Close(ssl_sock);
+ } else if (tcp_sock) {
+ PR_Close(tcp_sock);
+ }
+ if (local_file_fd)
+ PR_Close(local_file_fd);
+ VLOG(("httpserv: handle_connection: exiting\n"));
+
+ /* do a nice shutdown if asked. */
+ if (!strncmp(buf, stopCmd, sizeof stopCmd - 1)) {
+ VLOG(("httpserv: handle_connection: stop command"));
+ stop_server();
+ }
+ VLOG(("httpserv: handle_connection: exiting"));
+ return SECSuccess; /* success */
+}
+
+#ifdef XP_UNIX
+
+void
+sigusr1_handler(int sig)
+{
+ VLOG(("httpserv: sigusr1_handler: stop server"));
+ stop_server();
+}
+
+#endif
+
+SECStatus
+do_accepts(
+ PRFileDesc *listen_sock,
+ PRFileDesc *model_sock,
+ int requestCert)
+{
+ PRNetAddr addr;
+ PRErrorCode perr;
+#ifdef XP_UNIX
+ struct sigaction act;
+#endif
+
+ VLOG(("httpserv: do_accepts: starting"));
+ PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_HIGH);
+
+ acceptorThread = PR_GetCurrentThread();
+#ifdef XP_UNIX
+ /* set up the signal handler */
+ act.sa_handler = sigusr1_handler;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ if (sigaction(SIGUSR1, &act, NULL)) {
+ fprintf(stderr, "Error installing signal handler.\n");
+ exit(1);
+ }
+#endif
+ while (!stopping) {
+ PRFileDesc *tcp_sock;
+ PRCList *myLink;
+
+ FPRINTF(stderr, "\n\n\nhttpserv: About to call accept.\n");
+ tcp_sock = PR_Accept(listen_sock, &addr, PR_INTERVAL_NO_TIMEOUT);
+ if (tcp_sock == NULL) {
+ perr = PR_GetError();
+ if ((perr != PR_CONNECT_RESET_ERROR &&
+ perr != PR_PENDING_INTERRUPT_ERROR) ||
+ verbose) {
+ errWarn("PR_Accept");
+ }
+ if (perr == PR_CONNECT_RESET_ERROR) {
+ FPRINTF(stderr,
+ "Ignoring PR_CONNECT_RESET_ERROR error - continue\n");
+ continue;
+ }
+ stopping = 1;
+ break;
+ }
+
+ VLOG(("httpserv: do_accept: Got connection\n"));
+
+ PZ_Lock(qLock);
+ while (PR_CLIST_IS_EMPTY(&freeJobs) && !stopping) {
+ PZ_WaitCondVar(freeListNotEmptyCv, PR_INTERVAL_NO_TIMEOUT);
+ }
+ if (stopping) {
+ PZ_Unlock(qLock);
+ if (tcp_sock) {
+ PR_Close(tcp_sock);
+ }
+ break;
+ }
+ myLink = PR_LIST_HEAD(&freeJobs);
+ PR_REMOVE_AND_INIT_LINK(myLink);
+ /* could release qLock here and reaquire it 7 lines below, but
+ ** why bother for 4 assignment statements?
+ */
+ {
+ JOB *myJob = (JOB *)myLink;
+ myJob->tcp_sock = tcp_sock;
+ myJob->model_sock = model_sock;
+ myJob->requestCert = requestCert;
+ }
+
+ PR_APPEND_LINK(myLink, &jobQ);
+ PZ_NotifyCondVar(jobQNotEmptyCv);
+ PZ_Unlock(qLock);
+ }
+
+ FPRINTF(stderr, "httpserv: Closing listen socket.\n");
+ VLOG(("httpserv: do_accepts: exiting"));
+ if (listen_sock) {
+ PR_Close(listen_sock);
+ }
+ return SECSuccess;
+}
+
+PRFileDesc *
+getBoundListenSocket(unsigned short port)
+{
+ PRFileDesc *listen_sock;
+ int listenQueueDepth = 5 + (2 * maxThreads);
+ PRStatus prStatus;
+ PRNetAddr addr;
+ PRSocketOptionData opt;
+
+ addr.inet.family = PR_AF_INET;
+ addr.inet.ip = PR_INADDR_ANY;
+ addr.inet.port = PR_htons(port);
+
+ listen_sock = PR_NewTCPSocket();
+ if (listen_sock == NULL) {
+ errExit("PR_NewTCPSocket");
+ }
+
+ opt.option = PR_SockOpt_Nonblocking;
+ opt.value.non_blocking = PR_FALSE;
+ prStatus = PR_SetSocketOption(listen_sock, &opt);
+ if (prStatus < 0) {
+ PR_Close(listen_sock);
+ errExit("PR_SetSocketOption(PR_SockOpt_Nonblocking)");
+ }
+
+ opt.option = PR_SockOpt_Reuseaddr;
+ opt.value.reuse_addr = PR_TRUE;
+ prStatus = PR_SetSocketOption(listen_sock, &opt);
+ if (prStatus < 0) {
+ PR_Close(listen_sock);
+ errExit("PR_SetSocketOption(PR_SockOpt_Reuseaddr)");
+ }
+
+#ifndef WIN95
+ /* Set PR_SockOpt_Linger because it helps prevent a server bind issue
+ * after clean shutdown . See bug 331413 .
+ * Don't do it in the WIN95 build configuration because clean shutdown is
+ * not implemented, and PR_SockOpt_Linger causes a hang in ssl.sh .
+ * See bug 332348 */
+ opt.option = PR_SockOpt_Linger;
+ opt.value.linger.polarity = PR_TRUE;
+ opt.value.linger.linger = PR_SecondsToInterval(1);
+ prStatus = PR_SetSocketOption(listen_sock, &opt);
+ if (prStatus < 0) {
+ PR_Close(listen_sock);
+ errExit("PR_SetSocketOption(PR_SockOpt_Linger)");
+ }
+#endif
+
+ prStatus = PR_Bind(listen_sock, &addr);
+ if (prStatus < 0) {
+ PR_Close(listen_sock);
+ errExit("PR_Bind");
+ }
+
+ prStatus = PR_Listen(listen_sock, listenQueueDepth);
+ if (prStatus < 0) {
+ PR_Close(listen_sock);
+ errExit("PR_Listen");
+ }
+ return listen_sock;
+}
+
+void
+server_main(
+ PRFileDesc *listen_sock,
+ int requestCert,
+ SECKEYPrivateKey **privKey,
+ CERTCertificate **cert,
+ const char *expectedHostNameVal)
+{
+ PRFileDesc *model_sock = NULL;
+
+ /* Now, do the accepting, here in the main thread. */
+ do_accepts(listen_sock, model_sock, requestCert);
+
+ terminateWorkerThreads();
+
+ if (model_sock) {
+ PR_Close(model_sock);
+ }
+}
+
+int numChildren;
+PRProcess *child[MAX_PROCS];
+
+PRProcess *
+haveAChild(int argc, char **argv, PRProcessAttr *attr)
+{
+ PRProcess *newProcess;
+
+ newProcess = PR_CreateProcess(argv[0], argv, NULL, attr);
+ if (!newProcess) {
+ errWarn("Can't create new process.");
+ } else {
+ child[numChildren++] = newProcess;
+ }
+ return newProcess;
+}
+
+/* slightly adjusted version of ocsp_CreateCertID (not using issuer) */
+static CERTOCSPCertID *
+ocsp_CreateSelfCAID(PLArenaPool *arena, CERTCertificate *cert, PRTime time)
+{
+ CERTOCSPCertID *certID;
+ void *mark = PORT_ArenaMark(arena);
+ SECStatus rv;
+
+ PORT_Assert(arena != NULL);
+
+ certID = PORT_ArenaZNew(arena, CERTOCSPCertID);
+ if (certID == NULL) {
+ goto loser;
+ }
+
+ rv = SECOID_SetAlgorithmID(arena, &certID->hashAlgorithm, SEC_OID_SHA1,
+ NULL);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ if (CERT_GetSubjectNameDigest(arena, cert, SEC_OID_SHA1,
+ &(certID->issuerNameHash)) == NULL) {
+ goto loser;
+ }
+ certID->issuerSHA1NameHash.data = certID->issuerNameHash.data;
+ certID->issuerSHA1NameHash.len = certID->issuerNameHash.len;
+
+ if (CERT_GetSubjectNameDigest(arena, cert, SEC_OID_MD5,
+ &(certID->issuerMD5NameHash)) == NULL) {
+ goto loser;
+ }
+
+ if (CERT_GetSubjectNameDigest(arena, cert, SEC_OID_MD2,
+ &(certID->issuerMD2NameHash)) == NULL) {
+ goto loser;
+ }
+
+ if (CERT_GetSubjectPublicKeyDigest(arena, cert, SEC_OID_SHA1,
+ &certID->issuerKeyHash) == NULL) {
+ goto loser;
+ }
+ certID->issuerSHA1KeyHash.data = certID->issuerKeyHash.data;
+ certID->issuerSHA1KeyHash.len = certID->issuerKeyHash.len;
+ /* cache the other two hash algorithms as well */
+ if (CERT_GetSubjectPublicKeyDigest(arena, cert, SEC_OID_MD5,
+ &certID->issuerMD5KeyHash) == NULL) {
+ goto loser;
+ }
+ if (CERT_GetSubjectPublicKeyDigest(arena, cert, SEC_OID_MD2,
+ &certID->issuerMD2KeyHash) == NULL) {
+ goto loser;
+ }
+
+ PORT_ArenaUnmark(arena, mark);
+ return certID;
+
+loser:
+ PORT_ArenaRelease(arena, mark);
+ return NULL;
+}
+
+/* slightly adjusted version of CERT_CreateOCSPCertID */
+CERTOCSPCertID *
+cert_CreateSelfCAID(CERTCertificate *cert, PRTime time)
+{
+ PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ CERTOCSPCertID *certID;
+ PORT_Assert(arena != NULL);
+ if (!arena)
+ return NULL;
+
+ certID = ocsp_CreateSelfCAID(arena, cert, time);
+ if (!certID) {
+ PORT_FreeArena(arena, PR_FALSE);
+ return NULL;
+ }
+ certID->poolp = arena;
+ return certID;
+}
+
+int
+main(int argc, char **argv)
+{
+ char *progName = NULL;
+ const char *dir = ".";
+ char *passwd = NULL;
+ char *pwfile = NULL;
+ const char *pidFile = NULL;
+ char *tmp;
+ PRFileDesc *listen_sock;
+ int optionsFound = 0;
+ unsigned short port = 0;
+ SECStatus rv;
+ PRStatus prStatus;
+ PRBool bindOnly = PR_FALSE;
+ PRBool useLocalThreads = PR_FALSE;
+ PLOptState *optstate;
+ PLOptStatus status;
+ char emptyString[] = { "" };
+ char *certPrefix = emptyString;
+ caRevoInfo *revoInfo = NULL;
+ PRCList *caRevoIter = NULL;
+ PRBool provideOcsp = PR_FALSE;
+
+ tmp = strrchr(argv[0], '/');
+ tmp = tmp ? tmp + 1 : argv[0];
+ progName = strrchr(tmp, '\\');
+ progName = progName ? progName + 1 : tmp;
+
+ PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
+
+ /* please keep this list of options in ASCII collating sequence.
+ ** numbers, then capital letters, then lower case, alphabetical.
+ */
+ optstate = PL_CreateOptState(argc, argv,
+ "A:C:DO:P:bd:f:hi:p:t:vw:");
+ while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
+ ++optionsFound;
+ switch (optstate->option) {
+ /* A first, must be followed by C. Any other order is an error.
+ * A creates the object. C completes and moves into list.
+ */
+ case 'A':
+ provideOcsp = PR_TRUE;
+ if (revoInfo) {
+ Usage(progName);
+ exit(0);
+ }
+ revoInfo = PORT_New(caRevoInfo);
+ revoInfo->nickname = PORT_Strdup(optstate->value);
+ break;
+ case 'C':
+ if (!revoInfo) {
+ Usage(progName);
+ exit(0);
+ }
+ revoInfo->crlFilename = PORT_Strdup(optstate->value);
+ if (!caRevoInfos) {
+ PR_INIT_CLIST(&revoInfo->link);
+ caRevoInfos = revoInfo;
+ } else {
+ PR_APPEND_LINK(&revoInfo->link, &caRevoInfos->link);
+ }
+ revoInfo = NULL;
+ break;
+
+ case 'O':
+ if (!PL_strcasecmp(optstate->value, "all")) {
+ ocspMethodsAllowed = ocspGetAndPost;
+ } else if (!PL_strcasecmp(optstate->value, "get")) {
+ ocspMethodsAllowed = ocspGetOnly;
+ } else if (!PL_strcasecmp(optstate->value, "post")) {
+ ocspMethodsAllowed = ocspPostOnly;
+ } else if (!PL_strcasecmp(optstate->value, "random")) {
+ ocspMethodsAllowed = ocspRandomGetFailure;
+ } else if (!PL_strcasecmp(optstate->value, "get-unknown")) {
+ ocspMethodsAllowed = ocspGetUnknown;
+ } else {
+ Usage(progName);
+ exit(0);
+ }
+ break;
+
+ case 'D':
+ noDelay = PR_TRUE;
+ break;
+
+ case 'P':
+ certPrefix = PORT_Strdup(optstate->value);
+ break;
+
+ case 'b':
+ bindOnly = PR_TRUE;
+ break;
+
+ case 'd':
+ dir = optstate->value;
+ break;
+
+ case 'f':
+ pwdata.source = PW_FROMFILE;
+ pwdata.data = pwfile = PORT_Strdup(optstate->value);
+ break;
+
+ case 'h':
+ Usage(progName);
+ exit(0);
+ break;
+
+ case 'i':
+ pidFile = optstate->value;
+ break;
+
+ case 'p':
+ port = PORT_Atoi(optstate->value);
+ break;
+
+ case 't':
+ maxThreads = PORT_Atoi(optstate->value);
+ if (maxThreads > MAX_THREADS)
+ maxThreads = MAX_THREADS;
+ if (maxThreads < MIN_THREADS)
+ maxThreads = MIN_THREADS;
+ break;
+
+ case 'v':
+ verbose++;
+ break;
+
+ case 'w':
+ pwdata.source = PW_PLAINTEXT;
+ pwdata.data = passwd = PORT_Strdup(optstate->value);
+ break;
+
+ default:
+ case '?':
+ fprintf(stderr, "Unrecognized or bad option specified.\n");
+ fprintf(stderr, "Run '%s -h' for usage information.\n", progName);
+ exit(4);
+ break;
+ }
+ }
+ PL_DestroyOptState(optstate);
+ if (status == PL_OPT_BAD) {
+ fprintf(stderr, "Unrecognized or bad option specified.\n");
+ fprintf(stderr, "Run '%s -h' for usage information.\n", progName);
+ exit(5);
+ }
+ if (!optionsFound) {
+ Usage(progName);
+ exit(51);
+ }
+
+ /* The -b (bindOnly) option is only used by the ssl.sh test
+ * script on Linux to determine whether a previous httpserv
+ * process has fully died and freed the port. (Bug 129701)
+ */
+ if (bindOnly) {
+ listen_sock = getBoundListenSocket(port);
+ if (!listen_sock) {
+ exit(1);
+ }
+ if (listen_sock) {
+ PR_Close(listen_sock);
+ }
+ exit(0);
+ }
+
+ if (port == 0) {
+ fprintf(stderr, "Required argument 'port' must be non-zero value\n");
+ exit(7);
+ }
+
+ if (pidFile) {
+ FILE *tmpfile = fopen(pidFile, "w+");
+
+ if (tmpfile) {
+ fprintf(tmpfile, "%d", getpid());
+ fclose(tmpfile);
+ }
+ }
+
+ tmp = PR_GetEnvSecure("TMP");
+ if (!tmp)
+ tmp = PR_GetEnvSecure("TMPDIR");
+ if (!tmp)
+ tmp = PR_GetEnvSecure("TEMP");
+ /* we're an ordinary single process server. */
+ listen_sock = getBoundListenSocket(port);
+ prStatus = PR_SetFDInheritable(listen_sock, PR_FALSE);
+ if (prStatus != PR_SUCCESS)
+ errExit("PR_SetFDInheritable");
+
+ lm = PR_NewLogModule("TestCase");
+
+ /* set our password function */
+ PK11_SetPasswordFunc(SECU_GetModulePassword);
+
+ if (provideOcsp) {
+ /* Call the NSS initialization routines */
+ rv = NSS_Initialize(dir, certPrefix, certPrefix, SECMOD_DB, NSS_INIT_READONLY);
+ if (rv != SECSuccess) {
+ fputs("NSS_Init failed.\n", stderr);
+ exit(8);
+ }
+
+ if (caRevoInfos) {
+ caRevoIter = &caRevoInfos->link;
+ do {
+ PRFileDesc *inFile;
+ int rv = SECFailure;
+ SECItem crlDER;
+ crlDER.data = NULL;
+
+ revoInfo = (caRevoInfo *)caRevoIter;
+ revoInfo->cert = CERT_FindCertByNickname(
+ CERT_GetDefaultCertDB(), revoInfo->nickname);
+ if (!revoInfo->cert) {
+ fprintf(stderr, "cannot find cert with nickname %s\n",
+ revoInfo->nickname);
+ exit(1);
+ }
+ inFile = PR_Open(revoInfo->crlFilename, PR_RDONLY, 0);
+ if (inFile) {
+ rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE, PR_FALSE);
+ PR_Close(inFile);
+ inFile = NULL;
+ }
+ if (rv != SECSuccess) {
+ fprintf(stderr, "unable to read crl file %s\n",
+ revoInfo->crlFilename);
+ exit(1);
+ }
+ revoInfo->crl =
+ CERT_DecodeDERCrlWithFlags(NULL, &crlDER, SEC_CRL_TYPE,
+ CRL_DECODE_DEFAULT_OPTIONS);
+ SECITEM_FreeItem(&crlDER, PR_FALSE);
+ if (!revoInfo->crl) {
+ fprintf(stderr, "unable to decode crl file %s\n",
+ revoInfo->crlFilename);
+ exit(1);
+ }
+ if (CERT_CompareName(&revoInfo->crl->crl.name,
+ &revoInfo->cert->subject) != SECEqual) {
+ fprintf(stderr, "CRL %s doesn't match cert identified by preceding nickname %s\n",
+ revoInfo->crlFilename, revoInfo->nickname);
+ exit(1);
+ }
+ revoInfo->id = cert_CreateSelfCAID(revoInfo->cert, PR_Now());
+ caRevoIter = PR_NEXT_LINK(caRevoIter);
+ } while (caRevoIter != &caRevoInfos->link);
+ }
+ }
+
+ /* allocate the array of thread slots, and launch the worker threads. */
+ rv = launch_threads(&jobLoop, 0, 0, 0, useLocalThreads);
+
+ if (rv == SECSuccess) {
+ server_main(listen_sock, 0, 0, 0,
+ 0);
+ }
+
+ VLOG(("httpserv: server_thread: exiting"));
+
+ if (provideOcsp) {
+ if (caRevoInfos) {
+ PRCList *caRevoIter;
+
+ caRevoIter = &caRevoInfos->link;
+ do {
+ caRevoInfo *revoInfo = (caRevoInfo *)caRevoIter;
+ if (revoInfo->nickname)
+ PORT_Free(revoInfo->nickname);
+ if (revoInfo->crlFilename)
+ PORT_Free(revoInfo->crlFilename);
+ if (revoInfo->cert)
+ CERT_DestroyCertificate(revoInfo->cert);
+ if (revoInfo->id)
+ CERT_DestroyOCSPCertID(revoInfo->id);
+ if (revoInfo->crl)
+ SEC_DestroyCrl(revoInfo->crl);
+
+ caRevoIter = PR_NEXT_LINK(caRevoIter);
+ } while (caRevoIter != &caRevoInfos->link);
+ }
+ if (NSS_Shutdown() != SECSuccess) {
+ SECU_PrintError(progName, "NSS_Shutdown");
+ PR_Cleanup();
+ exit(1);
+ }
+ }
+ if (passwd) {
+ PORT_Free(passwd);
+ }
+ if (pwfile) {
+ PORT_Free(pwfile);
+ }
+ if (certPrefix && certPrefix != emptyString) {
+ PORT_Free(certPrefix);
+ }
+ PR_Cleanup();
+ printf("httpserv: normal termination\n");
+ return 0;
+}
diff --git a/nss/cmd/httpserv/httpserv.gyp b/nss/cmd/httpserv/httpserv.gyp
new file mode 100644
index 0000000..0067066
--- /dev/null
+++ b/nss/cmd/httpserv/httpserv.gyp
@@ -0,0 +1,30 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi',
+ '../../cmd/platlibs.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'httpserv',
+ 'type': 'executable',
+ 'sources': [
+ 'httpserv.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:dbm_exports',
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'target_defaults': {
+ 'defines': [
+ 'NSPR20'
+ ]
+ },
+ 'variables': {
+ 'module': 'nss'
+ }
+}
\ No newline at end of file
diff --git a/nss/cmd/httpserv/manifest.mn b/nss/cmd/httpserv/manifest.mn
new file mode 100644
index 0000000..e969661
--- /dev/null
+++ b/nss/cmd/httpserv/manifest.mn
@@ -0,0 +1,20 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+CORE_DEPTH = ../..
+
+DEFINES += -DNSPR20
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+CSRCS = httpserv.c
+
+# The MODULE is always implicitly required.
+# Listing it here in REQUIRES makes it appear twice in the cc command line.
+REQUIRES = seccmd dbm
+
+PROGRAM = httpserv
+
diff --git a/nss/cmd/lib/Makefile b/nss/cmd/lib/Makefile
new file mode 100644
index 0000000..0fb6c90
--- /dev/null
+++ b/nss/cmd/lib/Makefile
@@ -0,0 +1,49 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include config.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+export:: private_export
+
+
diff --git a/nss/cmd/lib/basicutil.c b/nss/cmd/lib/basicutil.c
new file mode 100644
index 0000000..8b491d7
--- /dev/null
+++ b/nss/cmd/lib/basicutil.c
@@ -0,0 +1,776 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+** secutil.c - various functions used by security stuff
+**
+*/
+
+#include "prtypes.h"
+#include "prtime.h"
+#include "prlong.h"
+#include "prerror.h"
+#include "prprf.h"
+#include "plgetopt.h"
+#include "prenv.h"
+#include "prnetdb.h"
+
+#include "basicutil.h"
+#include
+#include
+#include
+
+#ifdef XP_UNIX
+#include
+#endif
+
+#include "secoid.h"
+
+extern long DER_GetInteger(const SECItem *src);
+
+static PRBool wrapEnabled = PR_TRUE;
+
+void
+SECU_EnableWrap(PRBool enable)
+{
+ wrapEnabled = enable;
+}
+
+PRBool
+SECU_GetWrapEnabled(void)
+{
+ return wrapEnabled;
+}
+
+void
+SECU_PrintErrMsg(FILE *out, int level, const char *progName, const char *msg,
+ ...)
+{
+ va_list args;
+ PRErrorCode err = PORT_GetError();
+ const char *errString = PORT_ErrorToString(err);
+
+ va_start(args, msg);
+
+ SECU_Indent(out, level);
+ fprintf(out, "%s: ", progName);
+ vfprintf(out, msg, args);
+ if (errString != NULL && PORT_Strlen(errString) > 0)
+ fprintf(out, ": %s\n", errString);
+ else
+ fprintf(out, ": error %d\n", (int)err);
+
+ va_end(args);
+}
+
+void
+SECU_PrintError(const char *progName, const char *msg, ...)
+{
+ va_list args;
+ PRErrorCode err = PORT_GetError();
+ const char *errName = PR_ErrorToName(err);
+ const char *errString = PR_ErrorToString(err, 0);
+
+ va_start(args, msg);
+
+ fprintf(stderr, "%s: ", progName);
+ vfprintf(stderr, msg, args);
+
+ if (errName != NULL) {
+ fprintf(stderr, ": %s", errName);
+ } else {
+ fprintf(stderr, ": error %d", (int)err);
+ }
+
+ if (errString != NULL && PORT_Strlen(errString) > 0)
+ fprintf(stderr, ": %s\n", errString);
+
+ va_end(args);
+}
+
+void
+SECU_PrintSystemError(const char *progName, const char *msg, ...)
+{
+ va_list args;
+
+ va_start(args, msg);
+ fprintf(stderr, "%s: ", progName);
+ vfprintf(stderr, msg, args);
+ fprintf(stderr, ": %s\n", strerror(errno));
+ va_end(args);
+}
+
+SECStatus
+secu_StdinToItem(SECItem *dst)
+{
+ unsigned char buf[1000];
+ PRInt32 numBytes;
+ PRBool notDone = PR_TRUE;
+
+ dst->len = 0;
+ dst->data = NULL;
+
+ while (notDone) {
+ numBytes = PR_Read(PR_STDIN, buf, sizeof(buf));
+
+ if (numBytes < 0) {
+ return SECFailure;
+ }
+
+ if (numBytes == 0)
+ break;
+
+ if (dst->data) {
+ unsigned char *p = dst->data;
+ dst->data = (unsigned char *)PORT_Realloc(p, dst->len + numBytes);
+ if (!dst->data) {
+ PORT_Free(p);
+ }
+ } else {
+ dst->data = (unsigned char *)PORT_Alloc(numBytes);
+ }
+ if (!dst->data) {
+ return SECFailure;
+ }
+ PORT_Memcpy(dst->data + dst->len, buf, numBytes);
+ dst->len += numBytes;
+ }
+
+ return SECSuccess;
+}
+
+SECStatus
+SECU_FileToItem(SECItem *dst, PRFileDesc *src)
+{
+ PRFileInfo info;
+ PRInt32 numBytes;
+ PRStatus prStatus;
+
+ if (src == PR_STDIN)
+ return secu_StdinToItem(dst);
+
+ prStatus = PR_GetOpenFileInfo(src, &info);
+
+ if (prStatus != PR_SUCCESS) {
+ PORT_SetError(SEC_ERROR_IO);
+ return SECFailure;
+ }
+
+ /* XXX workaround for 3.1, not all utils zero dst before sending */
+ dst->data = 0;
+ if (!SECITEM_AllocItem(NULL, dst, info.size))
+ goto loser;
+
+ numBytes = PR_Read(src, dst->data, info.size);
+ if (numBytes != info.size) {
+ PORT_SetError(SEC_ERROR_IO);
+ goto loser;
+ }
+
+ return SECSuccess;
+loser:
+ SECITEM_FreeItem(dst, PR_FALSE);
+ dst->data = NULL;
+ return SECFailure;
+}
+
+SECStatus
+SECU_TextFileToItem(SECItem *dst, PRFileDesc *src)
+{
+ PRFileInfo info;
+ PRInt32 numBytes;
+ PRStatus prStatus;
+ unsigned char *buf;
+
+ if (src == PR_STDIN)
+ return secu_StdinToItem(dst);
+
+ prStatus = PR_GetOpenFileInfo(src, &info);
+
+ if (prStatus != PR_SUCCESS) {
+ PORT_SetError(SEC_ERROR_IO);
+ return SECFailure;
+ }
+
+ buf = (unsigned char *)PORT_Alloc(info.size);
+ if (!buf)
+ return SECFailure;
+
+ numBytes = PR_Read(src, buf, info.size);
+ if (numBytes != info.size) {
+ PORT_SetError(SEC_ERROR_IO);
+ goto loser;
+ }
+
+ if (buf[numBytes - 1] == '\n')
+ numBytes--;
+#ifdef _WINDOWS
+ if (buf[numBytes - 1] == '\r')
+ numBytes--;
+#endif
+
+ /* XXX workaround for 3.1, not all utils zero dst before sending */
+ dst->data = 0;
+ if (!SECITEM_AllocItem(NULL, dst, numBytes))
+ goto loser;
+
+ memcpy(dst->data, buf, numBytes);
+
+ PORT_Free(buf);
+ return SECSuccess;
+loser:
+ PORT_Free(buf);
+ return SECFailure;
+}
+
+#define INDENT_MULT 4
+void
+SECU_Indent(FILE *out, int level)
+{
+ int i;
+
+ for (i = 0; i < level; i++) {
+ fprintf(out, " ");
+ }
+}
+
+void
+SECU_Newline(FILE *out)
+{
+ fprintf(out, "\n");
+}
+
+void
+SECU_PrintAsHex(FILE *out, const SECItem *data, const char *m, int level)
+{
+ unsigned i;
+ int column = 0;
+ PRBool isString = PR_TRUE;
+ PRBool isWhiteSpace = PR_TRUE;
+ PRBool printedHex = PR_FALSE;
+ unsigned int limit = 15;
+
+ if (m) {
+ SECU_Indent(out, level);
+ fprintf(out, "%s:", m);
+ level++;
+ if (wrapEnabled)
+ fprintf(out, "\n");
+ }
+
+ if (wrapEnabled) {
+ SECU_Indent(out, level);
+ column = level * INDENT_MULT;
+ }
+ if (!data->len) {
+ fprintf(out, "(empty)\n");
+ return;
+ }
+ /* take a pass to see if it's all printable. */
+ for (i = 0; i < data->len; i++) {
+ unsigned char val = data->data[i];
+ if (!val || !isprint(val)) {
+ isString = PR_FALSE;
+ break;
+ }
+ if (isWhiteSpace && !isspace(val)) {
+ isWhiteSpace = PR_FALSE;
+ }
+ }
+
+ /* Short values, such as bit strings (which are printed with this
+ ** function) often look like strings, but we want to see the bits.
+ ** so this test assures that short values will be printed in hex,
+ ** perhaps in addition to being printed as strings.
+ ** The threshold size (4 bytes) is arbitrary.
+ */
+ if (!isString || data->len <= 4) {
+ for (i = 0; i < data->len; i++) {
+ if (i != data->len - 1) {
+ fprintf(out, "%02x:", data->data[i]);
+ column += 3;
+ } else {
+ fprintf(out, "%02x", data->data[i]);
+ column += 2;
+ break;
+ }
+ if (wrapEnabled &&
+ (column > 76 || (i % 16 == limit))) {
+ SECU_Newline(out);
+ SECU_Indent(out, level);
+ column = level * INDENT_MULT;
+ limit = i % 16;
+ }
+ }
+ printedHex = PR_TRUE;
+ }
+ if (isString && !isWhiteSpace) {
+ if (printedHex != PR_FALSE) {
+ SECU_Newline(out);
+ SECU_Indent(out, level);
+ column = level * INDENT_MULT;
+ }
+ for (i = 0; i < data->len; i++) {
+ unsigned char val = data->data[i];
+
+ if (val) {
+ fprintf(out, "%c", val);
+ column++;
+ } else {
+ column = 77;
+ }
+ if (wrapEnabled && column > 76) {
+ SECU_Newline(out);
+ SECU_Indent(out, level);
+ column = level * INDENT_MULT;
+ }
+ }
+ }
+
+ if (column != level * INDENT_MULT) {
+ SECU_Newline(out);
+ }
+}
+
+const char *hex = "0123456789abcdef";
+
+const char printable[257] = {
+ "................" /* 0x */
+ "................" /* 1x */
+ " !\"#$%&'()*+,-./" /* 2x */
+ "0123456789:;<=>?" /* 3x */
+ "@ABCDEFGHIJKLMNO" /* 4x */
+ "PQRSTUVWXYZ[\\]^_" /* 5x */
+ "`abcdefghijklmno" /* 6x */
+ "pqrstuvwxyz{|}~." /* 7x */
+ "................" /* 8x */
+ "................" /* 9x */
+ "................" /* ax */
+ "................" /* bx */
+ "................" /* cx */
+ "................" /* dx */
+ "................" /* ex */
+ "................" /* fx */
+};
+
+void
+SECU_PrintBuf(FILE *out, const char *msg, const void *vp, int len)
+{
+ const unsigned char *cp = (const unsigned char *)vp;
+ char buf[80];
+ char *bp;
+ char *ap;
+
+ fprintf(out, "%s [Len: %d]\n", msg, len);
+ memset(buf, ' ', sizeof buf);
+ bp = buf;
+ ap = buf + 50;
+ while (--len >= 0) {
+ unsigned char ch = *cp++;
+ *bp++ = hex[(ch >> 4) & 0xf];
+ *bp++ = hex[ch & 0xf];
+ *bp++ = ' ';
+ *ap++ = printable[ch];
+ if (ap - buf >= 66) {
+ *ap = 0;
+ fprintf(out, " %s\n", buf);
+ memset(buf, ' ', sizeof buf);
+ bp = buf;
+ ap = buf + 50;
+ }
+ }
+ if (bp > buf) {
+ *ap = 0;
+ fprintf(out, " %s\n", buf);
+ }
+}
+
+/* This expents i->data[0] to be the MSB of the integer.
+** if you want to print a DER-encoded integer (with the tag and length)
+** call SECU_PrintEncodedInteger();
+*/
+void
+SECU_PrintInteger(FILE *out, const SECItem *i, const char *m, int level)
+{
+ int iv;
+
+ if (!i || !i->len || !i->data) {
+ SECU_Indent(out, level);
+ if (m) {
+ fprintf(out, "%s: (null)\n", m);
+ } else {
+ fprintf(out, "(null)\n");
+ }
+ } else if (i->len > 4) {
+ SECU_PrintAsHex(out, i, m, level);
+ } else {
+ if (i->type == siUnsignedInteger && *i->data & 0x80) {
+ /* Make sure i->data has zero in the highest bite
+ * if i->data is an unsigned integer */
+ SECItem tmpI;
+ char data[] = { 0, 0, 0, 0, 0 };
+
+ PORT_Memcpy(data + 1, i->data, i->len);
+ tmpI.len = i->len + 1;
+ tmpI.data = (void *)data;
+
+ iv = DER_GetInteger(&tmpI);
+ } else {
+ iv = DER_GetInteger(i);
+ }
+ SECU_Indent(out, level);
+ if (m) {
+ fprintf(out, "%s: %d (0x%x)\n", m, iv, iv);
+ } else {
+ fprintf(out, "%d (0x%x)\n", iv, iv);
+ }
+ }
+}
+
+#if defined(DEBUG) || defined(FORCE_PR_ASSERT)
+/* Returns true iff a[i].flag has a duplicate in a[i+1 : count-1] */
+static PRBool
+HasShortDuplicate(int i, secuCommandFlag *a, int count)
+{
+ char target = a[i].flag;
+ int j;
+
+ /* duplicate '\0' flags are okay, they are used with long forms */
+ for (j = i + 1; j < count; j++) {
+ if (a[j].flag && a[j].flag == target) {
+ return PR_TRUE;
+ }
+ }
+ return PR_FALSE;
+}
+
+/* Returns true iff a[i].longform has a duplicate in a[i+1 : count-1] */
+static PRBool
+HasLongDuplicate(int i, secuCommandFlag *a, int count)
+{
+ int j;
+ char *target = a[i].longform;
+
+ if (!target)
+ return PR_FALSE;
+
+ for (j = i + 1; j < count; j++) {
+ if (a[j].longform && strcmp(a[j].longform, target) == 0) {
+ return PR_TRUE;
+ }
+ }
+ return PR_FALSE;
+}
+
+/* Returns true iff a has no short or long form duplicates
+ */
+PRBool
+HasNoDuplicates(secuCommandFlag *a, int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++) {
+ if (a[i].flag && HasShortDuplicate(i, a, count)) {
+ return PR_FALSE;
+ }
+ if (a[i].longform && HasLongDuplicate(i, a, count)) {
+ return PR_FALSE;
+ }
+ }
+ return PR_TRUE;
+}
+#endif
+
+SECStatus
+SECU_ParseCommandLine(int argc, char **argv, char *progName,
+ const secuCommand *cmd)
+{
+ PRBool found;
+ PLOptState *optstate;
+ PLOptStatus status;
+ char *optstring;
+ PLLongOpt *longopts = NULL;
+ int i, j;
+ int lcmd = 0, lopt = 0;
+
+ PR_ASSERT(HasNoDuplicates(cmd->commands, cmd->numCommands));
+ PR_ASSERT(HasNoDuplicates(cmd->options, cmd->numOptions));
+
+ optstring = (char *)PORT_Alloc(cmd->numCommands + 2 * cmd->numOptions + 1);
+ if (optstring == NULL)
+ return SECFailure;
+
+ j = 0;
+ for (i = 0; i < cmd->numCommands; i++) {
+ if (cmd->commands[i].flag) /* single character option ? */
+ optstring[j++] = cmd->commands[i].flag;
+ if (cmd->commands[i].longform)
+ lcmd++;
+ }
+ for (i = 0; i < cmd->numOptions; i++) {
+ if (cmd->options[i].flag) {
+ optstring[j++] = cmd->options[i].flag;
+ if (cmd->options[i].needsArg)
+ optstring[j++] = ':';
+ }
+ if (cmd->options[i].longform)
+ lopt++;
+ }
+
+ optstring[j] = '\0';
+
+ if (lcmd + lopt > 0) {
+ longopts = PORT_NewArray(PLLongOpt, lcmd + lopt + 1);
+ if (!longopts) {
+ PORT_Free(optstring);
+ return SECFailure;
+ }
+
+ j = 0;
+ for (i = 0; j < lcmd && i < cmd->numCommands; i++) {
+ if (cmd->commands[i].longform) {
+ longopts[j].longOptName = cmd->commands[i].longform;
+ longopts[j].longOption = 0;
+ longopts[j++].valueRequired = cmd->commands[i].needsArg;
+ }
+ }
+ lopt += lcmd;
+ for (i = 0; j < lopt && i < cmd->numOptions; i++) {
+ if (cmd->options[i].longform) {
+ longopts[j].longOptName = cmd->options[i].longform;
+ longopts[j].longOption = 0;
+ longopts[j++].valueRequired = cmd->options[i].needsArg;
+ }
+ }
+ longopts[j].longOptName = NULL;
+ }
+
+ optstate = PL_CreateLongOptState(argc, argv, optstring, longopts);
+ if (!optstate) {
+ PORT_Free(optstring);
+ PORT_Free(longopts);
+ return SECFailure;
+ }
+ /* Parse command line arguments */
+ while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
+ const char *optstatelong;
+ char option = optstate->option;
+
+ /* positional parameter, single-char option or long opt? */
+ if (optstate->longOptIndex == -1) {
+ /* not a long opt */
+ if (option == '\0')
+ continue; /* it's a positional parameter */
+ optstatelong = "";
+ } else {
+ /* long opt */
+ if (option == '\0')
+ option = '\377'; /* force unequal with all flags */
+ optstatelong = longopts[optstate->longOptIndex].longOptName;
+ }
+
+ found = PR_FALSE;
+
+ for (i = 0; i < cmd->numCommands; i++) {
+ if (cmd->commands[i].flag == option ||
+ cmd->commands[i].longform == optstatelong) {
+ cmd->commands[i].activated = PR_TRUE;
+ if (optstate->value) {
+ cmd->commands[i].arg = (char *)optstate->value;
+ }
+ found = PR_TRUE;
+ break;
+ }
+ }
+
+ if (found)
+ continue;
+
+ for (i = 0; i < cmd->numOptions; i++) {
+ if (cmd->options[i].flag == option ||
+ cmd->options[i].longform == optstatelong) {
+ cmd->options[i].activated = PR_TRUE;
+ if (optstate->value) {
+ cmd->options[i].arg = (char *)optstate->value;
+ } else if (cmd->options[i].needsArg) {
+ status = PL_OPT_BAD;
+ goto loser;
+ }
+ found = PR_TRUE;
+ break;
+ }
+ }
+
+ if (!found) {
+ status = PL_OPT_BAD;
+ break;
+ }
+ }
+
+loser:
+ PL_DestroyOptState(optstate);
+ PORT_Free(optstring);
+ if (longopts)
+ PORT_Free(longopts);
+ if (status == PL_OPT_BAD)
+ return SECFailure;
+ return SECSuccess;
+}
+
+char *
+SECU_GetOptionArg(const secuCommand *cmd, int optionNum)
+{
+ if (optionNum < 0 || optionNum >= cmd->numOptions)
+ return NULL;
+ if (cmd->options[optionNum].activated)
+ return PL_strdup(cmd->options[optionNum].arg);
+ else
+ return NULL;
+}
+
+void
+SECU_PrintPRandOSError(const char *progName)
+{
+ char buffer[513];
+ PRInt32 errLen = PR_GetErrorTextLength();
+ if (errLen > 0 && errLen < sizeof buffer) {
+ PR_GetErrorText(buffer);
+ }
+ SECU_PrintError(progName, "function failed");
+ if (errLen > 0 && errLen < sizeof buffer) {
+ PR_fprintf(PR_STDERR, "\t%s\n", buffer);
+ }
+}
+
+SECOidTag
+SECU_StringToSignatureAlgTag(const char *alg)
+{
+ SECOidTag hashAlgTag = SEC_OID_UNKNOWN;
+
+ if (alg) {
+ if (!PL_strcmp(alg, "MD2")) {
+ hashAlgTag = SEC_OID_MD2;
+ } else if (!PL_strcmp(alg, "MD4")) {
+ hashAlgTag = SEC_OID_MD4;
+ } else if (!PL_strcmp(alg, "MD5")) {
+ hashAlgTag = SEC_OID_MD5;
+ } else if (!PL_strcmp(alg, "SHA1")) {
+ hashAlgTag = SEC_OID_SHA1;
+ } else if (!PL_strcmp(alg, "SHA224")) {
+ hashAlgTag = SEC_OID_SHA224;
+ } else if (!PL_strcmp(alg, "SHA256")) {
+ hashAlgTag = SEC_OID_SHA256;
+ } else if (!PL_strcmp(alg, "SHA384")) {
+ hashAlgTag = SEC_OID_SHA384;
+ } else if (!PL_strcmp(alg, "SHA512")) {
+ hashAlgTag = SEC_OID_SHA512;
+ }
+ }
+ return hashAlgTag;
+}
+
+/* Caller ensures that dst is at least item->len*2+1 bytes long */
+void
+SECU_SECItemToHex(const SECItem *item, char *dst)
+{
+ if (dst && item && item->data) {
+ unsigned char *src = item->data;
+ unsigned int len = item->len;
+ for (; len > 0; --len, dst += 2) {
+ sprintf(dst, "%02x", *src++);
+ }
+ *dst = '\0';
+ }
+}
+
+static unsigned char
+nibble(char c)
+{
+ c = PORT_Tolower(c);
+ return (c >= '0' && c <= '9') ? c - '0' : (c >= 'a' && c <= 'f') ? c - 'a' + 10 : -1;
+}
+
+SECStatus
+SECU_SECItemHexStringToBinary(SECItem *srcdest)
+{
+ unsigned int i;
+
+ if (!srcdest) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ if (srcdest->len < 4 || (srcdest->len % 2)) {
+ /* too short to convert, or even number of characters */
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return SECFailure;
+ }
+ if (PORT_Strncasecmp((const char *)srcdest->data, "0x", 2)) {
+ /* wrong prefix */
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return SECFailure;
+ }
+
+ /* 1st pass to check for hex characters */
+ for (i = 2; i < srcdest->len; i++) {
+ char c = PORT_Tolower(srcdest->data[i]);
+ if (!((c >= '0' && c <= '9') ||
+ (c >= 'a' && c <= 'f'))) {
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return SECFailure;
+ }
+ }
+
+ /* 2nd pass to convert */
+ for (i = 2; i < srcdest->len; i += 2) {
+ srcdest->data[(i - 2) / 2] = (nibble(srcdest->data[i]) << 4) +
+ nibble(srcdest->data[i + 1]);
+ }
+
+ /* adjust length */
+ srcdest->len -= 2;
+ srcdest->len /= 2;
+ return SECSuccess;
+}
+
+SECItem *
+SECU_HexString2SECItem(PLArenaPool *arena, SECItem *item, const char *str)
+{
+ int i = 0;
+ int byteval = 0;
+ int tmp = PORT_Strlen(str);
+
+ PORT_Assert(arena);
+ PORT_Assert(item);
+
+ if ((tmp % 2) != 0) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
+ }
+
+ item = SECITEM_AllocItem(arena, item, tmp / 2);
+ if (item == NULL) {
+ return NULL;
+ }
+
+ while (str[i]) {
+ if ((str[i] >= '0') && (str[i] <= '9')) {
+ tmp = str[i] - '0';
+ } else if ((str[i] >= 'a') && (str[i] <= 'f')) {
+ tmp = str[i] - 'a' + 10;
+ } else if ((str[i] >= 'A') && (str[i] <= 'F')) {
+ tmp = str[i] - 'A' + 10;
+ } else {
+ /* item is in arena and gets freed by the caller */
+ return NULL;
+ }
+
+ byteval = byteval * 16 + tmp;
+ if ((i % 2) != 0) {
+ item->data[i / 2] = byteval;
+ byteval = 0;
+ }
+ i++;
+ }
+
+ return item;
+}
diff --git a/nss/cmd/lib/basicutil.h b/nss/cmd/lib/basicutil.h
new file mode 100644
index 0000000..4b3d5ff
--- /dev/null
+++ b/nss/cmd/lib/basicutil.h
@@ -0,0 +1,138 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#ifndef _BASIC_UTILS_H_
+#define _BASIC_UTILS_H_
+
+#include "seccomon.h"
+#include "secitem.h"
+#include "secoid.h"
+#include "secoidt.h"
+#include "secport.h"
+#include "prerror.h"
+#include "base64.h"
+#include "secasn1.h"
+#include "secder.h"
+#include
+
+#ifdef SECUTIL_NEW
+typedef int (*SECU_PPFunc)(PRFileDesc *out, SECItem *item,
+ char *msg, int level);
+#else
+typedef int (*SECU_PPFunc)(FILE *out, SECItem *item, char *msg, int level);
+#endif
+
+/* print out an error message */
+extern void SECU_PrintError(const char *progName, const char *msg, ...);
+
+/* print out a system error message */
+extern void SECU_PrintSystemError(const char *progName, const char *msg, ...);
+
+/* print a formatted error message */
+extern void SECU_PrintErrMsg(FILE *out, int level, const char *progName,
+ const char *msg, ...);
+
+/* Read the contents of a file into a SECItem */
+extern SECStatus SECU_FileToItem(SECItem *dst, PRFileDesc *src);
+extern SECStatus SECU_TextFileToItem(SECItem *dst, PRFileDesc *src);
+
+/* Indent based on "level" */
+extern void SECU_Indent(FILE *out, int level);
+
+/* Print a newline to out */
+extern void SECU_Newline(FILE *out);
+
+/* Print integer value and hex */
+extern void SECU_PrintInteger(FILE *out, const SECItem *i, const char *m,
+ int level);
+
+/* Print SECItem as hex */
+extern void SECU_PrintAsHex(FILE *out, const SECItem *i, const char *m,
+ int level);
+
+/* dump a buffer in hex and ASCII */
+extern void SECU_PrintBuf(FILE *out, const char *msg, const void *vp, int len);
+
+#ifdef HAVE_EPV_TEMPLATE
+/* Dump contents of private key */
+extern int SECU_PrintPrivateKey(FILE *out, SECItem *der, char *m, int level);
+#endif
+
+/* Init PKCS11 stuff */
+extern SECStatus SECU_PKCS11Init(PRBool readOnly);
+
+/* Dump contents of signed data */
+extern int SECU_PrintSignedData(FILE *out, SECItem *der, const char *m,
+ int level, SECU_PPFunc inner);
+
+extern void SECU_PrintString(FILE *out, const SECItem *si, const char *m,
+ int level);
+extern void SECU_PrintAny(FILE *out, const SECItem *i, const char *m, int level);
+
+extern void SECU_PrintPRandOSError(const char *progName);
+
+/* Caller ensures that dst is at least item->len*2+1 bytes long */
+void
+SECU_SECItemToHex(const SECItem *item, char *dst);
+
+/* Requires 0x prefix. Case-insensitive. Will do in-place replacement if
+ * successful */
+SECStatus
+SECU_SECItemHexStringToBinary(SECItem *srcdest);
+
+/*
+** Read a hex string into a SecItem.
+*/
+extern SECItem *SECU_HexString2SECItem(PLArenaPool *arena, SECItem *item,
+ const char *str);
+
+/*
+ *
+ * Utilities for parsing security tools command lines
+ *
+ */
+
+/* A single command flag */
+typedef struct {
+ char flag;
+ PRBool needsArg;
+ char *arg;
+ PRBool activated;
+ char *longform;
+} secuCommandFlag;
+
+/* A full array of command/option flags */
+typedef struct
+{
+ int numCommands;
+ int numOptions;
+
+ secuCommandFlag *commands;
+ secuCommandFlag *options;
+} secuCommand;
+
+/* fill the "arg" and "activated" fields for each flag */
+SECStatus
+SECU_ParseCommandLine(int argc, char **argv, char *progName,
+ const secuCommand *cmd);
+char *
+SECU_GetOptionArg(const secuCommand *cmd, int optionNum);
+
+/*
+ *
+ * Error messaging
+ *
+ */
+
+void printflags(char *trusts, unsigned int flags);
+
+#if !defined(XP_UNIX) && !defined(XP_OS2)
+extern int ffs(unsigned int i);
+#endif
+
+#include "secerr.h"
+
+extern const char *hex;
+extern const char printable[];
+
+#endif /* _BASIC_UTILS_H_ */
diff --git a/nss/cmd/lib/berparse.c b/nss/cmd/lib/berparse.c
new file mode 100644
index 0000000..8cd1eba
--- /dev/null
+++ b/nss/cmd/lib/berparse.c
@@ -0,0 +1,388 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#include "secutil.h"
+
+typedef enum {
+ tagDone,
+ lengthDone,
+ leafDone,
+ compositeDone,
+ notDone,
+ parseError,
+ parseComplete
+} ParseState;
+
+typedef unsigned char Byte;
+typedef void (*ParseProc)(BERParse *h, unsigned char **buf, int *len);
+typedef struct {
+ SECArb arb;
+ int pos; /* length from global start to item start */
+ SECArb *parent;
+} ParseStackElem;
+
+struct BERParseStr {
+ PLArenaPool *his;
+ PLArenaPool *mine;
+ ParseProc proc;
+ int stackDepth;
+ ParseStackElem *stackPtr;
+ ParseStackElem *stack;
+ int pending; /* bytes remaining to complete this part */
+ int pos; /* running length of consumed characters */
+ ParseState state;
+ PRBool keepLeaves;
+ PRBool derOnly;
+ BERFilterProc filter;
+ void *filterArg;
+ BERNotifyProc before;
+ void *beforeArg;
+ BERNotifyProc after;
+ void *afterArg;
+};
+
+#define UNKNOWN -1
+
+static unsigned char
+NextChar(BERParse *h, unsigned char **buf, int *len)
+{
+ unsigned char c = *(*buf)++;
+ (*len)--;
+ h->pos++;
+ if (h->filter)
+ (*h->filter)(h->filterArg, &c, 1);
+ return c;
+}
+
+static void
+ParseTag(BERParse *h, unsigned char **buf, int *len)
+{
+ SECArb *arb = &(h->stackPtr->arb);
+ arb->tag = NextChar(h, buf, len);
+
+ PORT_Assert(h->state == notDone);
+
+ /*
+ * NOTE: This does not handle the high-tag-number form
+ */
+ if ((arb->tag & DER_HIGH_TAG_NUMBER) == DER_HIGH_TAG_NUMBER) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ h->state = parseError;
+ return;
+ }
+
+ h->pending = UNKNOWN;
+ arb->length = UNKNOWN;
+ if (arb->tag & DER_CONSTRUCTED) {
+ arb->body.cons.numSubs = 0;
+ arb->body.cons.subs = NULL;
+ } else {
+ arb->body.item.len = UNKNOWN;
+ arb->body.item.data = NULL;
+ }
+
+ h->state = tagDone;
+}
+
+static void
+ParseLength(BERParse *h, unsigned char **buf, int *len)
+{
+ Byte b;
+ SECArb *arb = &(h->stackPtr->arb);
+
+ PORT_Assert(h->state == notDone);
+
+ if (h->pending == UNKNOWN) {
+ b = NextChar(h, buf, len);
+ if ((b & 0x80) == 0) { /* short form */
+ arb->length = b;
+ /*
+ * if the tag and the length are both zero bytes, then this
+ * should be the marker showing end of list for the
+ * indefinite length composite
+ */
+ if (arb->length == 0 && arb->tag == 0)
+ h->state = compositeDone;
+ else
+ h->state = lengthDone;
+ return;
+ }
+
+ h->pending = b & 0x7f;
+ /* 0 implies this is an indefinite length */
+ if (h->pending > 4) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ h->state = parseError;
+ return;
+ }
+ arb->length = 0;
+ }
+
+ while ((*len > 0) && (h->pending > 0)) {
+ b = NextChar(h, buf, len);
+ arb->length = (arb->length << 8) + b;
+ h->pending--;
+ }
+ if (h->pending == 0) {
+ if (h->derOnly && (arb->length == 0))
+ h->state = parseError;
+ else
+ h->state = lengthDone;
+ }
+ return;
+}
+
+static void
+ParseLeaf(BERParse *h, unsigned char **buf, int *len)
+{
+ int count;
+ SECArb *arb = &(h->stackPtr->arb);
+
+ PORT_Assert(h->state == notDone);
+ PORT_Assert(h->pending >= 0);
+
+ if (*len < h->pending)
+ count = *len;
+ else
+ count = h->pending;
+
+ if (h->keepLeaves)
+ memcpy(arb->body.item.data + arb->body.item.len, *buf, count);
+ if (h->filter)
+ (*h->filter)(h->filterArg, *buf, count);
+ *buf += count;
+ *len -= count;
+ arb->body.item.len += count;
+ h->pending -= count;
+ h->pos += count;
+ if (h->pending == 0) {
+ h->state = leafDone;
+ }
+ return;
+}
+
+static void
+CreateArbNode(BERParse *h)
+{
+ SECArb *arb = PORT_ArenaAlloc(h->his, sizeof(SECArb));
+
+ *arb = h->stackPtr->arb;
+
+ /*
+ * Special case closing the root
+ */
+ if (h->stackPtr == h->stack) {
+ PORT_Assert(arb->tag & DER_CONSTRUCTED);
+ h->state = parseComplete;
+ } else {
+ SECArb *parent = h->stackPtr->parent;
+ parent->body.cons.subs = DS_ArenaGrow(
+ h->his, parent->body.cons.subs,
+ (parent->body.cons.numSubs) * sizeof(SECArb *),
+ (parent->body.cons.numSubs + 1) * sizeof(SECArb *));
+ parent->body.cons.subs[parent->body.cons.numSubs] = arb;
+ parent->body.cons.numSubs++;
+ h->proc = ParseTag;
+ h->state = notDone;
+ h->pending = UNKNOWN;
+ }
+ if (h->after)
+ (*h->after)(h->afterArg, arb, h->stackPtr - h->stack, PR_FALSE);
+}
+
+SECStatus
+BER_ParseSome(BERParse *h, unsigned char *buf, int len)
+{
+ if (h->state == parseError)
+ return PR_TRUE;
+
+ while (len) {
+ (*h->proc)(h, &buf, &len);
+ if (h->state == parseComplete) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ h->state = parseError;
+ return PR_TRUE;
+ }
+ if (h->state == parseError)
+ return PR_TRUE;
+ PORT_Assert(h->state != parseComplete);
+
+ if (h->state <= compositeDone) {
+ if (h->proc == ParseTag) {
+ PORT_Assert(h->state == tagDone);
+ h->proc = ParseLength;
+ h->state = notDone;
+ } else if (h->proc == ParseLength) {
+ SECArb *arb = &(h->stackPtr->arb);
+ PORT_Assert(h->state == lengthDone || h->state == compositeDone);
+
+ if (h->before)
+ (*h->before)(h->beforeArg, arb,
+ h->stackPtr - h->stack, PR_TRUE);
+
+ /*
+ * Check to see if this is the end of an indefinite
+ * length composite
+ */
+ if (h->state == compositeDone) {
+ SECArb *parent = h->stackPtr->parent;
+ PORT_Assert(parent);
+ PORT_Assert(parent->tag & DER_CONSTRUCTED);
+ if (parent->length != 0) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ h->state = parseError;
+ return PR_TRUE;
+ }
+ /*
+ * NOTE: This does not check for an indefinite length
+ * composite being contained inside a definite length
+ * composite. It is not clear that is legal.
+ */
+ h->stackPtr--;
+ CreateArbNode(h);
+ } else {
+ h->stackPtr->pos = h->pos;
+
+ if (arb->tag & DER_CONSTRUCTED) {
+ SECArb *parent;
+ /*
+ * Make sure there is room on the stack before we
+ * stick anything else there.
+ */
+ PORT_Assert(h->stackPtr - h->stack < h->stackDepth);
+ if (h->stackPtr - h->stack == h->stackDepth - 1) {
+ int newDepth = h->stackDepth * 2;
+ h->stack = DS_ArenaGrow(h->mine, h->stack,
+ sizeof(ParseStackElem) *
+ h->stackDepth,
+ sizeof(ParseStackElem) *
+ newDepth);
+ h->stackPtr = h->stack + h->stackDepth + 1;
+ h->stackDepth = newDepth;
+ }
+ parent = &(h->stackPtr->arb);
+ h->stackPtr++;
+ h->stackPtr->parent = parent;
+ h->proc = ParseTag;
+ h->state = notDone;
+ h->pending = UNKNOWN;
+ } else {
+ if (arb->length < 0) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ h->state = parseError;
+ return PR_TRUE;
+ }
+ arb->body.item.len = 0;
+ if (arb->length > 0 && h->keepLeaves) {
+ arb->body.item.data =
+ PORT_ArenaAlloc(h->his, arb->length);
+ } else {
+ arb->body.item.data = NULL;
+ }
+ h->proc = ParseLeaf;
+ h->state = notDone;
+ h->pending = arb->length;
+ }
+ }
+ } else {
+ ParseStackElem *parent;
+ PORT_Assert(h->state = leafDone);
+ PORT_Assert(h->proc == ParseLeaf);
+
+ for (;;) {
+ CreateArbNode(h);
+ if (h->stackPtr == h->stack)
+ break;
+ parent = (h->stackPtr - 1);
+ PORT_Assert(parent->arb.tag & DER_CONSTRUCTED);
+ if (parent->arb.length == 0) /* need explicit end */
+ break;
+ if (parent->pos + parent->arb.length > h->pos)
+ break;
+ if (parent->pos + parent->arb.length < h->pos) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ h->state = parseError;
+ return PR_TRUE;
+ }
+ h->stackPtr = parent;
+ }
+ }
+ }
+ }
+ return PR_FALSE;
+}
+BERParse *
+BER_ParseInit(PLArenaPool *arena, PRBool derOnly)
+{
+ BERParse *h;
+ PLArenaPool *temp = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (temp == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return NULL;
+ }
+ h = PORT_ArenaAlloc(temp, sizeof(BERParse));
+ if (h == NULL) {
+ PORT_FreeArena(temp, PR_FALSE);
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return NULL;
+ }
+ h->his = arena;
+ h->mine = temp;
+ h->proc = ParseTag;
+ h->stackDepth = 20;
+ h->stack = PORT_ArenaZAlloc(h->mine,
+ sizeof(ParseStackElem) * h->stackDepth);
+ h->stackPtr = h->stack;
+ h->state = notDone;
+ h->pos = 0;
+ h->keepLeaves = PR_TRUE;
+ h->before = NULL;
+ h->after = NULL;
+ h->filter = NULL;
+ h->derOnly = derOnly;
+ return h;
+}
+
+SECArb *
+BER_ParseFini(BERParse *h)
+{
+ PLArenaPool *myArena = h->mine;
+ SECArb *arb;
+
+ if (h->state != parseComplete) {
+ arb = NULL;
+ } else {
+ arb = PORT_ArenaAlloc(h->his, sizeof(SECArb));
+ *arb = h->stackPtr->arb;
+ }
+
+ PORT_FreeArena(myArena, PR_FALSE);
+
+ return arb;
+}
+
+void
+BER_SetFilter(BERParse *h, BERFilterProc proc, void *instance)
+{
+ h->filter = proc;
+ h->filterArg = instance;
+}
+
+void
+BER_SetLeafStorage(BERParse *h, PRBool keep)
+{
+ h->keepLeaves = keep;
+}
+
+void
+BER_SetNotifyProc(BERParse *h, BERNotifyProc proc, void *instance,
+ PRBool beforeData)
+{
+ if (beforeData) {
+ h->before = proc;
+ h->beforeArg = instance;
+ } else {
+ h->after = proc;
+ h->afterArg = instance;
+ }
+}
diff --git a/nss/cmd/lib/config.mk b/nss/cmd/lib/config.mk
new file mode 100644
index 0000000..b8c03de
--- /dev/null
+++ b/nss/cmd/lib/config.mk
@@ -0,0 +1,15 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#
+# Override TARGETS variable so that only static libraries
+# are specifed as dependencies within rules.mk.
+#
+
+TARGETS = $(LIBRARY)
+SHARED_LIBRARY =
+IMPORT_LIBRARY =
+PROGRAM =
+
diff --git a/nss/cmd/lib/derprint.c b/nss/cmd/lib/derprint.c
new file mode 100644
index 0000000..08ef66d
--- /dev/null
+++ b/nss/cmd/lib/derprint.c
@@ -0,0 +1,594 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#include "secutil.h"
+#include "secoid.h"
+
+#ifdef __sun
+extern int fprintf(FILE *strm, const char *format, ... /* args */);
+extern int fflush(FILE *stream);
+#endif
+
+#define RIGHT_MARGIN 24
+/*#define RAW_BYTES 1 */
+
+static int prettyColumn = 0;
+
+static int
+getInteger256(const unsigned char *data, unsigned int nb)
+{
+ int val;
+
+ switch (nb) {
+ case 1:
+ val = data[0];
+ break;
+ case 2:
+ val = (data[0] << 8) | data[1];
+ break;
+ case 3:
+ val = (data[0] << 16) | (data[1] << 8) | data[2];
+ break;
+ case 4:
+ /* If the most significant bit of data[0] is 1, val would be negative.
+ * Treat it as an error.
+ */
+ if (data[0] & 0x80) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ return -1;
+ }
+ val = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
+ break;
+ default:
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ return -1;
+ }
+
+ return val;
+}
+
+static int
+prettyNewline(FILE *out)
+{
+ int rv;
+
+ if (prettyColumn != -1) {
+ rv = fprintf(out, "\n");
+ prettyColumn = -1;
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+ }
+ return 0;
+}
+
+static int
+prettyIndent(FILE *out, unsigned level)
+{
+ unsigned int i;
+ int rv;
+
+ if (prettyColumn == -1) {
+ prettyColumn = level;
+ for (i = 0; i < level; i++) {
+ rv = fprintf(out, " ");
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int
+prettyPrintByte(FILE *out, unsigned char item, unsigned int level)
+{
+ int rv;
+
+ rv = prettyIndent(out, level);
+ if (rv < 0)
+ return rv;
+
+ rv = fprintf(out, "%02x ", item);
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+
+ prettyColumn++;
+ if (prettyColumn >= RIGHT_MARGIN) {
+ return prettyNewline(out);
+ }
+
+ return 0;
+}
+
+static int
+prettyPrintLeaf(FILE *out, const unsigned char *data,
+ unsigned int len, unsigned int lv)
+{
+ unsigned int i;
+ int rv;
+
+ for (i = 0; i < len; i++) {
+ rv = prettyPrintByte(out, *data++, lv);
+ if (rv < 0)
+ return rv;
+ }
+ return prettyNewline(out);
+}
+
+static int
+prettyPrintStringStart(FILE *out, const unsigned char *str,
+ unsigned int len, unsigned int level)
+{
+#define BUF_SIZE 100
+ unsigned char buf[BUF_SIZE];
+ int rv;
+
+ if (len >= BUF_SIZE)
+ len = BUF_SIZE - 1;
+
+ rv = prettyNewline(out);
+ if (rv < 0)
+ return rv;
+
+ rv = prettyIndent(out, level);
+ if (rv < 0)
+ return rv;
+
+ memcpy(buf, str, len);
+ buf[len] = '\000';
+
+ rv = fprintf(out, "\"%s\"", buf);
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+
+ return 0;
+#undef BUF_SIZE
+}
+
+static int
+prettyPrintString(FILE *out, const unsigned char *str,
+ unsigned int len, unsigned int level, PRBool raw)
+{
+ int rv;
+
+ rv = prettyPrintStringStart(out, str, len, level);
+ if (rv < 0)
+ return rv;
+
+ rv = prettyNewline(out);
+ if (rv < 0)
+ return rv;
+
+ if (raw) {
+ rv = prettyPrintLeaf(out, str, len, level);
+ if (rv < 0)
+ return rv;
+ }
+
+ return 0;
+}
+
+static int
+prettyPrintTime(FILE *out, const unsigned char *str,
+ unsigned int len, unsigned int level, PRBool raw, PRBool utc)
+{
+ SECItem time_item;
+ int rv;
+
+ rv = prettyPrintStringStart(out, str, len, level);
+ if (rv < 0)
+ return rv;
+
+ time_item.data = (unsigned char *)str;
+ time_item.len = len;
+
+ rv = fprintf(out, " (");
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+
+ if (utc)
+ SECU_PrintUTCTime(out, &time_item, NULL, 0);
+ else
+ SECU_PrintGeneralizedTime(out, &time_item, NULL, 0);
+
+ rv = fprintf(out, ")");
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+
+ rv = prettyNewline(out);
+ if (rv < 0)
+ return rv;
+
+ if (raw) {
+ rv = prettyPrintLeaf(out, str, len, level);
+ if (rv < 0)
+ return rv;
+ }
+
+ return 0;
+}
+
+static int
+prettyPrintObjectID(FILE *out, const unsigned char *data,
+ unsigned int len, unsigned int level, PRBool raw)
+{
+ SECOidData *oiddata;
+ SECItem oiditem;
+ unsigned int i;
+ unsigned long val;
+ int rv;
+
+ /*
+ * First print the Object Id in numeric format
+ */
+
+ rv = prettyIndent(out, level);
+ if (rv < 0)
+ return rv;
+
+ if (len == 0) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ return -1;
+ }
+ val = data[0];
+ i = val % 40;
+ val = val / 40;
+ rv = fprintf(out, "%lu %u ", val, i);
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+
+ val = 0;
+ for (i = 1; i < len; ++i) {
+ unsigned long j;
+
+ j = data[i];
+ val = (val << 7) | (j & 0x7f);
+ if (j & 0x80)
+ continue;
+ rv = fprintf(out, "%lu ", val);
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+ val = 0;
+ }
+
+ /*
+ * Now try to look it up and print a symbolic version.
+ */
+ oiditem.data = (unsigned char *)data;
+ oiditem.len = len;
+ oiddata = SECOID_FindOID(&oiditem);
+ if (oiddata != NULL) {
+ i = PORT_Strlen(oiddata->desc);
+ if ((prettyColumn + 1 + (i / 3)) > RIGHT_MARGIN) {
+ rv = prettyNewline(out);
+ if (rv < 0)
+ return rv;
+ }
+
+ rv = prettyIndent(out, level);
+ if (rv < 0)
+ return rv;
+
+ rv = fprintf(out, "(%s)", oiddata->desc);
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+ }
+
+ rv = prettyNewline(out);
+ if (rv < 0)
+ return rv;
+
+ if (raw) {
+ rv = prettyPrintLeaf(out, data, len, level);
+ if (rv < 0)
+ return rv;
+ }
+
+ return 0;
+}
+
+static char *prettyTagType[32] = {
+ "End of Contents",
+ "Boolean",
+ "Integer",
+ "Bit String",
+ "Octet String",
+ "NULL",
+ "Object Identifier",
+ "0x07",
+ "0x08",
+ "0x09",
+ "Enumerated",
+ "0x0B",
+ "UTF8 String",
+ "0x0D",
+ "0x0E",
+ "0x0F",
+ "Sequence",
+ "Set",
+ "0x12",
+ "Printable String",
+ "T61 String",
+ "0x15",
+ "IA5 String",
+ "UTC Time",
+ "Generalized Time",
+ "0x19",
+ "Visible String",
+ "0x1B",
+ "Universal String",
+ "0x1D",
+ "BMP String",
+ "High-Tag-Number"
+};
+
+static int
+prettyPrintTag(FILE *out, const unsigned char *src, const unsigned char *end,
+ unsigned char *codep, unsigned int level, PRBool raw)
+{
+ int rv;
+ unsigned char code, tagnum;
+
+ if (src >= end) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ return -1;
+ }
+
+ code = *src;
+ tagnum = code & SEC_ASN1_TAGNUM_MASK;
+
+ /*
+ * NOTE: This code does not (yet) handle the high-tag-number form!
+ */
+ if (tagnum == SEC_ASN1_HIGH_TAG_NUMBER) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ return -1;
+ }
+
+ if (raw)
+ rv = prettyPrintByte(out, code, level);
+ else
+ rv = prettyIndent(out, level);
+
+ if (rv < 0)
+ return rv;
+
+ if (code & SEC_ASN1_CONSTRUCTED) {
+ rv = fprintf(out, "C-");
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+ }
+
+ switch (code & SEC_ASN1_CLASS_MASK) {
+ case SEC_ASN1_UNIVERSAL:
+ rv = fprintf(out, "%s ", prettyTagType[tagnum]);
+ break;
+ case SEC_ASN1_APPLICATION:
+ rv = fprintf(out, "Application: %d ", tagnum);
+ break;
+ case SEC_ASN1_CONTEXT_SPECIFIC:
+ rv = fprintf(out, "[%d] ", tagnum);
+ break;
+ case SEC_ASN1_PRIVATE:
+ rv = fprintf(out, "Private: %d ", tagnum);
+ break;
+ }
+
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+
+ *codep = code;
+
+ return 1;
+}
+
+static int
+prettyPrintLength(FILE *out, const unsigned char *data, const unsigned char *end,
+ int *lenp, PRBool *indefinitep, unsigned int lv, PRBool raw)
+{
+ unsigned char lbyte;
+ int lenLen;
+ int rv;
+
+ if (data >= end) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ return -1;
+ }
+
+ rv = fprintf(out, " ");
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+
+ *indefinitep = PR_FALSE;
+
+ lbyte = *data++;
+ lenLen = 1;
+ if (lbyte >= 0x80) {
+ /* Multibyte length */
+ unsigned nb = (unsigned)(lbyte & 0x7f);
+ if (nb > 4) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ return -1;
+ }
+ if (nb > 0) {
+ int il;
+
+ if ((data + nb) > end) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ return -1;
+ }
+ il = getInteger256(data, nb);
+ if (il < 0)
+ return -1;
+ *lenp = (unsigned)il;
+ } else {
+ *lenp = 0;
+ *indefinitep = PR_TRUE;
+ }
+ lenLen += nb;
+ if (raw) {
+ unsigned int i;
+
+ rv = prettyPrintByte(out, lbyte, lv);
+ if (rv < 0)
+ return rv;
+ for (i = 0; i < nb; i++) {
+ rv = prettyPrintByte(out, data[i], lv);
+ if (rv < 0)
+ return rv;
+ }
+ }
+ } else {
+ *lenp = lbyte;
+ if (raw) {
+ rv = prettyPrintByte(out, lbyte, lv);
+ if (rv < 0)
+ return rv;
+ }
+ }
+ if (*indefinitep)
+ rv = fprintf(out, "(indefinite)\n");
+ else
+ rv = fprintf(out, "(%d)\n", *lenp);
+ if (rv < 0) {
+ PORT_SetError(SEC_ERROR_IO);
+ return rv;
+ }
+
+ prettyColumn = -1;
+ return lenLen;
+}
+
+static int
+prettyPrintItem(FILE *out, const unsigned char *data, const unsigned char *end,
+ unsigned int lv, PRBool raw)
+{
+ int slen;
+ int lenLen;
+ const unsigned char *orig = data;
+ int rv;
+
+ while (data < end) {
+ unsigned char code;
+ PRBool indefinite;
+
+ slen = prettyPrintTag(out, data, end, &code, lv, raw);
+ if (slen < 0)
+ return slen;
+ data += slen;
+
+ lenLen = prettyPrintLength(out, data, end, &slen, &indefinite, lv, raw);
+ if (lenLen < 0)
+ return lenLen;
+ data += lenLen;
+
+ /*
+ * Just quit now if slen more bytes puts us off the end.
+ */
+ if ((data + slen) > end) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ return -1;
+ }
+
+ if (code & SEC_ASN1_CONSTRUCTED) {
+ if (slen > 0 || indefinite) {
+ slen = prettyPrintItem(out, data,
+ slen == 0 ? end : data + slen,
+ lv + 1, raw);
+ if (slen < 0)
+ return slen;
+ data += slen;
+ }
+ } else if (code == 0) {
+ if (slen != 0 || lenLen != 1) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ return -1;
+ }
+ break;
+ } else {
+ switch (code) {
+ case SEC_ASN1_PRINTABLE_STRING:
+ case SEC_ASN1_IA5_STRING:
+ case SEC_ASN1_VISIBLE_STRING:
+ rv = prettyPrintString(out, data, slen, lv + 1, raw);
+ if (rv < 0)
+ return rv;
+ break;
+ case SEC_ASN1_UTC_TIME:
+ rv = prettyPrintTime(out, data, slen, lv + 1, raw, PR_TRUE);
+ if (rv < 0)
+ return rv;
+ break;
+ case SEC_ASN1_GENERALIZED_TIME:
+ rv = prettyPrintTime(out, data, slen, lv + 1, raw, PR_FALSE);
+ if (rv < 0)
+ return rv;
+ break;
+ case SEC_ASN1_OBJECT_ID:
+ rv = prettyPrintObjectID(out, data, slen, lv + 1, raw);
+ if (rv < 0)
+ return rv;
+ break;
+ case SEC_ASN1_BOOLEAN: /* could do nicer job */
+ case SEC_ASN1_INTEGER: /* could do nicer job */
+ case SEC_ASN1_BIT_STRING: /* could do nicer job */
+ case SEC_ASN1_OCTET_STRING:
+ case SEC_ASN1_NULL:
+ case SEC_ASN1_ENUMERATED: /* could do nicer job, as INTEGER */
+ case SEC_ASN1_UTF8_STRING:
+ case SEC_ASN1_T61_STRING: /* print as printable string? */
+ case SEC_ASN1_UNIVERSAL_STRING:
+ case SEC_ASN1_BMP_STRING:
+ default:
+ rv = prettyPrintLeaf(out, data, slen, lv + 1);
+ if (rv < 0)
+ return rv;
+ break;
+ }
+ data += slen;
+ }
+ }
+
+ rv = prettyNewline(out);
+ if (rv < 0)
+ return rv;
+
+ return data - orig;
+}
+
+SECStatus
+DER_PrettyPrint(FILE *out, const SECItem *it, PRBool raw)
+{
+ int rv;
+
+ prettyColumn = -1;
+
+ rv = prettyPrintItem(out, it->data, it->data + it->len, 0, raw);
+ if (rv < 0)
+ return SECFailure;
+ return SECSuccess;
+}
diff --git a/nss/cmd/lib/exports.gyp b/nss/cmd/lib/exports.gyp
new file mode 100644
index 0000000..f6b4693
--- /dev/null
+++ b/nss/cmd/lib/exports.gyp
@@ -0,0 +1,27 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'cmd_lib_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'basicutil.h',
+ 'pk11table.h',
+ 'secutil.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/cmd/lib/ffs.c b/nss/cmd/lib/ffs.c
new file mode 100644
index 0000000..d1cbf67
--- /dev/null
+++ b/nss/cmd/lib/ffs.c
@@ -0,0 +1,21 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#if !defined(XP_UNIX) && !defined(XP_OS2)
+
+int
+ffs(unsigned int i)
+{
+ int rv = 1;
+
+ if (!i)
+ return 0;
+
+ while (!(i & 1)) {
+ i >>= 1;
+ ++rv;
+ }
+
+ return rv;
+}
+#endif
diff --git a/nss/cmd/lib/lib.gyp b/nss/cmd/lib/lib.gyp
new file mode 100644
index 0000000..6b7da58
--- /dev/null
+++ b/nss/cmd/lib/lib.gyp
@@ -0,0 +1,36 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'sectool',
+ 'type': 'static_library',
+ 'standalone_static_library': 1,
+ 'sources': [
+ 'basicutil.c',
+ 'derprint.c',
+ 'ffs.c',
+ 'moreoids.c',
+ 'pk11table.c',
+ 'pppolicy.c',
+ 'secpwd.c',
+ 'secutil.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'target_defaults': {
+ 'defines': [
+ 'NSPR20'
+ ]
+ },
+ 'variables': {
+ 'module': 'nss'
+ }
+}
\ No newline at end of file
diff --git a/nss/cmd/lib/manifest.mn b/nss/cmd/lib/manifest.mn
new file mode 100644
index 0000000..87440c0
--- /dev/null
+++ b/nss/cmd/lib/manifest.mn
@@ -0,0 +1,39 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+CORE_DEPTH = ../..
+
+LIBRARY_NAME = sectool
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+DEFINES = -DNSPR20
+
+ifdef NSS_BUILD_SOFTOKEN_ONLY
+PRIVATE_EXPORTS = basicutil.h \
+ pk11table.h \
+ $(NULL)
+
+CSRCS = basicutil.c \
+ pk11table.c \
+ $(NULL)
+else
+PRIVATE_EXPORTS = basicutil.h \
+ secutil.h \
+ pk11table.h \
+ $(NULL)
+
+CSRCS = basicutil.c \
+ secutil.c \
+ secpwd.c \
+ derprint.c \
+ moreoids.c \
+ pppolicy.c \
+ ffs.c \
+ pk11table.c \
+ $(NULL)
+endif
+
+NO_MD_RELEASE = 1
diff --git a/nss/cmd/lib/moreoids.c b/nss/cmd/lib/moreoids.c
new file mode 100644
index 0000000..ed5022c
--- /dev/null
+++ b/nss/cmd/lib/moreoids.c
@@ -0,0 +1,167 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "secoid.h"
+#include "secmodt.h" /* for CKM_INVALID_MECHANISM */
+
+#define OI(x) \
+ { \
+ siDEROID, (unsigned char *)x, sizeof x \
+ }
+#define OD(oid, tag, desc, mech, ext) \
+ { \
+ OI(oid) \
+ , tag, desc, mech, ext \
+ }
+#define ODN(oid, desc) \
+ { \
+ OI(oid) \
+ , 0, desc, CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION \
+ }
+
+#define OIDT static const unsigned char
+
+/* OIW Security Special Interest Group defined algorithms. */
+#define OIWSSIG 0x2B, 13, 3, 2
+
+OIDT oiwMD5RSA[] = { OIWSSIG, 3 };
+OIDT oiwDESCBC[] = { OIWSSIG, 7 };
+OIDT oiwRSAsig[] = { OIWSSIG, 11 };
+OIDT oiwDSA[] = { OIWSSIG, 12 };
+OIDT oiwMD5RSAsig[] = { OIWSSIG, 25 };
+OIDT oiwSHA1[] = { OIWSSIG, 26 };
+OIDT oiwDSASHA1[] = { OIWSSIG, 27 };
+OIDT oiwDSASHA1param[] = { OIWSSIG, 28 };
+OIDT oiwSHA1RSA[] = { OIWSSIG, 29 };
+
+/* Microsoft OIDs. (1 3 6 1 4 1 311 ... ) */
+#define MICROSOFT 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37
+
+OIDT mCTL[] = { MICROSOFT, 10, 3, 1 }; /* Cert Trust List signing */
+OIDT mTSS[] = { MICROSOFT, 10, 3, 2 }; /* Time Stamp Signing */
+OIDT mSGC[] = { MICROSOFT, 10, 3, 3 }; /* Server gated cryptography */
+OIDT mEFS[] = { MICROSOFT, 10, 3, 4 }; /* Encrypted File System */
+OIDT mSMIME[] = { MICROSOFT, 16, 4 }; /* SMIME encryption key prefs */
+
+OIDT mECRTT[] = { MICROSOFT, 20, 2 }; /* Enrollment cert type xtn */
+OIDT mEAGNT[] = { MICROSOFT, 20, 2, 1 }; /* Enrollment Agent */
+OIDT mKPSCL[] = { MICROSOFT, 20, 2, 2 }; /* KP SmartCard Logon */
+OIDT mNTPN[] = { MICROSOFT, 20, 2, 3 }; /* NT Principal Name */
+OIDT mCASRV[] = { MICROSOFT, 21, 1 }; /* CertServ CA version */
+
+/* AOL OIDs (1 3 6 1 4 1 1066 ... ) */
+#define AOL 0x2B, 0x06, 0x01, 0x04, 0x01, 0x88, 0x2A
+
+/* PKIX IDs (1 3 6 1 5 5 7 ...) */
+#define ID_PKIX 0x2B, 6, 1, 5, 5, 7
+/* PKIX Access Descriptors (methods for Authority Info Access Extns) */
+#define ID_AD ID_PKIX, 48
+
+OIDT padOCSP[] = { ID_AD, 1 }; /* OCSP method */
+OIDT padCAissuer[] = { ID_AD, 2 }; /* URI (for CRL ?) */
+OIDT padTimeStamp[] = { ID_AD, 3 }; /* time stamping */
+
+/* ISO Cert Extension type OIDs (id-ce) (2 5 29 ...) */
+#define X500 0x55
+#define X520_ATTRIBUTE_TYPE X500, 0x04
+#define X500_ALG X500, 0x08
+#define X500_ALG_ENCRYPTION X500_ALG, 0x01
+#define ID_CE X500, 29
+
+OIDT cePlcyObs[] = { ID_CE, 3 }; /* Cert policies, obsolete. */
+OIDT cePlcyCns[] = { ID_CE, 36 }; /* Cert policy constraints. */
+
+/* US Company arc (2 16 840 1 ...) */
+#define USCOM 0x60, 0x86, 0x48, 0x01
+#define USGOV USCOM, 0x65
+#define USDOD USGOV, 2
+#define ID_INFOSEC USDOD, 1
+
+/* Verisign PKI OIDs (2 16 840 1 113733 1 ...) */
+#define VERISIGN_PKI USCOM, 0x86, 0xf8, 0x45, 1
+#define VERISIGN_XTN VERISIGN_PKI, 6
+#define VERISIGN_POL VERISIGN_PKI, 7 /* Cert policies */
+#define VERISIGN_TNET VERISIGN_POL, 23 /* Verisign Trust Network */
+
+OIDT vcx7[] = { VERISIGN_XTN, 7 }; /* Cert Extension 7 (?) */
+OIDT vcp1[] = { VERISIGN_TNET, 1 }; /* class 1 cert policy */
+OIDT vcp2[] = { VERISIGN_TNET, 2 }; /* class 2 cert policy */
+OIDT vcp3[] = { VERISIGN_TNET, 3 }; /* class 3 cert policy */
+OIDT vcp4[] = { VERISIGN_TNET, 4 }; /* class 4 cert policy */
+
+/* ------------------------------------------------------------------- */
+static const SECOidData oids[] = {
+ /* OIW Security Special Interest Group OIDs */
+ ODN(oiwMD5RSA, "OIWSecSIG MD5 with RSA"),
+ ODN(oiwDESCBC, "OIWSecSIG DES CBC"),
+ ODN(oiwRSAsig, "OIWSecSIG RSA signature"),
+ ODN(oiwDSA, "OIWSecSIG DSA"),
+ ODN(oiwMD5RSAsig, "OIWSecSIG MD5 with RSA signature"),
+ ODN(oiwSHA1, "OIWSecSIG SHA1"),
+ ODN(oiwDSASHA1, "OIWSecSIG DSA with SHA1"),
+ ODN(oiwDSASHA1param, "OIWSecSIG DSA with SHA1 with params"),
+ ODN(oiwSHA1RSA, "OIWSecSIG MD5 with RSA"),
+
+ /* Microsoft OIDs */
+ ODN(mCTL, "Microsoft Cert Trust List signing"),
+ ODN(mTSS, "Microsoft Time Stamp signing"),
+ ODN(mSGC, "Microsoft SGC SSL server"),
+ ODN(mEFS, "Microsoft Encrypted File System"),
+ ODN(mSMIME, "Microsoft SMIME preferences"),
+ ODN(mECRTT, "Microsoft Enrollment Cert Type Extension"),
+ ODN(mEAGNT, "Microsoft Enrollment Agent"),
+ ODN(mKPSCL, "Microsoft KP SmartCard Logon"),
+ ODN(mNTPN, "Microsoft NT Principal Name"),
+ ODN(mCASRV, "Microsoft CertServ CA version"),
+
+ /* PKIX OIDs */
+ ODN(padOCSP, "PKIX OCSP method"),
+ ODN(padCAissuer, "PKIX CA Issuer method"),
+ ODN(padTimeStamp, "PKIX Time Stamping method"),
+
+ /* ID_CE OIDs. */
+ ODN(cePlcyObs, "Certificate Policies (Obsolete)"),
+ ODN(cePlcyCns, "Certificate Policy Constraints"),
+
+ /* Verisign OIDs. */
+ ODN(vcx7, "Verisign Cert Extension 7 (?)"),
+ ODN(vcp1, "Verisign Class 1 Certificate Policy"),
+ ODN(vcp2, "Verisign Class 2 Certificate Policy"),
+ ODN(vcp3, "Verisign Class 3 Certificate Policy"),
+ ODN(vcp4, "Verisign Class 4 Certificate Policy"),
+
+};
+
+static const unsigned int numOids = (sizeof oids) / (sizeof oids[0]);
+
+/* Fetch and register an oid if it hasn't been done already */
+void
+SECU_cert_fetchOID(SECOidTag *data, const SECOidData *src)
+{
+ if (*data == SEC_OID_UNKNOWN) {
+ /* AddEntry does the right thing if someone else has already
+ * added the oid. (that is return that oid tag) */
+ *data = SECOID_AddEntry(src);
+ }
+}
+
+SECStatus
+SECU_RegisterDynamicOids(void)
+{
+ unsigned int i;
+ SECStatus rv = SECSuccess;
+
+ for (i = 0; i < numOids; ++i) {
+ SECOidTag tag = SECOID_AddEntry(&oids[i]);
+ if (tag == SEC_OID_UNKNOWN) {
+ rv = SECFailure;
+#ifdef DEBUG_DYN_OIDS
+ fprintf(stderr, "Add OID[%d] failed\n", i);
+ } else {
+ fprintf(stderr, "Add OID[%d] returned tag %d\n", i, tag);
+#endif
+ }
+ }
+ return rv;
+}
diff --git a/nss/cmd/lib/pk11table.c b/nss/cmd/lib/pk11table.c
new file mode 100644
index 0000000..15c0a8d
--- /dev/null
+++ b/nss/cmd/lib/pk11table.c
@@ -0,0 +1,1517 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "pk11table.h"
+
+const char *_valueString[] = {
+ "None",
+ "Variable",
+ "CK_ULONG",
+ "Data",
+ "UTF8",
+ "CK_INFO",
+ "CK_SLOT_INFO",
+ "CK_TOKEN_INFO",
+ "CK_SESSION_INFO",
+ "CK_ATTRIBUTE",
+ "CK_MECHANISM",
+ "CK_MECHANISM_INFO",
+ "CK_C_INITIALIZE_ARGS",
+ "CK_FUNCTION_LIST"
+};
+
+const char **valueString = &_valueString[0];
+const int valueCount = sizeof(_valueString) / sizeof(_valueString[0]);
+
+const char *_constTypeString[] = {
+ "None",
+ "Bool",
+ "InfoFlags",
+ "SlotFlags",
+ "TokenFlags",
+ "SessionFlags",
+ "MechanismFlags",
+ "InitializeFlags",
+ "Users",
+ "SessionState",
+ "Object",
+ "Hardware",
+ "KeyType",
+ "CertificateType",
+ "Attribute",
+ "Mechanism",
+ "Result",
+ "Trust",
+ "AvailableSizes",
+ "CurrentSize"
+};
+
+const char **constTypeString = &_constTypeString[0];
+const int constTypeCount = sizeof(_constTypeString) / sizeof(_constTypeString[0]);
+
+#define mkEntry(x, t) \
+ { \
+ #x, x, Const##t, ConstNone \
+ }
+#define mkEntry2(x, t, t2) \
+ { \
+ #x, x, Const##t, Const##t2 \
+ }
+
+const Constant _consts[] = {
+ mkEntry(CK_FALSE, Bool),
+ mkEntry(CK_TRUE, Bool),
+
+ mkEntry(CKF_TOKEN_PRESENT, SlotFlags),
+ mkEntry(CKF_REMOVABLE_DEVICE, SlotFlags),
+ mkEntry(CKF_HW_SLOT, SlotFlags),
+
+ mkEntry(CKF_RNG, TokenFlags),
+ mkEntry(CKF_WRITE_PROTECTED, TokenFlags),
+ mkEntry(CKF_LOGIN_REQUIRED, TokenFlags),
+ mkEntry(CKF_USER_PIN_INITIALIZED, TokenFlags),
+ mkEntry(CKF_RESTORE_KEY_NOT_NEEDED, TokenFlags),
+ mkEntry(CKF_CLOCK_ON_TOKEN, TokenFlags),
+ mkEntry(CKF_PROTECTED_AUTHENTICATION_PATH, TokenFlags),
+ mkEntry(CKF_DUAL_CRYPTO_OPERATIONS, TokenFlags),
+ mkEntry(CKF_TOKEN_INITIALIZED, TokenFlags),
+ mkEntry(CKF_SECONDARY_AUTHENTICATION, TokenFlags),
+ mkEntry(CKF_USER_PIN_COUNT_LOW, TokenFlags),
+ mkEntry(CKF_USER_PIN_FINAL_TRY, TokenFlags),
+ mkEntry(CKF_USER_PIN_LOCKED, TokenFlags),
+ mkEntry(CKF_USER_PIN_TO_BE_CHANGED, TokenFlags),
+ mkEntry(CKF_SO_PIN_COUNT_LOW, TokenFlags),
+ mkEntry(CKF_SO_PIN_FINAL_TRY, TokenFlags),
+ mkEntry(CKF_SO_PIN_LOCKED, TokenFlags),
+ mkEntry(CKF_SO_PIN_TO_BE_CHANGED, TokenFlags),
+
+ mkEntry(CKF_RW_SESSION, SessionFlags),
+ mkEntry(CKF_SERIAL_SESSION, SessionFlags),
+
+ mkEntry(CKF_HW, MechanismFlags),
+ mkEntry(CKF_ENCRYPT, MechanismFlags),
+ mkEntry(CKF_DECRYPT, MechanismFlags),
+ mkEntry(CKF_DIGEST, MechanismFlags),
+ mkEntry(CKF_SIGN, MechanismFlags),
+ mkEntry(CKF_SIGN_RECOVER, MechanismFlags),
+ mkEntry(CKF_VERIFY, MechanismFlags),
+ mkEntry(CKF_VERIFY_RECOVER, MechanismFlags),
+ mkEntry(CKF_GENERATE, MechanismFlags),
+ mkEntry(CKF_GENERATE_KEY_PAIR, MechanismFlags),
+ mkEntry(CKF_WRAP, MechanismFlags),
+ mkEntry(CKF_UNWRAP, MechanismFlags),
+ mkEntry(CKF_DERIVE, MechanismFlags),
+ mkEntry(CKF_EC_FP, MechanismFlags),
+ mkEntry(CKF_EC_F_2M, MechanismFlags),
+ mkEntry(CKF_EC_ECPARAMETERS, MechanismFlags),
+ mkEntry(CKF_EC_NAMEDCURVE, MechanismFlags),
+ mkEntry(CKF_EC_UNCOMPRESS, MechanismFlags),
+ mkEntry(CKF_EC_COMPRESS, MechanismFlags),
+
+ mkEntry(CKF_LIBRARY_CANT_CREATE_OS_THREADS, InitializeFlags),
+ mkEntry(CKF_OS_LOCKING_OK, InitializeFlags),
+
+ mkEntry(CKU_SO, Users),
+ mkEntry(CKU_USER, Users),
+
+ mkEntry(CKS_RO_PUBLIC_SESSION, SessionState),
+ mkEntry(CKS_RO_USER_FUNCTIONS, SessionState),
+ mkEntry(CKS_RW_PUBLIC_SESSION, SessionState),
+ mkEntry(CKS_RW_USER_FUNCTIONS, SessionState),
+ mkEntry(CKS_RW_SO_FUNCTIONS, SessionState),
+
+ mkEntry(CKO_DATA, Object),
+ mkEntry(CKO_CERTIFICATE, Object),
+ mkEntry(CKO_PUBLIC_KEY, Object),
+ mkEntry(CKO_PRIVATE_KEY, Object),
+ mkEntry(CKO_SECRET_KEY, Object),
+ mkEntry(CKO_HW_FEATURE, Object),
+ mkEntry(CKO_DOMAIN_PARAMETERS, Object),
+ mkEntry(CKO_KG_PARAMETERS, Object),
+ mkEntry(CKO_NSS_CRL, Object),
+ mkEntry(CKO_NSS_SMIME, Object),
+ mkEntry(CKO_NSS_TRUST, Object),
+ mkEntry(CKO_NSS_BUILTIN_ROOT_LIST, Object),
+
+ mkEntry(CKH_MONOTONIC_COUNTER, Hardware),
+ mkEntry(CKH_CLOCK, Hardware),
+
+ mkEntry(CKK_RSA, KeyType),
+ mkEntry(CKK_DSA, KeyType),
+ mkEntry(CKK_DH, KeyType),
+ mkEntry(CKK_ECDSA, KeyType),
+ mkEntry(CKK_EC, KeyType),
+ mkEntry(CKK_X9_42_DH, KeyType),
+ mkEntry(CKK_KEA, KeyType),
+ mkEntry(CKK_GENERIC_SECRET, KeyType),
+ mkEntry(CKK_RC2, KeyType),
+ mkEntry(CKK_RC4, KeyType),
+ mkEntry(CKK_DES, KeyType),
+ mkEntry(CKK_DES2, KeyType),
+ mkEntry(CKK_DES3, KeyType),
+ mkEntry(CKK_CAST, KeyType),
+ mkEntry(CKK_CAST3, KeyType),
+ mkEntry(CKK_CAST5, KeyType),
+ mkEntry(CKK_CAST128, KeyType),
+ mkEntry(CKK_RC5, KeyType),
+ mkEntry(CKK_IDEA, KeyType),
+ mkEntry(CKK_SKIPJACK, KeyType),
+ mkEntry(CKK_BATON, KeyType),
+ mkEntry(CKK_JUNIPER, KeyType),
+ mkEntry(CKK_CDMF, KeyType),
+ mkEntry(CKK_AES, KeyType),
+ mkEntry(CKK_CAMELLIA, KeyType),
+ mkEntry(CKK_NSS_PKCS8, KeyType),
+
+ mkEntry(CKC_X_509, CertType),
+ mkEntry(CKC_X_509_ATTR_CERT, CertType),
+
+ mkEntry2(CKA_CLASS, Attribute, Object),
+ mkEntry2(CKA_TOKEN, Attribute, Bool),
+ mkEntry2(CKA_PRIVATE, Attribute, Bool),
+ mkEntry2(CKA_LABEL, Attribute, None),
+ mkEntry2(CKA_APPLICATION, Attribute, None),
+ mkEntry2(CKA_VALUE, Attribute, None),
+ mkEntry2(CKA_OBJECT_ID, Attribute, None),
+ mkEntry2(CKA_CERTIFICATE_TYPE, Attribute, CertType),
+ mkEntry2(CKA_ISSUER, Attribute, None),
+ mkEntry2(CKA_SERIAL_NUMBER, Attribute, None),
+ mkEntry2(CKA_AC_ISSUER, Attribute, None),
+ mkEntry2(CKA_OWNER, Attribute, None),
+ mkEntry2(CKA_ATTR_TYPES, Attribute, None),
+ mkEntry2(CKA_TRUSTED, Attribute, Bool),
+ mkEntry2(CKA_KEY_TYPE, Attribute, KeyType),
+ mkEntry2(CKA_SUBJECT, Attribute, None),
+ mkEntry2(CKA_ID, Attribute, None),
+ mkEntry2(CKA_SENSITIVE, Attribute, Bool),
+ mkEntry2(CKA_ENCRYPT, Attribute, Bool),
+ mkEntry2(CKA_DECRYPT, Attribute, Bool),
+ mkEntry2(CKA_WRAP, Attribute, Bool),
+ mkEntry2(CKA_UNWRAP, Attribute, Bool),
+ mkEntry2(CKA_SIGN, Attribute, Bool),
+ mkEntry2(CKA_SIGN_RECOVER, Attribute, Bool),
+ mkEntry2(CKA_VERIFY, Attribute, Bool),
+ mkEntry2(CKA_VERIFY_RECOVER, Attribute, Bool),
+ mkEntry2(CKA_DERIVE, Attribute, Bool),
+ mkEntry2(CKA_START_DATE, Attribute, None),
+ mkEntry2(CKA_END_DATE, Attribute, None),
+ mkEntry2(CKA_MODULUS, Attribute, None),
+ mkEntry2(CKA_MODULUS_BITS, Attribute, None),
+ mkEntry2(CKA_PUBLIC_EXPONENT, Attribute, None),
+ mkEntry2(CKA_PRIVATE_EXPONENT, Attribute, None),
+ mkEntry2(CKA_PRIME_1, Attribute, None),
+ mkEntry2(CKA_PRIME_2, Attribute, None),
+ mkEntry2(CKA_EXPONENT_1, Attribute, None),
+ mkEntry2(CKA_EXPONENT_2, Attribute, None),
+ mkEntry2(CKA_COEFFICIENT, Attribute, None),
+ mkEntry2(CKA_PRIME, Attribute, None),
+ mkEntry2(CKA_SUBPRIME, Attribute, None),
+ mkEntry2(CKA_BASE, Attribute, None),
+ mkEntry2(CKA_PRIME_BITS, Attribute, None),
+ mkEntry2(CKA_SUB_PRIME_BITS, Attribute, None),
+ mkEntry2(CKA_VALUE_BITS, Attribute, None),
+ mkEntry2(CKA_VALUE_LEN, Attribute, None),
+ mkEntry2(CKA_EXTRACTABLE, Attribute, Bool),
+ mkEntry2(CKA_LOCAL, Attribute, Bool),
+ mkEntry2(CKA_NEVER_EXTRACTABLE, Attribute, Bool),
+ mkEntry2(CKA_ALWAYS_SENSITIVE, Attribute, Bool),
+ mkEntry2(CKA_KEY_GEN_MECHANISM, Attribute, Mechanism),
+ mkEntry2(CKA_MODIFIABLE, Attribute, Bool),
+ mkEntry2(CKA_ECDSA_PARAMS, Attribute, None),
+ mkEntry2(CKA_EC_PARAMS, Attribute, None),
+ mkEntry2(CKA_EC_POINT, Attribute, None),
+ mkEntry2(CKA_SECONDARY_AUTH, Attribute, None),
+ mkEntry2(CKA_AUTH_PIN_FLAGS, Attribute, None),
+ mkEntry2(CKA_HW_FEATURE_TYPE, Attribute, Hardware),
+ mkEntry2(CKA_RESET_ON_INIT, Attribute, Bool),
+ mkEntry2(CKA_HAS_RESET, Attribute, Bool),
+ mkEntry2(CKA_NSS_URL, Attribute, None),
+ mkEntry2(CKA_NSS_EMAIL, Attribute, None),
+ mkEntry2(CKA_NSS_SMIME_INFO, Attribute, None),
+ mkEntry2(CKA_NSS_SMIME_TIMESTAMP, Attribute, None),
+ mkEntry2(CKA_NSS_PKCS8_SALT, Attribute, None),
+ mkEntry2(CKA_NSS_PASSWORD_CHECK, Attribute, None),
+ mkEntry2(CKA_NSS_EXPIRES, Attribute, None),
+ mkEntry2(CKA_NSS_KRL, Attribute, None),
+ mkEntry2(CKA_NSS_PQG_COUNTER, Attribute, None),
+ mkEntry2(CKA_NSS_PQG_SEED, Attribute, None),
+ mkEntry2(CKA_NSS_PQG_H, Attribute, None),
+ mkEntry2(CKA_NSS_PQG_SEED_BITS, Attribute, None),
+ mkEntry2(CKA_TRUST_DIGITAL_SIGNATURE, Attribute, Trust),
+ mkEntry2(CKA_TRUST_NON_REPUDIATION, Attribute, Trust),
+ mkEntry2(CKA_TRUST_KEY_ENCIPHERMENT, Attribute, Trust),
+ mkEntry2(CKA_TRUST_DATA_ENCIPHERMENT, Attribute, Trust),
+ mkEntry2(CKA_TRUST_KEY_AGREEMENT, Attribute, Trust),
+ mkEntry2(CKA_TRUST_KEY_CERT_SIGN, Attribute, Trust),
+ mkEntry2(CKA_TRUST_CRL_SIGN, Attribute, Trust),
+ mkEntry2(CKA_TRUST_SERVER_AUTH, Attribute, Trust),
+ mkEntry2(CKA_TRUST_CLIENT_AUTH, Attribute, Trust),
+ mkEntry2(CKA_TRUST_CODE_SIGNING, Attribute, Trust),
+ mkEntry2(CKA_TRUST_EMAIL_PROTECTION, Attribute, Trust),
+ mkEntry2(CKA_TRUST_IPSEC_END_SYSTEM, Attribute, Trust),
+ mkEntry2(CKA_TRUST_IPSEC_TUNNEL, Attribute, Trust),
+ mkEntry2(CKA_TRUST_IPSEC_USER, Attribute, Trust),
+ mkEntry2(CKA_TRUST_TIME_STAMPING, Attribute, Trust),
+ mkEntry2(CKA_CERT_SHA1_HASH, Attribute, None),
+ mkEntry2(CKA_CERT_MD5_HASH, Attribute, None),
+ mkEntry2(CKA_NETSCAPE_DB, Attribute, None),
+ mkEntry2(CKA_NETSCAPE_TRUST, Attribute, Trust),
+
+ mkEntry(CKM_RSA_PKCS, Mechanism),
+ mkEntry(CKM_RSA_9796, Mechanism),
+ mkEntry(CKM_RSA_X_509, Mechanism),
+ mkEntry(CKM_RSA_PKCS_KEY_PAIR_GEN, Mechanism),
+ mkEntry(CKM_MD2_RSA_PKCS, Mechanism),
+ mkEntry(CKM_MD5_RSA_PKCS, Mechanism),
+ mkEntry(CKM_SHA1_RSA_PKCS, Mechanism),
+ mkEntry(CKM_RIPEMD128_RSA_PKCS, Mechanism),
+ mkEntry(CKM_RIPEMD160_RSA_PKCS, Mechanism),
+ mkEntry(CKM_RSA_PKCS_OAEP, Mechanism),
+ mkEntry(CKM_RSA_X9_31_KEY_PAIR_GEN, Mechanism),
+ mkEntry(CKM_RSA_X9_31, Mechanism),
+ mkEntry(CKM_SHA1_RSA_X9_31, Mechanism),
+ mkEntry(CKM_DSA_KEY_PAIR_GEN, Mechanism),
+ mkEntry(CKM_DSA, Mechanism),
+ mkEntry(CKM_DSA_SHA1, Mechanism),
+ mkEntry(CKM_DH_PKCS_KEY_PAIR_GEN, Mechanism),
+ mkEntry(CKM_DH_PKCS_DERIVE, Mechanism),
+ mkEntry(CKM_X9_42_DH_DERIVE, Mechanism),
+ mkEntry(CKM_X9_42_DH_HYBRID_DERIVE, Mechanism),
+ mkEntry(CKM_X9_42_MQV_DERIVE, Mechanism),
+ mkEntry(CKM_SHA256_RSA_PKCS, Mechanism),
+ mkEntry(CKM_SHA384_RSA_PKCS, Mechanism),
+ mkEntry(CKM_SHA512_RSA_PKCS, Mechanism),
+ mkEntry(CKM_RC2_KEY_GEN, Mechanism),
+ mkEntry(CKM_RC2_ECB, Mechanism),
+ mkEntry(CKM_RC2_CBC, Mechanism),
+ mkEntry(CKM_RC2_MAC, Mechanism),
+ mkEntry(CKM_RC2_MAC_GENERAL, Mechanism),
+ mkEntry(CKM_RC2_CBC_PAD, Mechanism),
+ mkEntry(CKM_RC4_KEY_GEN, Mechanism),
+ mkEntry(CKM_RC4, Mechanism),
+ mkEntry(CKM_DES_KEY_GEN, Mechanism),
+ mkEntry(CKM_DES_ECB, Mechanism),
+ mkEntry(CKM_DES_CBC, Mechanism),
+ mkEntry(CKM_DES_MAC, Mechanism),
+ mkEntry(CKM_DES_MAC_GENERAL, Mechanism),
+ mkEntry(CKM_DES_CBC_PAD, Mechanism),
+ mkEntry(CKM_DES2_KEY_GEN, Mechanism),
+ mkEntry(CKM_DES3_KEY_GEN, Mechanism),
+ mkEntry(CKM_DES3_ECB, Mechanism),
+ mkEntry(CKM_DES3_CBC, Mechanism),
+ mkEntry(CKM_DES3_MAC, Mechanism),
+ mkEntry(CKM_DES3_MAC_GENERAL, Mechanism),
+ mkEntry(CKM_DES3_CBC_PAD, Mechanism),
+ mkEntry(CKM_CDMF_KEY_GEN, Mechanism),
+ mkEntry(CKM_CDMF_ECB, Mechanism),
+ mkEntry(CKM_CDMF_CBC, Mechanism),
+ mkEntry(CKM_CDMF_MAC, Mechanism),
+ mkEntry(CKM_CDMF_MAC_GENERAL, Mechanism),
+ mkEntry(CKM_CDMF_CBC_PAD, Mechanism),
+ mkEntry(CKM_MD2, Mechanism),
+ mkEntry(CKM_MD2_HMAC, Mechanism),
+ mkEntry(CKM_MD2_HMAC_GENERAL, Mechanism),
+ mkEntry(CKM_MD5, Mechanism),
+ mkEntry(CKM_MD5_HMAC, Mechanism),
+ mkEntry(CKM_MD5_HMAC_GENERAL, Mechanism),
+ mkEntry(CKM_SHA_1, Mechanism),
+ mkEntry(CKM_SHA_1_HMAC, Mechanism),
+ mkEntry(CKM_SHA_1_HMAC_GENERAL, Mechanism),
+ mkEntry(CKM_RIPEMD128, Mechanism),
+ mkEntry(CKM_RIPEMD128_HMAC, Mechanism),
+ mkEntry(CKM_RIPEMD128_HMAC_GENERAL, Mechanism),
+ mkEntry(CKM_RIPEMD160, Mechanism),
+ mkEntry(CKM_RIPEMD160_HMAC, Mechanism),
+ mkEntry(CKM_RIPEMD160_HMAC_GENERAL, Mechanism),
+ mkEntry(CKM_SHA256, Mechanism),
+ mkEntry(CKM_SHA256_HMAC_GENERAL, Mechanism),
+ mkEntry(CKM_SHA256_HMAC, Mechanism),
+ mkEntry(CKM_SHA384, Mechanism),
+ mkEntry(CKM_SHA384_HMAC_GENERAL, Mechanism),
+ mkEntry(CKM_SHA384_HMAC, Mechanism),
+ mkEntry(CKM_SHA512, Mechanism),
+ mkEntry(CKM_SHA512_HMAC_GENERAL, Mechanism),
+ mkEntry(CKM_SHA512_HMAC, Mechanism),
+ mkEntry(CKM_CAST_KEY_GEN, Mechanism),
+ mkEntry(CKM_CAST_ECB, Mechanism),
+ mkEntry(CKM_CAST_CBC, Mechanism),
+ mkEntry(CKM_CAST_MAC, Mechanism),
+ mkEntry(CKM_CAST_MAC_GENERAL, Mechanism),
+ mkEntry(CKM_CAST_CBC_PAD, Mechanism),
+ mkEntry(CKM_CAST3_KEY_GEN, Mechanism),
+ mkEntry(CKM_CAST3_ECB, Mechanism),
+ mkEntry(CKM_CAST3_CBC, Mechanism),
+ mkEntry(CKM_CAST3_MAC, Mechanism),
+ mkEntry(CKM_CAST3_MAC_GENERAL, Mechanism),
+ mkEntry(CKM_CAST3_CBC_PAD, Mechanism),
+ mkEntry(CKM_CAST5_KEY_GEN, Mechanism),
+ mkEntry(CKM_CAST128_KEY_GEN, Mechanism),
+ mkEntry(CKM_CAST5_ECB, Mechanism),
+ mkEntry(CKM_CAST128_ECB, Mechanism),
+ mkEntry(CKM_CAST5_CBC, Mechanism),
+ mkEntry(CKM_CAST128_CBC, Mechanism),
+ mkEntry(CKM_CAST5_MAC, Mechanism),
+ mkEntry(CKM_CAST128_MAC, Mechanism),
+ mkEntry(CKM_CAST5_MAC_GENERAL, Mechanism),
+ mkEntry(CKM_CAST128_MAC_GENERAL, Mechanism),
+ mkEntry(CKM_CAST5_CBC_PAD, Mechanism),
+ mkEntry(CKM_CAST128_CBC_PAD, Mechanism),
+ mkEntry(CKM_RC5_KEY_GEN, Mechanism),
+ mkEntry(CKM_RC5_ECB, Mechanism),
+ mkEntry(CKM_RC5_CBC, Mechanism),
+ mkEntry(CKM_RC5_MAC, Mechanism),
+ mkEntry(CKM_RC5_MAC_GENERAL, Mechanism),
+ mkEntry(CKM_RC5_CBC_PAD, Mechanism),
+ mkEntry(CKM_IDEA_KEY_GEN, Mechanism),
+ mkEntry(CKM_IDEA_ECB, Mechanism),
+ mkEntry(CKM_IDEA_CBC, Mechanism),
+ mkEntry(CKM_IDEA_MAC, Mechanism),
+ mkEntry(CKM_IDEA_MAC_GENERAL, Mechanism),
+ mkEntry(CKM_IDEA_CBC_PAD, Mechanism),
+ mkEntry(CKM_GENERIC_SECRET_KEY_GEN, Mechanism),
+ mkEntry(CKM_CONCATENATE_BASE_AND_KEY, Mechanism),
+ mkEntry(CKM_CONCATENATE_BASE_AND_DATA, Mechanism),
+ mkEntry(CKM_CONCATENATE_DATA_AND_BASE, Mechanism),
+ mkEntry(CKM_XOR_BASE_AND_DATA, Mechanism),
+ mkEntry(CKM_EXTRACT_KEY_FROM_KEY, Mechanism),
+ mkEntry(CKM_SSL3_PRE_MASTER_KEY_GEN, Mechanism),
+ mkEntry(CKM_SSL3_MASTER_KEY_DERIVE, Mechanism),
+ mkEntry(CKM_SSL3_KEY_AND_MAC_DERIVE, Mechanism),
+ mkEntry(CKM_SSL3_MASTER_KEY_DERIVE_DH, Mechanism),
+ mkEntry(CKM_TLS_PRE_MASTER_KEY_GEN, Mechanism),
+ mkEntry(CKM_TLS_MASTER_KEY_DERIVE, Mechanism),
+ mkEntry(CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256, Mechanism),
+ mkEntry(CKM_TLS_KEY_AND_MAC_DERIVE, Mechanism),
+ mkEntry(CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256, Mechanism),
+ mkEntry(CKM_TLS_MASTER_KEY_DERIVE_DH, Mechanism),
+ mkEntry(CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256, Mechanism),
+ mkEntry(CKM_SSL3_MD5_MAC, Mechanism),
+ mkEntry(CKM_SSL3_SHA1_MAC, Mechanism),
+ mkEntry(CKM_MD5_KEY_DERIVATION, Mechanism),
+ mkEntry(CKM_MD2_KEY_DERIVATION, Mechanism),
+ mkEntry(CKM_SHA1_KEY_DERIVATION, Mechanism),
+ mkEntry(CKM_SHA256_KEY_DERIVATION, Mechanism),
+ mkEntry(CKM_SHA384_KEY_DERIVATION, Mechanism),
+ mkEntry(CKM_SHA512_KEY_DERIVATION, Mechanism),
+ mkEntry(CKM_PBE_MD2_DES_CBC, Mechanism),
+ mkEntry(CKM_PBE_MD5_DES_CBC, Mechanism),
+ mkEntry(CKM_PBE_MD5_CAST_CBC, Mechanism),
+ mkEntry(CKM_PBE_MD5_CAST3_CBC, Mechanism),
+ mkEntry(CKM_PBE_MD5_CAST5_CBC, Mechanism),
+ mkEntry(CKM_PBE_MD5_CAST128_CBC, Mechanism),
+ mkEntry(CKM_PBE_SHA1_CAST5_CBC, Mechanism),
+ mkEntry(CKM_PBE_SHA1_CAST128_CBC, Mechanism),
+ mkEntry(CKM_PBE_SHA1_RC4_128, Mechanism),
+ mkEntry(CKM_PBE_SHA1_RC4_40, Mechanism),
+ mkEntry(CKM_PBE_SHA1_DES3_EDE_CBC, Mechanism),
+ mkEntry(CKM_PBE_SHA1_DES2_EDE_CBC, Mechanism),
+ mkEntry(CKM_PBE_SHA1_RC2_128_CBC, Mechanism),
+ mkEntry(CKM_PBE_SHA1_RC2_40_CBC, Mechanism),
+ mkEntry(CKM_PKCS5_PBKD2, Mechanism),
+ mkEntry(CKM_PBA_SHA1_WITH_SHA1_HMAC, Mechanism),
+ mkEntry(CKM_KEY_WRAP_LYNKS, Mechanism),
+ mkEntry(CKM_KEY_WRAP_SET_OAEP, Mechanism),
+ mkEntry(CKM_SKIPJACK_KEY_GEN, Mechanism),
+ mkEntry(CKM_SKIPJACK_ECB64, Mechanism),
+ mkEntry(CKM_SKIPJACK_CBC64, Mechanism),
+ mkEntry(CKM_SKIPJACK_OFB64, Mechanism),
+ mkEntry(CKM_SKIPJACK_CFB64, Mechanism),
+ mkEntry(CKM_SKIPJACK_CFB32, Mechanism),
+ mkEntry(CKM_SKIPJACK_CFB16, Mechanism),
+ mkEntry(CKM_SKIPJACK_CFB8, Mechanism),
+ mkEntry(CKM_SKIPJACK_WRAP, Mechanism),
+ mkEntry(CKM_SKIPJACK_PRIVATE_WRAP, Mechanism),
+ mkEntry(CKM_SKIPJACK_RELAYX, Mechanism),
+ mkEntry(CKM_KEA_KEY_PAIR_GEN, Mechanism),
+ mkEntry(CKM_KEA_KEY_DERIVE, Mechanism),
+ mkEntry(CKM_FORTEZZA_TIMESTAMP, Mechanism),
+ mkEntry(CKM_BATON_KEY_GEN, Mechanism),
+ mkEntry(CKM_BATON_ECB128, Mechanism),
+ mkEntry(CKM_BATON_ECB96, Mechanism),
+ mkEntry(CKM_BATON_CBC128, Mechanism),
+ mkEntry(CKM_BATON_COUNTER, Mechanism),
+ mkEntry(CKM_BATON_SHUFFLE, Mechanism),
+ mkEntry(CKM_BATON_WRAP, Mechanism),
+ mkEntry(CKM_ECDSA_KEY_PAIR_GEN, Mechanism),
+ mkEntry(CKM_EC_KEY_PAIR_GEN, Mechanism),
+ mkEntry(CKM_ECDSA, Mechanism),
+ mkEntry(CKM_ECDSA_SHA1, Mechanism),
+ mkEntry(CKM_ECDH1_DERIVE, Mechanism),
+ mkEntry(CKM_ECDH1_COFACTOR_DERIVE, Mechanism),
+ mkEntry(CKM_ECMQV_DERIVE, Mechanism),
+ mkEntry(CKM_JUNIPER_KEY_GEN, Mechanism),
+ mkEntry(CKM_JUNIPER_ECB128, Mechanism),
+ mkEntry(CKM_JUNIPER_CBC128, Mechanism),
+ mkEntry(CKM_JUNIPER_COUNTER, Mechanism),
+ mkEntry(CKM_JUNIPER_SHUFFLE, Mechanism),
+ mkEntry(CKM_JUNIPER_WRAP, Mechanism),
+ mkEntry(CKM_FASTHASH, Mechanism),
+ mkEntry(CKM_AES_KEY_GEN, Mechanism),
+ mkEntry(CKM_AES_ECB, Mechanism),
+ mkEntry(CKM_AES_CBC, Mechanism),
+ mkEntry(CKM_AES_MAC, Mechanism),
+ mkEntry(CKM_AES_MAC_GENERAL, Mechanism),
+ mkEntry(CKM_AES_CBC_PAD, Mechanism),
+ mkEntry(CKM_CAMELLIA_KEY_GEN, Mechanism),
+ mkEntry(CKM_CAMELLIA_ECB, Mechanism),
+ mkEntry(CKM_CAMELLIA_CBC, Mechanism),
+ mkEntry(CKM_CAMELLIA_MAC, Mechanism),
+ mkEntry(CKM_CAMELLIA_MAC_GENERAL, Mechanism),
+ mkEntry(CKM_CAMELLIA_CBC_PAD, Mechanism),
+ mkEntry(CKM_SEED_KEY_GEN, Mechanism),
+ mkEntry(CKM_SEED_ECB, Mechanism),
+ mkEntry(CKM_SEED_CBC, Mechanism),
+ mkEntry(CKM_SEED_MAC, Mechanism),
+ mkEntry(CKM_SEED_MAC_GENERAL, Mechanism),
+ mkEntry(CKM_SEED_CBC_PAD, Mechanism),
+ mkEntry(CKM_SEED_ECB_ENCRYPT_DATA, Mechanism),
+ mkEntry(CKM_SEED_CBC_ENCRYPT_DATA, Mechanism),
+ mkEntry(CKM_DSA_PARAMETER_GEN, Mechanism),
+ mkEntry(CKM_DH_PKCS_PARAMETER_GEN, Mechanism),
+ mkEntry(CKM_NSS_AES_KEY_WRAP, Mechanism),
+ mkEntry(CKM_NSS_AES_KEY_WRAP_PAD, Mechanism),
+ mkEntry(CKM_NETSCAPE_PBE_SHA1_DES_CBC, Mechanism),
+ mkEntry(CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC, Mechanism),
+ mkEntry(CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC, Mechanism),
+ mkEntry(CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC, Mechanism),
+ mkEntry(CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4, Mechanism),
+ mkEntry(CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4, Mechanism),
+ mkEntry(CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC, Mechanism),
+ mkEntry(CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN, Mechanism),
+ mkEntry(CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN, Mechanism),
+ mkEntry(CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN, Mechanism),
+ mkEntry(CKM_TLS_PRF_GENERAL, Mechanism),
+ mkEntry(CKM_NSS_TLS_PRF_GENERAL_SHA256, Mechanism),
+
+ mkEntry(CKR_OK, Result),
+ mkEntry(CKR_CANCEL, Result),
+ mkEntry(CKR_HOST_MEMORY, Result),
+ mkEntry(CKR_SLOT_ID_INVALID, Result),
+ mkEntry(CKR_GENERAL_ERROR, Result),
+ mkEntry(CKR_FUNCTION_FAILED, Result),
+ mkEntry(CKR_ARGUMENTS_BAD, Result),
+ mkEntry(CKR_NO_EVENT, Result),
+ mkEntry(CKR_NEED_TO_CREATE_THREADS, Result),
+ mkEntry(CKR_CANT_LOCK, Result),
+ mkEntry(CKR_ATTRIBUTE_READ_ONLY, Result),
+ mkEntry(CKR_ATTRIBUTE_SENSITIVE, Result),
+ mkEntry(CKR_ATTRIBUTE_TYPE_INVALID, Result),
+ mkEntry(CKR_ATTRIBUTE_VALUE_INVALID, Result),
+ mkEntry(CKR_DATA_INVALID, Result),
+ mkEntry(CKR_DATA_LEN_RANGE, Result),
+ mkEntry(CKR_DEVICE_ERROR, Result),
+ mkEntry(CKR_DEVICE_MEMORY, Result),
+ mkEntry(CKR_DEVICE_REMOVED, Result),
+ mkEntry(CKR_ENCRYPTED_DATA_INVALID, Result),
+ mkEntry(CKR_ENCRYPTED_DATA_LEN_RANGE, Result),
+ mkEntry(CKR_FUNCTION_CANCELED, Result),
+ mkEntry(CKR_FUNCTION_NOT_PARALLEL, Result),
+ mkEntry(CKR_FUNCTION_NOT_SUPPORTED, Result),
+ mkEntry(CKR_KEY_HANDLE_INVALID, Result),
+ mkEntry(CKR_KEY_SIZE_RANGE, Result),
+ mkEntry(CKR_KEY_TYPE_INCONSISTENT, Result),
+ mkEntry(CKR_KEY_NOT_NEEDED, Result),
+ mkEntry(CKR_KEY_CHANGED, Result),
+ mkEntry(CKR_KEY_NEEDED, Result),
+ mkEntry(CKR_KEY_INDIGESTIBLE, Result),
+ mkEntry(CKR_KEY_FUNCTION_NOT_PERMITTED, Result),
+ mkEntry(CKR_KEY_NOT_WRAPPABLE, Result),
+ mkEntry(CKR_KEY_UNEXTRACTABLE, Result),
+ mkEntry(CKR_KEY_PARAMS_INVALID, Result),
+ mkEntry(CKR_MECHANISM_INVALID, Result),
+ mkEntry(CKR_MECHANISM_PARAM_INVALID, Result),
+ mkEntry(CKR_OBJECT_HANDLE_INVALID, Result),
+ mkEntry(CKR_OPERATION_ACTIVE, Result),
+ mkEntry(CKR_OPERATION_NOT_INITIALIZED, Result),
+ mkEntry(CKR_PIN_INCORRECT, Result),
+ mkEntry(CKR_PIN_INVALID, Result),
+ mkEntry(CKR_PIN_LEN_RANGE, Result),
+ mkEntry(CKR_PIN_EXPIRED, Result),
+ mkEntry(CKR_PIN_LOCKED, Result),
+ mkEntry(CKR_SESSION_CLOSED, Result),
+ mkEntry(CKR_SESSION_COUNT, Result),
+ mkEntry(CKR_SESSION_HANDLE_INVALID, Result),
+ mkEntry(CKR_SESSION_PARALLEL_NOT_SUPPORTED, Result),
+ mkEntry(CKR_SESSION_READ_ONLY, Result),
+ mkEntry(CKR_SESSION_EXISTS, Result),
+ mkEntry(CKR_SESSION_READ_ONLY_EXISTS, Result),
+ mkEntry(CKR_SESSION_READ_WRITE_SO_EXISTS, Result),
+ mkEntry(CKR_SIGNATURE_INVALID, Result),
+ mkEntry(CKR_SIGNATURE_LEN_RANGE, Result),
+ mkEntry(CKR_TEMPLATE_INCOMPLETE, Result),
+ mkEntry(CKR_TEMPLATE_INCONSISTENT, Result),
+ mkEntry(CKR_TOKEN_NOT_PRESENT, Result),
+ mkEntry(CKR_TOKEN_NOT_RECOGNIZED, Result),
+ mkEntry(CKR_TOKEN_WRITE_PROTECTED, Result),
+ mkEntry(CKR_UNWRAPPING_KEY_HANDLE_INVALID, Result),
+ mkEntry(CKR_UNWRAPPING_KEY_SIZE_RANGE, Result),
+ mkEntry(CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT, Result),
+ mkEntry(CKR_USER_ALREADY_LOGGED_IN, Result),
+ mkEntry(CKR_USER_NOT_LOGGED_IN, Result),
+ mkEntry(CKR_USER_PIN_NOT_INITIALIZED, Result),
+ mkEntry(CKR_USER_TYPE_INVALID, Result),
+ mkEntry(CKR_USER_ANOTHER_ALREADY_LOGGED_IN, Result),
+ mkEntry(CKR_USER_TOO_MANY_TYPES, Result),
+ mkEntry(CKR_WRAPPED_KEY_INVALID, Result),
+ mkEntry(CKR_WRAPPED_KEY_LEN_RANGE, Result),
+ mkEntry(CKR_WRAPPING_KEY_HANDLE_INVALID, Result),
+ mkEntry(CKR_WRAPPING_KEY_SIZE_RANGE, Result),
+ mkEntry(CKR_WRAPPING_KEY_TYPE_INCONSISTENT, Result),
+ mkEntry(CKR_RANDOM_SEED_NOT_SUPPORTED, Result),
+ mkEntry(CKR_RANDOM_NO_RNG, Result),
+ mkEntry(CKR_DOMAIN_PARAMS_INVALID, Result),
+ mkEntry(CKR_BUFFER_TOO_SMALL, Result),
+ mkEntry(CKR_SAVED_STATE_INVALID, Result),
+ mkEntry(CKR_INFORMATION_SENSITIVE, Result),
+ mkEntry(CKR_STATE_UNSAVEABLE, Result),
+ mkEntry(CKR_CRYPTOKI_NOT_INITIALIZED, Result),
+ mkEntry(CKR_CRYPTOKI_ALREADY_INITIALIZED, Result),
+ mkEntry(CKR_MUTEX_BAD, Result),
+ mkEntry(CKR_MUTEX_NOT_LOCKED, Result),
+ mkEntry(CKR_VENDOR_DEFINED, Result),
+
+ mkEntry(CKT_NSS_TRUSTED, Trust),
+ mkEntry(CKT_NSS_TRUSTED_DELEGATOR, Trust),
+ mkEntry(CKT_NSS_NOT_TRUSTED, Trust),
+ mkEntry(CKT_NSS_MUST_VERIFY_TRUST, Trust),
+ mkEntry(CKT_NSS_TRUST_UNKNOWN, Trust),
+ mkEntry(CKT_NSS_VALID_DELEGATOR, Trust),
+
+ mkEntry(CK_EFFECTIVELY_INFINITE, AvailableSizes),
+ mkEntry(CK_UNAVAILABLE_INFORMATION, CurrentSize),
+};
+
+const Constant *consts = &_consts[0];
+const unsigned int constCount = sizeof(_consts) / sizeof(_consts[0]);
+
+const Commands _commands[] = {
+ { "C_Initialize",
+ F_C_Initialize,
+ "C_Initialize pInitArgs\n\n"
+ "C_Initialize initializes the PKCS #11 library.\n"
+ " pInitArgs if this is not NULL_PTR it gets cast to and dereferenced\n",
+ { ArgInitializeArgs, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "C_Finalize",
+ F_C_Finalize,
+ "C_Finalize pReserved\n\n"
+ "C_Finalize indicates that an application is done with the PKCS #11 library.\n"
+ " pReserved reserved. Should be NULL_PTR\n",
+ { ArgInitializeArgs, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "C_GetInfo",
+ F_C_GetInfo,
+ "C_GetInfo pInfo\n\n"
+ "C_GetInfo returns general information about PKCS #11.\n"
+ " pInfo location that receives information\n",
+ { ArgInfo | ArgOut, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "C_GetFunctionList",
+ F_C_GetFunctionList,
+ "C_GetFunctionList ppFunctionList\n\n"
+ "C_GetFunctionList returns the function list.\n"
+ " ppFunctionList receives pointer to function list\n",
+ { ArgFunctionList | ArgOut, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone } },
+ { "C_GetSlotList",
+ F_C_GetSlotList,
+ "C_GetSlotList tokenPresent pSlotList pulCount\n\n"
+ "C_GetSlotList obtains a list of slots in the system.\n"
+ " tokenPresent only slots with tokens?\n"
+ " pSlotList receives array of slot IDs\n"
+ " pulCount receives number of slots\n",
+ { ArgULong, ArgULong | ArgArray | ArgOut, ArgULong | ArgOut, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_GetSlotInfo",
+ F_C_GetSlotInfo,
+ "C_GetSlotInfo slotID pInfo\n\n"
+ "C_GetSlotInfo obtains information about a particular slot in the system.\n"
+ " slotID the ID of the slot\n"
+ " pInfo receives the slot information\n",
+ { ArgULong, ArgSlotInfo | ArgOut, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone } },
+ { "C_GetTokenInfo",
+ F_C_GetTokenInfo,
+ "C_GetTokenInfo slotID pInfo\n\n"
+ "C_GetTokenInfo obtains information about a particular token in the system.\n"
+ " slotID ID of the token's slot\n"
+ " pInfo receives the token information\n",
+ { ArgULong, ArgTokenInfo | ArgOut, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone } },
+ { "C_GetMechanismList",
+ F_C_GetMechanismList,
+ "C_GetMechanismList slotID pMechanismList pulCount\n\n"
+ "C_GetMechanismList obtains a list of mechanism types supported by a token.\n"
+ " slotID ID of token's slot\n"
+ " pMechanismList gets mech. array\n"
+ " pulCount gets # of mechs.\n",
+ { ArgULong, ArgULong | ArgArray | ArgOut, ArgULong | ArgOut, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_GetMechanismInfo",
+ F_C_GetMechanismInfo,
+ "C_GetMechanismInfo slotID type pInfo\n\n"
+ "C_GetMechanismInfo obtains information about a particular mechanism possibly\n"
+ "supported by a token.\n"
+ " slotID ID of the token's slot\n"
+ " type type of mechanism\n"
+ " pInfo receives mechanism info\n",
+ { ArgULong, ArgULong, ArgMechanismInfo | ArgOut, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone } },
+ { "C_InitToken",
+ F_C_InitToken,
+ "C_InitToken slotID pPin ulPinLen pLabel\n\n"
+ "C_InitToken initializes a token.\n"
+ " slotID ID of the token's slot\n"
+ " pPin the SO's initial PIN\n"
+ " ulPinLen length in bytes of the PIN\n"
+ " pLabel 32-byte token label (blank padded)\n",
+ { ArgULong, ArgUTF8, ArgULong, ArgUTF8, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone } },
+ { "C_InitPIN",
+ F_C_InitPIN,
+ "C_InitPIN hSession pPin ulPinLen\n\n"
+ "C_InitPIN initializes the normal user's PIN.\n"
+ " hSession the session's handle\n"
+ " pPin the normal user's PIN\n"
+ " ulPinLen length in bytes of the PIN\n",
+ { ArgULong, ArgUTF8, ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone } },
+ { "C_SetPIN",
+ F_C_SetPIN,
+ "C_SetPIN hSession pOldPin ulOldLen pNewPin ulNewLen\n\n"
+ "C_SetPIN modifies the PIN of the user who is logged in.\n"
+ " hSession the session's handle\n"
+ " pOldPin the old PIN\n"
+ " ulOldLen length of the old PIN\n"
+ " pNewPin the new PIN\n"
+ " ulNewLen length of the new PIN\n",
+ { ArgULong, ArgUTF8, ArgULong, ArgUTF8, ArgULong, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "C_OpenSession",
+ F_C_OpenSession,
+ "C_OpenSession slotID flags phSession\n\n"
+ "C_OpenSession opens a session between an application and a token.\n"
+ " slotID the slot's ID\n"
+ " flags from\n"
+ " phSession gets session handle\n",
+ { ArgULong, ArgULong, ArgULong | ArgOut, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone } },
+ { "C_CloseSession",
+ F_C_CloseSession,
+ "C_CloseSession hSession\n\n"
+ "C_CloseSession closes a session between an application and a token.\n"
+ " hSession the session's handle\n",
+ { ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone } },
+ { "C_CloseAllSessions",
+ F_C_CloseAllSessions,
+ "C_CloseAllSessions slotID\n\n"
+ "C_CloseAllSessions closes all sessions with a token.\n"
+ " slotID the token's slot\n",
+ { ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone } },
+ { "C_GetSessionInfo",
+ F_C_GetSessionInfo,
+ "C_GetSessionInfo hSession pInfo\n\n"
+ "C_GetSessionInfo obtains information about the session.\n"
+ " hSession the session's handle\n"
+ " pInfo receives session info\n",
+ { ArgULong, ArgSessionInfo | ArgOut, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone } },
+ { "C_GetOperationState",
+ F_C_GetOperationState,
+ "C_GetOperationState hSession pOpState pulOpStateLen\n\n"
+ "C_GetOperationState obtains the state of the cryptographic operation in a\n"
+ "session.\n"
+ " hSession session's handle\n"
+ " pOpState gets state\n"
+ " pulOpStateLen gets state length\n",
+ { ArgULong, ArgChar | ArgOut, ArgULong | ArgOut, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone } },
+ { "C_SetOperationState",
+ F_C_SetOperationState,
+ "C_SetOperationState hSession pOpState ulOpStateLen hEncKey hAuthKey\n\n"
+ "C_SetOperationState restores the state of the cryptographic operation in a\n"
+ "session.\n"
+ " hSession session's handle\n"
+ " pOpState holds state\n"
+ " ulOpStateLen holds state length\n"
+ " hEncKey en/decryption key\n"
+ " hAuthnKey sign/verify key\n",
+ { ArgULong, ArgChar | ArgOut, ArgULong, ArgULong, ArgULong, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone } },
+ { "C_Login",
+ F_C_Login,
+ "C_Login hSession userType pPin ulPinLen\n\n"
+ "C_Login logs a user into a token.\n"
+ " hSession the session's handle\n"
+ " userType the user type\n"
+ " pPin the user's PIN\n"
+ " ulPinLen the length of the PIN\n",
+ { ArgULong, ArgULong, ArgVar, ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone } },
+ { "C_Logout",
+ F_C_Logout,
+ "C_Logout hSession\n\n"
+ "C_Logout logs a user out from a token.\n"
+ " hSession the session's handle\n",
+ { ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone } },
+ { "C_CreateObject",
+ F_C_CreateObject,
+ "C_CreateObject hSession pTemplate ulCount phObject\n\n"
+ "C_CreateObject creates a new object.\n"
+ " hSession the session's handle\n"
+ " pTemplate the object's template\n"
+ " ulCount attributes in template\n"
+ " phObject gets new object's handle.\n",
+ { ArgULong, ArgAttribute | ArgArray, ArgULong, ArgULong | ArgOut, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_CopyObject",
+ F_C_CopyObject,
+ "C_CopyObject hSession hObject pTemplate ulCount phNewObject\n\n"
+ "C_CopyObject copies an object creating a new object for the copy.\n"
+ " hSession the session's handle\n"
+ " hObject the object's handle\n"
+ " pTemplate template for new object\n"
+ " ulCount attributes in template\n"
+ " phNewObject receives handle of copy\n",
+ { ArgULong, ArgULong, ArgAttribute | ArgArray, ArgULong, ArgULong | ArgOut, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_DestroyObject",
+ F_C_DestroyObject,
+ "C_DestroyObject hSession hObject\n\n"
+ "C_DestroyObject destroys an object.\n"
+ " hSession the session's handle\n"
+ " hObject the object's handle\n",
+ { ArgULong, ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone } },
+ { "C_GetObjectSize",
+ F_C_GetObjectSize,
+ "C_GetObjectSize hSession hObject pulSize\n\n"
+ "C_GetObjectSize gets the size of an object in bytes.\n"
+ " hSession the session's handle\n"
+ " hObject the object's handle\n"
+ " pulSize receives size of object\n",
+ { ArgULong, ArgULong, ArgULong | ArgOut, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone } },
+ { "C_GetAttributeValue",
+ F_C_GetAttributeValue,
+ "C_GetAttributeValue hSession hObject pTemplate ulCount\n\n"
+ "C_GetAttributeValue obtains the value of one or more object attributes.\n"
+ " hSession the session's handle\n"
+ " hObject the object's handle\n"
+ " pTemplate specifies attrs; gets vals\n"
+ " ulCount attributes in template\n",
+ { ArgULong, ArgULong, ArgAttribute | ArgArray, ArgULong, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone } },
+ { "C_SetAttributeValue",
+ F_C_SetAttributeValue,
+ "C_SetAttributeValue hSession hObject pTemplate ulCount\n\n"
+ "C_SetAttributeValue modifies the value of one or more object attributes\n"
+ " hSession the session's handle\n"
+ " hObject the object's handle\n"
+ " pTemplate specifies attrs and values\n"
+ " ulCount attributes in template\n",
+ { ArgULong, ArgULong, ArgAttribute | ArgArray, ArgULong, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone } },
+ { "C_FindObjectsInit",
+ F_C_FindObjectsInit,
+ "C_FindObjectsInit hSession pTemplate ulCount\n\n"
+ "C_FindObjectsInit initializes a search for token and session objects that\n"
+ "match a template.\n"
+ " hSession the session's handle\n"
+ " pTemplate attribute values to match\n"
+ " ulCount attrs in search template\n",
+ { ArgULong, ArgAttribute | ArgArray, ArgULong, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone } },
+ { "C_FindObjectsFinal",
+ F_C_FindObjectsFinal,
+ "C_FindObjectsFinal hSession\n\n"
+ "C_FindObjectsFinal finishes a search for token and session objects.\n"
+ " hSession the session's handle\n",
+ { ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone } },
+ { "C_FindObjects",
+ F_C_FindObjects,
+ "C_FindObjects hSession phObject ulMaxObjectCount pulObjectCount\n\n"
+ "C_FindObjects continues a search for token and session objects that match\n"
+ "a template obtaining additional object handles.\n"
+ " hSession session's handle\n"
+ " phObject gets obj. handles\n"
+ " ulMaxObjectCount max handles to get\n"
+ " pulObjectCount actual # returned\n",
+ { ArgULong, ArgULong | ArgOut, ArgULong, ArgULong | ArgOut, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_EncryptInit",
+ F_C_EncryptInit,
+ "C_EncryptInit hSession pMechanism hKey\n\n"
+ "C_EncryptInit initializes an encryption operation.\n"
+ " hSession the session's handle\n"
+ " pMechanism the encryption mechanism\n"
+ " hKey handle of encryption key\n",
+ { ArgULong, ArgMechanism, ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "C_EncryptUpdate",
+ F_C_EncryptUpdate,
+ "C_EncryptUpdate hSession pPart ulPartLen pEncryptedPart pulEncryptedPartLen\n"
+ "\n"
+ "C_EncryptUpdate continues a multiple-part encryption operation.\n"
+ " hSession session's handle\n"
+ " pPart the plaintext data\n"
+ " ulPartLen plaintext data len\n"
+ " pEncryptedPart gets ciphertext\n"
+ " pulEncryptedPartLen gets c-text size\n",
+ { ArgULong, ArgChar, ArgULong, ArgChar | ArgOut, ArgULong | ArgOut, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_EncryptFinal",
+ F_C_EncryptFinal,
+ "C_EncryptFinal hSession pLastEncryptedPart pulLastEncryptedPartLen\n\n"
+ "C_EncryptFinal finishes a multiple-part encryption operation.\n"
+ " hSession session handle\n"
+ " pLastEncryptedPart last c-text\n"
+ " pulLastEncryptedPartLen gets last size\n",
+ { ArgULong, ArgChar, ArgULong, ArgChar | ArgOut, ArgULong | ArgOut, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_Encrypt",
+ F_C_Encrypt,
+ "C_Encrypt hSession pData ulDataLen pEncryptedData pulEncryptedDataLen\n\n"
+ "C_Encrypt encrypts single-part data.\n"
+ " hSession session's handle\n"
+ " pData the plaintext data\n"
+ " ulDataLen bytes of plaintext\n"
+ " pEncryptedData gets ciphertext\n"
+ " pulEncryptedDataLen gets c-text size\n",
+ { ArgULong, ArgChar, ArgULong, ArgChar | ArgOut, ArgULong | ArgOut, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_DecryptInit",
+ F_C_DecryptInit,
+ "C_DecryptInit hSession pMechanism hKey\n\n"
+ "C_DecryptInit initializes a decryption operation.\n"
+ " hSession the session's handle\n"
+ " pMechanism the decryption mechanism\n"
+ " hKey handle of decryption key\n",
+ { ArgULong, ArgMechanism, ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "C_DecryptUpdate",
+ F_C_DecryptUpdate,
+ "C_DecryptUpdate hSession pEncryptedPart ulEncryptedPartLen pPart pulPartLen\n"
+ "\n"
+ "C_DecryptUpdate continues a multiple-part decryption operation.\n"
+ " hSession session's handle\n"
+ " pEncryptedPart encrypted data\n"
+ " ulEncryptedPartLen input length\n"
+ " pPart gets plaintext\n"
+ " pulPartLen p-text size\n",
+ { ArgULong, ArgChar, ArgULong, ArgChar | ArgOut, ArgULong | ArgOut, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_DecryptFinal",
+ F_C_DecryptFinal,
+ "C_DecryptFinal hSession pLastPart pulLastPartLen\n\n"
+ "C_DecryptFinal finishes a multiple-part decryption operation.\n"
+ " hSession the session's handle\n"
+ " pLastPart gets plaintext\n"
+ " pulLastPartLen p-text size\n",
+ { ArgULong, ArgChar, ArgULong, ArgChar | ArgOut, ArgULong | ArgOut, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_Decrypt",
+ F_C_Decrypt,
+ "C_Decrypt hSession pEncryptedData ulEncryptedDataLen pData pulDataLen\n\n"
+ "C_Decrypt decrypts encrypted data in a single part.\n"
+ " hSession session's handle\n"
+ " pEncryptedData ciphertext\n"
+ " ulEncryptedDataLen ciphertext length\n"
+ " pData gets plaintext\n"
+ " pulDataLen gets p-text size\n",
+ { ArgULong, ArgChar, ArgULong, ArgChar | ArgOut, ArgULong | ArgOut, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_DigestInit",
+ F_C_DigestInit,
+ "C_DigestInit hSession pMechanism\n\n"
+ "C_DigestInit initializes a message-digesting operation.\n"
+ " hSession the session's handle\n"
+ " pMechanism the digesting mechanism\n",
+ { ArgULong, ArgMechanism, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "C_DigestUpdate",
+ F_C_DigestUpdate,
+ "C_DigestUpdate hSession pPart ulPartLen\n\n"
+ "C_DigestUpdate continues a multiple-part message-digesting operation.\n"
+ " hSession the session's handle\n"
+ " pPart data to be digested\n"
+ " ulPartLen bytes of data to be digested\n",
+ { ArgULong, ArgChar, ArgULong, ArgChar | ArgOut, ArgULong | ArgOut, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_DigestKey",
+ F_C_DigestKey,
+ "C_DigestKey hSession hKey\n\n"
+ "C_DigestKey continues a multi-part message-digesting operation by digesting\n"
+ "the value of a secret key as part of the data already digested.\n"
+ " hSession the session's handle\n"
+ " hKey secret key to digest\n",
+ { ArgULong, ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone } },
+ { "C_DigestFinal",
+ F_C_DigestFinal,
+ "C_DigestFinal hSession pDigest pulDigestLen\n\n"
+ "C_DigestFinal finishes a multiple-part message-digesting operation.\n"
+ " hSession the session's handle\n"
+ " pDigest gets the message digest\n"
+ " pulDigestLen gets byte count of digest\n",
+ { ArgULong, ArgChar | ArgOut, ArgULong | ArgOut, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone } },
+ { "C_Digest",
+ F_C_Digest,
+ "C_Digest hSession pData ulDataLen pDigest pulDigestLen\n\n"
+ "C_Digest digests data in a single part.\n"
+ " hSession the session's handle\n"
+ " pData data to be digested\n"
+ " ulDataLen bytes of data to digest\n"
+ " pDigest gets the message digest\n"
+ " pulDigestLen gets digest length\n",
+ { ArgULong, ArgChar, ArgULong, ArgChar | ArgOut, ArgULong | ArgOut, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_SignInit",
+ F_C_SignInit,
+ "C_SignInit hSession pMechanism hKey\n\n"
+ "C_SignInit initializes a signature (private key encryption operation where\n"
+ "the signature is (will be) an appendix to the data and plaintext cannot be\n"
+ "recovered from the signature.\n"
+ " hSession the session's handle\n"
+ " pMechanism the signature mechanism\n"
+ " hKey handle of signature key\n",
+ { ArgULong, ArgMechanism, ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "C_SignUpdate",
+ F_C_SignUpdate,
+ "C_SignUpdate hSession pPart ulPartLen\n\n"
+ "C_SignUpdate continues a multiple-part signature operation where the\n"
+ "signature is (will be) an appendix to the data and plaintext cannot be\n"
+ "recovered from the signature.\n"
+ " hSession the session's handle\n"
+ " pPart the data to sign\n"
+ " ulPartLen count of bytes to sign\n",
+ { ArgULong, ArgChar | ArgOut, ArgULong | ArgOut, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone } },
+ { "C_SignFinal",
+ F_C_SignFinal,
+ "C_SignFinal hSession pSignature pulSignatureLen\n\n"
+ "C_SignFinal finishes a multiple-part signature operation returning the\n"
+ "signature.\n"
+ " hSession the session's handle\n"
+ " pSignature gets the signature\n"
+ " pulSignatureLen gets signature length\n",
+ { ArgULong, ArgChar | ArgOut, ArgULong | ArgOut, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone } },
+ { "C_SignRecoverInit",
+ F_C_SignRecoverInit,
+ "C_SignRecoverInit hSession pMechanism hKey\n\n"
+ "C_SignRecoverInit initializes a signature operation where the data can be\n"
+ "recovered from the signature.\n"
+ " hSession the session's handle\n"
+ " pMechanism the signature mechanism\n"
+ " hKey handle of the signature key\n",
+ { ArgULong, ArgMechanism, ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "C_SignRecover",
+ F_C_SignRecover,
+ "C_SignRecover hSession pData ulDataLen pSignature pulSignatureLen\n\n"
+ "C_SignRecover signs data in a single operation where the data can be\n"
+ "recovered from the signature.\n"
+ " hSession the session's handle\n"
+ " pData the data to sign\n"
+ " ulDataLen count of bytes to sign\n"
+ " pSignature gets the signature\n"
+ " pulSignatureLen gets signature length\n",
+ { ArgULong, ArgChar, ArgULong, ArgChar | ArgOut, ArgULong | ArgOut, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_Sign",
+ F_C_Sign,
+ "C_Sign hSession pData ulDataLen pSignature pulSignatureLen\n\n"
+ "C_Sign signs (encrypts with private key) data in a single part where the\n"
+ "signature is (will be) an appendix to the data and plaintext cannot be\n"
+ "recovered from the signature.\n"
+ " hSession the session's handle\n"
+ " pData the data to sign\n"
+ " ulDataLen count of bytes to sign\n"
+ " pSignature gets the signature\n"
+ " pulSignatureLen gets signature length\n",
+ { ArgULong, ArgChar, ArgULong, ArgChar | ArgOut, ArgULong | ArgOut, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_VerifyInit",
+ F_C_VerifyInit,
+ "C_VerifyInit hSession pMechanism hKey\n\n"
+ "C_VerifyInit initializes a verification operation where the signature is an\n"
+ "appendix to the data and plaintext cannot cannot be recovered from the\n"
+ "signature (e.g. DSA).\n"
+ " hSession the session's handle\n"
+ " pMechanism the verification mechanism\n"
+ " hKey verification key\n",
+ { ArgULong, ArgMechanism, ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "C_VerifyUpdate",
+ F_C_VerifyUpdate,
+ "C_VerifyUpdate hSession pPart ulPartLen\n\n"
+ "C_VerifyUpdate continues a multiple-part verification operation where the\n"
+ "signature is an appendix to the data and plaintext cannot be recovered from\n"
+ "the signature.\n"
+ " hSession the session's handle\n"
+ " pPart signed data\n"
+ " ulPartLen length of signed data\n",
+ { ArgULong, ArgChar | ArgOut, ArgULong | ArgOut, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone } },
+ { "C_VerifyFinal",
+ F_C_VerifyFinal,
+ "C_VerifyFinal hSession pSignature ulSignatureLen\n\n"
+ "C_VerifyFinal finishes a multiple-part verification operation checking the\n"
+ "signature.\n"
+ " hSession the session's handle\n"
+ " pSignature signature to verify\n"
+ " ulSignatureLen signature length\n",
+ { ArgULong, ArgChar | ArgOut, ArgULong | ArgOut, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone } },
+ { "C_VerifyRecoverInit",
+ F_C_VerifyRecoverInit,
+ "C_VerifyRecoverInit hSession pMechanism hKey\n\n"
+ "C_VerifyRecoverInit initializes a signature verification operation where the\n"
+ "data is recovered from the signature.\n"
+ " hSession the session's handle\n"
+ " pMechanism the verification mechanism\n"
+ " hKey verification key\n",
+ { ArgULong, ArgMechanism, ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "C_VerifyRecover",
+ F_C_VerifyRecover,
+ "C_VerifyRecover hSession pSignature ulSignatureLen pData pulDataLen\n\n"
+ "C_VerifyRecover verifies a signature in a single-part operation where the\n"
+ "data is recovered from the signature.\n"
+ " hSession the session's handle\n"
+ " pSignature signature to verify\n"
+ " ulSignatureLen signature length\n"
+ " pData gets signed data\n"
+ " pulDataLen gets signed data len\n",
+ { ArgULong, ArgChar, ArgULong, ArgChar | ArgOut, ArgULong | ArgOut, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_Verify",
+ F_C_Verify,
+ "C_Verify hSession pData ulDataLen pSignature ulSignatureLen\n\n"
+ "C_Verify verifies a signature in a single-part operation where the signature\n"
+ "is an appendix to the data and plaintext cannot be recovered from the\n"
+ "signature.\n"
+ " hSession the session's handle\n"
+ " pData signed data\n"
+ " ulDataLen length of signed data\n"
+ " pSignature signature\n"
+ " ulSignatureLen signature length*/\n",
+ { ArgULong, ArgChar, ArgULong, ArgChar | ArgOut, ArgULong | ArgOut, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_DigestEncryptUpdate",
+ F_C_DigestEncryptUpdate,
+ "C_DigestEncryptUpdate hSession pPart ulPartLen pEncryptedPart \\\n"
+ " pulEncryptedPartLen\n\n"
+ "C_DigestEncryptUpdate continues a multiple-part digesting and encryption\n"
+ "operation.\n"
+ " hSession session's handle\n"
+ " pPart the plaintext data\n"
+ " ulPartLen plaintext length\n"
+ " pEncryptedPart gets ciphertext\n"
+ " pulEncryptedPartLen gets c-text length\n",
+ { ArgULong, ArgChar, ArgULong, ArgChar | ArgOut, ArgULong | ArgOut, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_DecryptDigestUpdate",
+ F_C_DecryptDigestUpdate,
+ "C_DecryptDigestUpdate hSession pEncryptedPart ulEncryptedPartLen pPart \\\n"
+ " pulPartLen\n\n"
+ "C_DecryptDigestUpdate continues a multiple-part decryption and digesting\n"
+ "operation.\n"
+ " hSession session's handle\n"
+ " pEncryptedPart ciphertext\n"
+ " ulEncryptedPartLen ciphertext length\n"
+ " pPart gets plaintext\n"
+ " pulPartLen gets plaintext len\n",
+ { ArgULong, ArgChar, ArgULong, ArgChar | ArgOut, ArgULong | ArgOut, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_SignEncryptUpdate",
+ F_C_SignEncryptUpdate,
+ "C_SignEncryptUpdate hSession pPart ulPartLen pEncryptedPart \\\n"
+ " pulEncryptedPartLen\n\n"
+ "C_SignEncryptUpdate continues a multiple-part signing and encryption\n"
+ "operation.\n"
+ " hSession session's handle\n"
+ " pPart the plaintext data\n"
+ " ulPartLen plaintext length\n"
+ " pEncryptedPart gets ciphertext\n"
+ " pulEncryptedPartLen gets c-text length\n",
+ { ArgULong, ArgChar, ArgULong, ArgChar | ArgOut, ArgULong | ArgOut, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_DecryptVerifyUpdate",
+ F_C_DecryptVerifyUpdate,
+ "C_DecryptVerifyUpdate hSession pEncryptedPart ulEncryptedPartLen pPart \\\n"
+ " pulPartLen\n\n"
+ "C_DecryptVerifyUpdate continues a multiple-part decryption and verify\n"
+ "operation.\n"
+ " hSession session's handle\n"
+ " pEncryptedPart ciphertext\n"
+ " ulEncryptedPartLen ciphertext length\n"
+ " pPart gets plaintext\n"
+ " pulPartLen gets p-text length\n",
+ { ArgULong, ArgChar, ArgULong, ArgChar | ArgOut, ArgULong | ArgOut, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_GenerateKeyPair",
+ F_C_GenerateKeyPair,
+ "C_GenerateKeyPair hSession pMechanism pPublicKeyTemplate \\\n"
+ " ulPublicKeyAttributeCount pPrivateKeyTemplate ulPrivateKeyAttributeCount \\\n"
+ " phPublicKey phPrivateKey\n\n"
+ "C_GenerateKeyPair generates a public-key/private-key pair creating new key\n"
+ "objects.\n"
+ " hSession sessionhandle\n"
+ " pMechanism key-genmech.\n"
+ " pPublicKeyTemplate templatefor pub. key\n"
+ " ulPublicKeyAttributeCount # pub. attrs.\n"
+ " pPrivateKeyTemplate templatefor priv. key\n"
+ " ulPrivateKeyAttributeCount # priv. attrs.\n"
+ " phPublicKey gets pub. keyhandle\n"
+ " phPrivateKey getspriv. keyhandle\n",
+ { ArgULong, ArgMechanism, ArgAttribute | ArgArray, ArgULong,
+ ArgAttribute | ArgArray, ArgULong, ArgULong | ArgOut, ArgULong | ArgOut, ArgNone,
+ ArgNone } },
+ { "C_GenerateKey",
+ F_C_GenerateKey,
+ "C_GenerateKey hSession pMechanism pTemplate ulCount phKey\n\n"
+ "C_GenerateKey generates a secret key creating a new key object.\n"
+ " hSession the session's handle\n"
+ " pMechanism key generation mech.\n"
+ " pTemplate template for new key\n"
+ " ulCount # of attrs in template\n"
+ " phKey gets handle of new key\n",
+ { ArgULong, ArgMechanism, ArgAttribute | ArgArray, ArgULong, ArgULong | ArgOut,
+ ArgNone, ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_WrapKey",
+ F_C_WrapKey,
+ "C_WrapKey hSession pMechanism hWrappingKey hKey pWrappedKey pulWrappedKeyLen\n\n"
+ "C_WrapKey wraps (i.e. encrypts) a key.\n"
+ " hSession the session's handle\n"
+ " pMechanism the wrapping mechanism\n"
+ " hWrappingKey wrapping key\n"
+ " hKey key to be wrapped\n"
+ " pWrappedKey gets wrapped key\n"
+ " pulWrappedKeyLen gets wrapped key size\n",
+ { ArgULong, ArgMechanism, ArgULong, ArgULong, ArgULong, ArgChar | ArgOut,
+ ArgULong | ArgOut, ArgNone, ArgNone, ArgNone } },
+ { "C_UnwrapKey",
+ F_C_UnwrapKey,
+ "C_UnwrapKey hSession pMechanism hUnwrappingKey pWrappedKey ulWrappedKeyLen \\\n"
+ " pTemplate ulAttributeCount phKey\n\n"
+ "C_UnwrapKey unwraps (decrypts) a wrapped key creating a new key object.\n"
+ " hSession session's handle\n"
+ " pMechanism unwrapping mech.\n"
+ " hUnwrappingKey unwrapping key\n"
+ " pWrappedKey the wrapped key\n"
+ " ulWrappedKeyLen wrapped key len\n"
+ " pTemplate new key template\n"
+ " ulAttributeCount template length\n"
+ " phKey gets new handle\n",
+ { ArgULong, ArgMechanism, ArgULong, ArgChar, ArgULong, ArgAttribute | ArgArray,
+ ArgULong, ArgULong | ArgOut, ArgNone, ArgNone } },
+ { "C_DeriveKey",
+ F_C_DeriveKey,
+ "C_DeriveKey hSession pMechanism hBaseKey pTemplate ulAttributeCount phKey\n\n"
+ "C_DeriveKey derives a key from a base key creating a new key object.\n"
+ " hSession session's handle\n"
+ " pMechanism key deriv. mech.\n"
+ " hBaseKey base key\n"
+ " pTemplate new key template\n"
+ " ulAttributeCount template length\n"
+ " phKey gets new handle\n",
+ { ArgULong, ArgMechanism, ArgULong, ArgAttribute | ArgArray, ArgULong,
+ ArgULong | ArgOut, ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "C_SeedRandom",
+ F_C_SeedRandom,
+ "C_SeedRandom hSession pSeed ulSeedLen\n\n"
+ "C_SeedRandom mixes additional seed material into the token's random number\n"
+ "generator.\n"
+ " hSession the session's handle\n"
+ " pSeed the seed material\n"
+ " ulSeedLen length of seed material\n",
+ { ArgULong, ArgChar, ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone } },
+ { "C_GenerateRandom",
+ F_C_GenerateRandom,
+ "C_GenerateRandom hSession RandomData ulRandomLen\n\n"
+ "C_GenerateRandom generates random data.\n"
+ " hSession the session's handle\n"
+ " RandomData receives the random data\n"
+ " ulRandomLen # of bytes to generate\n",
+ { ArgULong, ArgChar, ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone } },
+ { "C_GetFunctionStatus",
+ F_C_GetFunctionStatus,
+ "C_GetFunctionStatus hSession\n\n"
+ "C_GetFunctionStatus is a legacy function; it obtains an updated status of\n"
+ "a function running in parallel with an application.\n"
+ " hSession the session's handle\n",
+ { ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone } },
+ { "C_CancelFunction",
+ F_C_CancelFunction,
+ "C_CancelFunction hSession\n\n"
+ "C_CancelFunction is a legacy function; it cancels a function running in\n"
+ "parallel.\n"
+ " hSession the session's handle\n",
+ { ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone } },
+ { "C_WaitForSlotEvent",
+ F_C_WaitForSlotEvent,
+ "C_WaitForSlotEvent flags pSlot pRserved\n\n"
+ "C_WaitForSlotEvent waits for a slot event (token insertion removal etc.)\n"
+ "to occur.\n"
+ " flags blocking/nonblocking flag\n"
+ " pSlot location that receives the slot ID\n"
+ " pRserved reserved. Should be NULL_PTR\n",
+ { ArgULong, ArgULong | ArgArray, ArgVar, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone } },
+ { "NewArray",
+ F_NewArray,
+ "NewArray varName varType array size\n\n"
+ "Creates a new array variable.\n"
+ " varName variable name of the new array\n"
+ " varType data type of the new array\n"
+ " size number of elements in the array\n",
+ { ArgVar | ArgNew, ArgVar, ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "NewInitArg",
+ F_NewInitializeArgs,
+ "NewInitArg varName flags string\n\n"
+ "Creates a new init variable.\n"
+ " varName variable name of the new initArg\n"
+ " flags value to set the flags field\n"
+ " string string parameter for init arg\n",
+ { ArgVar | ArgNew, ArgULong, ArgVar | ArgNew, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone } },
+ { "NewTemplate",
+ F_NewTemplate,
+ "NewTemplate varName attributeList\n\n"
+ "Create a new empty template and populate the attribute list\n"
+ " varName variable name of the new template\n"
+ " attributeList comma separated list of CKA_ATTRIBUTE types\n",
+ { ArgVar | ArgNew, ArgVar, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "NewMechanism",
+ F_NewMechanism,
+ "NewMechanism varName mechanismType\n\n"
+ "Create a new CK_MECHANISM object with type NULL parameters and specified type\n"
+ " varName variable name of the new mechansim\n"
+ " mechanismType CKM_ mechanism type value to set int the type field\n",
+ { ArgVar | ArgNew, ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "BuildTemplate",
+ F_BuildTemplate,
+ "BuildTemplate template\n\n"
+ "Allocates space for the value in a template which has the sizes filled in,\n"
+ "but no values allocated yet.\n"
+ " template variable name of the template\n",
+ { ArgAttribute, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "SetTemplate",
+ F_SetTemplate,
+ "SetTemplate template index value\n\n"
+ "Sets a particular element of a template to a CK_ULONG\n"
+ " template variable name of the template\n"
+ " index index into the template to the element to change\n"
+ " value 32 bit value to set in the template\n",
+ { ArgAttribute, ArgULong, ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "SetString",
+ F_SetStringVar,
+ "SetString varName string\n\n"
+ "Sets a particular variable to a string value\n"
+ " variable variable name of new string\n"
+ " string String to set the variable to\n",
+ { ArgVar | ArgNew, ArgVar, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "Set",
+ F_SetVar,
+ "Set varName value\n\n"
+ "Sets a particular variable to CK_ULONG\n"
+ " variable name of the new variable\n"
+ " value 32 bit value to set variable to\n",
+ { ArgVar | ArgNew, ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "Print",
+ F_Print,
+ "Print varName\n\n"
+ "prints a variable\n"
+ " variable name of the variable to print\n",
+ { ArgVar, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone } },
+ { "Delete",
+ F_Delete,
+ "Delete varName\n\n"
+ "delete a variable\n"
+ " variable name of the variable to delete\n",
+ { ArgVar | ArgNew, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "Load",
+ F_Load,
+ "load libraryName\n\n"
+ "load a pkcs #11 module\n"
+ " libraryName Name of a shared library\n",
+ { ArgVar, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone } },
+ { "Save",
+ F_SaveVar,
+ "Save filename variable\n\n"
+ "Saves the binary value of 'variable' in file 'filename'\n"
+ " fileName target file to save the variable in\n"
+ " variable variable to save\n",
+ { ArgVar | ArgNew, ArgVar, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "Restore",
+ F_RestoreVar,
+ "Restore filename variable\n\n"
+ "Restores a variable from a file\n"
+ " fileName target file to restore the variable from\n"
+ " variable variable to restore\n",
+ { ArgVar | ArgNew, ArgVar, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "Increment",
+ F_Increment,
+ "Increment variable value\n\n"
+ "Increment a variable by value\n",
+ { ArgVar, ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone } },
+ { "Decrement",
+ F_Decrement,
+ "Decrement variable value\n\n"
+ "Decrement a variable by value\n",
+ { ArgVar, ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone } },
+ { "List",
+ F_List,
+ "List all the variables\n",
+ { ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone } },
+ { "Unload",
+ F_Unload,
+ "Unload the currrently loaded PKCS #11 library\n",
+ { ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone } },
+ { "Run",
+ F_Run,
+ "Run filename\n\n"
+ "reads filename as script of commands to execute\n",
+ { ArgVar | ArgNew, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "Time",
+ F_Time,
+ "Time pkcs11 command\n\n"
+ "Execute a pkcs #11 command and time the results\n",
+ { ArgVar | ArgFull, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "System",
+ F_System,
+ "Set System Flag",
+ { ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone } },
+ { "LoopRun",
+ F_Loop,
+ "LoopRun filename var start end step\n\n"
+ "Run in a loop. Loop exit if scrip does and explicit quit (Quit QuitIf etc.)",
+ { ArgVar | ArgNew, ArgVar | ArgNew, ArgULong, ArgULong, ArgULong, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone } },
+ { "Help",
+ F_Help,
+ "Help [command]\n\n"
+ "print general help, or help for a specific command\n",
+ { ArgVar | ArgOpt, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "QuitIf",
+ F_QuitIf,
+ "QuitIf arg1 comparator arg2\n\n"
+ "Exit from this program if Condition is valid, valid comparators:\n"
+ " < > <= >= = !=\n",
+ { ArgULong, ArgVar | ArgNew, ArgULong, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone } },
+ { "QuitIfString",
+ F_QuitIfString,
+ "QuitIfString arg1 comparator arg2\n\n"
+ "Exit from this program if Condition is valid, valid comparators:\n"
+ " = !=\n",
+ { ArgVar | ArgNew, ArgVar | ArgNew, ArgVar | ArgNew, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone } },
+ { "Quit",
+ F_Quit,
+ "Exit from this program",
+ { ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
+ ArgNone } },
+};
+
+const Commands *commands = &_commands[0];
+const int commandCount = sizeof(_commands) / sizeof(_commands[0]);
+
+const Topics _topics[] = {
+ { "variables",
+ "Variables are random strings of characters. These should begin with alpha\n"
+ " characters, and should not contain any spaces, nor should they match any\n"
+ " built-in constants. There is some checking in the code for these things,\n"
+ " but it's not 100% and using invalid variable names can cause problems.\n"
+ " Variables are created by any 'OUT' parameter. If the variable does not\n"
+ " exist, it will be created. For in parameters variables must already exist.\n" },
+ { "constants",
+ "pk11util recognizes *lots* of constants. All CKA_, CKF_, CKO_, CKU_, CKS_,\n"
+ " CKC_, CKK_, CKH_, CKM_, CKT_ values from the PKCS #11 spec are recognized.\n"
+ " Constants can be specified with their fully qualified CK?_ value, or the\n"
+ " prefix can be dropped. Constants are matched case insensitve.\n" },
+ { "arrays",
+ "Arrays are special variables which represent 'C' arrays. Each array \n"
+ " variable can be referenced as a group (using just the name), or as \n"
+ " individual elements (with the [int] operator). Example:\n"
+ " print myArray # prints the full array.\n"
+ " print myArray[3] # prints the 3rd elemement of the array \n" },
+ { "sizes",
+ "Size operaters returns the size in bytes of a variable, or the number of\n"
+ " elements in an array.\n"
+ " size(var) and sizeof(var) return the size of var in bytes.\n"
+ " sizea(var) and sizeofarray(var) return the number of elements in var.\n"
+ " If var is not an array, sizea(var) returns 1.\n" },
+};
+
+const Topics *topics = &_topics[0];
+const int topicCount = sizeof(_topics) / sizeof(_topics[0]);
+
+const char *
+getName(CK_ULONG value, ConstType type)
+{
+ unsigned int i;
+
+ for (i = 0; i < constCount; i++) {
+ if (consts[i].type == type && consts[i].value == value) {
+ return consts[i].name;
+ }
+ if (type == ConstNone && consts[i].value == value) {
+ return consts[i].name;
+ }
+ }
+
+ return NULL;
+}
+
+const char *
+getNameFromAttribute(CK_ATTRIBUTE_TYPE type)
+{
+ return getName(type, ConstAttribute);
+}
+
+unsigned int
+totalKnownType(ConstType type)
+{
+ unsigned int count = 0;
+ unsigned int i;
+
+ for (i = 0; i < constCount; i++) {
+ if (consts[i].type == type)
+ count++;
+ }
+ return count;
+}
diff --git a/nss/cmd/lib/pk11table.h b/nss/cmd/lib/pk11table.h
new file mode 100644
index 0000000..3dea820
--- /dev/null
+++ b/nss/cmd/lib/pk11table.h
@@ -0,0 +1,178 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#ifndef _PK11_TABLE_H_
+#define _PK11_TABLE_H_
+
+/*
+ * Supported functions..
+ */
+#include
+#include "nspr.h"
+#include "prtypes.h"
+
+typedef enum {
+ F_No_Function,
+#undef CK_NEED_ARG_LIST
+#define CK_PKCS11_FUNCTION_INFO(func) F_##func,
+#include "pkcs11f.h"
+#undef CK_NEED_ARG_LISt
+#undef CK_PKCS11_FUNCTION_INFO
+ F_SetVar,
+ F_SetStringVar,
+ F_NewArray,
+ F_NewInitializeArgs,
+ F_NewTemplate,
+ F_NewMechanism,
+ F_BuildTemplate,
+ F_SetTemplate,
+ F_Print,
+ F_SaveVar,
+ F_RestoreVar,
+ F_Increment,
+ F_Decrement,
+ F_Delete,
+ F_List,
+ F_Run,
+ F_Load,
+ F_Unload,
+ F_System,
+ F_Loop,
+ F_Time,
+ F_Help,
+ F_Quit,
+ F_QuitIf,
+ F_QuitIfString
+} FunctionType;
+
+/*
+ * Supported Argument Types
+ */
+typedef enum {
+ ArgNone,
+ ArgVar,
+ ArgULong,
+ ArgChar,
+ ArgUTF8,
+ ArgInfo,
+ ArgSlotInfo,
+ ArgTokenInfo,
+ ArgSessionInfo,
+ ArgAttribute,
+ ArgMechanism,
+ ArgMechanismInfo,
+ ArgInitializeArgs,
+ ArgFunctionList,
+ /* Modifier Flags */
+ ArgMask = 0xff,
+ ArgOut = 0x100,
+ ArgArray = 0x200,
+ ArgNew = 0x400,
+ ArgFile = 0x800,
+ ArgStatic = 0x1000,
+ ArgOpt = 0x2000,
+ ArgFull = 0x4000
+} ArgType;
+
+typedef enum _constType {
+ ConstNone,
+ ConstBool,
+ ConstInfoFlags,
+ ConstSlotFlags,
+ ConstTokenFlags,
+ ConstSessionFlags,
+ ConstMechanismFlags,
+ ConstInitializeFlags,
+ ConstUsers,
+ ConstSessionState,
+ ConstObject,
+ ConstHardware,
+ ConstKeyType,
+ ConstCertType,
+ ConstAttribute,
+ ConstMechanism,
+ ConstResult,
+ ConstTrust,
+ ConstAvailableSizes,
+ ConstCurrentSize
+} ConstType;
+
+typedef struct _constant {
+ const char *name;
+ CK_ULONG value;
+ ConstType type;
+ ConstType attrType;
+} Constant;
+
+/*
+ * Values structures.
+ */
+typedef struct _values {
+ ArgType type;
+ ConstType constType;
+ int size;
+ char *filename;
+ void *data;
+ int reference;
+ int arraySize;
+} Value;
+
+/*
+ * Variables
+ */
+typedef struct _variable Variable;
+struct _variable {
+ Variable *next;
+ char *vname;
+ Value *value;
+};
+
+/* NOTE: if you change MAX_ARGS, you need to change the commands array
+ * below as well.
+ */
+
+#define MAX_ARGS 10
+/*
+ * structure for master command array
+ */
+typedef struct _commands {
+ char *fname;
+ FunctionType fType;
+ char *helpString;
+ ArgType args[MAX_ARGS];
+} Commands;
+
+typedef struct _module {
+ PRLibrary *library;
+ CK_FUNCTION_LIST *functionList;
+} Module;
+
+typedef struct _topics {
+ char *name;
+ char *helpString;
+} Topics;
+
+/*
+ * the command array itself. Make name to function and it's arguments
+ */
+
+extern const char **valueString;
+extern const int valueCount;
+extern const char **constTypeString;
+extern const int constTypeCount;
+extern const Constant *consts;
+extern const unsigned int constCount;
+extern const Commands *commands;
+extern const int commandCount;
+extern const Topics *topics;
+extern const int topicCount;
+
+extern const char *
+getName(CK_ULONG value, ConstType type);
+
+extern const char *
+getNameFromAttribute(CK_ATTRIBUTE_TYPE type);
+
+extern unsigned int totalKnownType(ConstType type);
+
+#endif /* _PK11_TABLE_H_ */
diff --git a/nss/cmd/lib/pppolicy.c b/nss/cmd/lib/pppolicy.c
new file mode 100644
index 0000000..aaf4559
--- /dev/null
+++ b/nss/cmd/lib/pppolicy.c
@@ -0,0 +1,263 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * Support for various policy related extensions
+ */
+
+#include "seccomon.h"
+#include "secport.h"
+#include "secder.h"
+#include "cert.h"
+#include "secoid.h"
+#include "secasn1.h"
+#include "secerr.h"
+#include "nspr.h"
+#include "secutil.h"
+
+/* This implementation is derived from the one in nss/lib/certdb/policyxtn.c .
+** The chief difference is the addition of the OPTIONAL flag to many
+** parts. The idea is to be able to parse and print as much of the
+** policy extension as possible, even if some parts are invalid.
+**
+** If this approach still is unable to decode policy extensions that
+** contain invalid parts, then the next approach will be to parse
+** the PolicyInfos as a SEQUENCE of ANYs, and then parse each of them
+** as PolicyInfos, with the PolicyQualifiers being ANYs, and finally
+** parse each of the PolicyQualifiers.
+*/
+
+static const SEC_ASN1Template secu_PolicyQualifierTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(CERTPolicyQualifier) },
+ { SEC_ASN1_OBJECT_ID,
+ offsetof(CERTPolicyQualifier, qualifierID) },
+ { SEC_ASN1_ANY | SEC_ASN1_OPTIONAL,
+ offsetof(CERTPolicyQualifier, qualifierValue) },
+ { 0 }
+};
+
+static const SEC_ASN1Template secu_PolicyInfoTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(CERTPolicyInfo) },
+ { SEC_ASN1_OBJECT_ID,
+ offsetof(CERTPolicyInfo, policyID) },
+ { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_OPTIONAL,
+ offsetof(CERTPolicyInfo, policyQualifiers),
+ secu_PolicyQualifierTemplate },
+ { 0 }
+};
+
+static const SEC_ASN1Template secu_CertificatePoliciesTemplate[] = {
+ { SEC_ASN1_SEQUENCE_OF,
+ offsetof(CERTCertificatePolicies, policyInfos),
+ secu_PolicyInfoTemplate, sizeof(CERTCertificatePolicies) }
+};
+
+static CERTCertificatePolicies *
+secu_DecodeCertificatePoliciesExtension(SECItem *extnValue)
+{
+ PLArenaPool *arena = NULL;
+ SECStatus rv;
+ CERTCertificatePolicies *policies;
+ CERTPolicyInfo **policyInfos, *policyInfo;
+ CERTPolicyQualifier **policyQualifiers, *policyQualifier;
+ SECItem newExtnValue;
+
+ /* make a new arena */
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if (!arena) {
+ goto loser;
+ }
+
+ /* allocate the certifiate policies structure */
+ policies = PORT_ArenaZNew(arena, CERTCertificatePolicies);
+ if (policies == NULL) {
+ goto loser;
+ }
+
+ policies->arena = arena;
+
+ /* copy the DER into the arena, since Quick DER returns data that points
+ into the DER input, which may get freed by the caller */
+ rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ /* decode the policy info */
+ rv = SEC_QuickDERDecodeItem(arena, policies,
+ secu_CertificatePoliciesTemplate,
+ &newExtnValue);
+
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ /* initialize the oid tags */
+ policyInfos = policies->policyInfos;
+ while (policyInfos != NULL && *policyInfos != NULL) {
+ policyInfo = *policyInfos;
+ policyInfo->oid = SECOID_FindOIDTag(&policyInfo->policyID);
+ policyQualifiers = policyInfo->policyQualifiers;
+ while (policyQualifiers && *policyQualifiers != NULL) {
+ policyQualifier = *policyQualifiers;
+ policyQualifier->oid =
+ SECOID_FindOIDTag(&policyQualifier->qualifierID);
+ policyQualifiers++;
+ }
+ policyInfos++;
+ }
+
+ return (policies);
+
+loser:
+ if (arena != NULL) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return (NULL);
+}
+
+static char *
+itemToString(SECItem *item)
+{
+ char *string;
+
+ string = PORT_ZAlloc(item->len + 1);
+ if (string == NULL)
+ return NULL;
+ PORT_Memcpy(string, item->data, item->len);
+ string[item->len] = 0;
+ return string;
+}
+
+static SECStatus
+secu_PrintUserNoticeQualifier(FILE *out, SECItem *qualifierValue,
+ char *msg, int level)
+{
+ CERTUserNotice *userNotice = NULL;
+ if (qualifierValue)
+ userNotice = CERT_DecodeUserNotice(qualifierValue);
+ if (userNotice) {
+ if (userNotice->noticeReference.organization.len != 0) {
+ char *string =
+ itemToString(&userNotice->noticeReference.organization);
+ SECItem **itemList = userNotice->noticeReference.noticeNumbers;
+
+ while (itemList && *itemList) {
+ SECU_PrintInteger(out, *itemList, string, level + 1);
+ itemList++;
+ }
+ PORT_Free(string);
+ }
+ if (userNotice->displayText.len != 0) {
+ SECU_PrintString(out, &userNotice->displayText,
+ "Display Text", level + 1);
+ }
+ CERT_DestroyUserNotice(userNotice);
+ return SECSuccess;
+ }
+ return SECFailure; /* caller will print this value */
+}
+
+static SECStatus
+secu_PrintPolicyQualifier(FILE *out, CERTPolicyQualifier *policyQualifier,
+ char *msg, int level)
+{
+ SECStatus rv;
+ SECItem *qualifierValue = &policyQualifier->qualifierValue;
+
+ SECU_PrintObjectID(out, &policyQualifier->qualifierID,
+ "Policy Qualifier Name", level);
+ if (!qualifierValue->data) {
+ SECU_Indent(out, level);
+ fprintf(out, "Error: missing qualifier\n");
+ } else
+ switch (policyQualifier->oid) {
+ case SEC_OID_PKIX_USER_NOTICE_QUALIFIER:
+ rv = secu_PrintUserNoticeQualifier(out, qualifierValue, msg, level);
+ if (SECSuccess == rv)
+ break;
+ /* fall through on error */
+ case SEC_OID_PKIX_CPS_POINTER_QUALIFIER:
+ default:
+ SECU_PrintAny(out, qualifierValue, "Policy Qualifier Data", level);
+ break;
+ }
+ return SECSuccess;
+}
+
+static SECStatus
+secu_PrintPolicyInfo(FILE *out, CERTPolicyInfo *policyInfo, char *msg, int level)
+{
+ CERTPolicyQualifier **policyQualifiers;
+
+ policyQualifiers = policyInfo->policyQualifiers;
+ SECU_PrintObjectID(out, &policyInfo->policyID, "Policy Name", level);
+
+ while (policyQualifiers && *policyQualifiers != NULL) {
+ secu_PrintPolicyQualifier(out, *policyQualifiers, "", level + 1);
+ policyQualifiers++;
+ }
+ return SECSuccess;
+}
+
+void
+SECU_PrintPolicy(FILE *out, SECItem *value, char *msg, int level)
+{
+ CERTCertificatePolicies *policies = NULL;
+ CERTPolicyInfo **policyInfos;
+
+ if (msg) {
+ SECU_Indent(out, level);
+ fprintf(out, "%s: \n", msg);
+ level++;
+ }
+ policies = secu_DecodeCertificatePoliciesExtension(value);
+ if (policies == NULL) {
+ SECU_PrintAny(out, value, "Invalid Policy Data", level);
+ return;
+ }
+
+ policyInfos = policies->policyInfos;
+ while (policyInfos && *policyInfos != NULL) {
+ secu_PrintPolicyInfo(out, *policyInfos, "", level);
+ policyInfos++;
+ }
+
+ CERT_DestroyCertificatePoliciesExtension(policies);
+}
+
+void
+SECU_PrintPrivKeyUsagePeriodExtension(FILE *out, SECItem *value,
+ char *msg, int level)
+{
+ CERTPrivKeyUsagePeriod *prd;
+ PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if (!arena) {
+ goto loser;
+ }
+ prd = CERT_DecodePrivKeyUsagePeriodExtension(arena, value);
+ if (!prd) {
+ goto loser;
+ }
+ if (prd->notBefore.data) {
+ SECU_PrintGeneralizedTime(out, &prd->notBefore, "Not Before", level);
+ }
+ if (prd->notAfter.data) {
+ SECU_PrintGeneralizedTime(out, &prd->notAfter, "Not After ", level);
+ }
+ if (!prd->notBefore.data && !prd->notAfter.data) {
+ SECU_Indent(out, level);
+ fprintf(out, "Error: notBefore or notAfter MUST be present.\n");
+ loser:
+ SECU_PrintAny(out, value, msg, level);
+ }
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+}
diff --git a/nss/cmd/lib/secpwd.c b/nss/cmd/lib/secpwd.c
new file mode 100644
index 0000000..7e99b27
--- /dev/null
+++ b/nss/cmd/lib/secpwd.c
@@ -0,0 +1,168 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#include "secutil.h"
+
+/*
+ * NOTE: The contents of this file are NOT used by the client.
+ * (They are part of the security library as a whole, but they are
+ * NOT USED BY THE CLIENT.) Do not change things on behalf of the
+ * client (like localizing strings), or add things that are only
+ * for the client (put them elsewhere).
+ */
+
+#ifdef XP_UNIX
+#include
+#endif
+
+#if defined(XP_UNIX) || defined(XP_BEOS)
+#include /* for isatty() */
+#endif
+
+#if defined(_WINDOWS)
+#include
+#include
+#define QUIET_FGETS quiet_fgets
+static char *quiet_fgets(char *buf, int length, FILE *input);
+#else
+#define QUIET_FGETS fgets
+#endif
+
+static void
+echoOff(int fd)
+{
+#if defined(XP_UNIX)
+ if (isatty(fd)) {
+ struct termios tio;
+ tcgetattr(fd, &tio);
+ tio.c_lflag &= ~ECHO;
+ tcsetattr(fd, TCSAFLUSH, &tio);
+ }
+#endif
+}
+
+static void
+echoOn(int fd)
+{
+#if defined(XP_UNIX)
+ if (isatty(fd)) {
+ struct termios tio;
+ tcgetattr(fd, &tio);
+ tio.c_lflag |= ECHO;
+ tcsetattr(fd, TCSAFLUSH, &tio);
+ }
+#endif
+}
+
+char *
+SEC_GetPassword(FILE *input, FILE *output, char *prompt,
+ PRBool (*ok)(char *))
+{
+#if defined(_WINDOWS)
+ int isTTY = (input == stdin);
+#define echoOn(x)
+#define echoOff(x)
+#else
+ int infd = fileno(input);
+ int isTTY = isatty(infd);
+#endif
+ char phrase[200] = { '\0' }; /* ensure EOF doesn't return junk */
+
+ for (;;) {
+ /* Prompt for password */
+ if (isTTY) {
+ fprintf(output, "%s", prompt);
+ fflush(output);
+ echoOff(infd);
+ }
+
+ if (QUIET_FGETS(phrase, sizeof(phrase), input) == NULL) {
+ return NULL;
+ }
+
+ if (isTTY) {
+ fprintf(output, "\n");
+ echoOn(infd);
+ }
+
+ /* stomp on newline */
+ phrase[PORT_Strlen(phrase) - 1] = 0;
+
+ /* Validate password */
+ if (!(*ok)(phrase)) {
+ /* Not weird enough */
+ if (!isTTY)
+ return NULL;
+ fprintf(output, "Password must be at least 8 characters long with one or more\n");
+ fprintf(output, "non-alphabetic characters\n");
+ continue;
+ }
+ return (char *)PORT_Strdup(phrase);
+ }
+}
+
+PRBool
+SEC_CheckPassword(char *cp)
+{
+ int len;
+ char *end;
+
+ len = PORT_Strlen(cp);
+ if (len < 8) {
+ return PR_FALSE;
+ }
+ end = cp + len;
+ while (cp < end) {
+ unsigned char ch = *cp++;
+ if (!((ch >= 'A') && (ch <= 'Z')) &&
+ !((ch >= 'a') && (ch <= 'z'))) {
+ /* pass phrase has at least one non alphabetic in it */
+ return PR_TRUE;
+ }
+ }
+ return PR_FALSE;
+}
+
+PRBool
+SEC_BlindCheckPassword(char *cp)
+{
+ if (cp != NULL) {
+ return PR_TRUE;
+ }
+ return PR_FALSE;
+}
+
+/* Get a password from the input terminal, without echoing */
+
+#if defined(_WINDOWS)
+static char *
+quiet_fgets(char *buf, int length, FILE *input)
+{
+ int c;
+ char *end = buf;
+
+ /* fflush (input); */
+ memset(buf, 0, length);
+
+ if (!isatty(fileno(input))) {
+ return fgets(buf, length, input);
+ }
+
+ while (1) {
+ c = getch(); /* getch gets a character from the console */
+
+ if (c == '\b') {
+ if (end > buf)
+ end--;
+ }
+
+ else if (--length > 0)
+ *end++ = c;
+
+ if (!c || c == '\n' || c == '\r')
+ break;
+ }
+
+ return buf;
+}
+#endif
diff --git a/nss/cmd/lib/secutil.c b/nss/cmd/lib/secutil.c
new file mode 100644
index 0000000..cb4752d
--- /dev/null
+++ b/nss/cmd/lib/secutil.c
@@ -0,0 +1,3962 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+** secutil.c - various functions used by security stuff
+**
+*/
+
+#include "prtypes.h"
+#include "prtime.h"
+#include "prlong.h"
+#include "prerror.h"
+#include "prprf.h"
+#include "plgetopt.h"
+#include "prenv.h"
+#include "prnetdb.h"
+
+#include "cryptohi.h"
+#include "secutil.h"
+#include "secpkcs7.h"
+#include "secpkcs5.h"
+#include
+#include
+#include
+
+#ifdef XP_UNIX
+#include
+#endif
+
+/* for SEC_TraverseNames */
+#include "cert.h"
+#include "certt.h"
+#include "certdb.h"
+
+#include "secmod.h"
+#include "pk11func.h"
+#include "secoid.h"
+
+static char consoleName[] = {
+#ifdef XP_UNIX
+ "/dev/tty"
+#else
+#ifdef XP_OS2
+ "\\DEV\\CON"
+#else
+ "CON:"
+#endif
+#endif
+};
+
+#include "nssutil.h"
+#include "ssl.h"
+#include "sslproto.h"
+
+static PRBool utf8DisplayEnabled = PR_FALSE;
+
+void
+SECU_EnableUtf8Display(PRBool enable)
+{
+ utf8DisplayEnabled = enable;
+}
+
+PRBool
+SECU_GetUtf8DisplayEnabled(void)
+{
+ return utf8DisplayEnabled;
+}
+
+static void
+secu_ClearPassword(char *p)
+{
+ if (p) {
+ PORT_Memset(p, 0, PORT_Strlen(p));
+ PORT_Free(p);
+ }
+}
+
+char *
+SECU_GetPasswordString(void *arg, char *prompt)
+{
+#ifndef _WINDOWS
+ char *p = NULL;
+ FILE *input, *output;
+
+ /* open terminal */
+ input = fopen(consoleName, "r");
+ if (input == NULL) {
+ fprintf(stderr, "Error opening input terminal for read\n");
+ return NULL;
+ }
+
+ output = fopen(consoleName, "w");
+ if (output == NULL) {
+ fprintf(stderr, "Error opening output terminal for write\n");
+ fclose(input);
+ return NULL;
+ }
+
+ p = SEC_GetPassword(input, output, prompt, SEC_BlindCheckPassword);
+
+ fclose(input);
+ fclose(output);
+
+ return p;
+
+#else
+ /* Win32 version of above. opening the console may fail
+ on windows95, and certainly isn't necessary.. */
+
+ char *p = NULL;
+
+ p = SEC_GetPassword(stdin, stdout, prompt, SEC_BlindCheckPassword);
+ return p;
+
+#endif
+}
+
+/*
+ * p a s s w o r d _ h a r d c o d e
+ *
+ * A function to use the password passed in the -f(pwfile) argument
+ * of the command line.
+ * After use once, null it out otherwise PKCS11 calls us forever.?
+ *
+ */
+char *
+SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg)
+{
+ char *phrases, *phrase;
+ PRFileDesc *fd;
+ PRInt32 nb;
+ char *pwFile = arg;
+ int i;
+ const long maxPwdFileSize = 4096;
+ char *tokenName = NULL;
+ int tokenLen = 0;
+
+ if (!pwFile)
+ return 0;
+
+ if (retry) {
+ return 0; /* no good retrying - the files contents will be the same */
+ }
+
+ phrases = PORT_ZAlloc(maxPwdFileSize);
+
+ if (!phrases) {
+ return 0; /* out of memory */
+ }
+
+ fd = PR_Open(pwFile, PR_RDONLY, 0);
+ if (!fd) {
+ fprintf(stderr, "No password file \"%s\" exists.\n", pwFile);
+ PORT_Free(phrases);
+ return NULL;
+ }
+
+ nb = PR_Read(fd, phrases, maxPwdFileSize);
+
+ PR_Close(fd);
+
+ if (nb == 0) {
+ fprintf(stderr, "password file contains no data\n");
+ PORT_Free(phrases);
+ return NULL;
+ }
+
+ if (slot) {
+ tokenName = PK11_GetTokenName(slot);
+ if (tokenName) {
+ tokenLen = PORT_Strlen(tokenName);
+ }
+ }
+ i = 0;
+ do {
+ int startphrase = i;
+ int phraseLen;
+
+ /* handle the Windows EOL case */
+ while (phrases[i] != '\r' && phrases[i] != '\n' && i < nb)
+ i++;
+ /* terminate passphrase */
+ phrases[i++] = '\0';
+ /* clean up any EOL before the start of the next passphrase */
+ while ((i < nb) && (phrases[i] == '\r' || phrases[i] == '\n')) {
+ phrases[i++] = '\0';
+ }
+ /* now analyze the current passphrase */
+ phrase = &phrases[startphrase];
+ if (!tokenName)
+ break;
+ if (PORT_Strncmp(phrase, tokenName, tokenLen))
+ continue;
+ phraseLen = PORT_Strlen(phrase);
+ if (phraseLen < (tokenLen + 1))
+ continue;
+ if (phrase[tokenLen] != ':')
+ continue;
+ phrase = &phrase[tokenLen + 1];
+ break;
+
+ } while (i < nb);
+
+ phrase = PORT_Strdup((char *)phrase);
+ PORT_Free(phrases);
+ return phrase;
+}
+
+char *
+SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg)
+{
+ char prompt[255];
+ secuPWData *pwdata = (secuPWData *)arg;
+ secuPWData pwnull = { PW_NONE, 0 };
+ secuPWData pwxtrn = { PW_EXTERNAL, "external" };
+
+ if (pwdata == NULL)
+ pwdata = &pwnull;
+
+ if (PK11_ProtectedAuthenticationPath(slot)) {
+ pwdata = &pwxtrn;
+ }
+ if (retry && pwdata->source != PW_NONE) {
+ PR_fprintf(PR_STDERR, "Incorrect password/PIN entered.\n");
+ return NULL;
+ }
+
+ switch (pwdata->source) {
+ case PW_NONE:
+ sprintf(prompt, "Enter Password or Pin for \"%s\":",
+ PK11_GetTokenName(slot));
+ return SECU_GetPasswordString(NULL, prompt);
+ case PW_FROMFILE:
+ return SECU_FilePasswd(slot, retry, pwdata->data);
+ case PW_EXTERNAL:
+ sprintf(prompt,
+ "Press Enter, then enter PIN for \"%s\" on external device.\n",
+ PK11_GetTokenName(slot));
+ (void)SECU_GetPasswordString(NULL, prompt);
+ /* Fall Through */
+ case PW_PLAINTEXT:
+ return PL_strdup(pwdata->data);
+ default:
+ break;
+ }
+
+ PR_fprintf(PR_STDERR, "Password check failed: No password found.\n");
+ return NULL;
+}
+
+char *
+secu_InitSlotPassword(PK11SlotInfo *slot, PRBool retry, void *arg)
+{
+ char *p0 = NULL;
+ char *p1 = NULL;
+ FILE *input, *output;
+ secuPWData *pwdata = arg;
+
+ if (pwdata->source == PW_FROMFILE) {
+ return SECU_FilePasswd(slot, retry, pwdata->data);
+ }
+ if (pwdata->source == PW_PLAINTEXT) {
+ return PL_strdup(pwdata->data);
+ }
+
+/* PW_NONE - get it from tty */
+/* open terminal */
+#ifdef _WINDOWS
+ input = stdin;
+#else
+ input = fopen(consoleName, "r");
+#endif
+ if (input == NULL) {
+ PR_fprintf(PR_STDERR, "Error opening input terminal for read\n");
+ return NULL;
+ }
+
+ /* we have no password, so initialize database with one */
+ PR_fprintf(PR_STDERR,
+ "Enter a password which will be used to encrypt your keys.\n"
+ "The password should be at least 8 characters long,\n"
+ "and should contain at least one non-alphabetic character.\n\n");
+
+ output = fopen(consoleName, "w");
+ if (output == NULL) {
+ PR_fprintf(PR_STDERR, "Error opening output terminal for write\n");
+#ifndef _WINDOWS
+ fclose(input);
+#endif
+ return NULL;
+ }
+
+ for (;;) {
+ if (p0)
+ PORT_Free(p0);
+ p0 = SEC_GetPassword(input, output, "Enter new password: ",
+ SEC_BlindCheckPassword);
+
+ if (p1)
+ PORT_Free(p1);
+ p1 = SEC_GetPassword(input, output, "Re-enter password: ",
+ SEC_BlindCheckPassword);
+ if (p0 && p1 && !PORT_Strcmp(p0, p1)) {
+ break;
+ }
+ PR_fprintf(PR_STDERR, "Passwords do not match. Try again.\n");
+ }
+
+ /* clear out the duplicate password string */
+ secu_ClearPassword(p1);
+
+ fclose(input);
+ fclose(output);
+
+ return p0;
+}
+
+SECStatus
+SECU_ChangePW(PK11SlotInfo *slot, char *passwd, char *pwFile)
+{
+ return SECU_ChangePW2(slot, passwd, 0, pwFile, 0);
+}
+
+SECStatus
+SECU_ChangePW2(PK11SlotInfo *slot, char *oldPass, char *newPass,
+ char *oldPwFile, char *newPwFile)
+{
+ SECStatus rv;
+ secuPWData pwdata, newpwdata;
+ char *oldpw = NULL, *newpw = NULL;
+
+ if (oldPass) {
+ pwdata.source = PW_PLAINTEXT;
+ pwdata.data = oldPass;
+ } else if (oldPwFile) {
+ pwdata.source = PW_FROMFILE;
+ pwdata.data = oldPwFile;
+ } else {
+ pwdata.source = PW_NONE;
+ pwdata.data = NULL;
+ }
+
+ if (newPass) {
+ newpwdata.source = PW_PLAINTEXT;
+ newpwdata.data = newPass;
+ } else if (newPwFile) {
+ newpwdata.source = PW_FROMFILE;
+ newpwdata.data = newPwFile;
+ } else {
+ newpwdata.source = PW_NONE;
+ newpwdata.data = NULL;
+ }
+
+ if (PK11_NeedUserInit(slot)) {
+ newpw = secu_InitSlotPassword(slot, PR_FALSE, &pwdata);
+ rv = PK11_InitPin(slot, (char *)NULL, newpw);
+ goto done;
+ }
+
+ for (;;) {
+ oldpw = SECU_GetModulePassword(slot, PR_FALSE, &pwdata);
+
+ if (PK11_CheckUserPassword(slot, oldpw) != SECSuccess) {
+ if (pwdata.source == PW_NONE) {
+ PR_fprintf(PR_STDERR, "Invalid password. Try again.\n");
+ } else {
+ PR_fprintf(PR_STDERR, "Invalid password.\n");
+ PORT_Memset(oldpw, 0, PL_strlen(oldpw));
+ PORT_Free(oldpw);
+ rv = SECFailure;
+ goto done;
+ }
+ } else
+ break;
+
+ PORT_Free(oldpw);
+ }
+
+ newpw = secu_InitSlotPassword(slot, PR_FALSE, &newpwdata);
+
+ rv = PK11_ChangePW(slot, oldpw, newpw);
+ if (rv != SECSuccess) {
+ PR_fprintf(PR_STDERR, "Failed to change password.\n");
+ } else {
+ PR_fprintf(PR_STDOUT, "Password changed successfully.\n");
+ }
+
+ PORT_Memset(oldpw, 0, PL_strlen(oldpw));
+ PORT_Free(oldpw);
+
+done:
+ if (newpw) {
+ PORT_Memset(newpw, 0, PL_strlen(newpw));
+ PORT_Free(newpw);
+ }
+ return rv;
+}
+
+struct matchobj {
+ SECItem index;
+ char *nname;
+ PRBool found;
+};
+
+char *
+SECU_DefaultSSLDir(void)
+{
+ char *dir;
+ static char sslDir[1000];
+
+ dir = PR_GetEnvSecure("SSL_DIR");
+ if (!dir)
+ return NULL;
+
+ if (strlen(dir) >= PR_ARRAY_SIZE(sslDir)) {
+ return NULL;
+ }
+ sprintf(sslDir, "%s", dir);
+
+ if (sslDir[strlen(sslDir) - 1] == '/')
+ sslDir[strlen(sslDir) - 1] = 0;
+
+ return sslDir;
+}
+
+char *
+SECU_AppendFilenameToDir(char *dir, char *filename)
+{
+ static char path[1000];
+
+ if (dir[strlen(dir) - 1] == '/')
+ sprintf(path, "%s%s", dir, filename);
+ else
+ sprintf(path, "%s/%s", dir, filename);
+ return path;
+}
+
+char *
+SECU_ConfigDirectory(const char *base)
+{
+ static PRBool initted = PR_FALSE;
+ const char *dir = ".netscape";
+ char *home;
+ static char buf[1000];
+
+ if (initted)
+ return buf;
+
+ if (base == NULL || *base == 0) {
+ home = PR_GetEnvSecure("HOME");
+ if (!home)
+ home = "";
+
+ if (*home && home[strlen(home) - 1] == '/')
+ sprintf(buf, "%.900s%s", home, dir);
+ else
+ sprintf(buf, "%.900s/%s", home, dir);
+ } else {
+ sprintf(buf, "%.900s", base);
+ if (buf[strlen(buf) - 1] == '/')
+ buf[strlen(buf) - 1] = 0;
+ }
+
+ initted = PR_TRUE;
+ return buf;
+}
+
+/*Turn off SSL for now */
+/* This gets called by SSL when server wants our cert & key */
+int
+SECU_GetClientAuthData(void *arg, PRFileDesc *fd,
+ struct CERTDistNamesStr *caNames,
+ struct CERTCertificateStr **pRetCert,
+ struct SECKEYPrivateKeyStr **pRetKey)
+{
+ SECKEYPrivateKey *key;
+ CERTCertificate *cert;
+ int errsave;
+
+ if (arg == NULL) {
+ fprintf(stderr, "no key/cert name specified for client auth\n");
+ return -1;
+ }
+ cert = PK11_FindCertFromNickname(arg, NULL);
+ errsave = PORT_GetError();
+ if (!cert) {
+ if (errsave == SEC_ERROR_BAD_PASSWORD)
+ fprintf(stderr, "Bad password\n");
+ else if (errsave > 0)
+ fprintf(stderr, "Unable to read cert (error %d)\n", errsave);
+ else if (errsave == SEC_ERROR_BAD_DATABASE)
+ fprintf(stderr, "Unable to get cert from database (%d)\n", errsave);
+ else
+ fprintf(stderr, "SECKEY_FindKeyByName: internal error %d\n", errsave);
+ return -1;
+ }
+
+ key = PK11_FindKeyByAnyCert(arg, NULL);
+ if (!key) {
+ fprintf(stderr, "Unable to get key (%d)\n", PORT_GetError());
+ return -1;
+ }
+
+ *pRetCert = cert;
+ *pRetKey = key;
+
+ return 0;
+}
+
+SECStatus
+SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii,
+ PRBool warnOnPrivateKeyInAsciiFile)
+{
+ SECStatus rv;
+ if (ascii) {
+ /* First convert ascii to binary */
+ SECItem filedata;
+ char *asc, *body;
+
+ /* Read in ascii data */
+ rv = SECU_FileToItem(&filedata, inFile);
+ if (rv != SECSuccess)
+ return rv;
+ asc = (char *)filedata.data;
+ if (!asc) {
+ fprintf(stderr, "unable to read data from input file\n");
+ return SECFailure;
+ }
+
+ if (warnOnPrivateKeyInAsciiFile && strstr(asc, "PRIVATE KEY")) {
+ fprintf(stderr, "Warning: ignoring private key. Consider to use "
+ "pk12util.\n");
+ }
+
+ /* check for headers and trailers and remove them */
+ if ((body = strstr(asc, "-----BEGIN")) != NULL) {
+ char *trailer = NULL;
+ asc = body;
+ body = PORT_Strchr(body, '\n');
+ if (!body)
+ body = PORT_Strchr(asc, '\r'); /* maybe this is a MAC file */
+ if (body)
+ trailer = strstr(++body, "-----END");
+ if (trailer != NULL) {
+ *trailer = '\0';
+ } else {
+ fprintf(stderr, "input has header but no trailer\n");
+ PORT_Free(filedata.data);
+ return SECFailure;
+ }
+ } else {
+ /* need one additional byte for zero terminator */
+ rv = SECITEM_ReallocItemV2(NULL, &filedata, filedata.len + 1);
+ if (rv != SECSuccess) {
+ PORT_Free(filedata.data);
+ return rv;
+ }
+ body = (char *)filedata.data;
+ body[filedata.len - 1] = '\0';
+ }
+
+ /* Convert to binary */
+ rv = ATOB_ConvertAsciiToItem(der, body);
+ if (rv != SECSuccess) {
+ fprintf(stderr, "error converting ascii to binary (%s)\n",
+ SECU_Strerror(PORT_GetError()));
+ PORT_Free(filedata.data);
+ return SECFailure;
+ }
+
+ PORT_Free(filedata.data);
+ } else {
+ /* Read in binary der */
+ rv = SECU_FileToItem(der, inFile);
+ if (rv != SECSuccess) {
+ fprintf(stderr, "error converting der (%s)\n",
+ SECU_Strerror(PORT_GetError()));
+ return SECFailure;
+ }
+ }
+ return SECSuccess;
+}
+
+#define INDENT_MULT 4
+
+SECStatus
+SECU_StripTagAndLength(SECItem *i)
+{
+ unsigned int start;
+
+ if (!i || !i->data || i->len < 2) { /* must be at least tag and length */
+ return SECFailure;
+ }
+ start = ((i->data[1] & 0x80) ? (i->data[1] & 0x7f) + 2 : 2);
+ if (i->len < start) {
+ return SECFailure;
+ }
+ i->data += start;
+ i->len -= start;
+ return SECSuccess;
+}
+
+static void
+secu_PrintRawStringQuotesOptional(FILE *out, SECItem *si, const char *m,
+ int level, PRBool quotes)
+{
+ int column;
+ unsigned int i;
+
+ if (m) {
+ SECU_Indent(out, level);
+ fprintf(out, "%s: ", m);
+ column = (level * INDENT_MULT) + strlen(m) + 2;
+ level++;
+ } else {
+ SECU_Indent(out, level);
+ column = level * INDENT_MULT;
+ }
+ if (quotes) {
+ fprintf(out, "\"");
+ column++;
+ }
+
+ for (i = 0; i < si->len; i++) {
+ unsigned char val = si->data[i];
+ unsigned char c;
+ if (SECU_GetWrapEnabled() && column > 76) {
+ SECU_Newline(out);
+ SECU_Indent(out, level);
+ column = level * INDENT_MULT;
+ }
+
+ if (utf8DisplayEnabled) {
+ if (val < 32)
+ c = '.';
+ else
+ c = val;
+ } else {
+ c = printable[val];
+ }
+ fprintf(out, "%c", c);
+ column++;
+ }
+
+ if (quotes) {
+ fprintf(out, "\"");
+ column++;
+ }
+ if (SECU_GetWrapEnabled() &&
+ (column != level * INDENT_MULT || column > 76)) {
+ SECU_Newline(out);
+ }
+}
+
+static void
+secu_PrintRawString(FILE *out, SECItem *si, const char *m, int level)
+{
+ secu_PrintRawStringQuotesOptional(out, si, m, level, PR_TRUE);
+}
+
+void
+SECU_PrintString(FILE *out, const SECItem *si, const char *m, int level)
+{
+ SECItem my = *si;
+
+ if (SECSuccess != SECU_StripTagAndLength(&my) || !my.len)
+ return;
+ secu_PrintRawString(out, &my, m, level);
+}
+
+/* print an unencoded boolean */
+static void
+secu_PrintBoolean(FILE *out, SECItem *i, const char *m, int level)
+{
+ int val = 0;
+
+ if (i->data && i->len) {
+ val = i->data[0];
+ }
+
+ if (!m) {
+ m = "Boolean";
+ }
+ SECU_Indent(out, level);
+ fprintf(out, "%s: %s\n", m, (val ? "True" : "False"));
+}
+
+/*
+ * Format and print "time". If the tag message "m" is not NULL,
+ * do indent formatting based on "level" and add a newline afterward;
+ * otherwise just print the formatted time string only.
+ */
+static void
+secu_PrintTime(FILE *out, const PRTime time, const char *m, int level)
+{
+ PRExplodedTime printableTime;
+ char *timeString;
+
+ /* Convert to local time */
+ PR_ExplodeTime(time, PR_GMTParameters, &printableTime);
+
+ timeString = PORT_Alloc(256);
+ if (timeString == NULL)
+ return;
+
+ if (m != NULL) {
+ SECU_Indent(out, level);
+ fprintf(out, "%s: ", m);
+ }
+
+ if (PR_FormatTime(timeString, 256, "%a %b %d %H:%M:%S %Y", &printableTime)) {
+ fputs(timeString, out);
+ }
+
+ if (m != NULL)
+ fprintf(out, "\n");
+
+ PORT_Free(timeString);
+}
+
+/*
+ * Format and print the UTC Time "t". If the tag message "m" is not NULL,
+ * do indent formatting based on "level" and add a newline afterward;
+ * otherwise just print the formatted time string only.
+ */
+void
+SECU_PrintUTCTime(FILE *out, const SECItem *t, const char *m, int level)
+{
+ PRTime time;
+ SECStatus rv;
+
+ rv = DER_UTCTimeToTime(&time, t);
+ if (rv != SECSuccess)
+ return;
+
+ secu_PrintTime(out, time, m, level);
+}
+
+/*
+ * Format and print the Generalized Time "t". If the tag message "m"
+ * is not NULL, * do indent formatting based on "level" and add a newline
+ * afterward; otherwise just print the formatted time string only.
+ */
+void
+SECU_PrintGeneralizedTime(FILE *out, const SECItem *t, const char *m, int level)
+{
+ PRTime time;
+ SECStatus rv;
+
+ rv = DER_GeneralizedTimeToTime(&time, t);
+ if (rv != SECSuccess)
+ return;
+
+ secu_PrintTime(out, time, m, level);
+}
+
+/*
+ * Format and print the UTC or Generalized Time "t". If the tag message
+ * "m" is not NULL, do indent formatting based on "level" and add a newline
+ * afterward; otherwise just print the formatted time string only.
+ */
+void
+SECU_PrintTimeChoice(FILE *out, const SECItem *t, const char *m, int level)
+{
+ switch (t->type) {
+ case siUTCTime:
+ SECU_PrintUTCTime(out, t, m, level);
+ break;
+
+ case siGeneralizedTime:
+ SECU_PrintGeneralizedTime(out, t, m, level);
+ break;
+
+ default:
+ PORT_Assert(0);
+ break;
+ }
+}
+
+/* This prints a SET or SEQUENCE */
+static void
+SECU_PrintSet(FILE *out, const SECItem *t, const char *m, int level)
+{
+ int type = t->data[0] & SEC_ASN1_TAGNUM_MASK;
+ int constructed = t->data[0] & SEC_ASN1_CONSTRUCTED;
+ const char *label;
+ SECItem my = *t;
+
+ if (!constructed) {
+ SECU_PrintAsHex(out, t, m, level);
+ return;
+ }
+ if (SECSuccess != SECU_StripTagAndLength(&my))
+ return;
+
+ SECU_Indent(out, level);
+ if (m) {
+ fprintf(out, "%s: ", m);
+ }
+
+ if (type == SEC_ASN1_SET)
+ label = "Set ";
+ else if (type == SEC_ASN1_SEQUENCE)
+ label = "Sequence ";
+ else
+ label = "";
+ fprintf(out, "%s{\n", label); /* } */
+
+ while (my.len >= 2) {
+ SECItem tmp = my;
+
+ if (tmp.data[1] & 0x80) {
+ unsigned int i;
+ unsigned int lenlen = tmp.data[1] & 0x7f;
+ if (lenlen > sizeof tmp.len)
+ break;
+ tmp.len = 0;
+ for (i = 0; i < lenlen; i++) {
+ tmp.len = (tmp.len << 8) | tmp.data[2 + i];
+ }
+ tmp.len += lenlen + 2;
+ } else {
+ tmp.len = tmp.data[1] + 2;
+ }
+ if (tmp.len > my.len) {
+ tmp.len = my.len;
+ }
+ my.data += tmp.len;
+ my.len -= tmp.len;
+ SECU_PrintAny(out, &tmp, NULL, level + 1);
+ }
+ SECU_Indent(out, level);
+ fprintf(out, /* { */ "}\n");
+}
+
+static void
+secu_PrintContextSpecific(FILE *out, const SECItem *i, const char *m, int level)
+{
+ int type = i->data[0] & SEC_ASN1_TAGNUM_MASK;
+ int constructed = i->data[0] & SEC_ASN1_CONSTRUCTED;
+ SECItem tmp;
+
+ if (constructed) {
+ char *m2;
+ if (!m)
+ m2 = PR_smprintf("[%d]", type);
+ else
+ m2 = PR_smprintf("%s: [%d]", m, type);
+ if (m2) {
+ SECU_PrintSet(out, i, m2, level);
+ PR_smprintf_free(m2);
+ }
+ return;
+ }
+
+ SECU_Indent(out, level);
+ if (m) {
+ fprintf(out, "%s: ", m);
+ }
+ fprintf(out, "[%d]\n", type);
+
+ tmp = *i;
+ if (SECSuccess == SECU_StripTagAndLength(&tmp))
+ SECU_PrintAsHex(out, &tmp, m, level + 1);
+}
+
+static void
+secu_PrintOctetString(FILE *out, const SECItem *i, const char *m, int level)
+{
+ SECItem tmp = *i;
+ if (SECSuccess == SECU_StripTagAndLength(&tmp))
+ SECU_PrintAsHex(out, &tmp, m, level);
+}
+
+static void
+secu_PrintBitString(FILE *out, const SECItem *i, const char *m, int level)
+{
+ int unused_bits;
+ SECItem tmp = *i;
+
+ if (SECSuccess != SECU_StripTagAndLength(&tmp) || tmp.len < 2)
+ return;
+
+ unused_bits = *tmp.data++;
+ tmp.len--;
+
+ SECU_PrintAsHex(out, &tmp, m, level);
+ if (unused_bits) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "(%d least significant bits unused)\n", unused_bits);
+ }
+}
+
+/* in a decoded bit string, the len member is a bit length. */
+static void
+secu_PrintDecodedBitString(FILE *out, const SECItem *i, const char *m, int level)
+{
+ int unused_bits;
+ SECItem tmp = *i;
+
+ unused_bits = (tmp.len & 0x7) ? 8 - (tmp.len & 7) : 0;
+ DER_ConvertBitString(&tmp); /* convert length to byte length */
+
+ SECU_PrintAsHex(out, &tmp, m, level);
+ if (unused_bits) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "(%d least significant bits unused)\n", unused_bits);
+ }
+}
+
+/* Print a DER encoded Boolean */
+void
+SECU_PrintEncodedBoolean(FILE *out, const SECItem *i, const char *m, int level)
+{
+ SECItem my = *i;
+ if (SECSuccess == SECU_StripTagAndLength(&my))
+ secu_PrintBoolean(out, &my, m, level);
+}
+
+/* Print a DER encoded integer */
+void
+SECU_PrintEncodedInteger(FILE *out, const SECItem *i, const char *m, int level)
+{
+ SECItem my = *i;
+ if (SECSuccess == SECU_StripTagAndLength(&my))
+ SECU_PrintInteger(out, &my, m, level);
+}
+
+/* Print a DER encoded OID */
+void
+SECU_PrintEncodedObjectID(FILE *out, const SECItem *i, const char *m, int level)
+{
+ SECItem my = *i;
+ if (SECSuccess == SECU_StripTagAndLength(&my))
+ SECU_PrintObjectID(out, &my, m, level);
+}
+
+static void
+secu_PrintBMPString(FILE *out, const SECItem *i, const char *m, int level)
+{
+ unsigned char *s;
+ unsigned char *d;
+ int len;
+ SECItem tmp = { 0, 0, 0 };
+ SECItem my = *i;
+
+ if (SECSuccess != SECU_StripTagAndLength(&my))
+ goto loser;
+ if (my.len % 2)
+ goto loser;
+ len = (int)(my.len / 2);
+ tmp.data = (unsigned char *)PORT_Alloc(len);
+ if (!tmp.data)
+ goto loser;
+ tmp.len = len;
+ for (s = my.data, d = tmp.data; len > 0; len--) {
+ PRUint32 bmpChar = (s[0] << 8) | s[1];
+ s += 2;
+ if (!isprint(bmpChar))
+ goto loser;
+ *d++ = (unsigned char)bmpChar;
+ }
+ secu_PrintRawString(out, &tmp, m, level);
+ PORT_Free(tmp.data);
+ return;
+
+loser:
+ SECU_PrintAsHex(out, i, m, level);
+ if (tmp.data)
+ PORT_Free(tmp.data);
+}
+
+static void
+secu_PrintUniversalString(FILE *out, const SECItem *i, const char *m, int level)
+{
+ unsigned char *s;
+ unsigned char *d;
+ int len;
+ SECItem tmp = { 0, 0, 0 };
+ SECItem my = *i;
+
+ if (SECSuccess != SECU_StripTagAndLength(&my))
+ goto loser;
+ if (my.len % 4)
+ goto loser;
+ len = (int)(my.len / 4);
+ tmp.data = (unsigned char *)PORT_Alloc(len);
+ if (!tmp.data)
+ goto loser;
+ tmp.len = len;
+ for (s = my.data, d = tmp.data; len > 0; len--) {
+ PRUint32 bmpChar = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
+ s += 4;
+ if (!isprint(bmpChar))
+ goto loser;
+ *d++ = (unsigned char)bmpChar;
+ }
+ secu_PrintRawString(out, &tmp, m, level);
+ PORT_Free(tmp.data);
+ return;
+
+loser:
+ SECU_PrintAsHex(out, i, m, level);
+ if (tmp.data)
+ PORT_Free(tmp.data);
+}
+
+static void
+secu_PrintUniversal(FILE *out, const SECItem *i, const char *m, int level)
+{
+ switch (i->data[0] & SEC_ASN1_TAGNUM_MASK) {
+ case SEC_ASN1_ENUMERATED:
+ case SEC_ASN1_INTEGER:
+ SECU_PrintEncodedInteger(out, i, m, level);
+ break;
+ case SEC_ASN1_OBJECT_ID:
+ SECU_PrintEncodedObjectID(out, i, m, level);
+ break;
+ case SEC_ASN1_BOOLEAN:
+ SECU_PrintEncodedBoolean(out, i, m, level);
+ break;
+ case SEC_ASN1_UTF8_STRING:
+ case SEC_ASN1_PRINTABLE_STRING:
+ case SEC_ASN1_VISIBLE_STRING:
+ case SEC_ASN1_IA5_STRING:
+ case SEC_ASN1_T61_STRING:
+ SECU_PrintString(out, i, m, level);
+ break;
+ case SEC_ASN1_GENERALIZED_TIME:
+ SECU_PrintGeneralizedTime(out, i, m, level);
+ break;
+ case SEC_ASN1_UTC_TIME:
+ SECU_PrintUTCTime(out, i, m, level);
+ break;
+ case SEC_ASN1_NULL:
+ SECU_Indent(out, level);
+ if (m && m[0])
+ fprintf(out, "%s: NULL\n", m);
+ else
+ fprintf(out, "NULL\n");
+ break;
+ case SEC_ASN1_SET:
+ case SEC_ASN1_SEQUENCE:
+ SECU_PrintSet(out, i, m, level);
+ break;
+ case SEC_ASN1_OCTET_STRING:
+ secu_PrintOctetString(out, i, m, level);
+ break;
+ case SEC_ASN1_BIT_STRING:
+ secu_PrintBitString(out, i, m, level);
+ break;
+ case SEC_ASN1_BMP_STRING:
+ secu_PrintBMPString(out, i, m, level);
+ break;
+ case SEC_ASN1_UNIVERSAL_STRING:
+ secu_PrintUniversalString(out, i, m, level);
+ break;
+ default:
+ SECU_PrintAsHex(out, i, m, level);
+ break;
+ }
+}
+
+void
+SECU_PrintAny(FILE *out, const SECItem *i, const char *m, int level)
+{
+ if (i && i->len && i->data) {
+ switch (i->data[0] & SEC_ASN1_CLASS_MASK) {
+ case SEC_ASN1_CONTEXT_SPECIFIC:
+ secu_PrintContextSpecific(out, i, m, level);
+ break;
+ case SEC_ASN1_UNIVERSAL:
+ secu_PrintUniversal(out, i, m, level);
+ break;
+ default:
+ SECU_PrintAsHex(out, i, m, level);
+ break;
+ }
+ }
+}
+
+static int
+secu_PrintValidity(FILE *out, CERTValidity *v, char *m, int level)
+{
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ SECU_PrintTimeChoice(out, &v->notBefore, "Not Before", level + 1);
+ SECU_PrintTimeChoice(out, &v->notAfter, "Not After ", level + 1);
+ return 0;
+}
+
+/* This function does NOT expect a DER type and length. */
+SECOidTag
+SECU_PrintObjectID(FILE *out, const SECItem *oid, const char *m, int level)
+{
+ SECOidData *oiddata;
+ char *oidString = NULL;
+
+ oiddata = SECOID_FindOID(oid);
+ if (oiddata != NULL) {
+ const char *name = oiddata->desc;
+ SECU_Indent(out, level);
+ if (m != NULL)
+ fprintf(out, "%s: ", m);
+ fprintf(out, "%s\n", name);
+ return oiddata->offset;
+ }
+ oidString = CERT_GetOidString(oid);
+ if (oidString) {
+ SECU_Indent(out, level);
+ if (m != NULL)
+ fprintf(out, "%s: ", m);
+ fprintf(out, "%s\n", oidString);
+ PR_smprintf_free(oidString);
+ return SEC_OID_UNKNOWN;
+ }
+ SECU_PrintAsHex(out, oid, m, level);
+ return SEC_OID_UNKNOWN;
+}
+
+typedef struct secuPBEParamsStr {
+ SECItem salt;
+ SECItem iterationCount;
+ SECItem keyLength;
+ SECAlgorithmID cipherAlg;
+ SECAlgorithmID kdfAlg;
+} secuPBEParams;
+
+SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
+
+/* SECOID_PKCS5_PBKDF2 */
+const SEC_ASN1Template secuKDF2Params[] =
+ {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(secuPBEParams) },
+ { SEC_ASN1_OCTET_STRING, offsetof(secuPBEParams, salt) },
+ { SEC_ASN1_INTEGER, offsetof(secuPBEParams, iterationCount) },
+ { SEC_ASN1_INTEGER, offsetof(secuPBEParams, keyLength) },
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(secuPBEParams, kdfAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { 0 }
+ };
+
+/* PKCS5v1 & PKCS12 */
+const SEC_ASN1Template secuPBEParamsTemp[] =
+ {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(secuPBEParams) },
+ { SEC_ASN1_OCTET_STRING, offsetof(secuPBEParams, salt) },
+ { SEC_ASN1_INTEGER, offsetof(secuPBEParams, iterationCount) },
+ { 0 }
+ };
+
+/* SEC_OID_PKCS5_PBES2, SEC_OID_PKCS5_PBMAC1 */
+const SEC_ASN1Template secuPBEV2Params[] =
+ {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(secuPBEParams) },
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(secuPBEParams, kdfAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(secuPBEParams, cipherAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { 0 }
+ };
+
+void
+secu_PrintRSAPSSParams(FILE *out, SECItem *value, char *m, int level)
+{
+ PLArenaPool *pool = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ SECStatus rv;
+ SECKEYRSAPSSParams param;
+ SECAlgorithmID maskHashAlg;
+
+ if (m) {
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ }
+
+ if (!pool) {
+ SECU_Indent(out, level);
+ fprintf(out, "Out of memory\n");
+ return;
+ }
+
+ PORT_Memset(¶m, 0, sizeof param);
+
+ rv = SEC_QuickDERDecodeItem(pool, ¶m,
+ SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate),
+ value);
+ if (rv == SECSuccess) {
+ if (!param.hashAlg) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Hash algorithm: default, SHA-1\n");
+ } else {
+ SECU_PrintObjectID(out, ¶m.hashAlg->algorithm,
+ "Hash algorithm", level + 1);
+ }
+ if (!param.maskAlg) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Mask algorithm: default, MGF1\n");
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Mask hash algorithm: default, SHA-1\n");
+ } else {
+ SECU_PrintObjectID(out, ¶m.maskAlg->algorithm,
+ "Mask algorithm", level + 1);
+ rv = SEC_QuickDERDecodeItem(pool, &maskHashAlg,
+ SEC_ASN1_GET(SECOID_AlgorithmIDTemplate),
+ ¶m.maskAlg->parameters);
+ if (rv == SECSuccess) {
+ SECU_PrintObjectID(out, &maskHashAlg.algorithm,
+ "Mask hash algorithm", level + 1);
+ } else {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Invalid mask generation algorithm parameters\n");
+ }
+ }
+ if (!param.saltLength.data) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Salt length: default, %i (0x%2X)\n", 20, 20);
+ } else {
+ SECU_PrintInteger(out, ¶m.saltLength, "Salt Length", level + 1);
+ }
+ } else {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Invalid RSA-PSS parameters\n");
+ }
+ PORT_FreeArena(pool, PR_FALSE);
+}
+
+void
+secu_PrintKDF2Params(FILE *out, SECItem *value, char *m, int level)
+{
+ PLArenaPool *pool = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ SECStatus rv;
+ secuPBEParams param;
+
+ if (m) {
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ }
+
+ if (!pool) {
+ SECU_Indent(out, level);
+ fprintf(out, "Out of memory\n");
+ return;
+ }
+
+ PORT_Memset(¶m, 0, sizeof param);
+ rv = SEC_QuickDERDecodeItem(pool, ¶m, secuKDF2Params, value);
+ if (rv == SECSuccess) {
+ SECU_PrintAsHex(out, ¶m.salt, "Salt", level + 1);
+ SECU_PrintInteger(out, ¶m.iterationCount, "Iteration Count",
+ level + 1);
+ SECU_PrintInteger(out, ¶m.keyLength, "Key Length", level + 1);
+ SECU_PrintAlgorithmID(out, ¶m.kdfAlg, "KDF algorithm", level + 1);
+ }
+ PORT_FreeArena(pool, PR_FALSE);
+}
+
+void
+secu_PrintPKCS5V2Params(FILE *out, SECItem *value, char *m, int level)
+{
+ PLArenaPool *pool = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ SECStatus rv;
+ secuPBEParams param;
+
+ if (m) {
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ }
+
+ if (!pool) {
+ SECU_Indent(out, level);
+ fprintf(out, "Out of memory\n");
+ return;
+ }
+
+ PORT_Memset(¶m, 0, sizeof param);
+ rv = SEC_QuickDERDecodeItem(pool, ¶m, secuPBEV2Params, value);
+ if (rv == SECSuccess) {
+ SECU_PrintAlgorithmID(out, ¶m.kdfAlg, "KDF", level + 1);
+ SECU_PrintAlgorithmID(out, ¶m.cipherAlg, "Cipher", level + 1);
+ }
+ PORT_FreeArena(pool, PR_FALSE);
+}
+
+void
+secu_PrintPBEParams(FILE *out, SECItem *value, char *m, int level)
+{
+ PLArenaPool *pool = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ SECStatus rv;
+ secuPBEParams param;
+
+ if (m) {
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ }
+
+ if (!pool) {
+ SECU_Indent(out, level);
+ fprintf(out, "Out of memory\n");
+ return;
+ }
+
+ PORT_Memset(¶m, 0, sizeof(secuPBEParams));
+ rv = SEC_QuickDERDecodeItem(pool, ¶m, secuPBEParamsTemp, value);
+ if (rv == SECSuccess) {
+ SECU_PrintAsHex(out, ¶m.salt, "Salt", level + 1);
+ SECU_PrintInteger(out, ¶m.iterationCount, "Iteration Count",
+ level + 1);
+ }
+ PORT_FreeArena(pool, PR_FALSE);
+}
+
+/* This function does NOT expect a DER type and length. */
+void
+SECU_PrintAlgorithmID(FILE *out, SECAlgorithmID *a, char *m, int level)
+{
+ SECOidTag algtag;
+ SECU_PrintObjectID(out, &a->algorithm, m, level);
+
+ algtag = SECOID_GetAlgorithmTag(a);
+ if (SEC_PKCS5IsAlgorithmPBEAlgTag(algtag)) {
+ switch (algtag) {
+ case SEC_OID_PKCS5_PBKDF2:
+ secu_PrintKDF2Params(out, &a->parameters, "Parameters", level + 1);
+ break;
+ case SEC_OID_PKCS5_PBES2:
+ secu_PrintPKCS5V2Params(out, &a->parameters, "Encryption", level + 1);
+ break;
+ case SEC_OID_PKCS5_PBMAC1:
+ secu_PrintPKCS5V2Params(out, &a->parameters, "MAC", level + 1);
+ break;
+ default:
+ secu_PrintPBEParams(out, &a->parameters, "Parameters", level + 1);
+ break;
+ }
+ return;
+ }
+
+ if (algtag == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) {
+ secu_PrintRSAPSSParams(out, &a->parameters, "Parameters", level + 1);
+ return;
+ }
+
+ if (a->parameters.len == 0 ||
+ (a->parameters.len == 2 &&
+ PORT_Memcmp(a->parameters.data, "\005\000", 2) == 0)) {
+ /* No arguments or NULL argument */
+ } else {
+ /* Print args to algorithm */
+ SECU_PrintAsHex(out, &a->parameters, "Args", level + 1);
+ }
+}
+
+static void
+secu_PrintAttribute(FILE *out, SEC_PKCS7Attribute *attr, char *m, int level)
+{
+ SECItem *value;
+ int i;
+ char om[100];
+
+ if (m) {
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ }
+
+ /*
+ * Should make this smarter; look at the type field and then decode
+ * and print the value(s) appropriately!
+ */
+ SECU_PrintObjectID(out, &(attr->type), "Type", level + 1);
+ if (attr->values != NULL) {
+ i = 0;
+ while ((value = attr->values[i++]) != NULL) {
+ sprintf(om, "Value (%d)%s", i, attr->encoded ? " (encoded)" : "");
+ if (attr->encoded || attr->typeTag == NULL) {
+ SECU_PrintAny(out, value, om, level + 1);
+ } else {
+ switch (attr->typeTag->offset) {
+ default:
+ SECU_PrintAsHex(out, value, om, level + 1);
+ break;
+ case SEC_OID_PKCS9_CONTENT_TYPE:
+ SECU_PrintObjectID(out, value, om, level + 1);
+ break;
+ case SEC_OID_PKCS9_SIGNING_TIME:
+ SECU_PrintTimeChoice(out, value, om, level + 1);
+ break;
+ }
+ }
+ }
+ }
+}
+
+#ifndef NSS_DISABLE_ECC
+static void
+secu_PrintECPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level)
+{
+ SECItem curveOID = { siBuffer, NULL, 0 };
+
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &pk->u.ec.publicValue, "PublicValue", level + 1);
+ /* For named curves, the DEREncodedParams field contains an
+ * ASN Object ID (0x06 is SEC_ASN1_OBJECT_ID).
+ */
+ if ((pk->u.ec.DEREncodedParams.len > 2) &&
+ (pk->u.ec.DEREncodedParams.data[0] == 0x06)) {
+ curveOID.len = pk->u.ec.DEREncodedParams.data[1];
+ curveOID.data = pk->u.ec.DEREncodedParams.data + 2;
+ SECU_PrintObjectID(out, &curveOID, "Curve", level + 1);
+ }
+}
+#endif /* NSS_DISABLE_ECC */
+
+void
+SECU_PrintRSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level)
+{
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &pk->u.rsa.modulus, "Modulus", level + 1);
+ SECU_PrintInteger(out, &pk->u.rsa.publicExponent, "Exponent", level + 1);
+ if (pk->u.rsa.publicExponent.len == 1 &&
+ pk->u.rsa.publicExponent.data[0] == 1) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Error: INVALID RSA KEY!\n");
+ }
+}
+
+void
+SECU_PrintDSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level)
+{
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &pk->u.dsa.params.prime, "Prime", level + 1);
+ SECU_PrintInteger(out, &pk->u.dsa.params.subPrime, "Subprime", level + 1);
+ SECU_PrintInteger(out, &pk->u.dsa.params.base, "Base", level + 1);
+ SECU_PrintInteger(out, &pk->u.dsa.publicValue, "PublicValue", level + 1);
+}
+
+static void
+secu_PrintSubjectPublicKeyInfo(FILE *out, PLArenaPool *arena,
+ CERTSubjectPublicKeyInfo *i, char *msg, int level)
+{
+ SECKEYPublicKey *pk;
+
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", msg);
+ SECU_PrintAlgorithmID(out, &i->algorithm, "Public Key Algorithm", level + 1);
+
+ pk = SECKEY_ExtractPublicKey(i);
+ if (pk) {
+ switch (pk->keyType) {
+ case rsaKey:
+ SECU_PrintRSAPublicKey(out, pk, "RSA Public Key", level + 1);
+ break;
+
+ case dsaKey:
+ SECU_PrintDSAPublicKey(out, pk, "DSA Public Key", level + 1);
+ break;
+
+#ifndef NSS_DISABLE_ECC
+ case ecKey:
+ secu_PrintECPublicKey(out, pk, "EC Public Key", level + 1);
+ break;
+#endif
+
+ case dhKey:
+ case fortezzaKey:
+ case keaKey:
+ SECU_Indent(out, level);
+ fprintf(out, "unable to format this SPKI algorithm type\n");
+ goto loser;
+ default:
+ SECU_Indent(out, level);
+ fprintf(out, "unknown SPKI algorithm type\n");
+ goto loser;
+ }
+ PORT_FreeArena(pk->arena, PR_FALSE);
+ } else {
+ SECU_PrintErrMsg(out, level, "Error", "Parsing public key");
+ loser:
+ if (i->subjectPublicKey.data) {
+ SECU_PrintAny(out, &i->subjectPublicKey, "Raw", level);
+ }
+ }
+}
+
+static void
+printStringWithoutCRLF(FILE *out, const char *str)
+{
+ const char *c = str;
+ while (*c) {
+ if (*c != '\r' && *c != '\n') {
+ fputc(*c, out);
+ }
+ ++c;
+ }
+}
+
+int
+SECU_PrintDumpDerIssuerAndSerial(FILE *out, SECItem *der, char *m,
+ int level)
+{
+ PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ CERTCertificate *c;
+ int rv = SEC_ERROR_NO_MEMORY;
+ char *derIssuerB64;
+ char *derSerialB64;
+
+ if (!arena)
+ return rv;
+
+ /* Decode certificate */
+ c = PORT_ArenaZNew(arena, CERTCertificate);
+ if (!c)
+ goto loser;
+ c->arena = arena;
+ rv = SEC_ASN1DecodeItem(arena, c,
+ SEC_ASN1_GET(CERT_CertificateTemplate), der);
+ if (rv) {
+ SECU_PrintErrMsg(out, 0, "Error", "Parsing extension");
+ goto loser;
+ }
+
+ SECU_PrintName(out, &c->subject, "Subject", 0);
+ if (!SECU_GetWrapEnabled()) /*SECU_PrintName didn't add newline*/
+ SECU_Newline(out);
+ SECU_PrintName(out, &c->issuer, "Issuer", 0);
+ if (!SECU_GetWrapEnabled()) /*SECU_PrintName didn't add newline*/
+ SECU_Newline(out);
+ SECU_PrintInteger(out, &c->serialNumber, "Serial Number", 0);
+
+ derIssuerB64 = BTOA_ConvertItemToAscii(&c->derIssuer);
+ derSerialB64 = BTOA_ConvertItemToAscii(&c->serialNumber);
+
+ fprintf(out, "Issuer DER Base64:\n");
+ if (SECU_GetWrapEnabled()) {
+ fprintf(out, "%s\n", derIssuerB64);
+ } else {
+ printStringWithoutCRLF(out, derIssuerB64);
+ fputs("\n", out);
+ }
+
+ fprintf(out, "Serial DER Base64:\n");
+ if (SECU_GetWrapEnabled()) {
+ fprintf(out, "%s\n", derSerialB64);
+ } else {
+ printStringWithoutCRLF(out, derSerialB64);
+ fputs("\n", out);
+ }
+
+ PORT_Free(derIssuerB64);
+ PORT_Free(derSerialB64);
+
+ fprintf(out, "Serial DER as C source: \n{ %d, \"", c->serialNumber.len);
+
+ {
+ unsigned int i;
+ for (i = 0; i < c->serialNumber.len; ++i) {
+ unsigned char *chardata = (unsigned char *)(c->serialNumber.data);
+ unsigned char c = *(chardata + i);
+
+ fprintf(out, "\\x%02x", c);
+ }
+ fprintf(out, "\" }\n");
+ }
+
+loser:
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+static SECStatus
+secu_PrintX509InvalidDate(FILE *out, SECItem *value, char *msg, int level)
+{
+ SECItem decodedValue;
+ SECStatus rv;
+ PRTime invalidTime;
+ char *formattedTime = NULL;
+
+ decodedValue.data = NULL;
+ rv = SEC_ASN1DecodeItem(NULL, &decodedValue,
+ SEC_ASN1_GET(SEC_GeneralizedTimeTemplate),
+ value);
+ if (rv == SECSuccess) {
+ rv = DER_GeneralizedTimeToTime(&invalidTime, &decodedValue);
+ if (rv == SECSuccess) {
+ formattedTime = CERT_GenTime2FormattedAscii(invalidTime, "%a %b %d %H:%M:%S %Y");
+ SECU_Indent(out, level + 1);
+ fprintf(out, "%s: %s\n", msg, formattedTime);
+ PORT_Free(formattedTime);
+ }
+ }
+ PORT_Free(decodedValue.data);
+ return (rv);
+}
+
+static SECStatus
+PrintExtKeyUsageExtension(FILE *out, SECItem *value, char *msg, int level)
+{
+ CERTOidSequence *os;
+ SECItem **op;
+
+ os = CERT_DecodeOidSequence(value);
+ if ((CERTOidSequence *)NULL == os) {
+ return SECFailure;
+ }
+
+ for (op = os->oids; *op; op++) {
+ SECU_PrintObjectID(out, *op, msg, level + 1);
+ }
+ CERT_DestroyOidSequence(os);
+ return SECSuccess;
+}
+
+static SECStatus
+secu_PrintBasicConstraints(FILE *out, SECItem *value, char *msg, int level)
+{
+ CERTBasicConstraints constraints;
+ SECStatus rv;
+
+ SECU_Indent(out, level);
+ if (msg) {
+ fprintf(out, "%s: ", msg);
+ }
+ rv = CERT_DecodeBasicConstraintValue(&constraints, value);
+ if (rv == SECSuccess && constraints.isCA) {
+ if (constraints.pathLenConstraint >= 0) {
+ fprintf(out, "Is a CA with a maximum path length of %d.\n",
+ constraints.pathLenConstraint);
+ } else {
+ fprintf(out, "Is a CA with no maximum path length.\n");
+ }
+ } else {
+ fprintf(out, "Is not a CA.\n");
+ }
+ return SECSuccess;
+}
+
+static const char *const nsTypeBits[] = {
+ "SSL Client",
+ "SSL Server",
+ "S/MIME",
+ "Object Signing",
+ "Reserved",
+ "SSL CA",
+ "S/MIME CA",
+ "ObjectSigning CA"
+};
+
+/* NSCertType is merely a bit string whose bits are displayed symbolically */
+static SECStatus
+secu_PrintNSCertType(FILE *out, SECItem *value, char *msg, int level)
+{
+ int unused;
+ int NS_Type;
+ int i;
+ int found = 0;
+ SECItem my = *value;
+
+ if ((my.data[0] != SEC_ASN1_BIT_STRING) ||
+ SECSuccess != SECU_StripTagAndLength(&my)) {
+ SECU_PrintAny(out, value, "Data", level);
+ return SECSuccess;
+ }
+
+ unused = (my.len == 2) ? (my.data[0] & 0x0f) : 0;
+ NS_Type = my.data[1] & (0xff << unused);
+
+ SECU_Indent(out, level);
+ if (msg) {
+ fprintf(out, "%s: ", msg);
+ } else {
+ fprintf(out, "Netscape Certificate Type: ");
+ }
+ for (i = 0; i < 8; i++) {
+ if ((0x80 >> i) & NS_Type) {
+ fprintf(out, "%c%s", (found ? ',' : '<'), nsTypeBits[i]);
+ found = 1;
+ }
+ }
+ fprintf(out, (found ? ">\n" : "none\n"));
+ return SECSuccess;
+}
+
+static const char *const usageBits[] = {
+ "Digital Signature", /* 0x80 */
+ "Non-Repudiation", /* 0x40 */
+ "Key Encipherment", /* 0x20 */
+ "Data Encipherment", /* 0x10 */
+ "Key Agreement", /* 0x08 */
+ "Certificate Signing", /* 0x04 */
+ "CRL Signing", /* 0x02 */
+ "Encipher Only", /* 0x01 */
+ "Decipher Only", /* 0x0080 */
+ NULL
+};
+
+/* X509KeyUsage is merely a bit string whose bits are displayed symbolically */
+static void
+secu_PrintX509KeyUsage(FILE *out, SECItem *value, char *msg, int level)
+{
+ int unused;
+ int usage;
+ int i;
+ int found = 0;
+ SECItem my = *value;
+
+ if ((my.data[0] != SEC_ASN1_BIT_STRING) ||
+ SECSuccess != SECU_StripTagAndLength(&my)) {
+ SECU_PrintAny(out, value, "Data", level);
+ return;
+ }
+
+ unused = (my.len >= 2) ? (my.data[0] & 0x0f) : 0;
+ usage = (my.len == 2) ? (my.data[1] & (0xff << unused)) << 8
+ : (my.data[1] << 8) |
+ (my.data[2] & (0xff << unused));
+
+ SECU_Indent(out, level);
+ fprintf(out, "Usages: ");
+ for (i = 0; usageBits[i]; i++) {
+ if ((0x8000 >> i) & usage) {
+ if (found)
+ SECU_Indent(out, level + 2);
+ fprintf(out, "%s\n", usageBits[i]);
+ found = 1;
+ }
+ }
+ if (!found) {
+ fprintf(out, "(none)\n");
+ }
+}
+
+static void
+secu_PrintIPAddress(FILE *out, SECItem *value, char *msg, int level)
+{
+ PRStatus st;
+ PRNetAddr addr;
+ char addrBuf[80];
+
+ memset(&addr, 0, sizeof addr);
+ if (value->len == 4) {
+ addr.inet.family = PR_AF_INET;
+ memcpy(&addr.inet.ip, value->data, value->len);
+ } else if (value->len == 16) {
+ addr.ipv6.family = PR_AF_INET6;
+ memcpy(addr.ipv6.ip.pr_s6_addr, value->data, value->len);
+ if (PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped)) {
+ /* convert to IPv4. */
+ addr.inet.family = PR_AF_INET;
+ memcpy(&addr.inet.ip, &addr.ipv6.ip.pr_s6_addr[12], 4);
+ memset(&addr.inet.pad[0], 0, sizeof addr.inet.pad);
+ }
+ } else {
+ goto loser;
+ }
+
+ st = PR_NetAddrToString(&addr, addrBuf, sizeof addrBuf);
+ if (st == PR_SUCCESS) {
+ SECU_Indent(out, level);
+ fprintf(out, "%s: %s\n", msg, addrBuf);
+ } else {
+ loser:
+ SECU_PrintAsHex(out, value, msg, level);
+ }
+}
+
+static void
+secu_PrintGeneralName(FILE *out, CERTGeneralName *gname, char *msg, int level)
+{
+ char label[40];
+ if (msg && msg[0]) {
+ SECU_Indent(out, level++);
+ fprintf(out, "%s: \n", msg);
+ }
+ switch (gname->type) {
+ case certOtherName:
+ SECU_PrintAny(out, &gname->name.OthName.name, "Other Name", level);
+ SECU_PrintObjectID(out, &gname->name.OthName.oid, "OID", level + 1);
+ break;
+ case certDirectoryName:
+ SECU_PrintName(out, &gname->name.directoryName, "Directory Name", level);
+ break;
+ case certRFC822Name:
+ secu_PrintRawString(out, &gname->name.other, "RFC822 Name", level);
+ break;
+ case certDNSName:
+ secu_PrintRawString(out, &gname->name.other, "DNS name", level);
+ break;
+ case certURI:
+ secu_PrintRawString(out, &gname->name.other, "URI", level);
+ break;
+ case certIPAddress:
+ secu_PrintIPAddress(out, &gname->name.other, "IP Address", level);
+ break;
+ case certRegisterID:
+ SECU_PrintObjectID(out, &gname->name.other, "Registered ID", level);
+ break;
+ case certX400Address:
+ SECU_PrintAny(out, &gname->name.other, "X400 Address", level);
+ break;
+ case certEDIPartyName:
+ SECU_PrintAny(out, &gname->name.other, "EDI Party", level);
+ break;
+ default:
+ PR_snprintf(label, sizeof label, "unknown type [%d]",
+ (int)gname->type - 1);
+ SECU_PrintAsHex(out, &gname->name.other, label, level);
+ break;
+ }
+}
+
+static void
+secu_PrintGeneralNames(FILE *out, CERTGeneralName *gname, char *msg, int level)
+{
+ CERTGeneralName *name = gname;
+ do {
+ secu_PrintGeneralName(out, name, msg, level);
+ name = CERT_GetNextGeneralName(name);
+ } while (name && name != gname);
+}
+
+static void
+secu_PrintAuthKeyIDExtension(FILE *out, SECItem *value, char *msg, int level)
+{
+ CERTAuthKeyID *kid = NULL;
+ PLArenaPool *pool = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if (!pool) {
+ SECU_PrintError("Error", "Allocating new ArenaPool");
+ return;
+ }
+ kid = CERT_DecodeAuthKeyID(pool, value);
+ if (!kid) {
+ SECU_PrintErrMsg(out, level, "Error", "Parsing extension");
+ SECU_PrintAny(out, value, "Data", level);
+ } else {
+ int keyIDPresent = (kid->keyID.data && kid->keyID.len);
+ int issuerPresent = kid->authCertIssuer != NULL;
+ int snPresent = (kid->authCertSerialNumber.data &&
+ kid->authCertSerialNumber.len);
+
+ if (keyIDPresent)
+ SECU_PrintAsHex(out, &kid->keyID, "Key ID", level);
+ if (issuerPresent)
+ secu_PrintGeneralName(out, kid->authCertIssuer, "Issuer", level);
+ if (snPresent)
+ SECU_PrintInteger(out, &kid->authCertSerialNumber,
+ "Serial Number", level);
+ }
+ PORT_FreeArena(pool, PR_FALSE);
+}
+
+static void
+secu_PrintAltNameExtension(FILE *out, SECItem *value, char *msg, int level)
+{
+ CERTGeneralName *nameList;
+ CERTGeneralName *current;
+ PLArenaPool *pool = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if (!pool) {
+ SECU_PrintError("Error", "Allocating new ArenaPool");
+ return;
+ }
+ nameList = current = CERT_DecodeAltNameExtension(pool, value);
+ if (!current) {
+ if (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND) {
+ /* Decoder found empty sequence, which is invalid. */
+ PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
+ }
+ SECU_PrintErrMsg(out, level, "Error", "Parsing extension");
+ SECU_PrintAny(out, value, "Data", level);
+ } else {
+ do {
+ secu_PrintGeneralName(out, current, msg, level);
+ current = CERT_GetNextGeneralName(current);
+ } while (current != nameList);
+ }
+ PORT_FreeArena(pool, PR_FALSE);
+}
+
+static void
+secu_PrintCRLDistPtsExtension(FILE *out, SECItem *value, char *msg, int level)
+{
+ CERTCrlDistributionPoints *dPoints;
+ PLArenaPool *pool = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if (!pool) {
+ SECU_PrintError("Error", "Allocating new ArenaPool");
+ return;
+ }
+ dPoints = CERT_DecodeCRLDistributionPoints(pool, value);
+ if (dPoints && dPoints->distPoints && dPoints->distPoints[0]) {
+ CRLDistributionPoint **pPoints = dPoints->distPoints;
+ CRLDistributionPoint *pPoint;
+ while (NULL != (pPoint = *pPoints++)) {
+ SECU_Indent(out, level);
+ fputs("Distribution point:\n", out);
+ if (pPoint->distPointType == generalName &&
+ pPoint->distPoint.fullName != NULL) {
+ secu_PrintGeneralNames(out, pPoint->distPoint.fullName, NULL,
+ level + 1);
+ } else if (pPoint->distPointType == relativeDistinguishedName &&
+ pPoint->distPoint.relativeName.avas) {
+ SECU_PrintRDN(out, &pPoint->distPoint.relativeName, "RDN",
+ level + 1);
+ } else if (pPoint->derDistPoint.data) {
+ SECU_PrintAny(out, &pPoint->derDistPoint, "Point", level + 1);
+ }
+ if (pPoint->reasons.data) {
+ secu_PrintDecodedBitString(out, &pPoint->reasons, "Reasons",
+ level + 1);
+ }
+ if (pPoint->crlIssuer) {
+ secu_PrintGeneralName(out, pPoint->crlIssuer, "CRL issuer",
+ level + 1);
+ }
+ }
+ } else {
+ SECU_PrintErrMsg(out, level, "Error", "Parsing extension");
+ SECU_PrintAny(out, value, "Data", level);
+ }
+ PORT_FreeArena(pool, PR_FALSE);
+}
+
+static void
+secu_PrintNameConstraintSubtree(FILE *out, CERTNameConstraint *value,
+ char *msg, int level)
+{
+ CERTNameConstraint *head = value;
+ SECU_Indent(out, level);
+ fprintf(out, "%s Subtree:\n", msg);
+ level++;
+ do {
+ secu_PrintGeneralName(out, &value->name, NULL, level);
+ if (value->min.data)
+ SECU_PrintInteger(out, &value->min, "Minimum", level + 1);
+ if (value->max.data)
+ SECU_PrintInteger(out, &value->max, "Maximum", level + 1);
+ value = CERT_GetNextNameConstraint(value);
+ } while (value != head);
+}
+
+static void
+secu_PrintNameConstraintsExtension(FILE *out, SECItem *value, char *msg, int level)
+{
+ CERTNameConstraints *cnstrnts;
+ PLArenaPool *pool = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if (!pool) {
+ SECU_PrintError("Error", "Allocating new ArenaPool");
+ return;
+ }
+ cnstrnts = CERT_DecodeNameConstraintsExtension(pool, value);
+ if (!cnstrnts) {
+ SECU_PrintErrMsg(out, level, "Error", "Parsing extension");
+ SECU_PrintAny(out, value, "Raw", level);
+ } else {
+ if (cnstrnts->permited)
+ secu_PrintNameConstraintSubtree(out, cnstrnts->permited,
+ "Permitted", level);
+ if (cnstrnts->excluded)
+ secu_PrintNameConstraintSubtree(out, cnstrnts->excluded,
+ "Excluded", level);
+ }
+ PORT_FreeArena(pool, PR_FALSE);
+}
+
+static void
+secu_PrintAuthorityInfoAcess(FILE *out, SECItem *value, char *msg, int level)
+{
+ CERTAuthInfoAccess **infos = NULL;
+ PLArenaPool *pool = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if (!pool) {
+ SECU_PrintError("Error", "Allocating new ArenaPool");
+ return;
+ }
+ infos = CERT_DecodeAuthInfoAccessExtension(pool, value);
+ if (!infos) {
+ SECU_PrintErrMsg(out, level, "Error", "Parsing extension");
+ SECU_PrintAny(out, value, "Raw", level);
+ } else {
+ CERTAuthInfoAccess *info;
+ while (NULL != (info = *infos++)) {
+ if (info->method.data) {
+ SECU_PrintObjectID(out, &info->method, "Method", level);
+ } else {
+ SECU_Indent(out, level);
+ fprintf(out, "Error: missing method\n");
+ }
+ if (info->location) {
+ secu_PrintGeneralName(out, info->location, "Location", level);
+ } else {
+ SECU_PrintAny(out, &info->derLocation, "Location", level);
+ }
+ }
+ }
+ PORT_FreeArena(pool, PR_FALSE);
+}
+
+void
+SECU_PrintExtensions(FILE *out, CERTCertExtension **extensions,
+ char *msg, int level)
+{
+ SECOidTag oidTag;
+
+ if (extensions) {
+ if (msg && *msg) {
+ SECU_Indent(out, level++);
+ fprintf(out, "%s:\n", msg);
+ }
+
+ while (*extensions) {
+ SECItem *tmpitem;
+
+ tmpitem = &(*extensions)->id;
+ SECU_PrintObjectID(out, tmpitem, "Name", level);
+
+ tmpitem = &(*extensions)->critical;
+ if (tmpitem->len) {
+ secu_PrintBoolean(out, tmpitem, "Critical", level);
+ }
+
+ oidTag = SECOID_FindOIDTag(&((*extensions)->id));
+ tmpitem = &((*extensions)->value);
+
+ switch (oidTag) {
+ case SEC_OID_X509_INVALID_DATE:
+ case SEC_OID_NS_CERT_EXT_CERT_RENEWAL_TIME:
+ secu_PrintX509InvalidDate(out, tmpitem, "Date", level);
+ break;
+ case SEC_OID_X509_CERTIFICATE_POLICIES:
+ SECU_PrintPolicy(out, tmpitem, "Data", level);
+ break;
+ case SEC_OID_NS_CERT_EXT_BASE_URL:
+ case SEC_OID_NS_CERT_EXT_REVOCATION_URL:
+ case SEC_OID_NS_CERT_EXT_CA_REVOCATION_URL:
+ case SEC_OID_NS_CERT_EXT_CA_CRL_URL:
+ case SEC_OID_NS_CERT_EXT_CA_CERT_URL:
+ case SEC_OID_NS_CERT_EXT_CERT_RENEWAL_URL:
+ case SEC_OID_NS_CERT_EXT_CA_POLICY_URL:
+ case SEC_OID_NS_CERT_EXT_HOMEPAGE_URL:
+ case SEC_OID_NS_CERT_EXT_LOST_PASSWORD_URL:
+ case SEC_OID_OCSP_RESPONDER:
+ SECU_PrintString(out, tmpitem, "URL", level);
+ break;
+ case SEC_OID_NS_CERT_EXT_COMMENT:
+ SECU_PrintString(out, tmpitem, "Comment", level);
+ break;
+ case SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME:
+ SECU_PrintString(out, tmpitem, "ServerName", level);
+ break;
+ case SEC_OID_NS_CERT_EXT_CERT_TYPE:
+ secu_PrintNSCertType(out, tmpitem, "Data", level);
+ break;
+ case SEC_OID_X509_BASIC_CONSTRAINTS:
+ secu_PrintBasicConstraints(out, tmpitem, "Data", level);
+ break;
+ case SEC_OID_X509_EXT_KEY_USAGE:
+ PrintExtKeyUsageExtension(out, tmpitem, NULL, level);
+ break;
+ case SEC_OID_X509_KEY_USAGE:
+ secu_PrintX509KeyUsage(out, tmpitem, NULL, level);
+ break;
+ case SEC_OID_X509_AUTH_KEY_ID:
+ secu_PrintAuthKeyIDExtension(out, tmpitem, NULL, level);
+ break;
+ case SEC_OID_X509_SUBJECT_ALT_NAME:
+ case SEC_OID_X509_ISSUER_ALT_NAME:
+ secu_PrintAltNameExtension(out, tmpitem, NULL, level);
+ break;
+ case SEC_OID_X509_CRL_DIST_POINTS:
+ secu_PrintCRLDistPtsExtension(out, tmpitem, NULL, level);
+ break;
+ case SEC_OID_X509_PRIVATE_KEY_USAGE_PERIOD:
+ SECU_PrintPrivKeyUsagePeriodExtension(out, tmpitem, NULL,
+ level);
+ break;
+ case SEC_OID_X509_NAME_CONSTRAINTS:
+ secu_PrintNameConstraintsExtension(out, tmpitem, NULL, level);
+ break;
+ case SEC_OID_X509_AUTH_INFO_ACCESS:
+ secu_PrintAuthorityInfoAcess(out, tmpitem, NULL, level);
+ break;
+
+ case SEC_OID_X509_CRL_NUMBER:
+ case SEC_OID_X509_REASON_CODE:
+
+ /* PKIX OIDs */
+ case SEC_OID_PKIX_OCSP:
+ case SEC_OID_PKIX_OCSP_BASIC_RESPONSE:
+ case SEC_OID_PKIX_OCSP_NONCE:
+ case SEC_OID_PKIX_OCSP_CRL:
+ case SEC_OID_PKIX_OCSP_RESPONSE:
+ case SEC_OID_PKIX_OCSP_NO_CHECK:
+ case SEC_OID_PKIX_OCSP_ARCHIVE_CUTOFF:
+ case SEC_OID_PKIX_OCSP_SERVICE_LOCATOR:
+ case SEC_OID_PKIX_REGCTRL_REGTOKEN:
+ case SEC_OID_PKIX_REGCTRL_AUTHENTICATOR:
+ case SEC_OID_PKIX_REGCTRL_PKIPUBINFO:
+ case SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS:
+ case SEC_OID_PKIX_REGCTRL_OLD_CERT_ID:
+ case SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY:
+ case SEC_OID_PKIX_REGINFO_UTF8_PAIRS:
+ case SEC_OID_PKIX_REGINFO_CERT_REQUEST:
+
+ /* Netscape extension OIDs. */
+ case SEC_OID_NS_CERT_EXT_NETSCAPE_OK:
+ case SEC_OID_NS_CERT_EXT_ISSUER_LOGO:
+ case SEC_OID_NS_CERT_EXT_SUBJECT_LOGO:
+ case SEC_OID_NS_CERT_EXT_ENTITY_LOGO:
+ case SEC_OID_NS_CERT_EXT_USER_PICTURE:
+
+ /* x.509 v3 Extensions */
+ case SEC_OID_X509_SUBJECT_DIRECTORY_ATTR:
+ case SEC_OID_X509_SUBJECT_KEY_ID:
+ case SEC_OID_X509_POLICY_MAPPINGS:
+ case SEC_OID_X509_POLICY_CONSTRAINTS:
+
+ default:
+ SECU_PrintAny(out, tmpitem, "Data", level);
+ break;
+ }
+
+ SECU_Newline(out);
+ extensions++;
+ }
+ }
+}
+
+/* An RDN is a subset of a DirectoryName, and we already know how to
+ * print those, so make a directory name out of the RDN, and print it.
+ */
+void
+SECU_PrintRDN(FILE *out, CERTRDN *rdn, const char *msg, int level)
+{
+ CERTName name;
+ CERTRDN *rdns[2];
+
+ name.arena = NULL;
+ name.rdns = rdns;
+ rdns[0] = rdn;
+ rdns[1] = NULL;
+ SECU_PrintName(out, &name, msg, level);
+}
+
+void
+SECU_PrintNameQuotesOptional(FILE *out, CERTName *name, const char *msg,
+ int level, PRBool quotes)
+{
+ char *nameStr = NULL;
+ char *str;
+ SECItem my;
+
+ if (!name) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return;
+ }
+ if (!name->rdns || !name->rdns[0]) {
+ str = "(empty)";
+ } else {
+ str = nameStr = CERT_NameToAscii(name);
+ }
+ if (!str) {
+ str = "!Invalid AVA!";
+ }
+ my.data = (unsigned char *)str;
+ my.len = PORT_Strlen(str);
+#if 1
+ secu_PrintRawStringQuotesOptional(out, &my, msg, level, quotes);
+#else
+ SECU_Indent(out, level);
+ fprintf(out, "%s: ", msg);
+ fprintf(out, str);
+ SECU_Newline(out);
+#endif
+ PORT_Free(nameStr);
+}
+
+void
+SECU_PrintName(FILE *out, CERTName *name, const char *msg, int level)
+{
+ SECU_PrintNameQuotesOptional(out, name, msg, level, PR_TRUE);
+}
+
+void
+printflags(char *trusts, unsigned int flags)
+{
+ if (flags & CERTDB_VALID_CA)
+ if (!(flags & CERTDB_TRUSTED_CA) &&
+ !(flags & CERTDB_TRUSTED_CLIENT_CA))
+ PORT_Strcat(trusts, "c");
+ if (flags & CERTDB_TERMINAL_RECORD)
+ if (!(flags & CERTDB_TRUSTED))
+ PORT_Strcat(trusts, "p");
+ if (flags & CERTDB_TRUSTED_CA)
+ PORT_Strcat(trusts, "C");
+ if (flags & CERTDB_TRUSTED_CLIENT_CA)
+ PORT_Strcat(trusts, "T");
+ if (flags & CERTDB_TRUSTED)
+ PORT_Strcat(trusts, "P");
+ if (flags & CERTDB_USER)
+ PORT_Strcat(trusts, "u");
+ if (flags & CERTDB_SEND_WARN)
+ PORT_Strcat(trusts, "w");
+ if (flags & CERTDB_INVISIBLE_CA)
+ PORT_Strcat(trusts, "I");
+ if (flags & CERTDB_GOVT_APPROVED_CA)
+ PORT_Strcat(trusts, "G");
+ return;
+}
+
+/* callback for listing certs through pkcs11 */
+SECStatus
+SECU_PrintCertNickname(CERTCertListNode *node, void *data)
+{
+ CERTCertTrust trust;
+ CERTCertificate *cert;
+ FILE *out;
+ char trusts[30];
+ char *name;
+
+ cert = node->cert;
+
+ PORT_Memset(trusts, 0, sizeof(trusts));
+ out = (FILE *)data;
+
+ name = node->appData;
+ if (!name || !name[0]) {
+ name = cert->nickname;
+ }
+ if (!name || !name[0]) {
+ name = cert->emailAddr;
+ }
+ if (!name || !name[0]) {
+ name = "(NULL)";
+ }
+
+ if (CERT_GetCertTrust(cert, &trust) == SECSuccess) {
+ printflags(trusts, trust.sslFlags);
+ PORT_Strcat(trusts, ",");
+ printflags(trusts, trust.emailFlags);
+ PORT_Strcat(trusts, ",");
+ printflags(trusts, trust.objectSigningFlags);
+ } else {
+ PORT_Memcpy(trusts, ",,", 3);
+ }
+ fprintf(out, "%-60s %-5s\n", name, trusts);
+
+ return (SECSuccess);
+}
+
+int
+SECU_DecodeAndPrintExtensions(FILE *out, SECItem *any, char *m, int level)
+{
+ CERTCertExtension **extensions = NULL;
+ PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ int rv = 0;
+
+ if (!arena)
+ return SEC_ERROR_NO_MEMORY;
+
+ rv = SEC_QuickDERDecodeItem(arena, &extensions,
+ SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate), any);
+ if (!rv)
+ SECU_PrintExtensions(out, extensions, m, level);
+ else
+ SECU_PrintAny(out, any, m, level);
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+/* print a decoded SET OF or SEQUENCE OF Extensions */
+int
+SECU_PrintSetOfExtensions(FILE *out, SECItem **any, char *m, int level)
+{
+ int rv = 0;
+ if (m && *m) {
+ SECU_Indent(out, level++);
+ fprintf(out, "%s:\n", m);
+ }
+ while (any && any[0]) {
+ rv |= SECU_DecodeAndPrintExtensions(out, any[0], "", level);
+ any++;
+ }
+ return rv;
+}
+
+/* print a decoded SET OF or SEQUENCE OF "ANY" */
+int
+SECU_PrintSetOfAny(FILE *out, SECItem **any, char *m, int level)
+{
+ int rv = 0;
+ if (m && *m) {
+ SECU_Indent(out, level++);
+ fprintf(out, "%s:\n", m);
+ }
+ while (any && any[0]) {
+ SECU_PrintAny(out, any[0], "", level);
+ any++;
+ }
+ return rv;
+}
+
+int
+SECU_PrintCertAttribute(FILE *out, CERTAttribute *attr, char *m, int level)
+{
+ int rv = 0;
+ SECOidTag tag;
+ tag = SECU_PrintObjectID(out, &attr->attrType, "Attribute Type", level);
+ if (tag == SEC_OID_PKCS9_EXTENSION_REQUEST) {
+ rv = SECU_PrintSetOfExtensions(out, attr->attrValue, "Extensions", level);
+ } else {
+ rv = SECU_PrintSetOfAny(out, attr->attrValue, "Attribute Values", level);
+ }
+ return rv;
+}
+
+int
+SECU_PrintCertAttributes(FILE *out, CERTAttribute **attrs, char *m, int level)
+{
+ int rv = 0;
+ while (attrs[0]) {
+ rv |= SECU_PrintCertAttribute(out, attrs[0], m, level + 1);
+ attrs++;
+ }
+ return rv;
+}
+
+int /* sometimes a PRErrorCode, other times a SECStatus. Sigh. */
+ SECU_PrintCertificateRequest(FILE *out, SECItem *der, char *m, int level)
+{
+ PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ CERTCertificateRequest *cr;
+ int rv = SEC_ERROR_NO_MEMORY;
+
+ if (!arena)
+ return rv;
+
+ /* Decode certificate request */
+ cr = PORT_ArenaZNew(arena, CERTCertificateRequest);
+ if (!cr)
+ goto loser;
+ cr->arena = arena;
+ rv = SEC_QuickDERDecodeItem(arena, cr,
+ SEC_ASN1_GET(CERT_CertificateRequestTemplate), der);
+ if (rv)
+ goto loser;
+
+ /* Pretty print it out */
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &cr->version, "Version", level + 1);
+ SECU_PrintName(out, &cr->subject, "Subject", level + 1);
+ if (!SECU_GetWrapEnabled()) /*SECU_PrintName didn't add newline*/
+ SECU_Newline(out);
+ secu_PrintSubjectPublicKeyInfo(out, arena, &cr->subjectPublicKeyInfo,
+ "Subject Public Key Info", level + 1);
+ if (cr->attributes)
+ SECU_PrintCertAttributes(out, cr->attributes, "Attributes", level + 1);
+ rv = 0;
+loser:
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+int
+SECU_PrintCertificate(FILE *out, const SECItem *der, const char *m, int level)
+{
+ PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ CERTCertificate *c;
+ int rv = SEC_ERROR_NO_MEMORY;
+ int iv;
+
+ if (!arena)
+ return rv;
+
+ /* Decode certificate */
+ c = PORT_ArenaZNew(arena, CERTCertificate);
+ if (!c)
+ goto loser;
+ c->arena = arena;
+ rv = SEC_ASN1DecodeItem(arena, c,
+ SEC_ASN1_GET(CERT_CertificateTemplate), der);
+ if (rv) {
+ SECU_Indent(out, level);
+ SECU_PrintErrMsg(out, level, "Error", "Parsing extension");
+ SECU_PrintAny(out, der, "Raw", level);
+ goto loser;
+ }
+ /* Pretty print it out */
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ iv = c->version.len ? DER_GetInteger(&c->version) : 0; /* version is optional */
+ SECU_Indent(out, level + 1);
+ fprintf(out, "%s: %d (0x%x)\n", "Version", iv + 1, iv);
+
+ SECU_PrintInteger(out, &c->serialNumber, "Serial Number", level + 1);
+ SECU_PrintAlgorithmID(out, &c->signature, "Signature Algorithm", level + 1);
+ SECU_PrintName(out, &c->issuer, "Issuer", level + 1);
+ if (!SECU_GetWrapEnabled()) /*SECU_PrintName didn't add newline*/
+ SECU_Newline(out);
+ secu_PrintValidity(out, &c->validity, "Validity", level + 1);
+ SECU_PrintName(out, &c->subject, "Subject", level + 1);
+ if (!SECU_GetWrapEnabled()) /*SECU_PrintName didn't add newline*/
+ SECU_Newline(out);
+ secu_PrintSubjectPublicKeyInfo(out, arena, &c->subjectPublicKeyInfo,
+ "Subject Public Key Info", level + 1);
+ if (c->issuerID.data)
+ secu_PrintDecodedBitString(out, &c->issuerID, "Issuer Unique ID", level + 1);
+ if (c->subjectID.data)
+ secu_PrintDecodedBitString(out, &c->subjectID, "Subject Unique ID", level + 1);
+ SECU_PrintExtensions(out, c->extensions, "Signed Extensions", level + 1);
+loser:
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+int
+SECU_PrintCertificateBasicInfo(FILE *out, const SECItem *der, const char *m, int level)
+{
+ PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ CERTCertificate *c;
+ int rv = SEC_ERROR_NO_MEMORY;
+
+ if (!arena)
+ return rv;
+
+ /* Decode certificate */
+ c = PORT_ArenaZNew(arena, CERTCertificate);
+ if (!c)
+ goto loser;
+ c->arena = arena;
+ rv = SEC_ASN1DecodeItem(arena, c,
+ SEC_ASN1_GET(CERT_CertificateTemplate), der);
+ if (rv) {
+ SECU_Indent(out, level);
+ SECU_PrintErrMsg(out, level, "Error", "Parsing extension");
+ SECU_PrintAny(out, der, "Raw", level);
+ goto loser;
+ }
+ /* Pretty print it out */
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &c->serialNumber, "Serial Number", level + 1);
+ SECU_PrintAlgorithmID(out, &c->signature, "Signature Algorithm", level + 1);
+ SECU_PrintName(out, &c->issuer, "Issuer", level + 1);
+ if (!SECU_GetWrapEnabled()) /*SECU_PrintName didn't add newline*/
+ SECU_Newline(out);
+ secu_PrintValidity(out, &c->validity, "Validity", level + 1);
+ SECU_PrintName(out, &c->subject, "Subject", level + 1);
+ if (!SECU_GetWrapEnabled()) /*SECU_PrintName didn't add newline*/
+ SECU_Newline(out);
+loser:
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+int
+SECU_PrintSubjectPublicKeyInfo(FILE *out, SECItem *der, char *m, int level)
+{
+ PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ int rv = SEC_ERROR_NO_MEMORY;
+ CERTSubjectPublicKeyInfo spki;
+
+ if (!arena)
+ return rv;
+
+ PORT_Memset(&spki, 0, sizeof spki);
+ rv = SEC_ASN1DecodeItem(arena, &spki,
+ SEC_ASN1_GET(CERT_SubjectPublicKeyInfoTemplate),
+ der);
+ if (!rv) {
+ if (m && *m) {
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ }
+ secu_PrintSubjectPublicKeyInfo(out, arena, &spki,
+ "Subject Public Key Info", level + 1);
+ }
+
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+#ifdef HAVE_EPV_TEMPLATE
+int
+SECU_PrintPrivateKey(FILE *out, SECItem *der, char *m, int level)
+{
+ PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ SECKEYEncryptedPrivateKeyInfo key;
+ int rv = SEC_ERROR_NO_MEMORY;
+
+ if (!arena)
+ return rv;
+
+ PORT_Memset(&key, 0, sizeof(key));
+ rv = SEC_ASN1DecodeItem(arena, &key,
+ SEC_ASN1_GET(SECKEY_EncryptedPrivateKeyInfoTemplate), der);
+ if (rv)
+ goto loser;
+
+ /* Pretty print it out */
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ SECU_PrintAlgorithmID(out, &key.algorithm, "Encryption Algorithm",
+ level + 1);
+ SECU_PrintAsHex(out, &key.encryptedData, "Encrypted Data", level + 1);
+loser:
+ PORT_FreeArena(arena, PR_TRUE);
+ return rv;
+}
+#endif
+
+int
+SECU_PrintFingerprints(FILE *out, SECItem *derCert, char *m, int level)
+{
+ unsigned char fingerprint[SHA256_LENGTH];
+ char *fpStr = NULL;
+ int err = PORT_GetError();
+ SECStatus rv;
+ SECItem fpItem;
+
+ /* Print SHA-256 fingerprint */
+ memset(fingerprint, 0, sizeof fingerprint);
+ rv = PK11_HashBuf(SEC_OID_SHA256, fingerprint, derCert->data, derCert->len);
+ fpItem.data = fingerprint;
+ fpItem.len = SHA256_LENGTH;
+ fpStr = CERT_Hexify(&fpItem, 1);
+ SECU_Indent(out, level);
+ fprintf(out, "%s (SHA-256):", m);
+ if (SECU_GetWrapEnabled()) {
+ fprintf(out, "\n");
+ SECU_Indent(out, level + 1);
+ } else {
+ fprintf(out, " ");
+ }
+ fprintf(out, "%s\n", fpStr);
+ PORT_Free(fpStr);
+ fpStr = NULL;
+ if (rv != SECSuccess && !err)
+ err = PORT_GetError();
+
+ /* print SHA1 fingerprint */
+ memset(fingerprint, 0, sizeof fingerprint);
+ rv = PK11_HashBuf(SEC_OID_SHA1, fingerprint, derCert->data, derCert->len);
+ fpItem.data = fingerprint;
+ fpItem.len = SHA1_LENGTH;
+ fpStr = CERT_Hexify(&fpItem, 1);
+ SECU_Indent(out, level);
+ fprintf(out, "%s (SHA1):", m);
+ if (SECU_GetWrapEnabled()) {
+ fprintf(out, "\n");
+ SECU_Indent(out, level + 1);
+ } else {
+ fprintf(out, " ");
+ }
+ fprintf(out, "%s\n", fpStr);
+ PORT_Free(fpStr);
+ if (SECU_GetWrapEnabled())
+ fprintf(out, "\n");
+
+ if (err)
+ PORT_SetError(err);
+ if (err || rv != SECSuccess)
+ return SECFailure;
+
+ return 0;
+}
+
+/*
+** PKCS7 Support
+*/
+
+/* forward declaration */
+static int
+secu_PrintPKCS7ContentInfo(FILE *, SEC_PKCS7ContentInfo *, char *, int);
+
+/*
+** secu_PrintPKCS7EncContent
+** Prints a SEC_PKCS7EncryptedContentInfo (without decrypting it)
+*/
+static void
+secu_PrintPKCS7EncContent(FILE *out, SEC_PKCS7EncryptedContentInfo *src,
+ char *m, int level)
+{
+ if (src->contentTypeTag == NULL)
+ src->contentTypeTag = SECOID_FindOID(&(src->contentType));
+
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Content Type: %s\n",
+ (src->contentTypeTag != NULL) ? src->contentTypeTag->desc
+ : "Unknown");
+ SECU_PrintAlgorithmID(out, &(src->contentEncAlg),
+ "Content Encryption Algorithm", level + 1);
+ SECU_PrintAsHex(out, &(src->encContent),
+ "Encrypted Content", level + 1);
+}
+
+/*
+** secu_PrintRecipientInfo
+** Prints a PKCS7RecipientInfo type
+*/
+static void
+secu_PrintRecipientInfo(FILE *out, SEC_PKCS7RecipientInfo *info, char *m,
+ int level)
+{
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(info->version), "Version", level + 1);
+
+ SECU_PrintName(out, &(info->issuerAndSN->issuer), "Issuer",
+ level + 1);
+ SECU_PrintInteger(out, &(info->issuerAndSN->serialNumber),
+ "Serial Number", level + 1);
+
+ /* Parse and display encrypted key */
+ SECU_PrintAlgorithmID(out, &(info->keyEncAlg),
+ "Key Encryption Algorithm", level + 1);
+ SECU_PrintAsHex(out, &(info->encKey), "Encrypted Key", level + 1);
+}
+
+/*
+** secu_PrintSignerInfo
+** Prints a PKCS7SingerInfo type
+*/
+static void
+secu_PrintSignerInfo(FILE *out, SEC_PKCS7SignerInfo *info, char *m, int level)
+{
+ SEC_PKCS7Attribute *attr;
+ int iv;
+ char om[100];
+
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(info->version), "Version", level + 1);
+
+ SECU_PrintName(out, &(info->issuerAndSN->issuer), "Issuer",
+ level + 1);
+ SECU_PrintInteger(out, &(info->issuerAndSN->serialNumber),
+ "Serial Number", level + 1);
+
+ SECU_PrintAlgorithmID(out, &(info->digestAlg), "Digest Algorithm",
+ level + 1);
+
+ if (info->authAttr != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Authenticated Attributes:\n");
+ iv = 0;
+ while ((attr = info->authAttr[iv++]) != NULL) {
+ sprintf(om, "Attribute (%d)", iv);
+ secu_PrintAttribute(out, attr, om, level + 2);
+ }
+ }
+
+ /* Parse and display signature */
+ SECU_PrintAlgorithmID(out, &(info->digestEncAlg),
+ "Digest Encryption Algorithm", level + 1);
+ SECU_PrintAsHex(out, &(info->encDigest), "Encrypted Digest", level + 1);
+
+ if (info->unAuthAttr != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Unauthenticated Attributes:\n");
+ iv = 0;
+ while ((attr = info->unAuthAttr[iv++]) != NULL) {
+ sprintf(om, "Attribute (%x)", iv);
+ secu_PrintAttribute(out, attr, om, level + 2);
+ }
+ }
+}
+
+/* callers of this function must make sure that the CERTSignedCrl
+ from which they are extracting the CERTCrl has been fully-decoded.
+ Otherwise it will not have the entries even though the CRL may have
+ some */
+
+void
+SECU_PrintCRLInfo(FILE *out, CERTCrl *crl, char *m, int level)
+{
+ CERTCrlEntry *entry;
+ int iv;
+ char om[100];
+
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ /* version is optional */
+ iv = crl->version.len ? DER_GetInteger(&crl->version) : 0;
+ SECU_Indent(out, level + 1);
+ fprintf(out, "%s: %d (0x%x)\n", "Version", iv + 1, iv);
+ SECU_PrintAlgorithmID(out, &(crl->signatureAlg), "Signature Algorithm",
+ level + 1);
+ SECU_PrintName(out, &(crl->name), "Issuer", level + 1);
+ SECU_PrintTimeChoice(out, &(crl->lastUpdate), "This Update", level + 1);
+ if (crl->nextUpdate.data && crl->nextUpdate.len) /* is optional */
+ SECU_PrintTimeChoice(out, &(crl->nextUpdate), "Next Update", level + 1);
+
+ if (crl->entries != NULL) {
+ iv = 0;
+ while ((entry = crl->entries[iv++]) != NULL) {
+ sprintf(om, "Entry %d (0x%x):\n", iv, iv);
+ SECU_Indent(out, level + 1);
+ fputs(om, out);
+ SECU_PrintInteger(out, &(entry->serialNumber), "Serial Number",
+ level + 2);
+ SECU_PrintTimeChoice(out, &(entry->revocationDate),
+ "Revocation Date", level + 2);
+ SECU_PrintExtensions(out, entry->extensions,
+ "Entry Extensions", level + 2);
+ }
+ }
+ SECU_PrintExtensions(out, crl->extensions, "CRL Extensions", level + 1);
+}
+
+/*
+** secu_PrintPKCS7Signed
+** Pretty print a PKCS7 signed data type (up to version 1).
+*/
+static int
+secu_PrintPKCS7Signed(FILE *out, SEC_PKCS7SignedData *src,
+ const char *m, int level)
+{
+ SECAlgorithmID *digAlg; /* digest algorithms */
+ SECItem *aCert; /* certificate */
+ CERTSignedCrl *aCrl; /* certificate revocation list */
+ SEC_PKCS7SignerInfo *sigInfo; /* signer information */
+ int rv, iv;
+ char om[100];
+
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(src->version), "Version", level + 1);
+
+ /* Parse and list digest algorithms (if any) */
+ if (src->digestAlgorithms != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Digest Algorithm List:\n");
+ iv = 0;
+ while ((digAlg = src->digestAlgorithms[iv++]) != NULL) {
+ sprintf(om, "Digest Algorithm (%x)", iv);
+ SECU_PrintAlgorithmID(out, digAlg, om, level + 2);
+ }
+ }
+
+ /* Now for the content */
+ rv = secu_PrintPKCS7ContentInfo(out, &(src->contentInfo),
+ "Content Information", level + 1);
+ if (rv != 0)
+ return rv;
+
+ /* Parse and list certificates (if any) */
+ if (src->rawCerts != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Certificate List:\n");
+ iv = 0;
+ while ((aCert = src->rawCerts[iv++]) != NULL) {
+ sprintf(om, "Certificate (%x)", iv);
+ rv = SECU_PrintSignedData(out, aCert, om, level + 2,
+ (SECU_PPFunc)SECU_PrintCertificate);
+ if (rv)
+ return rv;
+ }
+ }
+
+ /* Parse and list CRL's (if any) */
+ if (src->crls != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Signed Revocation Lists:\n");
+ iv = 0;
+ while ((aCrl = src->crls[iv++]) != NULL) {
+ sprintf(om, "Signed Revocation List (%x)", iv);
+ SECU_Indent(out, level + 2);
+ fprintf(out, "%s:\n", om);
+ SECU_PrintAlgorithmID(out, &aCrl->signatureWrap.signatureAlgorithm,
+ "Signature Algorithm", level + 3);
+ DER_ConvertBitString(&aCrl->signatureWrap.signature);
+ SECU_PrintAsHex(out, &aCrl->signatureWrap.signature, "Signature",
+ level + 3);
+ SECU_PrintCRLInfo(out, &aCrl->crl, "Certificate Revocation List",
+ level + 3);
+ }
+ }
+
+ /* Parse and list signatures (if any) */
+ if (src->signerInfos != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Signer Information List:\n");
+ iv = 0;
+ while ((sigInfo = src->signerInfos[iv++]) != NULL) {
+ sprintf(om, "Signer Information (%x)", iv);
+ secu_PrintSignerInfo(out, sigInfo, om, level + 2);
+ }
+ }
+
+ return 0;
+}
+
+/*
+** secu_PrintPKCS7Enveloped
+** Pretty print a PKCS7 enveloped data type (up to version 1).
+*/
+static void
+secu_PrintPKCS7Enveloped(FILE *out, SEC_PKCS7EnvelopedData *src,
+ const char *m, int level)
+{
+ SEC_PKCS7RecipientInfo *recInfo; /* pointer for signer information */
+ int iv;
+ char om[100];
+
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(src->version), "Version", level + 1);
+
+ /* Parse and list recipients (this is not optional) */
+ if (src->recipientInfos != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Recipient Information List:\n");
+ iv = 0;
+ while ((recInfo = src->recipientInfos[iv++]) != NULL) {
+ sprintf(om, "Recipient Information (%x)", iv);
+ secu_PrintRecipientInfo(out, recInfo, om, level + 2);
+ }
+ }
+
+ secu_PrintPKCS7EncContent(out, &src->encContentInfo,
+ "Encrypted Content Information", level + 1);
+}
+
+/*
+** secu_PrintPKCS7SignedEnveloped
+** Pretty print a PKCS7 singed and enveloped data type (up to version 1).
+*/
+static int
+secu_PrintPKCS7SignedAndEnveloped(FILE *out,
+ SEC_PKCS7SignedAndEnvelopedData *src,
+ const char *m, int level)
+{
+ SECAlgorithmID *digAlg; /* pointer for digest algorithms */
+ SECItem *aCert; /* pointer for certificate */
+ CERTSignedCrl *aCrl; /* pointer for certificate revocation list */
+ SEC_PKCS7SignerInfo *sigInfo; /* pointer for signer information */
+ SEC_PKCS7RecipientInfo *recInfo; /* pointer for recipient information */
+ int rv, iv;
+ char om[100];
+
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(src->version), "Version", level + 1);
+
+ /* Parse and list recipients (this is not optional) */
+ if (src->recipientInfos != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Recipient Information List:\n");
+ iv = 0;
+ while ((recInfo = src->recipientInfos[iv++]) != NULL) {
+ sprintf(om, "Recipient Information (%x)", iv);
+ secu_PrintRecipientInfo(out, recInfo, om, level + 2);
+ }
+ }
+
+ /* Parse and list digest algorithms (if any) */
+ if (src->digestAlgorithms != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Digest Algorithm List:\n");
+ iv = 0;
+ while ((digAlg = src->digestAlgorithms[iv++]) != NULL) {
+ sprintf(om, "Digest Algorithm (%x)", iv);
+ SECU_PrintAlgorithmID(out, digAlg, om, level + 2);
+ }
+ }
+
+ secu_PrintPKCS7EncContent(out, &src->encContentInfo,
+ "Encrypted Content Information", level + 1);
+
+ /* Parse and list certificates (if any) */
+ if (src->rawCerts != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Certificate List:\n");
+ iv = 0;
+ while ((aCert = src->rawCerts[iv++]) != NULL) {
+ sprintf(om, "Certificate (%x)", iv);
+ rv = SECU_PrintSignedData(out, aCert, om, level + 2,
+ (SECU_PPFunc)SECU_PrintCertificate);
+ if (rv)
+ return rv;
+ }
+ }
+
+ /* Parse and list CRL's (if any) */
+ if (src->crls != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Signed Revocation Lists:\n");
+ iv = 0;
+ while ((aCrl = src->crls[iv++]) != NULL) {
+ sprintf(om, "Signed Revocation List (%x)", iv);
+ SECU_Indent(out, level + 2);
+ fprintf(out, "%s:\n", om);
+ SECU_PrintAlgorithmID(out, &aCrl->signatureWrap.signatureAlgorithm,
+ "Signature Algorithm", level + 3);
+ DER_ConvertBitString(&aCrl->signatureWrap.signature);
+ SECU_PrintAsHex(out, &aCrl->signatureWrap.signature, "Signature",
+ level + 3);
+ SECU_PrintCRLInfo(out, &aCrl->crl, "Certificate Revocation List",
+ level + 3);
+ }
+ }
+
+ /* Parse and list signatures (if any) */
+ if (src->signerInfos != NULL) {
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Signer Information List:\n");
+ iv = 0;
+ while ((sigInfo = src->signerInfos[iv++]) != NULL) {
+ sprintf(om, "Signer Information (%x)", iv);
+ secu_PrintSignerInfo(out, sigInfo, om, level + 2);
+ }
+ }
+
+ return 0;
+}
+
+int
+SECU_PrintCrl(FILE *out, SECItem *der, char *m, int level)
+{
+ PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ CERTCrl *c = NULL;
+ int rv = SEC_ERROR_NO_MEMORY;
+
+ if (!arena)
+ return rv;
+ do {
+ /* Decode CRL */
+ c = PORT_ArenaZNew(arena, CERTCrl);
+ if (!c)
+ break;
+
+ rv = SEC_QuickDERDecodeItem(arena, c, SEC_ASN1_GET(CERT_CrlTemplate), der);
+ if (rv != SECSuccess)
+ break;
+ SECU_PrintCRLInfo(out, c, m, level);
+ } while (0);
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+/*
+** secu_PrintPKCS7Encrypted
+** Pretty print a PKCS7 encrypted data type (up to version 1).
+*/
+static void
+secu_PrintPKCS7Encrypted(FILE *out, SEC_PKCS7EncryptedData *src,
+ const char *m, int level)
+{
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(src->version), "Version", level + 1);
+
+ secu_PrintPKCS7EncContent(out, &src->encContentInfo,
+ "Encrypted Content Information", level + 1);
+}
+
+/*
+** secu_PrintPKCS7Digested
+** Pretty print a PKCS7 digested data type (up to version 1).
+*/
+static void
+secu_PrintPKCS7Digested(FILE *out, SEC_PKCS7DigestedData *src,
+ const char *m, int level)
+{
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ SECU_PrintInteger(out, &(src->version), "Version", level + 1);
+
+ SECU_PrintAlgorithmID(out, &src->digestAlg, "Digest Algorithm",
+ level + 1);
+ secu_PrintPKCS7ContentInfo(out, &src->contentInfo, "Content Information",
+ level + 1);
+ SECU_PrintAsHex(out, &src->digest, "Digest", level + 1);
+}
+
+/*
+** secu_PrintPKCS7ContentInfo
+** Takes a SEC_PKCS7ContentInfo type and sends the contents to the
+** appropriate function
+*/
+static int
+secu_PrintPKCS7ContentInfo(FILE *out, SEC_PKCS7ContentInfo *src,
+ char *m, int level)
+{
+ const char *desc;
+ SECOidTag kind;
+ int rv;
+
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ level++;
+
+ if (src->contentTypeTag == NULL)
+ src->contentTypeTag = SECOID_FindOID(&(src->contentType));
+
+ if (src->contentTypeTag == NULL) {
+ desc = "Unknown";
+ kind = SEC_OID_PKCS7_DATA;
+ } else {
+ desc = src->contentTypeTag->desc;
+ kind = src->contentTypeTag->offset;
+ }
+
+ if (src->content.data == NULL) {
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", desc);
+ level++;
+ SECU_Indent(out, level);
+ fprintf(out, "\n");
+ return 0;
+ }
+
+ rv = 0;
+ switch (kind) {
+ case SEC_OID_PKCS7_SIGNED_DATA: /* Signed Data */
+ rv = secu_PrintPKCS7Signed(out, src->content.signedData, desc, level);
+ break;
+
+ case SEC_OID_PKCS7_ENVELOPED_DATA: /* Enveloped Data */
+ secu_PrintPKCS7Enveloped(out, src->content.envelopedData, desc, level);
+ break;
+
+ case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: /* Signed and Enveloped */
+ rv = secu_PrintPKCS7SignedAndEnveloped(out,
+ src->content.signedAndEnvelopedData,
+ desc, level);
+ break;
+
+ case SEC_OID_PKCS7_DIGESTED_DATA: /* Digested Data */
+ secu_PrintPKCS7Digested(out, src->content.digestedData, desc, level);
+ break;
+
+ case SEC_OID_PKCS7_ENCRYPTED_DATA: /* Encrypted Data */
+ secu_PrintPKCS7Encrypted(out, src->content.encryptedData, desc, level);
+ break;
+
+ default:
+ SECU_PrintAsHex(out, src->content.data, desc, level);
+ break;
+ }
+
+ return rv;
+}
+
+/*
+** SECU_PrintPKCS7ContentInfo
+** Decode and print any major PKCS7 data type (up to version 1).
+*/
+int
+SECU_PrintPKCS7ContentInfo(FILE *out, SECItem *der, char *m, int level)
+{
+ SEC_PKCS7ContentInfo *cinfo;
+ int rv;
+
+ cinfo = SEC_PKCS7DecodeItem(der, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ if (cinfo != NULL) {
+ /* Send it to recursive parsing and printing module */
+ rv = secu_PrintPKCS7ContentInfo(out, cinfo, m, level);
+ SEC_PKCS7DestroyContentInfo(cinfo);
+ } else {
+ rv = -1;
+ }
+
+ return rv;
+}
+
+/*
+** End of PKCS7 functions
+*/
+
+void
+printFlags(FILE *out, unsigned int flags, int level)
+{
+ if (flags & CERTDB_TERMINAL_RECORD) {
+ SECU_Indent(out, level);
+ fprintf(out, "Terminal Record\n");
+ }
+ if (flags & CERTDB_TRUSTED) {
+ SECU_Indent(out, level);
+ fprintf(out, "Trusted\n");
+ }
+ if (flags & CERTDB_SEND_WARN) {
+ SECU_Indent(out, level);
+ fprintf(out, "Warn When Sending\n");
+ }
+ if (flags & CERTDB_VALID_CA) {
+ SECU_Indent(out, level);
+ fprintf(out, "Valid CA\n");
+ }
+ if (flags & CERTDB_TRUSTED_CA) {
+ SECU_Indent(out, level);
+ fprintf(out, "Trusted CA\n");
+ }
+ if (flags & CERTDB_NS_TRUSTED_CA) {
+ SECU_Indent(out, level);
+ fprintf(out, "Netscape Trusted CA\n");
+ }
+ if (flags & CERTDB_USER) {
+ SECU_Indent(out, level);
+ fprintf(out, "User\n");
+ }
+ if (flags & CERTDB_TRUSTED_CLIENT_CA) {
+ SECU_Indent(out, level);
+ fprintf(out, "Trusted Client CA\n");
+ }
+ if (flags & CERTDB_GOVT_APPROVED_CA) {
+ SECU_Indent(out, level);
+ fprintf(out, "Step-up\n");
+ }
+}
+
+void
+SECU_PrintTrustFlags(FILE *out, CERTCertTrust *trust, char *m, int level)
+{
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ SECU_Indent(out, level + 1);
+ fprintf(out, "SSL Flags:\n");
+ printFlags(out, trust->sslFlags, level + 2);
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Email Flags:\n");
+ printFlags(out, trust->emailFlags, level + 2);
+ SECU_Indent(out, level + 1);
+ fprintf(out, "Object Signing Flags:\n");
+ printFlags(out, trust->objectSigningFlags, level + 2);
+}
+
+int
+SECU_PrintDERName(FILE *out, SECItem *der, const char *m, int level)
+{
+ PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ CERTName *name;
+ int rv = SEC_ERROR_NO_MEMORY;
+
+ if (!arena)
+ return rv;
+
+ name = PORT_ArenaZNew(arena, CERTName);
+ if (!name)
+ goto loser;
+
+ rv = SEC_ASN1DecodeItem(arena, name, SEC_ASN1_GET(CERT_NameTemplate), der);
+ if (rv)
+ goto loser;
+
+ SECU_PrintName(out, name, m, level);
+ if (!SECU_GetWrapEnabled()) /*SECU_PrintName didn't add newline*/
+ SECU_Newline(out);
+loser:
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+typedef enum {
+ noSignature = 0,
+ withSignature = 1
+} SignatureOptionType;
+
+static int
+secu_PrintSignedDataSigOpt(FILE *out, SECItem *der, const char *m,
+ int level, SECU_PPFunc inner,
+ SignatureOptionType withSignature)
+{
+ PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ CERTSignedData *sd;
+ int rv = SEC_ERROR_NO_MEMORY;
+
+ if (!arena)
+ return rv;
+
+ /* Strip off the signature */
+ sd = PORT_ArenaZNew(arena, CERTSignedData);
+ if (!sd)
+ goto loser;
+
+ rv = SEC_ASN1DecodeItem(arena, sd, SEC_ASN1_GET(CERT_SignedDataTemplate),
+ der);
+ if (rv)
+ goto loser;
+
+ if (m) {
+ SECU_Indent(out, level);
+ fprintf(out, "%s:\n", m);
+ } else {
+ level -= 1;
+ }
+ rv = (*inner)(out, &sd->data, "Data", level + 1);
+
+ if (withSignature) {
+ SECU_PrintAlgorithmID(out, &sd->signatureAlgorithm, "Signature Algorithm",
+ level + 1);
+ DER_ConvertBitString(&sd->signature);
+ SECU_PrintAsHex(out, &sd->signature, "Signature", level + 1);
+ }
+ SECU_PrintFingerprints(out, der, "Fingerprint", level + 1);
+loser:
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+int
+SECU_PrintSignedData(FILE *out, SECItem *der, const char *m,
+ int level, SECU_PPFunc inner)
+{
+ return secu_PrintSignedDataSigOpt(out, der, m, level, inner,
+ withSignature);
+}
+
+int
+SECU_PrintSignedContent(FILE *out, SECItem *der, char *m,
+ int level, SECU_PPFunc inner)
+{
+ return secu_PrintSignedDataSigOpt(out, der, m, level, inner,
+ noSignature);
+}
+
+SECStatus
+SEC_PrintCertificateAndTrust(CERTCertificate *cert,
+ const char *label,
+ CERTCertTrust *trust)
+{
+ SECStatus rv;
+ SECItem data;
+ CERTCertTrust certTrust;
+ PK11SlotList *slotList;
+ PRBool falseAttributeFound = PR_FALSE;
+ PRBool trueAttributeFound = PR_FALSE;
+ const char *moz_policy_ca_info = NULL;
+
+ data.data = cert->derCert.data;
+ data.len = cert->derCert.len;
+
+ rv = SECU_PrintSignedData(stdout, &data, label, 0,
+ (SECU_PPFunc)SECU_PrintCertificate);
+ if (rv) {
+ return (SECFailure);
+ }
+
+ slotList = PK11_GetAllSlotsForCert(cert, NULL);
+ if (slotList) {
+ PK11SlotListElement *se = PK11_GetFirstSafe(slotList);
+ for (; se; se = PK11_GetNextSafe(slotList, se, PR_FALSE)) {
+ CK_OBJECT_HANDLE handle = PK11_FindCertInSlot(se->slot, cert, NULL);
+ if (handle != CK_INVALID_HANDLE) {
+ PORT_SetError(0);
+ if (PK11_HasAttributeSet(se->slot, handle,
+ CKA_NSS_MOZILLA_CA_POLICY, PR_FALSE)) {
+ trueAttributeFound = PR_TRUE;
+ } else if (!PORT_GetError()) {
+ falseAttributeFound = PR_TRUE;
+ }
+ }
+ }
+ PK11_FreeSlotList(slotList);
+ }
+
+ if (trueAttributeFound) {
+ moz_policy_ca_info = "true (attribute present)";
+ } else if (falseAttributeFound) {
+ moz_policy_ca_info = "false (attribute present)";
+ } else {
+ moz_policy_ca_info = "false (attribute missing)";
+ }
+ SECU_Indent(stdout, 1);
+ printf("Mozilla-CA-Policy: %s\n", moz_policy_ca_info);
+
+ if (trust) {
+ SECU_PrintTrustFlags(stdout, trust,
+ "Certificate Trust Flags", 1);
+ } else if (CERT_GetCertTrust(cert, &certTrust) == SECSuccess) {
+ SECU_PrintTrustFlags(stdout, &certTrust,
+ "Certificate Trust Flags", 1);
+ }
+
+ printf("\n");
+
+ return (SECSuccess);
+}
+
+static char *
+bestCertName(CERTCertificate *cert)
+{
+ if (cert->nickname) {
+ return cert->nickname;
+ }
+ if (cert->emailAddr && cert->emailAddr[0]) {
+ return cert->emailAddr;
+ }
+ return cert->subjectName;
+}
+
+void
+SECU_printCertProblemsOnDate(FILE *outfile, CERTCertDBHandle *handle,
+ CERTCertificate *cert, PRBool checksig,
+ SECCertificateUsage certUsage, void *pinArg, PRBool verbose,
+ PRTime datetime)
+{
+ CERTVerifyLog log;
+ CERTVerifyLogNode *node;
+
+ PRErrorCode err = PORT_GetError();
+
+ log.arena = PORT_NewArena(512);
+ log.head = log.tail = NULL;
+ log.count = 0;
+ CERT_VerifyCertificate(handle, cert, checksig, certUsage, datetime, pinArg, &log, NULL);
+
+ SECU_displayVerifyLog(outfile, &log, verbose);
+
+ for (node = log.head; node; node = node->next) {
+ if (node->cert)
+ CERT_DestroyCertificate(node->cert);
+ }
+ PORT_FreeArena(log.arena, PR_FALSE);
+
+ PORT_SetError(err); /* restore original error code */
+}
+
+void
+SECU_displayVerifyLog(FILE *outfile, CERTVerifyLog *log,
+ PRBool verbose)
+{
+ CERTVerifyLogNode *node = NULL;
+ unsigned int depth = (unsigned int)-1;
+ unsigned int flags = 0;
+ char *errstr = NULL;
+
+ if (log->count > 0) {
+ fprintf(outfile, "PROBLEM WITH THE CERT CHAIN:\n");
+ for (node = log->head; node; node = node->next) {
+ if (depth != node->depth) {
+ depth = node->depth;
+ fprintf(outfile, "CERT %d. %s %s:\n", depth,
+ bestCertName(node->cert),
+ depth ? "[Certificate Authority]" : "");
+ if (verbose) {
+ const char *emailAddr;
+ emailAddr = CERT_GetFirstEmailAddress(node->cert);
+ if (emailAddr) {
+ fprintf(outfile, "Email Address(es): ");
+ do {
+ fprintf(outfile, "%s\n", emailAddr);
+ emailAddr = CERT_GetNextEmailAddress(node->cert,
+ emailAddr);
+ } while (emailAddr);
+ }
+ }
+ }
+ fprintf(outfile, " ERROR %ld: %s\n", node->error,
+ SECU_Strerror(node->error));
+ errstr = NULL;
+ switch (node->error) {
+ case SEC_ERROR_INADEQUATE_KEY_USAGE:
+ flags = (unsigned int)((char *)node->arg - (char *)NULL);
+ switch (flags) {
+ case KU_DIGITAL_SIGNATURE:
+ errstr = "Cert cannot sign.";
+ break;
+ case KU_KEY_ENCIPHERMENT:
+ errstr = "Cert cannot encrypt.";
+ break;
+ case KU_KEY_CERT_SIGN:
+ errstr = "Cert cannot sign other certs.";
+ break;
+ default:
+ errstr = "[unknown usage].";
+ break;
+ }
+ break;
+ case SEC_ERROR_INADEQUATE_CERT_TYPE:
+ flags = (unsigned int)((char *)node->arg - (char *)NULL);
+ switch (flags) {
+ case NS_CERT_TYPE_SSL_CLIENT:
+ case NS_CERT_TYPE_SSL_SERVER:
+ errstr = "Cert cannot be used for SSL.";
+ break;
+ case NS_CERT_TYPE_SSL_CA:
+ errstr = "Cert cannot be used as an SSL CA.";
+ break;
+ case NS_CERT_TYPE_EMAIL:
+ errstr = "Cert cannot be used for SMIME.";
+ break;
+ case NS_CERT_TYPE_EMAIL_CA:
+ errstr = "Cert cannot be used as an SMIME CA.";
+ break;
+ case NS_CERT_TYPE_OBJECT_SIGNING:
+ errstr = "Cert cannot be used for object signing.";
+ break;
+ case NS_CERT_TYPE_OBJECT_SIGNING_CA:
+ errstr = "Cert cannot be used as an object signing CA.";
+ break;
+ default:
+ errstr = "[unknown usage].";
+ break;
+ }
+ break;
+ case SEC_ERROR_UNKNOWN_ISSUER:
+ case SEC_ERROR_UNTRUSTED_ISSUER:
+ case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
+ errstr = node->cert->issuerName;
+ break;
+ default:
+ break;
+ }
+ if (errstr) {
+ fprintf(stderr, " %s\n", errstr);
+ }
+ }
+ }
+}
+
+void
+SECU_printCertProblems(FILE *outfile, CERTCertDBHandle *handle,
+ CERTCertificate *cert, PRBool checksig,
+ SECCertificateUsage certUsage, void *pinArg, PRBool verbose)
+{
+ SECU_printCertProblemsOnDate(outfile, handle, cert, checksig,
+ certUsage, pinArg, verbose, PR_Now());
+}
+
+SECStatus
+SECU_StoreCRL(PK11SlotInfo *slot, SECItem *derCrl, PRFileDesc *outFile,
+ PRBool ascii, char *url)
+{
+ PORT_Assert(derCrl != NULL);
+ if (!derCrl) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ if (outFile != NULL) {
+ if (ascii) {
+ PR_fprintf(outFile, "%s\n%s\n%s\n", NS_CRL_HEADER,
+ BTOA_DataToAscii(derCrl->data, derCrl->len),
+ NS_CRL_TRAILER);
+ } else {
+ if (PR_Write(outFile, derCrl->data, derCrl->len) != derCrl->len) {
+ return SECFailure;
+ }
+ }
+ }
+ if (slot) {
+ CERTSignedCrl *newCrl = PK11_ImportCRL(slot, derCrl, url,
+ SEC_CRL_TYPE, NULL, 0, NULL, 0);
+ if (newCrl != NULL) {
+ SEC_DestroyCrl(newCrl);
+ return SECSuccess;
+ }
+ return SECFailure;
+ }
+ if (!outFile && !slot) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+SECStatus
+SECU_SignAndEncodeCRL(CERTCertificate *issuer, CERTSignedCrl *signCrl,
+ SECOidTag hashAlgTag, SignAndEncodeFuncExitStat *resCode)
+{
+ SECItem der;
+ SECKEYPrivateKey *caPrivateKey = NULL;
+ SECStatus rv;
+ PLArenaPool *arena;
+ SECOidTag algID;
+ void *dummy;
+
+ PORT_Assert(issuer != NULL && signCrl != NULL);
+ if (!issuer || !signCrl) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ arena = signCrl->arena;
+
+ caPrivateKey = PK11_FindKeyByAnyCert(issuer, NULL);
+ if (caPrivateKey == NULL) {
+ *resCode = noKeyFound;
+ return SECFailure;
+ }
+
+ algID = SEC_GetSignatureAlgorithmOidTag(caPrivateKey->keyType, hashAlgTag);
+ if (algID == SEC_OID_UNKNOWN) {
+ *resCode = noSignatureMatch;
+ rv = SECFailure;
+ goto done;
+ }
+
+ if (!signCrl->crl.signatureAlg.parameters.data) {
+ rv = SECOID_SetAlgorithmID(arena, &signCrl->crl.signatureAlg, algID, 0);
+ if (rv != SECSuccess) {
+ *resCode = failToEncode;
+ goto done;
+ }
+ }
+
+ der.len = 0;
+ der.data = NULL;
+ dummy = SEC_ASN1EncodeItem(arena, &der, &signCrl->crl,
+ SEC_ASN1_GET(CERT_CrlTemplate));
+ if (!dummy) {
+ *resCode = failToEncode;
+ rv = SECFailure;
+ goto done;
+ }
+
+ rv = SECU_DerSignDataCRL(arena, &signCrl->signatureWrap,
+ der.data, der.len, caPrivateKey, algID);
+ if (rv != SECSuccess) {
+ *resCode = failToSign;
+ goto done;
+ }
+
+ signCrl->derCrl = PORT_ArenaZNew(arena, SECItem);
+ if (signCrl->derCrl == NULL) {
+ *resCode = noMem;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ rv = SECFailure;
+ goto done;
+ }
+
+ signCrl->derCrl->len = 0;
+ signCrl->derCrl->data = NULL;
+ dummy = SEC_ASN1EncodeItem(arena, signCrl->derCrl, signCrl,
+ SEC_ASN1_GET(CERT_SignedCrlTemplate));
+ if (!dummy) {
+ *resCode = failToEncode;
+ rv = SECFailure;
+ goto done;
+ }
+
+done:
+ SECKEY_DestroyPrivateKey(caPrivateKey);
+ return rv;
+}
+
+SECStatus
+SECU_CopyCRL(PLArenaPool *destArena, CERTCrl *destCrl, CERTCrl *srcCrl)
+{
+ void *dummy;
+ SECStatus rv = SECSuccess;
+ SECItem der;
+
+ PORT_Assert(destArena && srcCrl && destCrl);
+ if (!destArena || !srcCrl || !destCrl) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ der.len = 0;
+ der.data = NULL;
+ dummy = SEC_ASN1EncodeItem(destArena, &der, srcCrl,
+ SEC_ASN1_GET(CERT_CrlTemplate));
+ if (!dummy) {
+ return SECFailure;
+ }
+
+ rv = SEC_QuickDERDecodeItem(destArena, destCrl,
+ SEC_ASN1_GET(CERT_CrlTemplate), &der);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ destCrl->arena = destArena;
+
+ return rv;
+}
+
+SECStatus
+SECU_DerSignDataCRL(PLArenaPool *arena, CERTSignedData *sd,
+ unsigned char *buf, int len, SECKEYPrivateKey *pk,
+ SECOidTag algID)
+{
+ SECItem it;
+ SECStatus rv;
+
+ it.data = 0;
+
+ /* XXX We should probably have some asserts here to make sure the key type
+ * and algID match
+ */
+
+ /* Sign input buffer */
+ rv = SEC_SignData(&it, buf, len, pk, algID);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ /* Fill out SignedData object */
+ PORT_Memset(sd, 0, sizeof(*sd));
+ sd->data.data = buf;
+ sd->data.len = len;
+ rv = SECITEM_CopyItem(arena, &sd->signature, &it);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ sd->signature.len <<= 3; /* convert to bit string */
+ rv = SECOID_SetAlgorithmID(arena, &sd->signatureAlgorithm, algID, 0);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+loser:
+ PORT_Free(it.data);
+ return rv;
+}
+
+#if 0
+
+/* we need access to the private function cert_FindExtension for this code to work */
+
+CERTAuthKeyID *
+SECU_FindCRLAuthKeyIDExten (PLArenaPool *arena, CERTSignedCrl *scrl)
+{
+ SECItem encodedExtenValue;
+ SECStatus rv;
+ CERTAuthKeyID *ret;
+ CERTCrl* crl;
+
+ if (!scrl) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
+ }
+
+ crl = &scrl->crl;
+
+ encodedExtenValue.data = NULL;
+ encodedExtenValue.len = 0;
+
+ rv = cert_FindExtension(crl->extensions, SEC_OID_X509_AUTH_KEY_ID,
+ &encodedExtenValue);
+ if ( rv != SECSuccess ) {
+ return (NULL);
+ }
+
+ ret = CERT_DecodeAuthKeyID (arena, &encodedExtenValue);
+
+ PORT_Free(encodedExtenValue.data);
+ encodedExtenValue.data = NULL;
+
+ return(ret);
+}
+
+#endif
+
+/*
+ * Find the issuer of a Crl. Use the authorityKeyID if it exists.
+ */
+CERTCertificate *
+SECU_FindCrlIssuer(CERTCertDBHandle *dbhandle, SECItem *subject,
+ CERTAuthKeyID *authorityKeyID, PRTime validTime)
+{
+ CERTCertificate *issuerCert = NULL;
+ CERTCertList *certList = NULL;
+ CERTCertTrust trust;
+
+ if (!subject) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
+ }
+
+ certList =
+ CERT_CreateSubjectCertList(NULL, dbhandle, subject,
+ validTime, PR_TRUE);
+ if (certList) {
+ CERTCertListNode *node = CERT_LIST_HEAD(certList);
+
+ /* XXX and authoritykeyid in the future */
+ while (!CERT_LIST_END(node, certList)) {
+ CERTCertificate *cert = node->cert;
+ /* check cert CERTCertTrust data is allocated, check cert
+ usage extension, check that cert has pkey in db. Select
+ the first (newest) user cert */
+ if (CERT_GetCertTrust(cert, &trust) == SECSuccess &&
+ CERT_CheckCertUsage(cert, KU_CRL_SIGN) == SECSuccess &&
+ CERT_IsUserCert(cert)) {
+
+ issuerCert = CERT_DupCertificate(cert);
+ break;
+ }
+ node = CERT_LIST_NEXT(node);
+ }
+ CERT_DestroyCertList(certList);
+ }
+ return (issuerCert);
+}
+
+/* Encodes and adds extensions to the CRL or CRL entries. */
+SECStatus
+SECU_EncodeAndAddExtensionValue(PLArenaPool *arena, void *extHandle,
+ void *value, PRBool criticality, int extenType,
+ EXTEN_EXT_VALUE_ENCODER EncodeValueFn)
+{
+ SECItem encodedValue;
+ SECStatus rv;
+
+ encodedValue.data = NULL;
+ encodedValue.len = 0;
+ do {
+ rv = (*EncodeValueFn)(arena, value, &encodedValue);
+ if (rv != SECSuccess)
+ break;
+
+ rv = CERT_AddExtension(extHandle, extenType, &encodedValue,
+ criticality, PR_TRUE);
+ if (rv != SECSuccess)
+ break;
+ } while (0);
+
+ return (rv);
+}
+
+CERTCertificate *
+SECU_FindCertByNicknameOrFilename(CERTCertDBHandle *handle,
+ char *name, PRBool ascii,
+ void *pwarg)
+{
+ CERTCertificate *the_cert;
+ the_cert = CERT_FindCertByNicknameOrEmailAddr(handle, name);
+ if (the_cert) {
+ return the_cert;
+ }
+ the_cert = PK11_FindCertFromNickname(name, pwarg);
+ if (!the_cert) {
+ /* Don't have a cert with name "name" in the DB. Try to
+ * open a file with such name and get the cert from there.*/
+ SECStatus rv;
+ SECItem item = { 0, NULL, 0 };
+ PRFileDesc *fd = PR_Open(name, PR_RDONLY, 0777);
+ if (!fd) {
+ return NULL;
+ }
+ rv = SECU_ReadDERFromFile(&item, fd, ascii, PR_FALSE);
+ PR_Close(fd);
+ if (rv != SECSuccess || !item.len) {
+ PORT_Free(item.data);
+ return NULL;
+ }
+ the_cert = CERT_NewTempCertificate(handle, &item,
+ NULL /* nickname */,
+ PR_FALSE /* isPerm */,
+ PR_TRUE /* copyDER */);
+ PORT_Free(item.data);
+ }
+ return the_cert;
+}
+
+/* Convert a SSL/TLS protocol version string into the respective numeric value
+ * defined by the SSL_LIBRARY_VERSION_* constants,
+ * while accepting a flexible set of case-insensitive identifiers.
+ *
+ * Caller must specify bufLen, allowing the function to operate on substrings.
+ */
+static SECStatus
+SECU_GetSSLVersionFromName(const char *buf, size_t bufLen, PRUint16 *version)
+{
+ if (!buf || !version) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ if (!PL_strncasecmp(buf, "ssl3", bufLen)) {
+ *version = SSL_LIBRARY_VERSION_3_0;
+ return SECSuccess;
+ }
+ if (!PL_strncasecmp(buf, "tls1.0", bufLen)) {
+ *version = SSL_LIBRARY_VERSION_TLS_1_0;
+ return SECSuccess;
+ }
+ if (!PL_strncasecmp(buf, "tls1.1", bufLen)) {
+ *version = SSL_LIBRARY_VERSION_TLS_1_1;
+ return SECSuccess;
+ }
+ if (!PL_strncasecmp(buf, "tls1.2", bufLen)) {
+ *version = SSL_LIBRARY_VERSION_TLS_1_2;
+ return SECSuccess;
+ }
+
+ if (!PL_strncasecmp(buf, "tls1.3", bufLen)) {
+ *version = SSL_LIBRARY_VERSION_TLS_1_3;
+ return SECSuccess;
+ }
+
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+}
+
+SECStatus
+SECU_ParseSSLVersionRangeString(const char *input,
+ const SSLVersionRange defaultVersionRange,
+ SSLVersionRange *vrange)
+{
+ const char *colonPos;
+ size_t colonIndex;
+ const char *maxStr;
+
+ if (!input || !vrange) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ // We don't support SSL2 any longer.
+ if (defaultVersionRange.min < SSL_LIBRARY_VERSION_3_0 ||
+ defaultVersionRange.max < SSL_LIBRARY_VERSION_3_0) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ if (!strcmp(input, ":")) {
+ /* special value, use default */
+ *vrange = defaultVersionRange;
+ return SECSuccess;
+ }
+
+ colonPos = strchr(input, ':');
+ if (!colonPos) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ colonIndex = colonPos - input;
+ maxStr = colonPos + 1;
+
+ if (!colonIndex) {
+ /* colon was first character, min version is empty */
+ vrange->min = defaultVersionRange.min;
+ } else {
+ PRUint16 version;
+ /* colonIndex is equivalent to the length of the min version substring */
+ if (SECU_GetSSLVersionFromName(input, colonIndex, &version) != SECSuccess) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ vrange->min = version;
+ }
+
+ if (!*maxStr) {
+ vrange->max = defaultVersionRange.max;
+ } else {
+ PRUint16 version;
+ /* if max version is empty, then maxStr points to the string terminator */
+ if (SECU_GetSSLVersionFromName(maxStr, strlen(maxStr), &version) !=
+ SECSuccess) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ vrange->max = version;
+ }
+
+ if (vrange->min > vrange->max) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ return SECSuccess;
+}
+
+SSLNamedGroup
+groupNameToNamedGroup(char *name)
+{
+ if (PL_strlen(name) == 4) {
+ if (!strncmp(name, "P256", 4)) {
+ return ssl_grp_ec_secp256r1;
+ }
+ if (!strncmp(name, "P384", 4)) {
+ return ssl_grp_ec_secp384r1;
+ }
+ if (!strncmp(name, "P521", 4)) {
+ return ssl_grp_ec_secp521r1;
+ }
+ }
+ if (PL_strlen(name) == 6) {
+ if (!strncmp(name, "x25519", 6)) {
+ return ssl_grp_ec_curve25519;
+ }
+ if (!strncmp(name, "FF2048", 6)) {
+ return ssl_grp_ffdhe_2048;
+ }
+ if (!strncmp(name, "FF3072", 6)) {
+ return ssl_grp_ffdhe_3072;
+ }
+ if (!strncmp(name, "FF4096", 6)) {
+ return ssl_grp_ffdhe_4096;
+ }
+ if (!strncmp(name, "FF6144", 6)) {
+ return ssl_grp_ffdhe_6144;
+ }
+ if (!strncmp(name, "FF8192", 6)) {
+ return ssl_grp_ffdhe_8192;
+ }
+ }
+
+ return ssl_grp_none;
+}
+
+SECStatus
+parseGroupList(const char *arg, SSLNamedGroup **enabledGroups,
+ unsigned int *enabledGroupsCount)
+{
+ SSLNamedGroup *groups;
+ char *str;
+ char *p;
+ unsigned int numValues = 0;
+ unsigned int count = 0;
+
+ /* Count the number of groups. */
+ str = PORT_Strdup(arg);
+ if (!str) {
+ return SECFailure;
+ }
+ p = strtok(str, ",");
+ while (p) {
+ ++numValues;
+ p = strtok(NULL, ",");
+ }
+ PORT_Free(str);
+ str = NULL;
+ groups = PORT_ZNewArray(SSLNamedGroup, numValues);
+ if (!groups) {
+ goto done;
+ }
+
+ /* Get group names. */
+ str = PORT_Strdup(arg);
+ if (!str) {
+ goto done;
+ }
+ p = strtok(str, ",");
+ while (p) {
+ SSLNamedGroup group = groupNameToNamedGroup(p);
+ if (group == ssl_grp_none) {
+ count = 0;
+ goto done;
+ }
+ groups[count++] = group;
+ p = strtok(NULL, ",");
+ }
+
+done:
+ if (str) {
+ PORT_Free(str);
+ }
+ if (!count) {
+ PORT_Free(groups);
+ return SECFailure;
+ }
+
+ *enabledGroupsCount = count;
+ *enabledGroups = groups;
+ return SECSuccess;
+}
diff --git a/nss/cmd/lib/secutil.h b/nss/cmd/lib/secutil.h
new file mode 100644
index 0000000..c121c55
--- /dev/null
+++ b/nss/cmd/lib/secutil.h
@@ -0,0 +1,436 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#ifndef _SEC_UTIL_H_
+#define _SEC_UTIL_H_
+
+#include "seccomon.h"
+#include "secitem.h"
+#include "secport.h"
+#include "prerror.h"
+#include "base64.h"
+#include "key.h"
+#include "secpkcs7.h"
+#include "secasn1.h"
+#include "secder.h"
+#include
+
+#include "basicutil.h"
+#include "sslerr.h"
+#include "sslt.h"
+
+#define SEC_CT_PRIVATE_KEY "private-key"
+#define SEC_CT_PUBLIC_KEY "public-key"
+#define SEC_CT_CERTIFICATE "certificate"
+#define SEC_CT_CERTIFICATE_REQUEST "certificate-request"
+#define SEC_CT_CERTIFICATE_ID "certificate-identity"
+#define SEC_CT_PKCS7 "pkcs7"
+#define SEC_CT_CRL "crl"
+#define SEC_CT_NAME "name"
+
+#define NS_CERTREQ_HEADER "-----BEGIN NEW CERTIFICATE REQUEST-----"
+#define NS_CERTREQ_TRAILER "-----END NEW CERTIFICATE REQUEST-----"
+
+#define NS_CERT_HEADER "-----BEGIN CERTIFICATE-----"
+#define NS_CERT_TRAILER "-----END CERTIFICATE-----"
+
+#define NS_CRL_HEADER "-----BEGIN CRL-----"
+#define NS_CRL_TRAILER "-----END CRL-----"
+
+#define SECU_Strerror PORT_ErrorToString
+
+typedef struct {
+ enum {
+ PW_NONE = 0,
+ PW_FROMFILE = 1,
+ PW_PLAINTEXT = 2,
+ PW_EXTERNAL = 3
+ } source;
+ char *data;
+} secuPWData;
+
+/*
+** Change a password on a token, or initialize a token with a password
+** if it does not already have one.
+** Use passwd to send the password in plaintext, pwFile to specify a
+** file containing the password, or NULL for both to prompt the user.
+*/
+SECStatus SECU_ChangePW(PK11SlotInfo *slot, char *passwd, char *pwFile);
+
+/*
+** Change a password on a token, or initialize a token with a password
+** if it does not already have one.
+** In this function, you can specify both the old and new passwords
+** as either a string or file. NOTE: any you don't specify will
+** be prompted for
+*/
+SECStatus SECU_ChangePW2(PK11SlotInfo *slot, char *oldPass, char *newPass,
+ char *oldPwFile, char *newPwFile);
+
+/* These were stolen from the old sec.h... */
+/*
+** Check a password for legitimacy. Passwords must be at least 8
+** characters long and contain one non-alphabetic. Return DSTrue if the
+** password is ok, DSFalse otherwise.
+*/
+extern PRBool SEC_CheckPassword(char *password);
+
+/*
+** Blind check of a password. Complement to SEC_CheckPassword which
+** ignores length and content type, just retuning DSTrue is the password
+** exists, DSFalse if NULL
+*/
+extern PRBool SEC_BlindCheckPassword(char *password);
+
+/*
+** Get a password.
+** First prompt with "msg" on "out", then read the password from "in".
+** The password is then checked using "chkpw".
+*/
+extern char *SEC_GetPassword(FILE *in, FILE *out, char *msg,
+ PRBool (*chkpw)(char *));
+
+char *SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg);
+
+char *SECU_GetPasswordString(void *arg, char *prompt);
+
+/*
+** Write a dongle password.
+** Uses MD5 to hash constant system data (hostname, etc.), and then
+** creates RC4 key to encrypt a password "pw" into a file "fd".
+*/
+extern SECStatus SEC_WriteDongleFile(int fd, char *pw);
+
+/*
+** Get a dongle password.
+** Uses MD5 to hash constant system data (hostname, etc.), and then
+** creates RC4 key to decrypt and return a password from file "fd".
+*/
+extern char *SEC_ReadDongleFile(int fd);
+
+/* End stolen headers */
+
+/* Just sticks the two strings together with a / if needed */
+char *SECU_AppendFilenameToDir(char *dir, char *filename);
+
+/* Returns result of PR_GetEnvSecure("SSL_DIR") or NULL */
+extern char *SECU_DefaultSSLDir(void);
+
+/*
+** Should be called once during initialization to set the default
+** directory for looking for cert.db, key.db, and cert-nameidx.db files
+** Removes trailing '/' in 'base'
+** If 'base' is NULL, defaults to set to .netscape in home directory.
+*/
+extern char *SECU_ConfigDirectory(const char *base);
+
+/*
+** Basic callback function for SSL_GetClientAuthDataHook
+*/
+extern int
+SECU_GetClientAuthData(void *arg, PRFileDesc *fd,
+ struct CERTDistNamesStr *caNames,
+ struct CERTCertificateStr **pRetCert,
+ struct SECKEYPrivateKeyStr **pRetKey);
+
+extern PRBool SECU_GetWrapEnabled(void);
+extern void SECU_EnableWrap(PRBool enable);
+
+extern PRBool SECU_GetUtf8DisplayEnabled(void);
+extern void SECU_EnableUtf8Display(PRBool enable);
+
+/* revalidate the cert and print information about cert verification
+ * failure at time == now */
+extern void
+SECU_printCertProblems(FILE *outfile, CERTCertDBHandle *handle,
+ CERTCertificate *cert, PRBool checksig,
+ SECCertificateUsage certUsage, void *pinArg, PRBool verbose);
+
+/* revalidate the cert and print information about cert verification
+ * failure at specified time */
+extern void
+SECU_printCertProblemsOnDate(FILE *outfile, CERTCertDBHandle *handle,
+ CERTCertificate *cert, PRBool checksig, SECCertificateUsage certUsage,
+ void *pinArg, PRBool verbose, PRTime datetime);
+
+/* print out CERTVerifyLog info. */
+extern void
+SECU_displayVerifyLog(FILE *outfile, CERTVerifyLog *log,
+ PRBool verbose);
+
+/* Read in a DER from a file, may be ascii */
+extern SECStatus
+SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii,
+ PRBool warnOnPrivateKeyInAsciiFile);
+
+/* Print integer value and hex */
+extern void SECU_PrintInteger(FILE *out, const SECItem *i, const char *m,
+ int level);
+
+/* Print ObjectIdentifier symbolically */
+extern SECOidTag SECU_PrintObjectID(FILE *out, const SECItem *oid,
+ const char *m, int level);
+
+/* Print AlgorithmIdentifier symbolically */
+extern void SECU_PrintAlgorithmID(FILE *out, SECAlgorithmID *a, char *m,
+ int level);
+
+/*
+ * Format and print the UTC Time "t". If the tag message "m" is not NULL,
+ * do indent formatting based on "level" and add a newline afterward;
+ * otherwise just print the formatted time string only.
+ */
+extern void SECU_PrintUTCTime(FILE *out, const SECItem *t, const char *m,
+ int level);
+
+/*
+ * Format and print the Generalized Time "t". If the tag message "m"
+ * is not NULL, * do indent formatting based on "level" and add a newline
+ * afterward; otherwise just print the formatted time string only.
+ */
+extern void SECU_PrintGeneralizedTime(FILE *out, const SECItem *t,
+ const char *m, int level);
+
+/*
+ * Format and print the UTC or Generalized Time "t". If the tag message
+ * "m" is not NULL, do indent formatting based on "level" and add a newline
+ * afterward; otherwise just print the formatted time string only.
+ */
+extern void SECU_PrintTimeChoice(FILE *out, const SECItem *t, const char *m,
+ int level);
+
+/* callback for listing certs through pkcs11 */
+extern SECStatus SECU_PrintCertNickname(CERTCertListNode *cert, void *data);
+
+/* Dump all certificate nicknames in a database */
+extern SECStatus
+SECU_PrintCertificateNames(CERTCertDBHandle *handle, PRFileDesc *out,
+ PRBool sortByName, PRBool sortByTrust);
+
+/* See if nickname already in database. Return 1 true, 0 false, -1 error */
+int SECU_CheckCertNameExists(CERTCertDBHandle *handle, char *nickname);
+
+/* Dump contents of cert req */
+extern int SECU_PrintCertificateRequest(FILE *out, SECItem *der, char *m,
+ int level);
+
+/* Dump contents of certificate */
+extern int SECU_PrintCertificate(FILE *out, const SECItem *der, const char *m,
+ int level);
+
+extern int SECU_PrintCertificateBasicInfo(FILE *out, const SECItem *der, const char *m,
+ int level);
+
+extern int SECU_PrintDumpDerIssuerAndSerial(FILE *out, SECItem *der, char *m,
+ int level);
+
+/* Dump contents of a DER certificate name (issuer or subject) */
+extern int SECU_PrintDERName(FILE *out, SECItem *der, const char *m, int level);
+
+/* print trust flags on a cert */
+extern void SECU_PrintTrustFlags(FILE *out, CERTCertTrust *trust, char *m,
+ int level);
+
+extern int SECU_PrintSubjectPublicKeyInfo(FILE *out, SECItem *der, char *m,
+ int level);
+
+#ifdef HAVE_EPV_TEMPLATE
+/* Dump contents of private key */
+extern int SECU_PrintPrivateKey(FILE *out, SECItem *der, char *m, int level);
+#endif
+
+/* Dump contents of an RSA public key */
+extern void SECU_PrintRSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level);
+
+/* Dump contents of a DSA public key */
+extern void SECU_PrintDSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level);
+
+/* Print the MD5 and SHA1 fingerprints of a cert */
+extern int SECU_PrintFingerprints(FILE *out, SECItem *derCert, char *m,
+ int level);
+
+/* Pretty-print any PKCS7 thing */
+extern int SECU_PrintPKCS7ContentInfo(FILE *out, SECItem *der, char *m,
+ int level);
+
+/* Init PKCS11 stuff */
+extern SECStatus SECU_PKCS11Init(PRBool readOnly);
+
+/* Dump contents of signed data */
+extern int SECU_PrintSignedData(FILE *out, SECItem *der, const char *m,
+ int level, SECU_PPFunc inner);
+
+/* Dump contents of signed data, excluding the signature */
+extern int SECU_PrintSignedContent(FILE *out, SECItem *der, char *m, int level,
+ SECU_PPFunc inner);
+
+/* Print cert data and its trust flags */
+extern SECStatus SEC_PrintCertificateAndTrust(CERTCertificate *cert,
+ const char *label,
+ CERTCertTrust *trust);
+
+extern int SECU_PrintCrl(FILE *out, SECItem *der, char *m, int level);
+
+extern void
+SECU_PrintCRLInfo(FILE *out, CERTCrl *crl, char *m, int level);
+
+extern void SECU_PrintString(FILE *out, const SECItem *si, const char *m,
+ int level);
+extern void SECU_PrintAny(FILE *out, const SECItem *i, const char *m, int level);
+
+extern void SECU_PrintPolicy(FILE *out, SECItem *value, char *msg, int level);
+extern void SECU_PrintPrivKeyUsagePeriodExtension(FILE *out, SECItem *value,
+ char *msg, int level);
+
+extern void SECU_PrintExtensions(FILE *out, CERTCertExtension **extensions,
+ char *msg, int level);
+
+extern void SECU_PrintNameQuotesOptional(FILE *out, CERTName *name,
+ const char *msg, int level,
+ PRBool quotes);
+extern void SECU_PrintName(FILE *out, CERTName *name, const char *msg,
+ int level);
+extern void SECU_PrintRDN(FILE *out, CERTRDN *rdn, const char *msg, int level);
+
+#ifdef SECU_GetPassword
+/* Convert a High public Key to a Low public Key */
+extern SECKEYLowPublicKey *SECU_ConvHighToLow(SECKEYPublicKey *pubHighKey);
+#endif
+
+extern char *SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg);
+
+extern SECStatus DER_PrettyPrint(FILE *out, const SECItem *it, PRBool raw);
+
+extern char *SECU_SECModDBName(void);
+
+/* Fetch and register an oid if it hasn't been done already */
+extern void SECU_cert_fetchOID(SECOidTag *data, const SECOidData *src);
+
+extern SECStatus SECU_RegisterDynamicOids(void);
+
+/* Identifies hash algorithm tag by its string representation. */
+extern SECOidTag SECU_StringToSignatureAlgTag(const char *alg);
+
+/* Store CRL in output file or pk11 db. Also
+ * encodes with base64 and exports to file if ascii flag is set
+ * and file is not NULL. */
+extern SECStatus SECU_StoreCRL(PK11SlotInfo *slot, SECItem *derCrl,
+ PRFileDesc *outFile, PRBool ascii, char *url);
+
+/*
+** DER sign a single block of data using private key encryption and the
+** MD5 hashing algorithm. This routine first computes a digital signature
+** using SEC_SignData, then wraps it with an CERTSignedData and then der
+** encodes the result.
+** "arena" is the memory arena to use to allocate data from
+** "sd" returned CERTSignedData
+** "result" the final der encoded data (memory is allocated)
+** "buf" the input data to sign
+** "len" the amount of data to sign
+** "pk" the private key to encrypt with
+*/
+extern SECStatus SECU_DerSignDataCRL(PLArenaPool *arena, CERTSignedData *sd,
+ unsigned char *buf, int len,
+ SECKEYPrivateKey *pk, SECOidTag algID);
+
+typedef enum {
+ noKeyFound = 1,
+ noSignatureMatch = 2,
+ failToEncode = 3,
+ failToSign = 4,
+ noMem = 5
+} SignAndEncodeFuncExitStat;
+
+extern SECStatus
+SECU_SignAndEncodeCRL(CERTCertificate *issuer, CERTSignedCrl *signCrl,
+ SECOidTag hashAlgTag, SignAndEncodeFuncExitStat *resCode);
+
+extern SECStatus
+SECU_CopyCRL(PLArenaPool *destArena, CERTCrl *destCrl, CERTCrl *srcCrl);
+
+/*
+** Finds the crl Authority Key Id extension. Returns NULL if no such extension
+** was found.
+*/
+CERTAuthKeyID *
+SECU_FindCRLAuthKeyIDExten(PLArenaPool *arena, CERTSignedCrl *crl);
+
+/*
+ * Find the issuer of a crl. Cert usage should be checked before signing a crl.
+ */
+CERTCertificate *
+SECU_FindCrlIssuer(CERTCertDBHandle *dbHandle, SECItem *subject,
+ CERTAuthKeyID *id, PRTime validTime);
+
+/* call back function used in encoding of an extension. Called from
+ * SECU_EncodeAndAddExtensionValue */
+typedef SECStatus (*EXTEN_EXT_VALUE_ENCODER)(PLArenaPool *extHandleArena,
+ void *value, SECItem *encodedValue);
+
+/* Encodes and adds extensions to the CRL or CRL entries. */
+SECStatus
+SECU_EncodeAndAddExtensionValue(PLArenaPool *arena, void *extHandle,
+ void *value, PRBool criticality, int extenType,
+ EXTEN_EXT_VALUE_ENCODER EncodeValueFn);
+
+/* Caller ensures that dst is at least item->len*2+1 bytes long */
+void
+SECU_SECItemToHex(const SECItem *item, char *dst);
+
+/* Requires 0x prefix. Case-insensitive. Will do in-place replacement if
+ * successful */
+SECStatus
+SECU_SECItemHexStringToBinary(SECItem *srcdest);
+
+/* Parse a version range string, with "min" and "max" version numbers,
+ * separated by colon (":"), and return the result in vr and v2.
+ *
+ * Both min and max values are optional.
+ * The following syntax is used to specify the enabled protocol versions:
+ * A string with only a max value is expected as ":{max}",
+ * and all implemented versions less than or equal to max will be enabled.
+ * A string with only a min value is expected as "{min}:",
+ * and all implemented versions greater than or equal to min will be enabled.
+ * A string consisting of a colon only means "all versions enabled".
+ *
+ * In order to avoid a link dependency from libsectool to libssl,
+ * the caller must provide the desired default values for the min/max values,
+ * by providing defaultVersionRange (which can be obtained from libssl by
+ * calling SSL_VersionRangeGetSupported).
+ */
+SECStatus
+SECU_ParseSSLVersionRangeString(const char *input,
+ const SSLVersionRange defaultVersionRange,
+ SSLVersionRange *vrange);
+/*
+** Read a hex string into a SecItem.
+*/
+extern SECItem *SECU_HexString2SECItem(PLArenaPool *arena, SECItem *item,
+ const char *str);
+
+SECStatus parseGroupList(const char *arg, SSLNamedGroup **enabledGroups,
+ unsigned int *enabledGroupsCount);
+SSLNamedGroup groupNameToNamedGroup(char *name);
+
+/*
+ *
+ * Error messaging
+ *
+ */
+
+void printflags(char *trusts, unsigned int flags);
+
+#if !defined(XP_UNIX) && !defined(XP_OS2)
+extern int ffs(unsigned int i);
+#endif
+
+/* Finds certificate by searching it in the DB or by examinig file
+ * in the local directory. */
+CERTCertificate *
+SECU_FindCertByNicknameOrFilename(CERTCertDBHandle *handle,
+ char *name, PRBool ascii,
+ void *pwarg);
+#include "secerr.h"
+#include "sslerr.h"
+
+#endif /* _SEC_UTIL_H_ */
diff --git a/nss/cmd/libpkix/Makefile b/nss/cmd/libpkix/Makefile
new file mode 100755
index 0000000..1de5ef2
--- /dev/null
+++ b/nss/cmd/libpkix/Makefile
@@ -0,0 +1,46 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platrules.mk
+
diff --git a/nss/cmd/libpkix/config.mk b/nss/cmd/libpkix/config.mk
new file mode 100644
index 0000000..672f6ff
--- /dev/null
+++ b/nss/cmd/libpkix/config.mk
@@ -0,0 +1,9 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+TARGETS = $(LIBRARY)
+SHARED_LIBRARY =
+IMPORT_LIBRARY =
+PROGRAM =
diff --git a/nss/cmd/libpkix/manifest.mn b/nss/cmd/libpkix/manifest.mn
new file mode 100755
index 0000000..4f232a5
--- /dev/null
+++ b/nss/cmd/libpkix/manifest.mn
@@ -0,0 +1,11 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+PKIX_DEPTH = .
+PLAT_DEPTH = $(PKIX_DEPTH)/..
+CORE_DEPTH = $(PKIX_DEPTH)/../..
+
+DIRS = testutil pkix_pl pkix sample_apps perf pkixutil \
+ $(NULL)
diff --git a/nss/cmd/libpkix/perf/Makefile b/nss/cmd/libpkix/perf/Makefile
new file mode 100755
index 0000000..b724102
--- /dev/null
+++ b/nss/cmd/libpkix/perf/Makefile
@@ -0,0 +1,46 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(PKIX_DEPTH)/config.mk
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platrules.mk
+
diff --git a/nss/cmd/libpkix/perf/libpkix_buildthreads.c b/nss/cmd/libpkix/perf/libpkix_buildthreads.c
new file mode 100644
index 0000000..4b8d438
--- /dev/null
+++ b/nss/cmd/libpkix/perf/libpkix_buildthreads.c
@@ -0,0 +1,337 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * libpkixBuildThreads.c
+ *
+ * libpkix Builder Performance Evaluation application (multi-threaded)
+ *
+ */
+
+#include
+#include
+
+#include "secutil.h"
+
+#include "nspr.h"
+#include "prtypes.h"
+#include "prtime.h"
+#include "prlong.h"
+
+#include "pk11func.h"
+#include "secasn1.h"
+#include "cert.h"
+#include "cryptohi.h"
+#include "secoid.h"
+#include "certdb.h"
+#include "nss.h"
+
+#include "pkix.h"
+#include "pkix_tools.h"
+#include "pkix_pl_cert.h"
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+#undef pkixTempResult
+#define PERF_DECREF(obj) \
+ { \
+ PKIX_Error *pkixTempResult = NULL; \
+ if (obj) { \
+ pkixTempResult = PKIX_PL_Object_DecRef((PKIX_PL_Object *)(obj), plContext); \
+ obj = NULL; \
+ } \
+ }
+
+static void finish(char *message, int code);
+
+typedef struct ThreadDataStr tData;
+
+struct ThreadDataStr {
+ CERTCertificate *anchor;
+ char *eecertName;
+ PRIntervalTime duration;
+ CERTCertDBHandle *handle;
+ PRUint32 iterations;
+};
+
+#define PKIX_LOGGER_ON 1
+
+#ifdef PKIX_LOGGER_ON
+
+char *logLevels[] = {
+ "None",
+ "Fatal Error",
+ "Error",
+ "Warning",
+ "Debug",
+ "Trace"
+};
+
+static PKIX_Error *
+loggerCallback(
+ PKIX_Logger *logger,
+ PKIX_PL_String *message,
+ PKIX_UInt32 logLevel,
+ PKIX_ERRORCLASS logComponent,
+ void *plContext)
+{
+ char *msg = NULL;
+ static int callCount = 0;
+
+ msg = PKIX_String2ASCII(message, plContext);
+ printf("Logging %s (%s): %s\n",
+ logLevels[logLevel],
+ PKIX_ERRORCLASSNAMES[logComponent],
+ msg);
+ PR_Free((void *)msg);
+
+ return (NULL);
+}
+
+#endif /* PKIX_LOGGER_ON */
+
+static void
+ThreadEntry(void *data)
+{
+ tData *tdata = (tData *)data;
+ PRIntervalTime duration = tdata->duration;
+ PRIntervalTime start = PR_IntervalNow();
+
+ PKIX_List *anchors = NULL;
+ PKIX_ProcessingParams *procParams = NULL;
+ PKIX_BuildResult *buildResult = NULL;
+ CERTCertificate *nsseecert;
+ PKIX_PL_Cert *eeCert = NULL;
+ PKIX_CertStore *certStore = NULL;
+ PKIX_List *certStores = NULL;
+ PKIX_ComCertSelParams *certSelParams = NULL;
+ PKIX_CertSelector *certSelector = NULL;
+ PKIX_PL_Date *nowDate = NULL;
+ void *state = NULL; /* only relevant with non-blocking I/O */
+ void *nbioContext = NULL; /* only relevant with non-blocking I/O */
+
+ PR_ASSERT(duration);
+ if (!duration) {
+ return;
+ }
+
+ do {
+
+ /* libpkix code */
+
+ /* keep more update time, testing cache */
+ PKIX_PL_Date_Create_UTCTime(NULL, &nowDate, plContext);
+
+ /* CertUsage is 0x10 and no NSS arena */
+ /* We haven't determined how we obtain the value of wincx */
+
+ nsseecert = CERT_FindCertByNicknameOrEmailAddr(tdata->handle,
+ tdata->eecertName);
+ if (!nsseecert)
+ finish("Unable to find eecert.\n", 1);
+
+ pkix_pl_Cert_CreateWithNSSCert(nsseecert, &eeCert, plContext);
+
+ PKIX_List_Create(&anchors, plContext);
+
+ /*
+ * This code is retired.
+ * pkix_pl_Cert_CreateWithNSSCert
+ * (tdata->anchor, &anchorCert, NULL);
+ * PKIX_TrustAnchor_CreateWithCert(anchorCert, &anchor, NULL);
+ * PKIX_List_AppendItem(anchors, (PKIX_PL_Object *)anchor, NULL);
+ */
+
+ PKIX_ProcessingParams_Create(anchors, &procParams, plContext);
+
+ PKIX_ProcessingParams_SetRevocationEnabled(procParams, PKIX_TRUE, plContext);
+
+ PKIX_ProcessingParams_SetDate(procParams, nowDate, plContext);
+
+ /* create CertSelector with target certificate in params */
+
+ PKIX_ComCertSelParams_Create(&certSelParams, plContext);
+
+ PKIX_ComCertSelParams_SetCertificate(certSelParams, eeCert, plContext);
+
+ PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext);
+
+ PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, certSelParams, plContext);
+
+ PKIX_ProcessingParams_SetTargetCertConstraints(procParams, certSelector, plContext);
+
+ PKIX_PL_Pk11CertStore_Create(&certStore, plContext);
+
+ PKIX_List_Create(&certStores, plContext);
+ PKIX_List_AppendItem(certStores, (PKIX_PL_Object *)certStore, plContext);
+ PKIX_ProcessingParams_SetCertStores(procParams, certStores, plContext);
+
+ PKIX_BuildChain(procParams,
+ &nbioContext,
+ &state,
+ &buildResult,
+ NULL,
+ plContext);
+
+ /*
+ * As long as we use only CertStores with blocking I/O, we
+ * know we must be done at this point.
+ */
+
+ if (!buildResult) {
+ (void)fprintf(stderr, "libpkix BuildChain failed.\n");
+ PORT_Assert(0);
+ return;
+ }
+
+ tdata->iterations++;
+
+ PERF_DECREF(nowDate);
+ PERF_DECREF(anchors);
+ PERF_DECREF(procParams);
+ PERF_DECREF(buildResult);
+ PERF_DECREF(certStore);
+ PERF_DECREF(certStores);
+ PERF_DECREF(certSelParams);
+ PERF_DECREF(certSelector);
+ PERF_DECREF(eeCert);
+
+ } while ((PR_IntervalNow() - start) < duration);
+}
+
+static void
+Test(
+ CERTCertificate *anchor,
+ char *eecertName,
+ PRIntervalTime duration,
+ CERTCertDBHandle *handle,
+ PRUint32 threads)
+{
+ tData data;
+ tData **alldata;
+ PRIntervalTime starttime, endtime, elapsed;
+ PRUint32 msecs;
+ float total = 0;
+ PRThread **pthreads = NULL;
+ PRUint32 i = 0;
+
+ data.duration = duration;
+ data.anchor = anchor;
+ data.eecertName = eecertName;
+ data.handle = handle;
+
+ data.iterations = 0;
+
+ starttime = PR_IntervalNow();
+ pthreads = (PRThread **)PR_Malloc(threads * sizeof(PRThread *));
+ alldata = (tData **)PR_Malloc(threads * sizeof(tData *));
+ for (i = 0; i < threads; i++) {
+ alldata[i] = (tData *)PR_Malloc(sizeof(tData));
+ *alldata[i] = data;
+ pthreads[i] =
+ PR_CreateThread(PR_USER_THREAD,
+ ThreadEntry,
+ (void *)alldata[i],
+ PR_PRIORITY_NORMAL,
+ PR_GLOBAL_THREAD,
+ PR_JOINABLE_THREAD,
+ 0);
+ }
+
+ for (i = 0; i < threads; i++) {
+ tData *args = alldata[i];
+ PR_JoinThread(pthreads[i]);
+ total += args->iterations;
+ PR_Free((void *)args);
+ }
+
+ PR_Free((void *)pthreads);
+ PR_Free((void *)alldata);
+ endtime = PR_IntervalNow();
+
+ endtime = PR_IntervalNow();
+ elapsed = endtime - starttime;
+ msecs = PR_IntervalToMilliseconds(elapsed);
+ total /= msecs;
+ total *= 1000;
+ (void)fprintf(stdout, "%f operations per second.\n", total);
+}
+
+static void
+finish(char *message, int code)
+{
+ (void)printf(message);
+ exit(code);
+}
+
+static void
+usage(char *progname)
+{
+ (void)printf("Usage : %s <-d certStoreDirectory> "
+ " \n\n",
+ progname);
+ finish("", 0);
+}
+
+int
+libpkix_buildthreads(int argc, char **argv)
+{
+ CERTCertDBHandle *handle = NULL;
+ CERTCertificate *eecert = NULL;
+ PRIntervalTime duration = PR_SecondsToInterval(1);
+ PRUint32 threads = 1;
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_UInt32 j = 0;
+ PKIX_Logger *logger = NULL;
+ void *wincx = NULL;
+
+ /* if (argc != 5) -- when TrustAnchor used to be on command line */
+ if (argc != 4) {
+ usage(argv[0]);
+ }
+ if (atoi(argv[1]) > 0) {
+ duration = PR_SecondsToInterval(atoi(argv[1]));
+ }
+ if (atoi(argv[2]) > 0) {
+ threads = atoi(argv[2]);
+ }
+
+ PKIX_PL_NssContext_Create(certificateUsageEmailSigner, PKIX_FALSE,
+ NULL, &plContext);
+
+ handle = CERT_GetDefaultCertDB();
+ PR_ASSERT(handle);
+
+#ifdef PKIX_LOGGER_ON
+
+ /* set logger to log trace and up */
+ PKIX_SetLoggers(NULL, plContext);
+ PKIX_Logger_Create(loggerCallback, NULL, &logger, plContext);
+ PKIX_Logger_SetMaxLoggingLevel(logger, PKIX_LOGGER_LEVEL_WARNING, plContext);
+ PKIX_AddLogger(logger, plContext);
+
+#endif /* PKIX_LOGGER_ON */
+
+ /*
+ * This code is retired
+ * anchor = CERT_FindCertByNicknameOrEmailAddr(handle, argv[3]);
+ * if (!anchor) finish("Unable to find anchor.\n", 1);
+ *
+ * eecert = CERT_FindCertByNicknameOrEmailAddr(handle, argv[4]);
+
+ * if (!eecert) finish("Unable to find eecert.\n", 1);
+ *
+ * Test(anchor, eecert, duration, threads);
+ */
+
+ Test(NULL, argv[3], duration, handle, threads);
+
+ PERF_DECREF(logger);
+
+ PKIX_Shutdown(plContext);
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/perf/manifest.mn b/nss/cmd/libpkix/perf/manifest.mn
new file mode 100755
index 0000000..005c96c
--- /dev/null
+++ b/nss/cmd/libpkix/perf/manifest.mn
@@ -0,0 +1,21 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+PKIX_DEPTH = ..
+PLAT_DEPTH = $(PKIX_DEPTH)/..
+CORE_DEPTH = $(PKIX_DEPTH)/../../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+CSRCS = libpkix_buildthreads.c \
+ nss_threads.c \
+ $(NULL)
+
+LIBRARY_NAME = pkixtoolperf
+
+SOURCE_LIB_DIR = $(PKIX_DEPTH)/$(OBJDIR)
+
+NO_MD_RELEASE = 1
diff --git a/nss/cmd/libpkix/perf/nss_threads.c b/nss/cmd/libpkix/perf/nss_threads.c
new file mode 100644
index 0000000..202f128
--- /dev/null
+++ b/nss/cmd/libpkix/perf/nss_threads.c
@@ -0,0 +1,158 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * nssThreads.c
+ *
+ * NSS Performance Evaluation application (multi-threaded)
+ *
+ */
+
+#include
+#include
+
+#include "secutil.h"
+
+#include "nspr.h"
+#include "prtypes.h"
+#include "prtime.h"
+#include "prlong.h"
+
+#include "pk11func.h"
+#include "secasn1.h"
+#include "cert.h"
+#include "cryptohi.h"
+#include "secoid.h"
+#include "certdb.h"
+#include "nss.h"
+
+typedef struct ThreadDataStr tData;
+
+struct ThreadDataStr {
+ CERTCertificate* cert;
+ PRIntervalTime duration;
+ PRUint32 iterations;
+};
+
+static void
+ThreadEntry(void* data)
+{
+ tData* tdata = (tData*)data;
+ PRIntervalTime duration = tdata->duration;
+ PRTime now = PR_Now();
+ PRIntervalTime start = PR_IntervalNow();
+
+ PR_ASSERT(duration);
+ if (!duration) {
+ return;
+ }
+ do {
+ SECStatus rv = CERT_VerifyCertificate(CERT_GetDefaultCertDB(),
+ tdata->cert,
+ PR_TRUE,
+ certificateUsageEmailSigner,
+ now,
+ NULL,
+ NULL,
+ NULL);
+ if (rv != SECSuccess) {
+ (void)fprintf(stderr, "Validation failed.\n");
+ PORT_Assert(0);
+ return;
+ }
+ tdata->iterations++;
+ } while ((PR_IntervalNow() - start) < duration);
+}
+
+static void
+Test(CERTCertificate* cert, PRIntervalTime duration, PRUint32 threads)
+{
+ tData data;
+ tData** alldata;
+ PRIntervalTime starttime, endtime, elapsed;
+ PRUint32 msecs;
+ float total = 0;
+ PRThread** pthreads = NULL;
+ PRUint32 i = 0;
+
+ data.duration = duration;
+ data.cert = cert;
+ data.iterations = 0;
+
+ starttime = PR_IntervalNow();
+ pthreads = (PRThread**)PR_Malloc(threads * sizeof(PRThread*));
+ alldata = (tData**)PR_Malloc(threads * sizeof(tData*));
+ for (i = 0; i < threads; i++) {
+ alldata[i] = (tData*)PR_Malloc(sizeof(tData));
+ *alldata[i] = data;
+ pthreads[i] =
+ PR_CreateThread(PR_USER_THREAD,
+ ThreadEntry,
+ (void*)alldata[i],
+ PR_PRIORITY_NORMAL,
+ PR_GLOBAL_THREAD,
+ PR_JOINABLE_THREAD,
+ 0);
+ }
+ for (i = 0; i < threads; i++) {
+ tData* args = alldata[i];
+ PR_JoinThread(pthreads[i]);
+ total += args->iterations;
+ PR_Free((void*)args);
+ }
+ PR_Free((void*)pthreads);
+ PR_Free((void*)alldata);
+ endtime = PR_IntervalNow();
+
+ endtime = PR_IntervalNow();
+ elapsed = endtime - starttime;
+ msecs = PR_IntervalToMilliseconds(elapsed);
+ total /= msecs;
+ total *= 1000;
+ (void)fprintf(stdout, "%f operations per second.\n", total);
+}
+
+static void
+finish(char* message, int code)
+{
+ (void)printf(message);
+ exit(code);
+}
+
+static void
+usage(char* progname)
+{
+ (void)printf("Usage : %s \n\n",
+ progname);
+ finish("", 0);
+}
+
+int
+nss_threads(int argc, char** argv)
+{
+ SECStatus rv = SECSuccess;
+ CERTCertDBHandle* handle = NULL;
+ CERTCertificate* cert = NULL;
+ PRIntervalTime duration = PR_SecondsToInterval(1);
+ PRUint32 threads = 1;
+ if (argc != 4) {
+ usage(argv[0]);
+ }
+ if (atoi(argv[1]) > 0) {
+ duration = PR_SecondsToInterval(atoi(argv[1]));
+ }
+ if (atoi(argv[2]) > 0) {
+ threads = atoi(argv[2]);
+ }
+
+ handle = CERT_GetDefaultCertDB();
+ PR_ASSERT(handle);
+ cert = CERT_FindCertByNicknameOrEmailAddr(handle, argv[3]);
+ if (!cert) {
+ finish("Unable to find certificate.\n", 1);
+ }
+ Test(cert, duration, threads);
+
+ CERT_DestroyCertificate(cert);
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/Makefile b/nss/cmd/libpkix/pkix/Makefile
new file mode 100755
index 0000000..ab4ffbd
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/Makefile
@@ -0,0 +1,48 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(PKIX_DEPTH)/config.mk
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platrules.mk
+
diff --git a/nss/cmd/libpkix/pkix/certsel/Makefile b/nss/cmd/libpkix/pkix/certsel/Makefile
new file mode 100755
index 0000000..09ca5f1
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/certsel/Makefile
@@ -0,0 +1,47 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(PKIX_DEPTH)/config.mk
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platrules.mk
diff --git a/nss/cmd/libpkix/pkix/certsel/manifest.mn b/nss/cmd/libpkix/pkix/certsel/manifest.mn
new file mode 100755
index 0000000..2e8198c
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/certsel/manifest.mn
@@ -0,0 +1,21 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+PKIX_DEPTH = ../..
+PLAT_DEPTH = $(PKIX_DEPTH)/..
+CORE_DEPTH = $(PKIX_DEPTH)/../../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+CSRCS = test_certselector.c \
+ test_comcertselparams.c \
+ $(NULL)
+
+LIBRARY_NAME=pkixtoolcertsel
+
+SOURCE_LIB_DIR=$(PKIX_DEPTH)/$(OBJDIR)
+
+NO_MD_RELEASE = 1
diff --git a/nss/cmd/libpkix/pkix/certsel/test_certselector.c b/nss/cmd/libpkix/pkix/certsel/test_certselector.c
new file mode 100644
index 0000000..cbe7737
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/certsel/test_certselector.c
@@ -0,0 +1,1683 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_certselector.c
+ *
+ * Test Cert Selector
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+#define PKIX_TEST_CERTSELECTOR_KEYUSAGE_NUM_CERTS 5
+#define PKIX_TEST_CERTSELECTOR_EXTKEYUSAGE_NUM_CERTS 2
+#define PKIX_TEST_CERTSELECTOR_CERTVALID_NUM_CERTS 2
+#define PKIX_TEST_CERTSELECTOR_ISSUER_NUM_CERTS 4
+#define PKIX_TEST_CERTSELECTOR_SERIALNUMBER_NUM_CERTS 1
+
+static void *plContext = NULL;
+
+/*
+ * The first three certs are used to obtain policies to test
+ * policy matching. Changing the table could break tests.
+ */
+static char *certList[] = {
+#define POLICY1CERT 0
+ "GoodCACert.crt",
+#define ANYPOLICYCERT 1
+ "anyPolicyCACert.crt",
+#define POLICY2CERT 2
+ "PoliciesP12CACert.crt",
+#define SUBJECTCERT 3
+ "PoliciesP3CACert.crt",
+ "PoliciesP1234CACert.crt",
+ "pathLenConstraint0CACert.crt",
+ "pathLenConstraint1CACert.crt",
+ "pathLenConstraint6CACert.crt",
+ "TrustAnchorRootCertificate.crt",
+ "GoodsubCACert.crt",
+ "AnyPolicyTest14EE.crt",
+ "UserNoticeQualifierTest16EE.crt"
+};
+#define NUMCERTS (sizeof(certList) / sizeof(certList[0]))
+
+/*
+ * Following are Certs values for NameConstraints tests
+ *
+ * Cert0:nameConstraintsDN1subCA1Cert.crt:
+ * Subject:CN=nameConstraints DN1 subCA1,OU=permittedSubtree1,
+ * O=Test Certificates,C=US
+ * Permitted Name:(OU=permittedSubtree2,OU=permittedSubtree1,
+ * O=Test Certificates,C=US)
+ * Excluded Name: (EMPTY)
+ * Cert1:nameConstraintsDN3subCA2Cert.crt:
+ * Subject:CN=nameConstraints DN3 subCA2,O=Test Certificates,C=US
+ * Permitted Name:(O=Test Certificates,C=US)
+ * Excluded Name:(EMPTY)
+ * Cert2:nameConstraintsDN2CACert.crt
+ * Subject:CN=nameConstraints DN2 CA,O=Test Certificates,C=US
+ * Permitted Name:(OU=permittedSubtree1,O=Test Certificates,C=US,
+ * OU=permittedSubtree2,O=Test Certificates,C=US)
+ * Excluded Name:(EMPTY)
+ * Cert3:nameConstraintsDN3subCA1Cert.crt
+ * Subject:CN=nameConstraints DN3 subCA1,O=Test Certificates,C=US
+ * Permitted Name:(EMPTY)
+ * Excluded Name:(OU=excludedSubtree2,O=Test Certificates,C=US)
+ * Cert4:nameConstraintsDN4CACert.crt
+ * Subject:CN=nameConstraints DN4 CA,O=Test Certificates,C=US
+ * Permitted Name:(EMPTY)
+ * Excluded Name:(OU=excludedSubtree1,O=Test Certificates,C=US,
+ * OU=excludedSubtree2,O=Test Certificates,C=US)
+ * Cert5:nameConstraintsDN5CACert.crt
+ * Subject:CN=nameConstraints DN5 CA,O=Test Certificates,C=US
+ * Permitted Name:(OU=permittedSubtree1,O=Test Certificates,C=US)
+ * Excluded Name:(OU=excludedSubtree1,OU=permittedSubtree1,
+ * O=Test Certificates,C=US)
+ * Cert6:ValidDNnameConstraintsTest1EE.crt
+ * Subject:CN=Valid DN nameConstraints EE Certificate Test1,
+ * OU=permittedSubtree1,O=Test Certificates,C=US
+ *
+ */
+static char *ncCertList[] = {
+ "nameConstraintsDN1subCA1Cert.crt",
+ "nameConstraintsDN3subCA2Cert.crt",
+ "nameConstraintsDN2CACert.crt",
+ "nameConstraintsDN3subCA1Cert.crt",
+ "nameConstraintsDN4CACert.crt",
+ "nameConstraintsDN5CACert.crt",
+ "ValidDNnameConstraintsTest1EE.crt"
+};
+#define NUMNCCERTS (sizeof(ncCertList) / sizeof(ncCertList[0]))
+
+static char *sanCertList[] = {
+ "InvalidDNnameConstraintsTest3EE.crt",
+ "InvalidDNSnameConstraintsTest38EE.crt"
+};
+#define NUMSANCERTS (sizeof(sanCertList) / sizeof(sanCertList[0]))
+
+/*
+ * This function calls the CertSelector pointed to by "selector" for each
+ * cert in the List pointed to by "certs", and compares the results against
+ * the bit array given by the UInt32 "expectedResults". If the first cert is
+ * expected to pass, the lower-order bit of "expectedResults" should be 1.
+ * If the second cert is expected to pass, the second bit of "expectedResults"
+ * should be 1, and so on. If more than 32 certs are provided, only the first
+ * 32 will be checked. It is not an error to provide more bits than needed.
+ * (For example, if you expect every cert to pass, "expectedResult" can be
+ * set to 0xFFFFFFFF, even if the chain has fewer than 32 certs.)
+ */
+static void
+testSelector(
+ PKIX_CertSelector *selector,
+ PKIX_List *certs,
+ PKIX_UInt32 expectedResults)
+{
+ PKIX_UInt32 i = 0;
+ PKIX_UInt32 numCerts = 0;
+ PKIX_PL_Cert *cert = NULL;
+ PKIX_CertSelector_MatchCallback callback = NULL;
+ PKIX_Error *errReturn = NULL;
+ PKIX_Boolean result = PKIX_TRUE;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_GetMatchCallback(selector, &callback, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certs, &numCerts, plContext));
+ if (numCerts > 32) {
+ numCerts = 32;
+ }
+
+ for (i = 0; i < numCerts; i++) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certs, i, (PKIX_PL_Object **)&cert, plContext));
+ errReturn = callback(selector, cert, &result, plContext);
+
+ if (errReturn || result == PKIX_FALSE) {
+ if ((expectedResults & 1) == 1) {
+ testError("selector unexpectedly failed");
+ (void)printf(" processing cert:\t%d\n", i);
+ }
+ } else {
+ if ((expectedResults & 1) == 0) {
+ testError("selector unexpectedly passed");
+ (void)printf(" processing cert:\t%d\n", i);
+ }
+ }
+
+ expectedResults = expectedResults >> 1;
+ PKIX_TEST_DECREF_BC(cert);
+ PKIX_TEST_DECREF_BC(errReturn);
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(cert);
+ PKIX_TEST_DECREF_AC(errReturn);
+
+ PKIX_TEST_RETURN();
+}
+
+/*
+ * This function gets a policy from the Cert pointed to by "cert", according
+ * to the index provided by "index", creates an immutable List containing the
+ * OID of that policy, and stores the result at "pPolicyList".
+ */
+static void
+testGetPolicyFromCert(
+ PKIX_PL_Cert *cert,
+ PKIX_UInt32 index,
+ PKIX_List **pPolicyList)
+{
+ PKIX_List *policyInfo = NULL;
+ PKIX_PL_CertPolicyInfo *firstPolicy = NULL;
+ PKIX_PL_OID *policyOID = NULL;
+ PKIX_List *list = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetPolicyInformation(cert, &policyInfo, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(policyInfo,
+ index,
+ (PKIX_PL_Object **)&firstPolicy,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CertPolicyInfo_GetPolicyId(firstPolicy, &policyOID, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&list, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(list, (PKIX_PL_Object *)policyOID, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetImmutable(list, plContext));
+
+ *pPolicyList = list;
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(policyInfo);
+ PKIX_TEST_DECREF_AC(firstPolicy);
+ PKIX_TEST_DECREF_AC(policyOID);
+
+ PKIX_TEST_RETURN();
+}
+
+/*
+ * This custom matchCallback will pass any Certificate which has no
+ * CertificatePolicies extension and any Certificate whose Policies
+ * extension include a CertPolicyQualifier.
+ */
+static PKIX_Error *
+custom_CertSelector_MatchCallback(
+ PKIX_CertSelector *selector,
+ PKIX_PL_Cert *cert,
+ PKIX_Boolean *pResult,
+ void *plContext)
+{
+ PKIX_UInt32 i = 0;
+ PKIX_UInt32 numPolicies = 0;
+ PKIX_List *certPolicies = NULL;
+ PKIX_List *quals = NULL;
+ PKIX_PL_CertPolicyInfo *policy = NULL;
+ PKIX_Error *error = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ *pResult = PKIX_TRUE;
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetPolicyInformation(cert, &certPolicies, plContext));
+
+ if (certPolicies) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certPolicies, &numPolicies, plContext));
+
+ for (i = 0; i < numPolicies; i++) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certPolicies,
+ i,
+ (PKIX_PL_Object **)&policy,
+ plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CertPolicyInfo_GetPolQualifiers(policy, &quals, plContext));
+ if (quals) {
+ goto cleanup;
+ }
+ PKIX_TEST_DECREF_BC(policy);
+ }
+ PKIX_TEST_DECREF_BC(certPolicies);
+ *pResult = PKIX_FALSE;
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Error_Create(PKIX_CERTSELECTOR_ERROR,
+ NULL,
+ NULL,
+ PKIX_TESTPOLICYEXTWITHNOPOLICYQUALIFIERS,
+ &error,
+ plContext));
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(certPolicies);
+ PKIX_TEST_DECREF_AC(policy);
+ PKIX_TEST_DECREF_AC(quals);
+
+ return (error);
+}
+
+/*
+ * This custom matchCallback will pass any Certificate whose
+ * CertificatePolicies extension asserts the Policy specified by
+ * the OID in the CertSelectorContext object.
+ */
+static PKIX_Error *
+custom_CertSelector_MatchOIDCallback(
+ PKIX_CertSelector *selector,
+ PKIX_PL_Cert *cert,
+ PKIX_Boolean *pResult,
+ void *plContext)
+{
+ PKIX_UInt32 i = 0;
+ PKIX_UInt32 numPolicies = 0;
+ PKIX_Boolean match = PKIX_FALSE;
+ PKIX_PL_Object *certSelectorContext = NULL;
+ PKIX_PL_OID *constraintOID = NULL;
+ PKIX_List *certPolicies = NULL;
+ PKIX_PL_CertPolicyInfo *policy = NULL;
+ PKIX_PL_OID *policyOID = NULL;
+ PKIX_PL_String *errorDesc = NULL;
+ PKIX_Error *error = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ *pResult = PKIX_TRUE;
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_GetCertSelectorContext(selector, &certSelectorContext, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_CheckType(certSelectorContext, PKIX_OID_TYPE, plContext));
+
+ constraintOID = (PKIX_PL_OID *)certSelectorContext;
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetPolicyInformation(cert, &certPolicies, plContext));
+
+ if (certPolicies) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certPolicies, &numPolicies, plContext));
+
+ for (i = 0; i < numPolicies; i++) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certPolicies,
+ i,
+ (PKIX_PL_Object **)&policy,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CertPolicyInfo_GetPolicyId(policy, &policyOID, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)policyOID,
+ (PKIX_PL_Object *)constraintOID,
+ &match,
+ plContext));
+
+ if (match) {
+ goto cleanup;
+ }
+ PKIX_TEST_DECREF_BC(policy);
+ PKIX_TEST_DECREF_BC(policyOID);
+ }
+ }
+
+ PKIX_TEST_DECREF_BC(certSelectorContext);
+ PKIX_TEST_DECREF_BC(certPolicies);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Error_Create(PKIX_CERTSELECTOR_ERROR,
+ NULL,
+ NULL,
+ PKIX_TESTNOMATCHINGPOLICY,
+ &error,
+ plContext));
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(certSelectorContext);
+ PKIX_TEST_DECREF_AC(certPolicies);
+ PKIX_TEST_DECREF_AC(policy);
+ PKIX_TEST_DECREF_AC(policyOID);
+ PKIX_TEST_DECREF_AC(errorDesc);
+
+ return (error);
+}
+
+static void
+testSubjectMatch(
+ PKIX_List *certs,
+ PKIX_PL_Cert *certNameToMatch)
+{
+ PKIX_CertSelector *selector = NULL;
+ PKIX_ComCertSelParams *subjParams = NULL;
+ PKIX_PL_X500Name *subjectName = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("Subject name match");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &selector, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&subjParams, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetSubject(certNameToMatch, &subjectName, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetSubject(subjParams, subjectName, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, subjParams, plContext));
+ testSelector(selector, certs, 0x008);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(selector);
+ PKIX_TEST_DECREF_AC(subjParams);
+ PKIX_TEST_DECREF_AC(subjectName);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testBasicConstraintsMatch(
+ PKIX_List *certs)
+{
+ PKIX_CertSelector *selector = NULL;
+ PKIX_ComCertSelParams *bcParams = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("Basic Constraints match");
+ subTest(" pathLenContraint = -2: pass only EE's");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &selector, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&bcParams, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetBasicConstraints(bcParams, -2, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, bcParams, plContext));
+ testSelector(selector, certs, 0xC00);
+
+ subTest(" pathLenContraint = -1: pass all certs");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetBasicConstraints(bcParams, -1, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, bcParams, plContext));
+ testSelector(selector, certs, 0xFFF);
+
+ subTest(" pathLenContraint = 1: pass only certs with pathLen >= 1");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetBasicConstraints(bcParams, 1, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, bcParams, plContext));
+ testSelector(selector, certs, 0x3DF);
+
+ subTest(" pathLenContraint = 2: pass only certs with pathLen >= 2");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetBasicConstraints(bcParams, 2, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, bcParams, plContext));
+ testSelector(selector, certs, 0x39F);
+
+cleanup:
+ PKIX_TEST_DECREF_AC(selector);
+ PKIX_TEST_DECREF_AC(bcParams);
+
+ PKIX_TEST_RETURN();
+}
+
+static void testPolicyMatch(
+ PKIX_List *certs,
+ PKIX_PL_Cert *NIST1Cert, /* a source for policy NIST1 */
+ PKIX_PL_Cert *NIST2Cert, /* a source for policy NIST2 */
+ PKIX_PL_Cert *anyPolicyCert) /* a source for policy anyPolicy */
+{
+ PKIX_CertSelector *selector = NULL;
+ PKIX_List *emptyList = NULL; /* no members */
+ PKIX_List *policy1List = NULL; /* OIDs */
+ PKIX_List *policy2List = NULL; /* OIDs */
+ PKIX_List *anyPolicyList = NULL; /* OIDs */
+ PKIX_ComCertSelParams *polParams = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("Policy match");
+ testGetPolicyFromCert(NIST1Cert, 0, &policy1List);
+ testGetPolicyFromCert(NIST2Cert, 1, &policy2List);
+ testGetPolicyFromCert(anyPolicyCert, 0, &anyPolicyList);
+
+ subTest(" Pass certs with any CertificatePolicies extension");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&emptyList, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&polParams, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetPolicy(polParams, emptyList, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &selector, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, polParams, plContext));
+ testSelector(selector, certs, 0xEFF);
+ PKIX_TEST_DECREF_BC(polParams);
+
+ subTest(" Pass only certs with policy NIST1");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&polParams, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetPolicy(polParams, policy1List, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, polParams, plContext));
+ testSelector(selector, certs, 0xEF5);
+ PKIX_TEST_DECREF_BC(polParams);
+
+ subTest(" Pass only certs with policy NIST2");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&polParams, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetPolicy(polParams, policy2List, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, polParams, plContext));
+ testSelector(selector, certs, 0x814);
+ PKIX_TEST_DECREF_BC(polParams);
+
+ subTest(" Pass only certs with policy anyPolicy");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&polParams, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetPolicy(polParams, anyPolicyList, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, polParams, plContext));
+ testSelector(selector, certs, 0x002);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(selector);
+ PKIX_TEST_DECREF_AC(emptyList);
+ PKIX_TEST_DECREF_AC(policy1List);
+ PKIX_TEST_DECREF_AC(policy2List);
+ PKIX_TEST_DECREF_AC(anyPolicyList);
+ PKIX_TEST_DECREF_AC(polParams);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testCertificateMatch(
+ PKIX_List *certs,
+ PKIX_PL_Cert *certToMatch)
+{
+ PKIX_CertSelector *selector = NULL;
+ PKIX_ComCertSelParams *params = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("Certificate match");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &selector, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(¶ms, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetCertificate(params, certToMatch, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, params, plContext));
+ testSelector(selector, certs, 0x008);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(selector);
+ PKIX_TEST_DECREF_AC(params);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testNameConstraintsMatch(PKIX_List *certs)
+{
+ PKIX_CertSelector *selector = NULL;
+ PKIX_ComCertSelParams *params = NULL;
+ PKIX_PL_Cert *cert = NULL;
+ PKIX_PL_CertNameConstraints *permitNameConstraints1 = NULL;
+ PKIX_PL_CertNameConstraints *permitNameConstraints2 = NULL;
+ PKIX_PL_CertNameConstraints *permitNameConstraints3 = NULL;
+ PKIX_PL_CertNameConstraints *excludeNameConstraints1 = NULL;
+ PKIX_PL_CertNameConstraints *excludeNameConstraints2 = NULL;
+ PKIX_PL_CertNameConstraints *excludeNameConstraints3 = NULL;
+ PKIX_UInt32 numCerts = 0;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("test NameConstraints Cert Selector");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certs, &numCerts, plContext));
+
+ subTest(" PKIX_PL_Cert_GetNameConstraints ");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certs, 0, (PKIX_PL_Object **)&cert, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetNameConstraints(cert, &permitNameConstraints1, plContext));
+ PKIX_TEST_DECREF_BC(cert);
+
+ subTest(" PKIX_PL_Cert_GetNameConstraints ");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certs, 1, (PKIX_PL_Object **)&cert, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetNameConstraints(cert, &permitNameConstraints2, plContext));
+ PKIX_TEST_DECREF_BC(cert);
+
+ subTest(" PKIX_PL_Cert_GetNameConstraints ");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certs, 2, (PKIX_PL_Object **)&cert, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetNameConstraints(cert, &permitNameConstraints3, plContext));
+ PKIX_TEST_DECREF_BC(cert);
+
+ subTest(" PKIX_PL_Cert_GetNameConstraints ");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certs, 3, (PKIX_PL_Object **)&cert, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetNameConstraints(cert, &excludeNameConstraints1, plContext));
+ PKIX_TEST_DECREF_BC(cert);
+
+ subTest(" PKIX_PL_Cert_GetNameConstraints ");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certs, 4, (PKIX_PL_Object **)&cert, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetNameConstraints(cert, &excludeNameConstraints2, plContext));
+ PKIX_TEST_DECREF_BC(cert);
+
+ subTest(" PKIX_PL_Cert_GetNameConstraints ");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certs, 5, (PKIX_PL_Object **)&cert, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetNameConstraints(cert, &excludeNameConstraints3, plContext));
+ PKIX_TEST_DECREF_BC(cert);
+
+ subTest(" Create Selector and ComCertSelParams");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &selector, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(¶ms, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, params, plContext));
+
+ subTest(" CertNameConstraints testing permitted NONE");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetNameConstraints(params, permitNameConstraints1, plContext));
+ testSelector(selector, certs, 0x0);
+
+ subTest(" PKIX_ComCertSelParams_SetNameConstraint Reset");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetNameConstraints(params, NULL, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, params, plContext));
+
+ subTest(" CertNameConstraints testing permitted ALL");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetNameConstraints(params, permitNameConstraints2, plContext));
+ testSelector(selector, certs, 0x07F);
+
+ subTest(" CertNameConstraints testing permitted TWO");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetNameConstraints(params, permitNameConstraints3, plContext));
+ testSelector(selector, certs, 0x0041);
+
+ subTest(" PKIX_ComCertSelParams_SetNameConstraint Reset");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetNameConstraints(params, NULL, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, params, plContext));
+
+ subTest(" CertNameConstraints testing excluded");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetNameConstraints(params, excludeNameConstraints1, plContext));
+ testSelector(selector, certs, 0x07F);
+
+ subTest(" CertNameConstraints testing excluded");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetNameConstraints(params, excludeNameConstraints2, plContext));
+ testSelector(selector, certs, 0x07F);
+
+ subTest(" CertNameConstraints testing excluded");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetNameConstraints(params, excludeNameConstraints3, plContext));
+ testSelector(selector, certs, 0x41);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(selector);
+ PKIX_TEST_DECREF_AC(params);
+ PKIX_TEST_DECREF_AC(permitNameConstraints1);
+ PKIX_TEST_DECREF_AC(permitNameConstraints2);
+ PKIX_TEST_DECREF_AC(permitNameConstraints3);
+ PKIX_TEST_DECREF_AC(excludeNameConstraints1);
+ PKIX_TEST_DECREF_AC(excludeNameConstraints2);
+ PKIX_TEST_DECREF_AC(excludeNameConstraints3);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testPathToNamesMatch(PKIX_List *certs)
+{
+ PKIX_CertSelector *selector = NULL;
+ PKIX_ComCertSelParams *params = NULL;
+ PKIX_List *nameList = NULL;
+ PKIX_PL_GeneralName *name = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("test PathToName Cert Selector");
+
+ subTest(" PKIX_PL_GeneralName List create");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&nameList, plContext));
+
+ subTest(" Add directory name ");
+ name = createGeneralName(PKIX_DIRECTORY_NAME,
+ "O=NotATest Certificates,C=US",
+ plContext);
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(nameList, (PKIX_PL_Object *)name, plContext));
+
+ subTest(" Create Selector and ComCertSelParams");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &selector, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(¶ms, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, params, plContext));
+
+ subTest(" PKIX_ComCertSelParams_SetPathToNames");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetPathToNames(params, nameList, plContext));
+
+ subTest(" Permitting THREE");
+ testSelector(selector, certs, 0x58);
+
+ subTest(" Remove directory name ");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_DeleteItem(nameList, 0, plContext));
+ PKIX_TEST_DECREF_BC(name);
+
+ subTest(" PKIX_ComCertSelParams_SetPathToNames Reset");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetPathToNames(params, NULL, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, params, plContext));
+
+ subTest(" Add directory name ");
+ name = createGeneralName(PKIX_DIRECTORY_NAME,
+ "OU=permittedSubtree1,O=Test Certificates,C=US",
+ plContext);
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(nameList, (PKIX_PL_Object *)name, plContext));
+
+ subTest(" PKIX_ComCertSelParams_SetPathToNames");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetPathToNames(params, nameList, plContext));
+
+ subTest(" Permitting SIX");
+ testSelector(selector, certs, 0x5F);
+
+ subTest(" Remove directory name ");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_DeleteItem(nameList, 0, plContext));
+ PKIX_TEST_DECREF_BC(name);
+
+ subTest(" PKIX_ComCertSelParams_SetNameConstraint Reset");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetPathToNames(params, NULL, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, params, plContext));
+
+ subTest(" Add directory name ");
+ name = createGeneralName(PKIX_DIRECTORY_NAME,
+ "O=Test Certificates,C=US",
+ plContext);
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(nameList, (PKIX_PL_Object *)name, plContext));
+ PKIX_TEST_DECREF_BC(name);
+
+ subTest(" PKIX_ComCertSelParams_SetPathToNames");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetPathToNames(params, nameList, plContext));
+
+ subTest(" Permitting FOUR");
+ testSelector(selector, certs, 0x47);
+
+ subTest(" Only directory name ");
+ name = createGeneralName(PKIX_DIRECTORY_NAME,
+ "OU=permittedSubtree1,O=Test Certificates,C=US",
+ plContext);
+
+ subTest(" PKIX_ComCertSelParams_AddPathToName");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_AddPathToName(params, name, plContext));
+ PKIX_TEST_DECREF_BC(name);
+
+ subTest(" Permitting FOUR");
+ testSelector(selector, certs, 0x47);
+
+ subTest(" PKIX_ComCertSelParams_SetNameConstraint Reset");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetPathToNames(params, NULL, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, params, plContext));
+ PKIX_TEST_DECREF_BC(nameList);
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&nameList, plContext));
+
+ subTest(" Add directory name ");
+ name = createGeneralName(PKIX_DIRECTORY_NAME, "CN=Valid DN nameConstraints EE "
+ "Certificate Test1,OU=permittedSubtree1,"
+ "O=Test Certificates,C=US",
+ plContext);
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(nameList, (PKIX_PL_Object *)name, plContext));
+ PKIX_TEST_DECREF_BC(name);
+
+ subTest(" PKIX_ComCertSelParams_SetPathToNames");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetPathToNames(params, nameList, plContext));
+
+ subTest(" Permitting SIX");
+ testSelector(selector, certs, 0x7e);
+
+ subTest(" Add directory name ");
+ name = createGeneralName(PKIX_DIRECTORY_NAME,
+ "OU=permittedSubtree1,O=Test",
+ plContext);
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(nameList, (PKIX_PL_Object *)name, plContext));
+ PKIX_TEST_DECREF_BC(name);
+
+ subTest(" PKIX_ComCertSelParams_SetPathToNames");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetPathToNames(params, nameList, plContext));
+
+ subTest(" Permitting SIX");
+ testSelector(selector, certs, 0x58);
+
+ subTest(" Add directory name ");
+ name = createGeneralName(PKIX_DIRECTORY_NAME, "O=Test Certificates,C=US", plContext);
+
+ subTest(" PKIX_ComCertSelParams_SetPathToNames Reset");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetPathToNames(params, NULL, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_AddPathToName(params, name, plContext));
+ PKIX_TEST_DECREF_BC(name);
+
+ subTest(" Permitting FOUR");
+ testSelector(selector, certs, 0x47);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(selector);
+ PKIX_TEST_DECREF_AC(params);
+ PKIX_TEST_DECREF_AC(nameList);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testSubjAltNamesMatch(PKIX_List *certs)
+{
+ PKIX_CertSelector *selector = NULL;
+ PKIX_ComCertSelParams *params = NULL;
+ PKIX_List *nameList = NULL;
+ PKIX_PL_GeneralName *name = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("test SubjAltNames Cert Selector");
+
+ subTest(" PKIX_PL_GeneralName List create");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&nameList, plContext));
+
+ subTest(" Create Selector and ComCertSelParams");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &selector, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(¶ms, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, params, plContext));
+
+ subTest(" Add directory name ");
+ name = createGeneralName(PKIX_DIRECTORY_NAME,
+ "CN=Invalid DN nameConstraints EE Certificate Test3,"
+ "OU=excludedSubtree1,O=Test Certificates,C=US",
+ plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(nameList, (PKIX_PL_Object *)name, plContext));
+
+ subTest(" PKIX_ComCertSelParams_SetSubjAltNames");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetSubjAltNames(params, nameList, plContext));
+
+ PKIX_TEST_DECREF_BC(name);
+ PKIX_TEST_DECREF_BC(nameList);
+
+ subTest(" Permitting ONE");
+ testSelector(selector, certs, 0x1);
+
+ subTest(" Add DNS name ");
+ name = createGeneralName(PKIX_DNS_NAME,
+ "mytestcertificates.gov",
+ plContext);
+
+ subTest(" PKIX_ComCertSelParams_AddSubjAltName");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_AddSubjAltName(params, name, plContext));
+ PKIX_TEST_DECREF_BC(name);
+
+ subTest(" Permitting NONE");
+ testSelector(selector, certs, 0x0);
+
+ subTest(" PKIX_ComCertSelParams_SetMatchAllSubjAltNames to FALSE");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetMatchAllSubjAltNames(params, PKIX_FALSE, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, params, plContext));
+
+ subTest(" Permitting TWO");
+ testSelector(selector, certs, 0x3);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(selector);
+ PKIX_TEST_DECREF_AC(params);
+ PKIX_TEST_DECREF_AC(name);
+ PKIX_TEST_DECREF_AC(nameList);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testCertificateValidMatch(
+ PKIX_List *certs)
+{
+ PKIX_CertSelector *selector = NULL;
+ PKIX_ComCertSelParams *params = NULL;
+ PKIX_PL_String *stringRep = NULL;
+ PKIX_PL_Date *testDate = NULL;
+ char *asciiRep = "050501000000Z";
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("CertificateValid match");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &selector, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(¶ms, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII, asciiRep, 0, &stringRep, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Date_Create_UTCTime(stringRep, &testDate, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetCertificateValid(params, testDate, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, params, plContext));
+ testSelector(selector, certs, 0xFFFFFFFF);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(selector);
+ PKIX_TEST_DECREF_AC(params);
+ PKIX_TEST_DECREF_AC(stringRep);
+ PKIX_TEST_DECREF_AC(testDate);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+test_customCallback1(PKIX_List *certs)
+{
+ PKIX_CertSelector *selector = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("custom matchCallback");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(custom_CertSelector_MatchCallback,
+ NULL,
+ &selector,
+ plContext));
+
+ testSelector(selector, certs, 0x900);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(selector);
+
+ PKIX_TEST_RETURN();
+}
+
+static void test_customCallback2(PKIX_List *certs,
+ PKIX_PL_Cert *anyPolicyCert) /* a source for policy anyPolicy */
+{
+ PKIX_CertSelector *selector = NULL;
+ PKIX_List *anyPolicyList = NULL; /* OIDs */
+ PKIX_PL_OID *policyOID = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("custom matchCallback with CertSelectorContext");
+
+ testGetPolicyFromCert(anyPolicyCert, 0, &anyPolicyList);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(anyPolicyList, 0, (PKIX_PL_Object **)&policyOID, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(custom_CertSelector_MatchOIDCallback,
+ (PKIX_PL_Object *)policyOID,
+ &selector,
+ plContext));
+
+ testSelector(selector, certs, (1 << ANYPOLICYCERT));
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(selector);
+ PKIX_TEST_DECREF_AC(anyPolicyList);
+ PKIX_TEST_DECREF_AC(policyOID);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testExtendedKeyUsageMatch(char *certDir)
+{
+ PKIX_ComCertSelParams *goodParams = NULL;
+ PKIX_PL_OID *ekuOid = NULL;
+ PKIX_List *ekuOidList = NULL;
+ PKIX_PL_String *dirString = NULL;
+ PKIX_CertStore_CertCallback certCallback;
+ PKIX_CertStore *certStore = NULL;
+ PKIX_CertSelector *certSelector = NULL;
+ PKIX_List *certList = NULL;
+ PKIX_UInt32 numCert = 0;
+ void *nbioContext = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("test Extended KeyUsage Cert Selector");
+
+ subTest(" PKIX_ComCertSelParams_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&goodParams, plContext));
+
+ subTest(" Create Extended Key Usage OID List");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&ekuOidList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create("1.3.6.1.5.5.7.3.2", &ekuOid, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(ekuOidList, (PKIX_PL_Object *)ekuOid, plContext));
+
+ PKIX_TEST_DECREF_BC(ekuOid);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create("1.3.6.1.5.5.7.3.3", &ekuOid, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(ekuOidList, (PKIX_PL_Object *)ekuOid, plContext));
+
+ PKIX_TEST_DECREF_BC(ekuOid);
+
+ subTest(" PKIX_ComCertSelParams_SetExtendedKeyUsage");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetExtendedKeyUsage(goodParams, ekuOidList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII, certDir, 0, &dirString, plContext));
+
+ subTest(" PKIX_PL_CollectionCertStoreContext_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CollectionCertStore_Create(dirString, &certStore, plContext));
+
+ subTest(" PKIX_CertSelector_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, goodParams, plContext));
+
+ subTest(" PKIX_CertStore_GetCertCallback");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertStore_GetCertCallback(certStore, &certCallback, NULL));
+
+ subTest(" Getting data from Cert Callback");
+ PKIX_TEST_EXPECT_NO_ERROR(certCallback(certStore, certSelector, &nbioContext, &certList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certList, &numCert, plContext));
+
+ if (numCert != PKIX_TEST_CERTSELECTOR_EXTKEYUSAGE_NUM_CERTS) {
+ pkixTestErrorMsg = "unexpected Cert number mismatch";
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(ekuOid);
+ PKIX_TEST_DECREF_AC(ekuOidList);
+ PKIX_TEST_DECREF_AC(goodParams);
+ PKIX_TEST_DECREF_AC(dirString);
+ PKIX_TEST_DECREF_AC(certList);
+ PKIX_TEST_DECREF_AC(certSelector);
+ PKIX_TEST_DECREF_AC(certStore);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testKeyUsageMatch(char *certDir)
+{
+ PKIX_ComCertSelParams *goodParams = NULL;
+ PKIX_PL_String *dirString = NULL;
+ PKIX_CertStore_CertCallback certCallback;
+ PKIX_CertStore *certStore = NULL;
+ PKIX_CertSelector *certSelector = NULL;
+ PKIX_List *certList = NULL;
+ PKIX_UInt32 numCert = 0;
+ void *nbioContext = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("test KeyUsage Cert Selector");
+
+ subTest(" PKIX_ComCertSelParams_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&goodParams, plContext));
+
+ subTest(" PKIX_ComCertSelParams_SetKeyUsage");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetKeyUsage(goodParams, PKIX_CRL_SIGN, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII, certDir, 0, &dirString, plContext));
+
+ subTest(" PKIX_PL_CollectionCertStoreContext_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CollectionCertStore_Create(dirString, &certStore, plContext));
+
+ subTest(" PKIX_CertSelector_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, goodParams, plContext));
+
+ subTest(" PKIX_CertStore_GetCertCallback");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertStore_GetCertCallback(certStore, &certCallback, NULL));
+
+ subTest(" Getting data from Cert Callback");
+ PKIX_TEST_EXPECT_NO_ERROR(certCallback(certStore, certSelector, &nbioContext, &certList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certList, &numCert, plContext));
+
+ if (numCert != PKIX_TEST_CERTSELECTOR_KEYUSAGE_NUM_CERTS) {
+ pkixTestErrorMsg = "unexpected Cert number mismatch";
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(goodParams);
+ PKIX_TEST_DECREF_AC(dirString);
+ PKIX_TEST_DECREF_AC(certList);
+ PKIX_TEST_DECREF_AC(certSelector);
+ PKIX_TEST_DECREF_AC(certStore);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testCertValidMatch(char *certDir)
+{
+ PKIX_ComCertSelParams *goodParams = NULL;
+ PKIX_PL_Date *validDate = NULL;
+ PKIX_PL_String *dirString = NULL;
+ PKIX_CertStore_CertCallback certCallback;
+ PKIX_CertStore *certStore = NULL;
+ PKIX_CertSelector *certSelector = NULL;
+ PKIX_List *certList = NULL;
+ PKIX_UInt32 numCert = 0;
+ void *nbioContext = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("test CertValid Cert Selector");
+
+ subTest(" PKIX_ComCertSelParams_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&goodParams, plContext));
+
+ validDate = createDate("050601000000Z", plContext);
+
+ subTest(" PKIX_ComCertSelParams_SetCertificateValid");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetCertificateValid(goodParams, validDate, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII, certDir, 0, &dirString, plContext));
+
+ subTest(" PKIX_PL_CollectionCertStoreContext_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CollectionCertStore_Create(dirString, &certStore, plContext));
+
+ subTest(" PKIX_CertSelector_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, goodParams, plContext));
+
+ subTest(" PKIX_CertStore_GetCertCallback");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertStore_GetCertCallback(certStore, &certCallback, NULL));
+
+ subTest(" Getting data from Cert Callback");
+ PKIX_TEST_EXPECT_NO_ERROR(certCallback(certStore, certSelector, &nbioContext, &certList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certList, &numCert, plContext));
+
+ if (numCert != PKIX_TEST_CERTSELECTOR_CERTVALID_NUM_CERTS) {
+ pkixTestErrorMsg = "unexpected Cert number mismatch";
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(goodParams);
+ PKIX_TEST_DECREF_AC(validDate);
+ PKIX_TEST_DECREF_AC(dirString);
+ PKIX_TEST_DECREF_AC(certList);
+ PKIX_TEST_DECREF_AC(certSelector);
+ PKIX_TEST_DECREF_AC(certStore);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testIssuerMatch(char *certDir)
+{
+ PKIX_ComCertSelParams *goodParams = NULL;
+ PKIX_PL_X500Name *issuer = NULL;
+ PKIX_PL_String *issuerStr = NULL;
+ PKIX_PL_String *dirString = NULL;
+ PKIX_CertStore_CertCallback certCallback;
+ PKIX_CertStore *certStore = NULL;
+ PKIX_CertSelector *certSelector = NULL;
+ PKIX_List *certList = NULL;
+ char *issuerName = "CN=science,O=mit,C=US";
+ PKIX_UInt32 numCert = 0;
+ void *nbioContext = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("test Issuer Cert Selector");
+
+ subTest(" PKIX_ComCertSelParams_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&goodParams, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII, issuerName, 0, &issuerStr, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_X500Name_Create(issuerStr, &issuer, plContext));
+
+ subTest(" PKIX_ComCertSelParams_SetIssuer");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetIssuer(goodParams, issuer, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII, certDir, 0, &dirString, plContext));
+
+ subTest(" PKIX_PL_CollectionCertStoreContext_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CollectionCertStore_Create(dirString, &certStore, plContext));
+
+ subTest(" PKIX_CertSelector_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, goodParams, plContext));
+
+ subTest(" PKIX_CertStore_GetCertCallback");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertStore_GetCertCallback(certStore, &certCallback, NULL));
+
+ subTest(" Getting data from Cert Callback");
+ PKIX_TEST_EXPECT_NO_ERROR(certCallback(certStore, certSelector, &nbioContext, &certList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certList, &numCert, plContext));
+
+ if (numCert != PKIX_TEST_CERTSELECTOR_ISSUER_NUM_CERTS) {
+ pkixTestErrorMsg = "unexpected Cert number mismatch";
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(goodParams);
+ PKIX_TEST_DECREF_AC(issuer);
+ PKIX_TEST_DECREF_AC(issuerStr);
+ PKIX_TEST_DECREF_AC(dirString);
+ PKIX_TEST_DECREF_AC(certList);
+ PKIX_TEST_DECREF_AC(certSelector);
+ PKIX_TEST_DECREF_AC(certStore);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testSerialNumberVersionMatch(char *certDir)
+{
+ PKIX_ComCertSelParams *goodParams = NULL;
+ PKIX_PL_BigInt *serialNumber = NULL;
+ PKIX_PL_String *serialNumberStr = NULL;
+ PKIX_PL_String *dirString = NULL;
+ PKIX_CertStore_CertCallback certCallback;
+ PKIX_CertStore *certStore = NULL;
+ PKIX_CertSelector *certSelector = NULL;
+ PKIX_List *certList = NULL;
+ PKIX_UInt32 numCert = 0;
+ void *nbioContext = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("test Serial Number Cert Selector");
+
+ subTest(" PKIX_ComCertSelParams_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&goodParams, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII, "01", 0, &serialNumberStr, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_BigInt_Create(serialNumberStr, &serialNumber, plContext));
+
+ subTest(" PKIX_ComCertSelParams_SetSerialNumber");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetSerialNumber(goodParams, serialNumber, plContext));
+
+ subTest(" PKIX_ComCertSelParams_SetVersion");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetVersion(goodParams, 0, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII, certDir, 0, &dirString, plContext));
+
+ subTest(" PKIX_PL_CollectionCertStoreContext_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CollectionCertStore_Create(dirString, &certStore, plContext));
+
+ subTest(" PKIX_CertSelector_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, goodParams, plContext));
+
+ subTest(" PKIX_CertStore_GetCertCallback");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertStore_GetCertCallback(certStore, &certCallback, NULL));
+
+ subTest(" Getting data from Cert Callback");
+ PKIX_TEST_EXPECT_NO_ERROR(certCallback(certStore, certSelector, &nbioContext, &certList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certList, &numCert, plContext));
+
+ PKIX_TEST_DECREF_BC(certList);
+
+ if (numCert != 0) {
+ pkixTestErrorMsg = "unexpected Version mismatch";
+ }
+
+ subTest(" PKIX_ComCertSelParams_SetVersion");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetVersion(goodParams, 2, plContext));
+
+ subTest(" Getting data from Cert Callback");
+ PKIX_TEST_EXPECT_NO_ERROR(certCallback(certStore, certSelector, &nbioContext, &certList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certList, &numCert, plContext));
+
+ if (numCert != PKIX_TEST_CERTSELECTOR_SERIALNUMBER_NUM_CERTS) {
+ pkixTestErrorMsg = "unexpected Serial Number mismatch";
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(goodParams);
+ PKIX_TEST_DECREF_AC(serialNumber);
+ PKIX_TEST_DECREF_AC(serialNumberStr);
+ PKIX_TEST_DECREF_AC(dirString);
+ PKIX_TEST_DECREF_AC(certList);
+ PKIX_TEST_DECREF_AC(certSelector);
+ PKIX_TEST_DECREF_AC(certStore);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testSubjKeyIdMatch(PKIX_List *certs)
+{
+ PKIX_CertSelector *selector = NULL;
+ PKIX_ComCertSelParams *params = NULL;
+ PKIX_PL_Cert *cert = NULL;
+ PKIX_PL_ByteArray *selSubjKeyId = NULL;
+ PKIX_UInt32 item = 0;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("test Subject Key Id Cert Selector");
+
+ item = 2;
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certs, item, (PKIX_PL_Object **)&cert, plContext));
+
+ subTest(" PKIX_PL_Cert_GetSubjectKeyIdentifier");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetSubjectKeyIdentifier(cert, &selSubjKeyId, plContext));
+
+ subTest(" Create Selector and ComCertSelParams");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &selector, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(¶ms, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, params, plContext));
+
+ subTest(" PKIX_ComCertSelParams_SetSubjKeyIdentifier");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetSubjKeyIdentifier(params, selSubjKeyId, plContext));
+
+ subTest(" Select One");
+ testSelector(selector, certs, 1 << item);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(selSubjKeyId);
+ PKIX_TEST_DECREF_AC(cert);
+ PKIX_TEST_DECREF_AC(params);
+ PKIX_TEST_DECREF_AC(selector);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testAuthKeyIdMatch(PKIX_List *certs)
+{
+ PKIX_CertSelector *selector = NULL;
+ PKIX_ComCertSelParams *params = NULL;
+ PKIX_PL_Cert *cert = NULL;
+ PKIX_PL_ByteArray *selAuthKeyId = NULL;
+ PKIX_UInt32 item = 0;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("test Auth Key Id Cert Selector");
+
+ item = 3;
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certs, item, (PKIX_PL_Object **)&cert, plContext));
+
+ subTest(" PKIX_PL_Cert_GetAuthorityKeyIdentifier");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetAuthorityKeyIdentifier(cert, &selAuthKeyId, plContext));
+
+ subTest(" Create Selector and ComCertSelParams");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &selector, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(¶ms, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, params, plContext));
+
+ subTest(" PKIX_ComCertSelParams_SetAuthorityKeyIdentifier");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetAuthorityKeyIdentifier(params, selAuthKeyId, plContext));
+
+ subTest(" Select TWO");
+ testSelector(selector, certs, (1 << item) | (1 << 1));
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(selAuthKeyId);
+ PKIX_TEST_DECREF_AC(cert);
+ PKIX_TEST_DECREF_AC(params);
+ PKIX_TEST_DECREF_AC(selector);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testSubjPKAlgIdMatch(PKIX_List *certs)
+{
+ PKIX_CertSelector *selector = NULL;
+ PKIX_ComCertSelParams *params = NULL;
+ PKIX_PL_Cert *cert = NULL;
+ PKIX_PL_OID *selAlgId = NULL;
+ PKIX_UInt32 item = 0;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("test Subject Public Key Algorithm Id Cert Selector");
+
+ item = 0;
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certs, item, (PKIX_PL_Object **)&cert, plContext));
+
+ subTest(" PKIX_PL_Cert_GetSubjectPublicKeyAlgId");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetSubjectPublicKeyAlgId(cert, &selAlgId, plContext));
+
+ subTest(" Create Selector and ComCertSelParams");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &selector, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(¶ms, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, params, plContext));
+
+ subTest(" PKIX_ComCertSelParams_SetSubjPKAlgId");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetSubjPKAlgId(params, selAlgId, plContext));
+
+ subTest(" Select All");
+ testSelector(selector, certs, 0x7F);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(selAlgId);
+ PKIX_TEST_DECREF_AC(cert);
+ PKIX_TEST_DECREF_AC(params);
+ PKIX_TEST_DECREF_AC(selector);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testSubjPublicKeyMatch(PKIX_List *certs)
+{
+ PKIX_CertSelector *selector = NULL;
+ PKIX_ComCertSelParams *params = NULL;
+ PKIX_PL_Cert *cert = NULL;
+ PKIX_PL_PublicKey *selPublicKey = NULL;
+ PKIX_UInt32 item = 0;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("test Subject Public Key Cert Selector");
+
+ item = 5;
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certs, item, (PKIX_PL_Object **)&cert, plContext));
+
+ subTest(" PKIX_PL_Cert_GetSubjectPublicKey");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetSubjectPublicKey(cert, &selPublicKey, plContext));
+
+ subTest(" Create Selector and ComCertSelParams");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &selector, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(¶ms, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, params, plContext));
+
+ subTest(" PKIX_ComCertSelParams_SetSubjPubKey");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetSubjPubKey(params, selPublicKey, plContext));
+
+ subTest(" Select ONE");
+ testSelector(selector, certs, 1 << item);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(selPublicKey);
+ PKIX_TEST_DECREF_AC(cert);
+ PKIX_TEST_DECREF_AC(params);
+ PKIX_TEST_DECREF_AC(selector);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+test_CertSelector_Duplicate(PKIX_CertSelector *selector)
+{
+ PKIX_Int32 goodBasicConstraints = 0;
+ PKIX_Int32 equalBasicConstraints = 0;
+ PKIX_CertSelector *dupSelector = NULL;
+ PKIX_ComCertSelParams *goodParams = NULL;
+ PKIX_ComCertSelParams *equalParams = NULL;
+ PKIX_CertSelector_MatchCallback goodCallback = NULL;
+ PKIX_CertSelector_MatchCallback equalCallback = NULL;
+ PKIX_PL_X500Name *goodSubject = NULL;
+ PKIX_PL_X500Name *equalSubject = NULL;
+ PKIX_List *goodPolicy = NULL;
+ PKIX_List *equalPolicy = NULL;
+ PKIX_PL_Cert *goodCert = NULL;
+ PKIX_PL_Cert *equalCert = NULL;
+ PKIX_PL_Date *goodDate = NULL;
+ PKIX_PL_Date *equalDate = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("test_CertSelector_Duplicate");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Duplicate((PKIX_PL_Object *)selector,
+ (PKIX_PL_Object **)&dupSelector,
+ plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_GetCommonCertSelectorParams(selector, &goodParams, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_GetCommonCertSelectorParams(dupSelector, &equalParams, plContext));
+ /* There is no equals function, so look at components separately. */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetSubject(goodParams, &goodSubject, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetSubject(equalParams, &equalSubject, plContext));
+ if (goodSubject && equalSubject) {
+ testEqualsHelper((PKIX_PL_Object *)goodSubject,
+ (PKIX_PL_Object *)equalSubject,
+ PKIX_TRUE,
+ plContext);
+ } else {
+ if
+ PKIX_EXACTLY_ONE_NULL(goodSubject, equalSubject)
+ {
+ pkixTestErrorMsg = "Subject Names are not equal!";
+ goto cleanup;
+ }
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetPolicy(goodParams, &goodPolicy, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetPolicy(equalParams, &equalPolicy, plContext));
+ if (goodPolicy && equalPolicy) {
+ testEqualsHelper((PKIX_PL_Object *)goodPolicy,
+ (PKIX_PL_Object *)equalPolicy,
+ PKIX_TRUE,
+ plContext);
+ } else {
+ if
+ PKIX_EXACTLY_ONE_NULL(goodPolicy, equalPolicy)
+ {
+ pkixTestErrorMsg = "Policy Lists are not equal!";
+ goto cleanup;
+ }
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetCertificate(goodParams, &goodCert, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetCertificate(equalParams, &equalCert, plContext));
+ if (goodCert && equalCert) {
+ testEqualsHelper((PKIX_PL_Object *)goodCert,
+ (PKIX_PL_Object *)equalCert,
+ PKIX_TRUE,
+ plContext);
+ } else {
+ if
+ PKIX_EXACTLY_ONE_NULL(goodCert, equalCert)
+ {
+ pkixTestErrorMsg = "Cert Lists are not equal!";
+ goto cleanup;
+ }
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetCertificateValid(goodParams, &goodDate, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetCertificateValid(equalParams, &equalDate, plContext));
+ if (goodCert && equalCert) {
+ testEqualsHelper((PKIX_PL_Object *)goodDate,
+ (PKIX_PL_Object *)equalDate,
+ PKIX_TRUE,
+ plContext);
+ } else {
+ if
+ PKIX_EXACTLY_ONE_NULL(goodDate, equalDate)
+ {
+ pkixTestErrorMsg = "Date Lists are not equal!";
+ goto cleanup;
+ }
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetBasicConstraints(goodParams, &goodBasicConstraints, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetBasicConstraints(equalParams, &equalBasicConstraints, plContext));
+ if (goodBasicConstraints != equalBasicConstraints) {
+ pkixTestErrorMsg = "BasicConstraints are not equal!";
+ goto cleanup;
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_GetMatchCallback(selector, &goodCallback, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_GetMatchCallback(dupSelector, &equalCallback, plContext));
+ if (goodCallback != equalCallback) {
+ pkixTestErrorMsg = "MatchCallbacks are not equal!";
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(dupSelector);
+ PKIX_TEST_DECREF_AC(goodParams);
+ PKIX_TEST_DECREF_AC(equalParams);
+ PKIX_TEST_DECREF_AC(goodSubject);
+ PKIX_TEST_DECREF_AC(equalSubject);
+ PKIX_TEST_DECREF_AC(goodPolicy);
+ PKIX_TEST_DECREF_AC(equalPolicy);
+ PKIX_TEST_DECREF_AC(goodCert);
+ PKIX_TEST_DECREF_AC(equalCert);
+ PKIX_TEST_DECREF_AC(goodDate);
+ PKIX_TEST_DECREF_AC(equalDate);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+printUsage(void)
+{
+ (void)printf("\nUSAGE:\ttest_certselector \n\n");
+}
+
+int
+test_certselector(int argc, char *argv[])
+{
+
+ PKIX_UInt32 i = 0;
+ PKIX_UInt32 j = 0;
+ PKIX_UInt32 actualMinorVersion;
+
+ PKIX_CertSelector *emptySelector = NULL;
+ PKIX_List *certs = NULL;
+ PKIX_List *nameConstraintsCerts = NULL;
+ PKIX_List *subjAltNamesCerts = NULL;
+ PKIX_PL_Cert *cert = NULL;
+ PKIX_PL_Cert *policy1Cert = NULL;
+ PKIX_PL_Cert *policy2Cert = NULL;
+ PKIX_PL_Cert *anyPolicyCert = NULL;
+ PKIX_PL_Cert *subjectCert = NULL;
+ PKIX_ComCertSelParams *selParams = NULL;
+ char *certDir = NULL;
+ char *dirName = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ startTests("CertSelector");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ if (argc < 3) {
+ printUsage();
+ return (0);
+ }
+
+ dirName = argv[j + 1];
+ certDir = argv[j + 3];
+
+ /* Create a List of certs to use in testing the selector */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&certs, plContext));
+
+ for (i = 0; i < NUMCERTS; i++) {
+
+ cert = createCert(dirName, certList[i], plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(certs, (PKIX_PL_Object *)cert, plContext));
+ if (i == POLICY1CERT) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_IncRef((PKIX_PL_Object *)cert, plContext));
+ policy1Cert = cert;
+ }
+ if (i == ANYPOLICYCERT) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_IncRef((PKIX_PL_Object *)cert, plContext));
+ anyPolicyCert = cert;
+ }
+ if (i == POLICY2CERT) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_IncRef((PKIX_PL_Object *)cert, plContext));
+ policy2Cert = cert;
+ }
+ if (i == SUBJECTCERT) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_IncRef((PKIX_PL_Object *)cert, plContext));
+ subjectCert = cert;
+ }
+ PKIX_TEST_DECREF_BC(cert);
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&nameConstraintsCerts, plContext));
+
+ for (i = 0; i < NUMNCCERTS; i++) {
+
+ cert = createCert(dirName, ncCertList[i], plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(nameConstraintsCerts,
+ (PKIX_PL_Object *)cert,
+ plContext));
+
+ PKIX_TEST_DECREF_BC(cert);
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&subjAltNamesCerts, plContext));
+
+ for (i = 0; i < NUMSANCERTS; i++) {
+
+ cert = createCert(dirName, sanCertList[i], plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(subjAltNamesCerts,
+ (PKIX_PL_Object *)cert,
+ plContext));
+
+ PKIX_TEST_DECREF_BC(cert);
+ }
+
+ subTest("test_CertSelector_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &emptySelector, plContext));
+
+ subTest("Default Match, no parameters set");
+ testSelector(emptySelector, certs, 0xFFFFFFFF);
+
+ testSubjectMatch(certs, subjectCert);
+
+ testBasicConstraintsMatch(certs);
+
+ testPolicyMatch(certs, policy1Cert, policy2Cert, anyPolicyCert);
+
+ testCertificateMatch(certs, subjectCert);
+
+ testCertificateValidMatch(certs);
+
+ subTest("Combination: pass only EE certs that assert some policy");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&selParams, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetBasicConstraints(selParams, -2, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(emptySelector, selParams, plContext));
+ testSelector(emptySelector, certs, 0xC00);
+
+ testNameConstraintsMatch(nameConstraintsCerts);
+
+ testPathToNamesMatch(nameConstraintsCerts);
+
+ testSubjAltNamesMatch(subjAltNamesCerts);
+
+ testExtendedKeyUsageMatch(certDir);
+
+ testKeyUsageMatch(certDir);
+
+ testIssuerMatch(certDir);
+
+ testSerialNumberVersionMatch(certDir);
+
+ testCertValidMatch(certDir);
+
+ testSubjKeyIdMatch(nameConstraintsCerts);
+
+ testAuthKeyIdMatch(nameConstraintsCerts);
+
+ testSubjPKAlgIdMatch(nameConstraintsCerts);
+
+ testSubjPublicKeyMatch(nameConstraintsCerts);
+
+ test_CertSelector_Duplicate(emptySelector);
+
+ test_customCallback1(certs);
+
+ test_customCallback2(certs, anyPolicyCert);
+
+ subTest("test_CertSelector_Destroy");
+
+ PKIX_TEST_DECREF_BC(emptySelector);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(emptySelector);
+ PKIX_TEST_DECREF_AC(certs);
+ PKIX_TEST_DECREF_AC(cert);
+ PKIX_TEST_DECREF_AC(policy1Cert);
+ PKIX_TEST_DECREF_AC(policy2Cert);
+ PKIX_TEST_DECREF_AC(anyPolicyCert);
+ PKIX_TEST_DECREF_AC(subjectCert);
+ PKIX_TEST_DECREF_AC(selParams);
+ PKIX_TEST_DECREF_AC(nameConstraintsCerts);
+ PKIX_TEST_DECREF_AC(subjAltNamesCerts);
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("CertSelector");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/certsel/test_comcertselparams.c b/nss/cmd/libpkix/pkix/certsel/test_comcertselparams.c
new file mode 100644
index 0000000..57f192a
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/certsel/test_comcertselparams.c
@@ -0,0 +1,800 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_comcertselparams.c
+ *
+ * Test Common Cert Selector Params
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+static void
+test_CreateOIDList(PKIX_List *certPolicyInfos, PKIX_List **pPolicyOIDs)
+{
+ PKIX_UInt32 i = 0;
+ PKIX_UInt32 numInfos = 0;
+ PKIX_PL_CertPolicyInfo *certPolicyInfo = NULL;
+ PKIX_PL_OID *policyOID = NULL;
+ PKIX_List *certPolicies = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ /* Convert from List of CertPolicyInfos to List of OIDs */
+ if (certPolicyInfos) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certPolicyInfos, &numInfos, plContext));
+ }
+
+ if (numInfos > 0) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&certPolicies, plContext));
+ }
+ for (i = 0; i < numInfos; i++) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certPolicyInfos,
+ i,
+ (PKIX_PL_Object **)&certPolicyInfo,
+ plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CertPolicyInfo_GetPolicyId(certPolicyInfo, &policyOID, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(certPolicies, (PKIX_PL_Object *)policyOID, plContext));
+ PKIX_TEST_DECREF_BC(certPolicyInfo);
+ PKIX_TEST_DECREF_BC(policyOID);
+ }
+
+ *pPolicyOIDs = certPolicies;
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(certPolicyInfo);
+ PKIX_TEST_DECREF_AC(policyOID);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+test_NameConstraints(char *dirName)
+{
+ PKIX_PL_Cert *goodCert = NULL;
+ PKIX_PL_CertNameConstraints *getNameConstraints = NULL;
+ PKIX_PL_CertNameConstraints *setNameConstraints = NULL;
+ PKIX_ComCertSelParams *goodParams = NULL;
+ char *expectedAscii =
+ "[\n"
+ "\t\tPermitted Name: (OU=permittedSubtree1,"
+ "O=Test Certificates,C=US, OU=permittedSubtree2,"
+ "O=Test Certificates,C=US)\n"
+ "\t\tExcluded Name: (EMPTY)\n"
+ "\t]\n";
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("Create Cert for NameConstraints test");
+
+ goodCert = createCert(dirName, "nameConstraintsDN2CACert.crt", plContext);
+
+ subTest("PKIX_PL_Cert_GetNameConstraints");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetNameConstraints(goodCert, &setNameConstraints, plContext));
+
+ subTest("PKIX_ComCertSelParams_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&goodParams, plContext));
+
+ subTest("PKIX_ComCertSelParams_SetNameConstraints");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetNameConstraints(goodParams, setNameConstraints, plContext));
+
+ subTest("PKIX_ComCertSelParams_GetNameConstraints");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetNameConstraints(goodParams, &getNameConstraints, plContext));
+
+ subTest("Compare NameConstraints");
+ testEqualsHelper((PKIX_PL_Object *)setNameConstraints,
+ (PKIX_PL_Object *)getNameConstraints,
+ PKIX_TRUE,
+ plContext);
+
+ subTest("Compare NameConstraints with canned string");
+ testToStringHelper((PKIX_PL_Object *)getNameConstraints,
+ expectedAscii,
+ plContext);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(goodCert);
+ PKIX_TEST_DECREF_AC(getNameConstraints);
+ PKIX_TEST_DECREF_AC(setNameConstraints);
+ PKIX_TEST_DECREF_AC(goodParams);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+test_PathToNames(void)
+{
+ PKIX_ComCertSelParams *goodParams = NULL;
+ PKIX_List *setGenNames = NULL;
+ PKIX_List *getGenNames = NULL;
+ PKIX_PL_GeneralName *rfc822GenName = NULL;
+ PKIX_PL_GeneralName *dnsGenName = NULL;
+ PKIX_PL_GeneralName *dirGenName = NULL;
+ PKIX_PL_GeneralName *uriGenName = NULL;
+ PKIX_PL_GeneralName *oidGenName = NULL;
+ char *rfc822Name = "john.doe@labs.com";
+ char *dnsName = "comcast.net";
+ char *dirName = "cn=john, ou=labs, o=sun, c=us";
+ char *uriName = "http://comcast.net";
+ char *oidName = "1.2.840.11";
+ char *expectedAscii =
+ "(john.doe@labs.com, "
+ "comcast.net, "
+ "CN=john,OU=labs,O=sun,C=us, "
+ "http://comcast.net)";
+ char *expectedAsciiAll =
+ "(john.doe@labs.com, "
+ "comcast.net, "
+ "CN=john,OU=labs,O=sun,C=us, "
+ "http://comcast.net, "
+ "1.2.840.11)";
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_PL_GeneralName_Create");
+ dnsGenName = createGeneralName(PKIX_DNS_NAME, dnsName, plContext);
+ uriGenName = createGeneralName(PKIX_URI_NAME, uriName, plContext);
+ oidGenName = createGeneralName(PKIX_OID_NAME, oidName, plContext);
+ dirGenName = createGeneralName(PKIX_DIRECTORY_NAME, dirName, plContext);
+ rfc822GenName = createGeneralName(PKIX_RFC822_NAME,
+ rfc822Name,
+ plContext);
+
+ subTest("PKIX_PL_GeneralName List create and append");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&setGenNames, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(setGenNames, (PKIX_PL_Object *)rfc822GenName, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(setGenNames, (PKIX_PL_Object *)dnsGenName, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(setGenNames, (PKIX_PL_Object *)dirGenName, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(setGenNames, (PKIX_PL_Object *)uriGenName, plContext));
+
+ subTest("PKIX_ComCertSelParams_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&goodParams, plContext));
+
+ subTest("PKIX_ComCertSelParams_SetPathToNames");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetPathToNames(goodParams, setGenNames, plContext));
+
+ subTest("PKIX_ComCertSelParams_GetPathToNames");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetPathToNames(goodParams, &getGenNames, plContext));
+
+ subTest("Compare GeneralName List");
+ testEqualsHelper((PKIX_PL_Object *)setGenNames,
+ (PKIX_PL_Object *)getGenNames,
+ PKIX_TRUE,
+ plContext);
+
+ subTest("Compare GeneralName List with canned string");
+ testToStringHelper((PKIX_PL_Object *)getGenNames,
+ expectedAscii,
+ plContext);
+
+ subTest("PKIX_ComCertSelParams_AddPathToName");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_AddPathToName(goodParams, oidGenName, plContext));
+
+ PKIX_TEST_DECREF_BC(getGenNames);
+
+ subTest("PKIX_ComCertSelParams_GetPathToNames");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetPathToNames(goodParams, &getGenNames, plContext));
+
+ subTest("Compare GeneralName List with canned string");
+ testToStringHelper((PKIX_PL_Object *)getGenNames,
+ expectedAsciiAll,
+ plContext);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(goodParams);
+ PKIX_TEST_DECREF_AC(setGenNames);
+ PKIX_TEST_DECREF_AC(getGenNames);
+ PKIX_TEST_DECREF_AC(rfc822GenName);
+ PKIX_TEST_DECREF_AC(dnsGenName);
+ PKIX_TEST_DECREF_AC(dirGenName);
+ PKIX_TEST_DECREF_AC(uriGenName);
+ PKIX_TEST_DECREF_AC(oidGenName);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+test_SubjAltNames(void)
+{
+ PKIX_ComCertSelParams *goodParams = NULL;
+ PKIX_List *setGenNames = NULL;
+ PKIX_List *getGenNames = NULL;
+ PKIX_PL_GeneralName *rfc822GenName = NULL;
+ PKIX_PL_GeneralName *dnsGenName = NULL;
+ PKIX_PL_GeneralName *dirGenName = NULL;
+ PKIX_PL_GeneralName *uriGenName = NULL;
+ PKIX_PL_GeneralName *oidGenName = NULL;
+ PKIX_Boolean matchAll = PKIX_TRUE;
+ char *rfc822Name = "john.doe@labs.com";
+ char *dnsName = "comcast.net";
+ char *dirName = "cn=john, ou=labs, o=sun, c=us";
+ char *uriName = "http://comcast.net";
+ char *oidName = "1.2.840.11";
+ char *expectedAscii =
+ "(john.doe@labs.com, "
+ "comcast.net, "
+ "CN=john,OU=labs,O=sun,C=us, "
+ "http://comcast.net)";
+ char *expectedAsciiAll =
+ "(john.doe@labs.com, "
+ "comcast.net, "
+ "CN=john,OU=labs,O=sun,C=us, "
+ "http://comcast.net, "
+ "1.2.840.11)";
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_PL_GeneralName_Create");
+ dnsGenName = createGeneralName(PKIX_DNS_NAME, dnsName, plContext);
+ uriGenName = createGeneralName(PKIX_URI_NAME, uriName, plContext);
+ oidGenName = createGeneralName(PKIX_OID_NAME, oidName, plContext);
+ dirGenName = createGeneralName(PKIX_DIRECTORY_NAME, dirName, plContext);
+ rfc822GenName = createGeneralName(PKIX_RFC822_NAME,
+ rfc822Name,
+ plContext);
+
+ subTest("PKIX_PL_GeneralName List create and append");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&setGenNames, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(setGenNames, (PKIX_PL_Object *)rfc822GenName, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(setGenNames, (PKIX_PL_Object *)dnsGenName, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(setGenNames, (PKIX_PL_Object *)dirGenName, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(setGenNames, (PKIX_PL_Object *)uriGenName, plContext));
+
+ subTest("PKIX_ComCertSelParams_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&goodParams, plContext));
+
+ subTest("PKIX_ComCertSelParams_SetSubjAltNames");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetSubjAltNames(goodParams, setGenNames, plContext));
+
+ subTest("PKIX_ComCertSelParams_GetSubjAltNames");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetSubjAltNames(goodParams, &getGenNames, plContext));
+
+ subTest("Compare GeneralName List");
+ testEqualsHelper((PKIX_PL_Object *)setGenNames,
+ (PKIX_PL_Object *)getGenNames,
+ PKIX_TRUE,
+ plContext);
+
+ subTest("Compare GeneralName List with canned string");
+ testToStringHelper((PKIX_PL_Object *)getGenNames,
+ expectedAscii,
+ plContext);
+
+ subTest("PKIX_ComCertSelParams_AddSubjAltName");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_AddSubjAltName(goodParams, oidGenName, plContext));
+
+ PKIX_TEST_DECREF_BC(getGenNames);
+
+ subTest("PKIX_ComCertSelParams_GetSubjAltNames");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetSubjAltNames(goodParams, &getGenNames, plContext));
+
+ subTest("Compare GeneralName List with canned string");
+ testToStringHelper((PKIX_PL_Object *)getGenNames,
+ expectedAsciiAll,
+ plContext);
+
+ subTest("PKIX_ComCertSelParams_GetMatchAllSubjAltNames");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetMatchAllSubjAltNames(goodParams, &matchAll, plContext));
+ if (matchAll != PKIX_TRUE) {
+ testError("unexpected mismatch ");
+ }
+
+ subTest("PKIX_ComCertSelParams_SetMatchAllSubjAltNames");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetMatchAllSubjAltNames(goodParams, PKIX_FALSE, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetMatchAllSubjAltNames(goodParams, &matchAll, plContext));
+ if (matchAll != PKIX_FALSE) {
+ testError("unexpected mismatch ");
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(goodParams);
+ PKIX_TEST_DECREF_AC(setGenNames);
+ PKIX_TEST_DECREF_AC(getGenNames);
+ PKIX_TEST_DECREF_AC(rfc822GenName);
+ PKIX_TEST_DECREF_AC(dnsGenName);
+ PKIX_TEST_DECREF_AC(dirGenName);
+ PKIX_TEST_DECREF_AC(uriGenName);
+ PKIX_TEST_DECREF_AC(oidGenName);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+test_KeyUsages(void)
+{
+ PKIX_ComCertSelParams *goodParams = NULL;
+ PKIX_PL_OID *ekuOid = NULL;
+ PKIX_List *setExtKeyUsage = NULL;
+ PKIX_List *getExtKeyUsage = NULL;
+ PKIX_UInt32 getKeyUsage = 0;
+ PKIX_UInt32 setKeyUsage = 0x1FF;
+ PKIX_Boolean isEqual = PKIX_FALSE;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_ComCertSelParams_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&goodParams, plContext));
+
+ subTest("PKIX_ComCertSelParams_SetKeyUsage");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetKeyUsage(goodParams, setKeyUsage, plContext));
+
+ subTest("PKIX_ComCertSelParams_GetKeyUsage");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetKeyUsage(goodParams, &getKeyUsage, plContext));
+
+ if (setKeyUsage != getKeyUsage) {
+ testError("unexpected KeyUsage mismatch ");
+ }
+
+ subTest("PKIX_PL_OID List create and append");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&setExtKeyUsage, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create("1.3.6.1.5.5.7.3.1", &ekuOid, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(setExtKeyUsage, (PKIX_PL_Object *)ekuOid, plContext));
+ PKIX_TEST_DECREF_BC(ekuOid);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create("1.3.6.1.5.5.7.3.8", &ekuOid, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(setExtKeyUsage, (PKIX_PL_Object *)ekuOid, plContext));
+ PKIX_TEST_DECREF_BC(ekuOid);
+
+ subTest("PKIX_ComCertSelParams_SetExtendedKeyUsage");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetExtendedKeyUsage(goodParams, setExtKeyUsage, plContext));
+
+ subTest("PKIX_ComCertSelParams_GetExtendedKeyUsage");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetExtendedKeyUsage(goodParams, &getExtKeyUsage, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)setExtKeyUsage,
+ (PKIX_PL_Object *)getExtKeyUsage,
+ &isEqual,
+ plContext));
+
+ if (isEqual == PKIX_FALSE) {
+ testError("unexpected ExtKeyUsage mismatch ");
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(ekuOid);
+ PKIX_TEST_DECREF_AC(setExtKeyUsage);
+ PKIX_TEST_DECREF_AC(getExtKeyUsage);
+ PKIX_TEST_DECREF_AC(goodParams);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+test_Version_Issuer_SerialNumber(void)
+{
+ PKIX_ComCertSelParams *goodParams = NULL;
+ PKIX_UInt32 version = 0;
+ PKIX_PL_X500Name *setIssuer = NULL;
+ PKIX_PL_X500Name *getIssuer = NULL;
+ PKIX_PL_String *str = NULL;
+ PKIX_PL_BigInt *setSerialNumber = NULL;
+ PKIX_PL_BigInt *getSerialNumber = NULL;
+ PKIX_Boolean isEqual = PKIX_FALSE;
+ char *bigInt = "999999999999999999";
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_ComCertSelParams_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&goodParams, plContext));
+
+ /* Version */
+ subTest("PKIX_ComCertSelParams_SetVersion");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetVersion(goodParams, 2, plContext));
+
+ subTest("PKIX_ComCertSelParams_GetVersion");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetVersion(goodParams, &version, plContext));
+
+ if (version != 2) {
+ testError("unexpected Version mismatch ");
+ }
+
+ /* Issuer */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII, "CN=Test,O=Sun,C=US", 0, &str, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_X500Name_Create(str, &setIssuer, plContext));
+
+ PKIX_TEST_DECREF_BC(str);
+
+ subTest("PKIX_ComCertSelParams_SetIssuer");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetIssuer(goodParams, setIssuer, plContext));
+
+ subTest("PKIX_ComCertSelParams_GetIssuer");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetIssuer(goodParams, &getIssuer, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)setIssuer,
+ (PKIX_PL_Object *)getIssuer,
+ &isEqual,
+ plContext));
+
+ if (isEqual == PKIX_FALSE) {
+ testError("unexpected Issuer mismatch ");
+ }
+
+ /* Serial Number */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII, bigInt, PL_strlen(bigInt), &str, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_BigInt_Create(str, &setSerialNumber, plContext));
+
+ subTest("PKIX_ComCertSelParams_SetSerialNumber");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetSerialNumber(goodParams, setSerialNumber, plContext));
+
+ subTest("PKIX_ComCertSelParams_GetSerialNumber");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetSerialNumber(goodParams, &getSerialNumber, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)setSerialNumber,
+ (PKIX_PL_Object *)getSerialNumber,
+ &isEqual,
+ plContext));
+
+ if (isEqual == PKIX_FALSE) {
+ testError("unexpected Serial Number mismatch ");
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(str);
+ PKIX_TEST_DECREF_AC(setIssuer);
+ PKIX_TEST_DECREF_AC(getIssuer);
+ PKIX_TEST_DECREF_AC(setSerialNumber);
+ PKIX_TEST_DECREF_AC(getSerialNumber);
+ PKIX_TEST_DECREF_AC(goodParams);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+test_SubjKeyId_AuthKeyId(void)
+{
+ PKIX_ComCertSelParams *goodParams = NULL;
+ PKIX_PL_ByteArray *setKeyId = NULL;
+ PKIX_PL_ByteArray *getKeyId = NULL;
+ PKIX_Boolean isEqual = PKIX_FALSE;
+
+ PKIX_TEST_STD_VARS();
+
+ /* Subject Key Identifier */
+ subTest("PKIX_PL_ByteArray_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_ByteArray_Create((void *)"66099", 1, &setKeyId, plContext));
+
+ subTest("PKIX_ComCertSelParams_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&goodParams, plContext));
+
+ subTest("PKIX_ComCertSelParams_SetSubjectKeyIdentifier");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetSubjKeyIdentifier(goodParams, setKeyId, plContext));
+
+ subTest("PKIX_ComCertSelParams_GetSubjectKeyIdentifier");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetSubjKeyIdentifier(goodParams, &getKeyId, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)setKeyId,
+ (PKIX_PL_Object *)getKeyId,
+ &isEqual,
+ plContext));
+
+ if (isEqual == PKIX_FALSE) {
+ testError("unexpected Subject Key Id mismatch ");
+ }
+
+ PKIX_TEST_DECREF_BC(setKeyId);
+ PKIX_TEST_DECREF_BC(getKeyId);
+
+ /* Authority Key Identifier */
+ subTest("PKIX_PL_ByteArray_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_ByteArray_Create((void *)"11022", 1, &setKeyId, plContext));
+
+ subTest("PKIX_ComCertSelParams_SetAuthorityKeyIdentifier");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetAuthorityKeyIdentifier(goodParams, setKeyId, plContext));
+
+ subTest("PKIX_ComCertSelParams_GetAuthorityKeyIdentifier");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetAuthorityKeyIdentifier(goodParams, &getKeyId, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)setKeyId,
+ (PKIX_PL_Object *)getKeyId,
+ &isEqual,
+ plContext));
+
+ if (isEqual == PKIX_FALSE) {
+ testError("unexpected Auth Key Id mismatch ");
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(setKeyId);
+ PKIX_TEST_DECREF_AC(getKeyId);
+ PKIX_TEST_DECREF_AC(goodParams);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+test_SubjAlgId_SubjPublicKey(char *dirName)
+{
+ PKIX_ComCertSelParams *goodParams = NULL;
+ PKIX_PL_OID *setAlgId = NULL;
+ PKIX_PL_OID *getAlgId = NULL;
+ PKIX_PL_Cert *goodCert = NULL;
+ PKIX_PL_PublicKey *setPublicKey = NULL;
+ PKIX_PL_PublicKey *getPublicKey = NULL;
+ PKIX_Boolean isEqual = PKIX_FALSE;
+
+ PKIX_TEST_STD_VARS();
+
+ /* Subject Algorithm Identifier */
+ subTest("PKIX_PL_OID_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create("1.1.2.3", &setAlgId, plContext));
+
+ subTest("PKIX_ComCertSelParams_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&goodParams, plContext));
+
+ subTest("PKIX_ComCertSelParams_SetSubjPKAlgId");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetSubjPKAlgId(goodParams, setAlgId, plContext));
+
+ subTest("PKIX_ComCertSelParams_GetSubjPKAlgId");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetSubjPKAlgId(goodParams, &getAlgId, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)setAlgId,
+ (PKIX_PL_Object *)getAlgId,
+ &isEqual,
+ plContext));
+
+ if (isEqual == PKIX_FALSE) {
+ testError("unexpected Subject Public Key Alg mismatch "
+ "");
+ }
+
+ /* Subject Public Key */
+ subTest("Getting Cert for Subject Public Key");
+
+ goodCert = createCert(dirName, "nameConstraintsDN2CACert.crt", plContext);
+
+ subTest("PKIX_PL_Cert_GetSubjectPublicKey");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetSubjectPublicKey(goodCert, &setPublicKey, plContext));
+
+ subTest("PKIX_ComCertSelParams_SetSubjPubKey");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetSubjPubKey(goodParams, setPublicKey, plContext));
+
+ subTest("PKIX_ComCertSelParams_GetSubjPubKey");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetSubjPubKey(goodParams, &getPublicKey, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)setPublicKey,
+ (PKIX_PL_Object *)getPublicKey,
+ &isEqual,
+ plContext));
+
+ if (isEqual == PKIX_FALSE) {
+ testError("unexpected Subject Public Key mismatch "
+ "");
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(setAlgId);
+ PKIX_TEST_DECREF_AC(getAlgId);
+ PKIX_TEST_DECREF_AC(goodParams);
+ PKIX_TEST_DECREF_AC(goodCert);
+ PKIX_TEST_DECREF_AC(setPublicKey);
+ PKIX_TEST_DECREF_AC(getPublicKey);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+printUsage(void)
+{
+ (void)printf("\nUSAGE:\ttest_comcertselparams \n\n");
+}
+
+int
+test_comcertselparams(int argc, char *argv[])
+{
+
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_UInt32 j = 0;
+
+ PKIX_PL_Cert *testCert = NULL;
+ PKIX_PL_Cert *goodCert = NULL;
+ PKIX_PL_Cert *equalCert = NULL;
+ PKIX_PL_Cert *diffCert = NULL;
+ PKIX_PL_CertBasicConstraints *goodBasicConstraints = NULL;
+ PKIX_PL_CertBasicConstraints *diffBasicConstraints = NULL;
+ PKIX_List *testPolicyInfos = NULL; /* CertPolicyInfos */
+ PKIX_List *cert2PolicyInfos = NULL; /* CertPolicyInfos */
+
+ PKIX_ComCertSelParams *goodParams = NULL;
+ PKIX_ComCertSelParams *equalParams = NULL;
+ PKIX_PL_X500Name *goodSubject = NULL;
+ PKIX_PL_X500Name *equalSubject = NULL;
+ PKIX_PL_X500Name *diffSubject = NULL;
+ PKIX_PL_X500Name *testSubject = NULL;
+ PKIX_Int32 goodMinPathLength = 0;
+ PKIX_Int32 equalMinPathLength = 0;
+ PKIX_Int32 diffMinPathLength = 0;
+ PKIX_Int32 testMinPathLength = 0;
+ PKIX_List *goodPolicies = NULL; /* OIDs */
+ PKIX_List *equalPolicies = NULL; /* OIDs */
+ PKIX_List *testPolicies = NULL; /* OIDs */
+ PKIX_List *cert2Policies = NULL; /* OIDs */
+
+ PKIX_PL_Date *testDate = NULL;
+ PKIX_PL_Date *goodDate = NULL;
+ PKIX_PL_Date *equalDate = NULL;
+ PKIX_PL_String *stringRep = NULL;
+ char *asciiRep = NULL;
+ char *dirName = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ if (argc < 2) {
+ printUsage();
+ return (0);
+ }
+
+ startTests("ComCertSelParams");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ dirName = argv[j + 1];
+
+ asciiRep = "050501000000Z";
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII, asciiRep, 0, &stringRep, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Date_Create_UTCTime(stringRep, &testDate, plContext));
+
+ testCert = createCert(dirName, "PoliciesP1234CACert.crt", plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetSubject(testCert, &testSubject, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetBasicConstraints(testCert, &goodBasicConstraints, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_BasicConstraints_GetPathLenConstraint(goodBasicConstraints, &testMinPathLength, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetPolicyInformation(testCert, &testPolicyInfos, plContext));
+
+ /* Convert from List of CertPolicyInfos to List of OIDs */
+ test_CreateOIDList(testPolicyInfos, &testPolicies);
+
+ subTest("Create goodParams and set its fields");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&goodParams, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetSubject(goodParams, testSubject, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetBasicConstraints(goodParams, testMinPathLength, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetCertificateValid(goodParams, testDate, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetPolicy(goodParams, testPolicies, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetCertificate(goodParams, testCert, plContext));
+
+ subTest("Duplicate goodParams and verify copy");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Duplicate((PKIX_PL_Object *)goodParams,
+ (PKIX_PL_Object **)&equalParams,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetSubject(goodParams, &goodSubject, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetBasicConstraints(goodParams, &goodMinPathLength, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetCertificate(goodParams, &goodCert, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetCertificateValid(goodParams, &goodDate, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetPolicy(goodParams, &goodPolicies, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetSubject(equalParams, &equalSubject, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetBasicConstraints(equalParams, &equalMinPathLength, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetPolicy(equalParams, &equalPolicies, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetCertificate(equalParams, &equalCert, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetCertificateValid(equalParams, &equalDate, plContext));
+
+ testEqualsHelper((PKIX_PL_Object *)goodSubject,
+ (PKIX_PL_Object *)equalSubject,
+ PKIX_TRUE,
+ plContext);
+
+ if (goodMinPathLength != equalMinPathLength) {
+ testError("unexpected mismatch");
+ (void)printf("goodMinPathLength:\t%d\n", goodMinPathLength);
+ (void)printf("equalMinPathLength:\t%d\n", equalMinPathLength);
+ }
+
+ testEqualsHelper((PKIX_PL_Object *)goodPolicies,
+ (PKIX_PL_Object *)equalPolicies,
+ PKIX_TRUE,
+ plContext);
+
+ testEqualsHelper((PKIX_PL_Object *)goodCert,
+ (PKIX_PL_Object *)equalCert,
+ PKIX_TRUE,
+ plContext);
+
+ testEqualsHelper((PKIX_PL_Object *)goodDate,
+ (PKIX_PL_Object *)equalDate,
+ PKIX_TRUE,
+ plContext);
+
+ PKIX_TEST_DECREF_BC(equalSubject);
+ PKIX_TEST_DECREF_BC(equalPolicies);
+ PKIX_TEST_DECREF_BC(equalCert);
+ PKIX_TEST_DECREF_AC(equalDate);
+
+ subTest("Set different values and verify differences");
+
+ diffCert = createCert(dirName, "pathLenConstraint6CACert.crt", plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetSubject(diffCert, &diffSubject, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetBasicConstraints(diffCert, &diffBasicConstraints, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_BasicConstraints_GetPathLenConstraint(diffBasicConstraints, &diffMinPathLength, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetPolicyInformation(diffCert, &cert2PolicyInfos, plContext));
+ test_CreateOIDList(cert2PolicyInfos, &cert2Policies);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetSubject(
+ equalParams, diffSubject, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetBasicConstraints(equalParams, diffMinPathLength, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetPolicy(equalParams, cert2Policies, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetSubject(equalParams, &equalSubject, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetBasicConstraints(equalParams, &equalMinPathLength, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetPolicy(equalParams, &equalPolicies, plContext));
+
+ testEqualsHelper((PKIX_PL_Object *)goodSubject,
+ (PKIX_PL_Object *)equalSubject,
+ PKIX_FALSE,
+ plContext);
+
+ if (goodMinPathLength == equalMinPathLength) {
+ testError("unexpected match");
+ (void)printf("goodMinPathLength:\t%d\n", goodMinPathLength);
+ (void)printf("equalMinPathLength:\t%d\n", equalMinPathLength);
+ }
+
+ testEqualsHelper((PKIX_PL_Object *)goodPolicies,
+ (PKIX_PL_Object *)equalPolicies,
+ PKIX_FALSE,
+ plContext);
+
+ test_NameConstraints(dirName);
+ test_PathToNames();
+ test_SubjAltNames();
+ test_KeyUsages();
+ test_Version_Issuer_SerialNumber();
+ test_SubjKeyId_AuthKeyId();
+ test_SubjAlgId_SubjPublicKey(dirName);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(testSubject);
+ PKIX_TEST_DECREF_AC(goodSubject);
+ PKIX_TEST_DECREF_AC(equalSubject);
+ PKIX_TEST_DECREF_AC(diffSubject);
+ PKIX_TEST_DECREF_AC(testSubject);
+ PKIX_TEST_DECREF_AC(goodPolicies);
+ PKIX_TEST_DECREF_AC(equalPolicies);
+ PKIX_TEST_DECREF_AC(testPolicies);
+ PKIX_TEST_DECREF_AC(cert2Policies);
+ PKIX_TEST_DECREF_AC(goodParams);
+ PKIX_TEST_DECREF_AC(equalParams);
+ PKIX_TEST_DECREF_AC(goodCert);
+ PKIX_TEST_DECREF_AC(diffCert);
+ PKIX_TEST_DECREF_AC(testCert);
+ PKIX_TEST_DECREF_AC(goodBasicConstraints);
+ PKIX_TEST_DECREF_AC(diffBasicConstraints);
+ PKIX_TEST_DECREF_AC(testPolicyInfos);
+ PKIX_TEST_DECREF_AC(cert2PolicyInfos);
+ PKIX_TEST_DECREF_AC(stringRep);
+ PKIX_TEST_DECREF_AC(testDate);
+ PKIX_TEST_DECREF_AC(goodDate);
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("ComCertSelParams");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/checker/Makefile b/nss/cmd/libpkix/pkix/checker/Makefile
new file mode 100755
index 0000000..09ca5f1
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/checker/Makefile
@@ -0,0 +1,47 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(PKIX_DEPTH)/config.mk
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platrules.mk
diff --git a/nss/cmd/libpkix/pkix/checker/manifest.mn b/nss/cmd/libpkix/pkix/checker/manifest.mn
new file mode 100755
index 0000000..3101e02
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/checker/manifest.mn
@@ -0,0 +1,19 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+PKIX_DEPTH = ../..
+PLAT_DEPTH = $(PKIX_DEPTH)/..
+CORE_DEPTH = $(PKIX_DEPTH)/../../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+CSRCS = test_certchainchecker.c
+
+LIBRARY_NAME=pkixtoolchecker
+
+SOURCE_LIB_DIR=$(PKIX_DEPTH)/$(OBJDIR)
+
+NO_MD_RELEASE = 1
diff --git a/nss/cmd/libpkix/pkix/checker/test_certchainchecker.c b/nss/cmd/libpkix/pkix/checker/test_certchainchecker.c
new file mode 100644
index 0000000..5fab3a6
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/checker/test_certchainchecker.c
@@ -0,0 +1,185 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_certchainchecker.c
+ *
+ * Test Cert Chain Checker
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+static PKIX_Error *
+dummyChecker_Check(
+ PKIX_CertChainChecker *checker,
+ PKIX_PL_Cert *cert,
+ PKIX_List *unresolvedCriticalExtensions,
+ void **pNBIOContext,
+ void *plContext)
+{
+ goto cleanup;
+
+cleanup:
+
+ return (NULL);
+}
+
+static void
+test_CertChainChecker_Duplicate(PKIX_CertChainChecker *original)
+{
+ PKIX_Boolean originalForward = PKIX_FALSE;
+ PKIX_Boolean copyForward = PKIX_FALSE;
+ PKIX_Boolean originalForwardDir = PKIX_FALSE;
+ PKIX_Boolean copyForwardDir = PKIX_FALSE;
+ PKIX_CertChainChecker *copy = NULL;
+ PKIX_CertChainChecker_CheckCallback originalCallback = NULL;
+ PKIX_CertChainChecker_CheckCallback copyCallback = NULL;
+ PKIX_PL_Object *originalState = NULL;
+ PKIX_PL_Object *copyState = NULL;
+ PKIX_List *originalList = NULL;
+ PKIX_List *copyList = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("CertChainChecker_Duplicate");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Duplicate((PKIX_PL_Object *)original,
+ (PKIX_PL_Object **)©,
+ plContext));
+
+ subTest("CertChainChecker_GetCheckCallback");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertChainChecker_GetCheckCallback(original, &originalCallback, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertChainChecker_GetCheckCallback(copy, ©Callback, plContext));
+ if (originalCallback != copyCallback) {
+ pkixTestErrorMsg = "CheckCallback functions are not equal!";
+ goto cleanup;
+ }
+
+ subTest("CertChainChecker_IsForwardCheckingSupported");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertChainChecker_IsForwardCheckingSupported(original, &originalForward, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertChainChecker_IsForwardCheckingSupported(copy, ©Forward, plContext));
+ if (originalForward != copyForward) {
+ pkixTestErrorMsg = "ForwardChecking booleans are not equal!";
+ goto cleanup;
+ }
+
+ subTest("CertChainChecker_IsForwardDirectionExpected");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertChainChecker_IsForwardDirectionExpected(original, &originalForwardDir, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertChainChecker_IsForwardDirectionExpected(copy, ©ForwardDir, plContext));
+ if (originalForwardDir != copyForwardDir) {
+ pkixTestErrorMsg = "ForwardDirection booleans are not equal!";
+ goto cleanup;
+ }
+
+ subTest("CertChainChecker_GetCertChainCheckerState");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertChainChecker_GetCertChainCheckerState(original, &originalState, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertChainChecker_GetCertChainCheckerState(copy, ©State, plContext));
+ testEqualsHelper(originalState, copyState, PKIX_TRUE, plContext);
+
+ subTest("CertChainChecker_GetSupportedExtensions");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertChainChecker_GetSupportedExtensions(original, &originalList, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertChainChecker_GetSupportedExtensions(copy, ©List, plContext));
+ testEqualsHelper((PKIX_PL_Object *)originalList,
+ (PKIX_PL_Object *)copyList,
+ PKIX_TRUE,
+ plContext);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(copy);
+ PKIX_TEST_DECREF_AC(originalState);
+ PKIX_TEST_DECREF_AC(copyState);
+ PKIX_TEST_DECREF_AC(originalList);
+ PKIX_TEST_DECREF_AC(copyList);
+
+ PKIX_TEST_RETURN();
+}
+
+int
+test_certchainchecker(int argc, char *argv[])
+{
+
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_PL_OID *bcOID = NULL;
+ PKIX_PL_OID *ncOID = NULL;
+ PKIX_PL_OID *cpOID = NULL;
+ PKIX_PL_OID *pmOID = NULL;
+ PKIX_PL_OID *pcOID = NULL;
+ PKIX_PL_OID *iaOID = NULL;
+ PKIX_CertChainChecker *dummyChecker = NULL;
+ PKIX_List *supportedExtensions = NULL;
+ PKIX_PL_Object *initialState = NULL;
+ PKIX_UInt32 j = 0;
+
+ PKIX_TEST_STD_VARS();
+
+ startTests("CertChainChecker");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&supportedExtensions, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create(PKIX_BASICCONSTRAINTS_OID, &bcOID, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(supportedExtensions, (PKIX_PL_Object *)bcOID, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create(PKIX_NAMECONSTRAINTS_OID, &ncOID, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(supportedExtensions, (PKIX_PL_Object *)ncOID, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create(PKIX_CERTIFICATEPOLICIES_OID, &cpOID, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(supportedExtensions, (PKIX_PL_Object *)cpOID, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create(PKIX_POLICYMAPPINGS_OID, &pmOID, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(supportedExtensions, (PKIX_PL_Object *)pmOID, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create(PKIX_POLICYCONSTRAINTS_OID, &pcOID, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(supportedExtensions, (PKIX_PL_Object *)pcOID, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create(PKIX_INHIBITANYPOLICY_OID, &iaOID, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(supportedExtensions, (PKIX_PL_Object *)iaOID, plContext));
+
+ PKIX_TEST_DECREF_BC(bcOID);
+ PKIX_TEST_DECREF_BC(ncOID);
+ PKIX_TEST_DECREF_BC(cpOID);
+ PKIX_TEST_DECREF_BC(pmOID);
+ PKIX_TEST_DECREF_BC(pcOID);
+ PKIX_TEST_DECREF_BC(iaOID);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_IncRef((PKIX_PL_Object *)supportedExtensions, plContext));
+
+ initialState = (PKIX_PL_Object *)supportedExtensions;
+
+ subTest("CertChainChecker_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertChainChecker_Create(dummyChecker_Check, /* PKIX_CertChainChecker_CheckCallback */
+ PKIX_FALSE, /* forwardCheckingSupported */
+ PKIX_FALSE, /* forwardDirectionExpected */
+ supportedExtensions,
+ NULL, /* PKIX_PL_Object *initialState */
+ &dummyChecker,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertChainChecker_SetCertChainCheckerState(dummyChecker, initialState, plContext));
+
+ test_CertChainChecker_Duplicate(dummyChecker);
+
+ subTest("CertChainChecker_Destroy");
+ PKIX_TEST_DECREF_BC(dummyChecker);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(dummyChecker);
+ PKIX_TEST_DECREF_AC(initialState);
+ PKIX_TEST_DECREF_AC(supportedExtensions);
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("CertChainChecker");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/crlsel/Makefile b/nss/cmd/libpkix/pkix/crlsel/Makefile
new file mode 100755
index 0000000..09ca5f1
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/crlsel/Makefile
@@ -0,0 +1,47 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(PKIX_DEPTH)/config.mk
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platrules.mk
diff --git a/nss/cmd/libpkix/pkix/crlsel/manifest.mn b/nss/cmd/libpkix/pkix/crlsel/manifest.mn
new file mode 100755
index 0000000..dfac43b
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/crlsel/manifest.mn
@@ -0,0 +1,21 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+PKIX_DEPTH = ../..
+PLAT_DEPTH = $(PKIX_DEPTH)/..
+CORE_DEPTH = $(PKIX_DEPTH)/../../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+CSRCS = test_crlselector.c \
+ test_comcrlselparams.c \
+ $(NULL)
+
+LIBRARY_NAME=pkixtoolcrlsel
+
+SOURCE_LIB_DIR=$(PKIX_DEPTH)/$(OBJDIR)
+
+NO_MD_RELEASE = 1
diff --git a/nss/cmd/libpkix/pkix/crlsel/test_comcrlselparams.c b/nss/cmd/libpkix/pkix/crlsel/test_comcrlselparams.c
new file mode 100644
index 0000000..fcc5ef5
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/crlsel/test_comcrlselparams.c
@@ -0,0 +1,406 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_comcrlselparams.c
+ *
+ * Test ComCRLSelParams Type
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+static void
+testIssuer(PKIX_ComCRLSelParams *goodObject)
+{
+ PKIX_PL_String *issuer1String = NULL;
+ PKIX_PL_String *issuer2String = NULL;
+ PKIX_PL_String *issuer3String = NULL;
+ PKIX_PL_X500Name *issuerName1 = NULL;
+ PKIX_PL_X500Name *issuerName2 = NULL;
+ PKIX_PL_X500Name *issuerName3 = NULL;
+ PKIX_List *setIssuerList = NULL;
+ PKIX_List *getIssuerList = NULL;
+ PKIX_PL_String *issuerListString = NULL;
+ char *name1 = "CN=yassir,OU=bcn,OU=east,O=sun,C=us";
+ char *name2 = "CN=richard,OU=bcn,OU=east,O=sun,C=us";
+ char *name3 = "CN=hanfei,OU=bcn,OU=east,O=sun,C=us";
+ PKIX_Int32 length;
+ PKIX_Boolean result = PKIX_FALSE;
+ char *expectedAscii =
+ "(CN=yassir,OU=bcn,OU=east,O=sun,"
+ "C=us, CN=richard,OU=bcn,OU=east,O=sun,C=us, "
+ "CN=hanfei,OU=bcn,OU=east,O=sun,C=us)";
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_ComCRLSelParams Create Issuers");
+
+ length = PL_strlen(name1);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_UTF8,
+ name1,
+ length,
+ &issuer1String,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_X500Name_Create(issuer1String,
+ &issuerName1,
+ plContext));
+
+ length = PL_strlen(name2);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_UTF8,
+ name2,
+ length,
+ &issuer2String,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_X500Name_Create(issuer2String,
+ &issuerName2,
+ plContext));
+
+ length = PL_strlen(name3);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_UTF8,
+ name3,
+ length,
+ &issuer3String,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_X500Name_Create(issuer3String,
+ &issuerName3,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&setIssuerList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(setIssuerList,
+ (PKIX_PL_Object *)issuerName1,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(setIssuerList,
+ (PKIX_PL_Object *)issuerName2,
+ plContext));
+
+ subTest("PKIX_ComCRLSelParams_AddIssuerName");
+
+ /* Test adding an issuer to an empty list */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_AddIssuerName(goodObject, issuerName3, plContext));
+
+ subTest("PKIX_ComCRLSelParams_GetIssuerNames");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_GetIssuerNames(goodObject, &getIssuerList, plContext));
+
+ /* DECREF for GetIssuerNames */
+ PKIX_TEST_DECREF_BC(getIssuerList);
+ /* DECREF for AddIssuerName so next SetIssuerName start clean */
+ PKIX_TEST_DECREF_BC(getIssuerList);
+
+ /* Test setting issuer names on the list */
+ subTest("PKIX_ComCRLSelParams_SetIssuerNames");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_SetIssuerNames(goodObject, setIssuerList, plContext));
+
+ subTest("PKIX_ComCRLSelParams_GetIssuerNames");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_GetIssuerNames(goodObject, &getIssuerList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)setIssuerList,
+ (PKIX_PL_Object *)getIssuerList,
+ &result,
+ plContext));
+
+ if (result != PKIX_TRUE) {
+ pkixTestErrorMsg = "unexpected Issuers mismatch";
+ }
+
+ /* Test adding an issuer to existing list */
+ subTest("PKIX_ComCRLSelParams_AddIssuerName");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_AddIssuerName(goodObject, issuerName3, plContext));
+
+ subTest("PKIX_ComCRLSelParams_GetIssuerNames");
+ PKIX_TEST_DECREF_BC(getIssuerList);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_GetIssuerNames(goodObject, &getIssuerList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)getIssuerList,
+ &issuerListString,
+ plContext));
+
+ testToStringHelper((PKIX_PL_Object *)getIssuerList,
+ expectedAscii, plContext);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(issuer1String);
+ PKIX_TEST_DECREF_AC(issuer2String);
+ PKIX_TEST_DECREF_AC(issuer3String);
+ PKIX_TEST_DECREF_AC(issuerListString);
+ PKIX_TEST_DECREF_AC(issuerName1);
+ PKIX_TEST_DECREF_AC(issuerName2);
+ PKIX_TEST_DECREF_AC(issuerName3);
+ PKIX_TEST_DECREF_AC(setIssuerList);
+ PKIX_TEST_DECREF_AC(getIssuerList);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testCertificateChecking(
+ char *dataCentralDir,
+ char *goodInput,
+ PKIX_ComCRLSelParams *goodObject)
+{
+ PKIX_PL_Cert *setCert = NULL;
+ PKIX_PL_Cert *getCert = NULL;
+ PKIX_Boolean result = PKIX_FALSE;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("Test CertificateChecking Cert Create");
+ setCert = createCert(dataCentralDir, goodInput, plContext);
+ if (setCert == NULL) {
+ pkixTestErrorMsg = "create certificate failed";
+ goto cleanup;
+ }
+
+ subTest("PKIX_ComCRLSelParams_SetCertificateChecking");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_SetCertificateChecking(goodObject, setCert, plContext));
+
+ subTest("PKIX_ComCRLSelParams_GetCertificateChecking");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_GetCertificateChecking(goodObject, &getCert, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)setCert,
+ (PKIX_PL_Object *)getCert,
+ &result, plContext));
+
+ if (result != PKIX_TRUE) {
+ pkixTestErrorMsg = "unexpected Cert mismatch";
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(setCert);
+ PKIX_TEST_DECREF_AC(getCert);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testDateAndTime(PKIX_ComCRLSelParams *goodObject)
+{
+
+ PKIX_PL_Date *setDate = NULL;
+ PKIX_PL_Date *getDate = NULL;
+ char *asciiDate = "040329134847Z";
+ PKIX_Boolean result = PKIX_FALSE;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_ComCRLSelParams_Date Create");
+ setDate = createDate(asciiDate, plContext);
+
+ subTest("PKIX_ComCRLSelParams_SetDateAndTime");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_SetDateAndTime(goodObject, setDate, plContext));
+
+ subTest("PKIX_ComCRLSelParams_GetDateAndTime");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_GetDateAndTime(goodObject, &getDate, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)setDate,
+ (PKIX_PL_Object *)getDate,
+ &result, plContext));
+
+ if (result != PKIX_TRUE) {
+ pkixTestErrorMsg = "unexpected DateAndTime mismatch";
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(setDate);
+ PKIX_TEST_DECREF_AC(getDate);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testMaxMinCRLNumbers(PKIX_ComCRLSelParams *goodObject)
+{
+ PKIX_PL_BigInt *setMaxCrlNumber = NULL;
+ PKIX_PL_BigInt *getMaxCrlNumber = NULL;
+ PKIX_PL_BigInt *setMinCrlNumber = NULL;
+ PKIX_PL_BigInt *getMinCrlNumber = NULL;
+ char *asciiCrlNumber1 = "01";
+ char *asciiCrlNumber99999 = "0909090909";
+ PKIX_PL_String *crlNumber1String = NULL;
+ PKIX_PL_String *crlNumber99999String = NULL;
+
+ PKIX_Boolean result = PKIX_FALSE;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_ComCRLSelParams_SetMinCRLNumber");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII,
+ asciiCrlNumber1,
+ PL_strlen(asciiCrlNumber1),
+ &crlNumber1String,
+ NULL));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_BigInt_Create(crlNumber1String, &setMinCrlNumber, NULL));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_SetMinCRLNumber(goodObject, setMinCrlNumber, NULL));
+
+ subTest("PKIX_ComCRLSelParams_GetMinCRLNumber");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_GetMinCRLNumber(goodObject, &getMinCrlNumber, NULL));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)setMinCrlNumber,
+ (PKIX_PL_Object *)getMinCrlNumber,
+ &result, NULL));
+
+ if (result != PKIX_TRUE) {
+ pkixTestErrorMsg = "unexpected Minimum CRL Number mismatch";
+ }
+
+ subTest("PKIX_ComCRLSelParams_SetMaxCRLNumber");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII,
+ asciiCrlNumber99999,
+ PL_strlen(asciiCrlNumber99999),
+ &crlNumber99999String,
+ NULL));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_BigInt_Create(crlNumber99999String, &setMaxCrlNumber, NULL));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_SetMaxCRLNumber(goodObject, setMaxCrlNumber, NULL));
+
+ subTest("PKIX_ComCRLSelParams_GetMaxCRLNumber");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_GetMaxCRLNumber(goodObject, &getMaxCrlNumber, NULL));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)setMaxCrlNumber,
+ (PKIX_PL_Object *)getMaxCrlNumber,
+ &result, NULL));
+
+ if (result != PKIX_TRUE) {
+ pkixTestErrorMsg = "unexpected Maximum CRL Number mismatch";
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(setMaxCrlNumber);
+ PKIX_TEST_DECREF_AC(getMaxCrlNumber);
+ PKIX_TEST_DECREF_AC(setMinCrlNumber);
+ PKIX_TEST_DECREF_AC(getMinCrlNumber);
+ PKIX_TEST_DECREF_AC(crlNumber1String);
+ PKIX_TEST_DECREF_AC(crlNumber99999String);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testDuplicate(PKIX_ComCRLSelParams *goodObject)
+{
+
+ PKIX_ComCRLSelParams *dupObject = NULL;
+ PKIX_Boolean result = PKIX_FALSE;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_ComCRLSelParams_Duplicate");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Duplicate((PKIX_PL_Object *)goodObject,
+ (PKIX_PL_Object **)&dupObject,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)goodObject,
+ (PKIX_PL_Object *)dupObject,
+ &result, plContext));
+
+ if (result != PKIX_TRUE) {
+ pkixTestErrorMsg =
+ "unexpected Duplicate ComCRLSelParams mismatch";
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(dupObject);
+ PKIX_TEST_RETURN();
+}
+
+static void
+printUsage(char *pName)
+{
+ printf("\nUSAGE: %s \n\n", pName);
+}
+
+/* Functional tests for ComCRLSelParams public functions */
+
+int
+test_comcrlselparams(int argc, char *argv[])
+{
+
+ char *dataCentralDir = NULL;
+ char *goodInput = "yassir2yassir";
+ PKIX_ComCRLSelParams *goodObject = NULL;
+ PKIX_ComCRLSelParams *diffObject = NULL;
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_UInt32 j = 0;
+
+ PKIX_TEST_STD_VARS();
+
+ startTests("ComCRLSelParams");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ if (argc < 2) {
+ printUsage(argv[0]);
+ return (0);
+ }
+
+ dataCentralDir = argv[j + 1];
+
+ subTest("PKIX_ComCRLSelParams_Create");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_Create(&goodObject,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_Create(&diffObject,
+ plContext));
+
+ testIssuer(goodObject);
+
+ testCertificateChecking(dataCentralDir, goodInput, goodObject);
+
+ testDateAndTime(goodObject);
+
+ testMaxMinCRLNumbers(goodObject);
+
+ testDuplicate(goodObject);
+
+ PKIX_TEST_EQ_HASH_TOSTR_DUP(goodObject,
+ goodObject,
+ diffObject,
+ NULL,
+ ComCRLSelParams,
+ PKIX_TRUE);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(goodObject);
+ PKIX_TEST_DECREF_AC(diffObject);
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("ComCRLSelParams");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/crlsel/test_crlselector.c b/nss/cmd/libpkix/pkix/crlsel/test_crlselector.c
new file mode 100644
index 0000000..f17406b
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/crlsel/test_crlselector.c
@@ -0,0 +1,168 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_crlselector.c
+ *
+ * Test CRLSelector Type
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+static void
+testGetMatchCallback(PKIX_CRLSelector *goodObject)
+{
+ PKIX_CRLSelector_MatchCallback mCallback = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("testGetMatchCallback");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CRLSelector_GetMatchCallback(goodObject, &mCallback, plContext));
+
+ if (mCallback == NULL) {
+ pkixTestErrorMsg = "MatchCallback is NULL";
+ }
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetCRLSelectorContext(PKIX_CRLSelector *goodObject)
+{
+ PKIX_PL_Object *context = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("testGetCRLSelectorContext");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CRLSelector_GetCRLSelectorContext(goodObject, (void *)&context, plContext));
+
+ if (context == NULL) {
+ pkixTestErrorMsg = "CRLSelectorContext is NULL";
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(context);
+ PKIX_TEST_RETURN();
+}
+
+static void
+testCommonCRLSelectorParams(PKIX_CRLSelector *goodObject)
+{
+ PKIX_ComCRLSelParams *setParams = NULL;
+ PKIX_ComCRLSelParams *getParams = NULL;
+ PKIX_PL_Date *setDate = NULL;
+ char *asciiDate = "040329134847Z";
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_ComCRLSelParams_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_Create(&setParams,
+ plContext));
+
+ subTest("PKIX_ComCRLSelParams_Date Create");
+
+ setDate = createDate(asciiDate, plContext);
+
+ subTest("PKIX_ComCRLSelParams_SetDateAndTime");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_SetDateAndTime(setParams, setDate, plContext));
+
+ subTest("PKIX_CRLSelector_SetCommonCRLSelectorParams");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CRLSelector_SetCommonCRLSelectorParams(
+ goodObject, setParams, plContext));
+
+ subTest("PKIX_CRLSelector_GetCommonCRLSelectorParams");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CRLSelector_GetCommonCRLSelectorParams(
+ goodObject, &getParams, plContext));
+
+ testEqualsHelper((PKIX_PL_Object *)setParams,
+ (PKIX_PL_Object *)getParams,
+ PKIX_TRUE,
+ plContext);
+
+ testHashcodeHelper((PKIX_PL_Object *)setParams,
+ (PKIX_PL_Object *)getParams,
+ PKIX_TRUE,
+ plContext);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(setDate);
+ PKIX_TEST_DECREF_AC(setParams);
+ PKIX_TEST_DECREF_AC(getParams);
+
+ PKIX_TEST_RETURN();
+}
+
+/* Functional tests for CRLSelector public functions */
+
+int
+test_crlselector(int argc, char *argv[])
+{
+
+ PKIX_PL_Date *context = NULL;
+ PKIX_CRLSelector *goodObject = NULL;
+ PKIX_CRLSelector *diffObject = NULL;
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_UInt32 j = 0;
+ char *asciiDate = "040329134847Z";
+
+ PKIX_TEST_STD_VARS();
+
+ startTests("CRLSelector");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ context = createDate(asciiDate, plContext);
+
+ subTest("PKIX_CRLSelector_Create");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CRLSelector_Create(NULL,
+ (PKIX_PL_Object *)context,
+ &goodObject,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CRLSelector_Create(NULL,
+ (PKIX_PL_Object *)context,
+ &diffObject,
+ plContext));
+
+ testGetMatchCallback(goodObject);
+
+ testGetCRLSelectorContext(goodObject);
+
+ testCommonCRLSelectorParams(goodObject);
+
+ PKIX_TEST_EQ_HASH_TOSTR_DUP(goodObject,
+ goodObject,
+ diffObject,
+ NULL,
+ CRLSelector,
+ PKIX_TRUE);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(goodObject);
+ PKIX_TEST_DECREF_AC(diffObject);
+ PKIX_TEST_DECREF_AC(context);
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("CRLSelector");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/manifest.mn b/nss/cmd/libpkix/pkix/manifest.mn
new file mode 100755
index 0000000..895bf52
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/manifest.mn
@@ -0,0 +1,11 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+PKIX_DEPTH = ..
+PLAT_DEPTH = $(PKIX_DEPTH)/..
+CORE_DEPTH = $(PKIX_DEPTH)/../../..
+
+DIRS = certsel checker crlsel params results store top util \
+ $(NULL)
diff --git a/nss/cmd/libpkix/pkix/params/Makefile b/nss/cmd/libpkix/pkix/params/Makefile
new file mode 100755
index 0000000..09ca5f1
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/params/Makefile
@@ -0,0 +1,47 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(PKIX_DEPTH)/config.mk
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platrules.mk
diff --git a/nss/cmd/libpkix/pkix/params/manifest.mn b/nss/cmd/libpkix/pkix/params/manifest.mn
new file mode 100755
index 0000000..a2e7e67
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/params/manifest.mn
@@ -0,0 +1,23 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+PKIX_DEPTH = ../..
+PLAT_DEPTH = $(PKIX_DEPTH)/..
+CORE_DEPTH = $(PKIX_DEPTH)/../../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+CSRCS = test_procparams.c \
+ test_trustanchor.c \
+ test_valparams.c \
+ test_resourcelimits.c \
+ $(NULL)
+
+LIBRARY_NAME=pkixtoolparams
+
+SOURCE_LIB_DIR=$(PKIX_DEPTH)/$(OBJDIR)
+
+NO_MD_RELEASE = 1
diff --git a/nss/cmd/libpkix/pkix/params/test_procparams.c b/nss/cmd/libpkix/pkix/params/test_procparams.c
new file mode 100644
index 0000000..419322a
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/params/test_procparams.c
@@ -0,0 +1,478 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_procparams.c
+ *
+ * Test ProcessingParams Type
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+static void
+testDestroy(void *goodObject, void *equalObject, void *diffObject)
+{
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_ProcessingParams_Destroy");
+
+ PKIX_TEST_DECREF_BC(goodObject);
+ PKIX_TEST_DECREF_BC(equalObject);
+ PKIX_TEST_DECREF_BC(diffObject);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetAnchors(
+ PKIX_ProcessingParams *goodObject,
+ PKIX_ProcessingParams *equalObject)
+{
+
+ PKIX_List *goodAnchors = NULL;
+ PKIX_List *equalAnchors = NULL;
+
+ PKIX_TEST_STD_VARS();
+ subTest("PKIX_ProcessingParams_GetTrustAnchors");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_GetTrustAnchors(goodObject, &goodAnchors, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_GetTrustAnchors(equalObject, &equalAnchors, plContext));
+
+ testEqualsHelper((PKIX_PL_Object *)goodAnchors,
+ (PKIX_PL_Object *)equalAnchors,
+ PKIX_TRUE,
+ plContext);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(goodAnchors);
+ PKIX_TEST_DECREF_AC(equalAnchors);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetSetDate(
+ PKIX_ProcessingParams *goodObject,
+ PKIX_ProcessingParams *equalObject)
+{
+
+ PKIX_PL_Date *setDate = NULL;
+ PKIX_PL_Date *getDate = NULL;
+ char *asciiDate = "040329134847Z";
+
+ PKIX_TEST_STD_VARS();
+ subTest("PKIX_ProcessingParams_Get/SetDate");
+
+ setDate = createDate(asciiDate, plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetDate(goodObject, setDate, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_GetDate(goodObject, &getDate, plContext));
+
+ testEqualsHelper((PKIX_PL_Object *)setDate,
+ (PKIX_PL_Object *)getDate,
+ PKIX_TRUE,
+ plContext);
+
+ /* we want to make sure that goodObject and equalObject are "equal" */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetDate(equalObject, setDate, plContext));
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(setDate);
+ PKIX_TEST_DECREF_AC(getDate);
+
+ PKIX_TEST_RETURN();
+}
+
+static PKIX_Error *
+userChecker1cb(
+ PKIX_CertChainChecker *checker,
+ PKIX_PL_Cert *cert,
+ PKIX_List *unresolvedCriticalExtensions, /* list of PKIX_PL_OID */
+ void **pNBIOContext,
+ void *plContext)
+{
+ return (NULL);
+}
+
+static void
+testGetSetCertChainCheckers(
+ PKIX_ProcessingParams *goodObject,
+ PKIX_ProcessingParams *equalObject)
+{
+
+ PKIX_CertChainChecker *checker = NULL;
+ PKIX_List *setCheckersList = NULL;
+ PKIX_List *getCheckersList = NULL;
+ PKIX_PL_Date *date = NULL;
+ char *asciiDate = "040329134847Z";
+
+ PKIX_TEST_STD_VARS();
+ subTest("PKIX_ProcessingParams_Get/SetCertChainCheckers");
+
+ date = createDate(asciiDate, plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertChainChecker_Create(userChecker1cb,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ NULL,
+ (PKIX_PL_Object *)date,
+ &checker,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&setCheckersList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(setCheckersList, (PKIX_PL_Object *)checker, plContext));
+ PKIX_TEST_DECREF_BC(checker);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetCertChainCheckers(goodObject, setCheckersList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertChainChecker_Create(userChecker1cb,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ NULL,
+ (PKIX_PL_Object *)date,
+ &checker,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_AddCertChainChecker(goodObject, checker, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_GetCertChainCheckers(goodObject, &getCheckersList, plContext));
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(setCheckersList);
+ PKIX_TEST_DECREF_AC(getCheckersList);
+ PKIX_TEST_DECREF_AC(date);
+ PKIX_TEST_DECREF_BC(checker);
+
+ PKIX_TEST_RETURN();
+}
+
+static PKIX_Error *
+userChecker2cb(
+ PKIX_RevocationChecker *checker,
+ PKIX_PL_Cert *cert,
+ PKIX_UInt32 *pResult,
+ void *plContext)
+{
+ return (NULL);
+}
+
+static void
+testGetSetRevocationCheckers(
+ PKIX_ProcessingParams *goodObject,
+ PKIX_ProcessingParams *equalObject)
+{
+
+ PKIX_RevocationChecker *checker = NULL;
+ PKIX_List *setCheckersList = NULL;
+ PKIX_List *getCheckersList = NULL;
+ PKIX_PL_Date *date = NULL;
+ char *asciiDate = "040329134847Z";
+
+ PKIX_TEST_STD_VARS();
+ subTest("PKIX_ProcessingParams_Get/SetRevocationCheckers");
+
+ date = createDate(asciiDate, plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_RevocationChecker_Create(userChecker2cb,
+ (PKIX_PL_Object *)date,
+ &checker,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&setCheckersList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(setCheckersList,
+ (PKIX_PL_Object *)checker,
+ plContext));
+ PKIX_TEST_DECREF_BC(checker);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetRevocationCheckers(goodObject, setCheckersList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_RevocationChecker_Create(userChecker2cb,
+ (PKIX_PL_Object *)date,
+ &checker,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_AddRevocationChecker(goodObject, checker, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_GetRevocationCheckers(goodObject, &getCheckersList, plContext));
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(setCheckersList);
+ PKIX_TEST_DECREF_AC(getCheckersList);
+ PKIX_TEST_DECREF_AC(date);
+ PKIX_TEST_DECREF_BC(checker);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetSetResourceLimits(
+ PKIX_ProcessingParams *goodObject,
+ PKIX_ProcessingParams *equalObject)
+
+{
+ PKIX_ResourceLimits *resourceLimits1 = NULL;
+ PKIX_ResourceLimits *resourceLimits2 = NULL;
+
+ PKIX_TEST_STD_VARS();
+ subTest("PKIX_ProcessingParams_Get/SetResourceLimits");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_Create(&resourceLimits1, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_Create(&resourceLimits2, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_SetMaxFanout(resourceLimits1, 3, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_SetMaxDepth(resourceLimits1, 3, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_SetMaxTime(resourceLimits1, 2, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetResourceLimits(goodObject, resourceLimits1, plContext));
+
+ PKIX_TEST_DECREF_BC(resourceLimits2);
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_GetResourceLimits(goodObject, &resourceLimits2, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetResourceLimits(equalObject, resourceLimits2, plContext));
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(resourceLimits1);
+ PKIX_TEST_DECREF_AC(resourceLimits2);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetSetConstraints(PKIX_ProcessingParams *goodObject)
+{
+
+ PKIX_CertSelector *setConstraints = NULL;
+ PKIX_CertSelector *getConstraints = NULL;
+
+ PKIX_TEST_STD_VARS();
+ subTest("PKIX_ProcessingParams_Get/SetTargetCertConstraints");
+
+ /*
+ * After createConstraints is implemented
+ * setConstraints = createConstraints();
+ */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetTargetCertConstraints(goodObject, setConstraints, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_GetTargetCertConstraints(goodObject, &getConstraints, plContext));
+
+ testEqualsHelper((PKIX_PL_Object *)setConstraints,
+ (PKIX_PL_Object *)getConstraints,
+ PKIX_TRUE,
+ plContext);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(setConstraints);
+ PKIX_TEST_DECREF_AC(getConstraints);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetSetInitialPolicies(
+ PKIX_ProcessingParams *goodObject,
+ char *asciiPolicyOID)
+{
+ PKIX_PL_OID *policyOID = NULL;
+ PKIX_List *setPolicyList = NULL;
+ PKIX_List *getPolicyList = NULL;
+
+ PKIX_TEST_STD_VARS();
+ subTest("PKIX_ProcessingParams_Get/SetInitialPolicies");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create(asciiPolicyOID, &policyOID, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&setPolicyList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(setPolicyList, (PKIX_PL_Object *)policyOID, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetImmutable(setPolicyList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetInitialPolicies(goodObject, setPolicyList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_GetInitialPolicies(goodObject, &getPolicyList, plContext));
+
+ testEqualsHelper((PKIX_PL_Object *)setPolicyList,
+ (PKIX_PL_Object *)getPolicyList,
+ PKIX_TRUE,
+ plContext);
+
+cleanup:
+ PKIX_TEST_DECREF_AC(policyOID);
+ PKIX_TEST_DECREF_AC(setPolicyList);
+ PKIX_TEST_DECREF_AC(getPolicyList);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetSetPolicyQualifiersRejected(
+ PKIX_ProcessingParams *goodObject,
+ PKIX_Boolean rejected)
+{
+ PKIX_Boolean getRejected = PKIX_FALSE;
+
+ PKIX_TEST_STD_VARS();
+ subTest("PKIX_ProcessingParams_Get/SetPolicyQualifiersRejected");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetPolicyQualifiersRejected(goodObject, rejected, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_GetPolicyQualifiersRejected(goodObject, &getRejected, plContext));
+
+ if (rejected != getRejected) {
+ testError("GetPolicyQualifiersRejected returned unexpected value");
+ }
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+printUsage(char *pName)
+{
+ printf("\nUSAGE: %s \n\n", pName);
+}
+
+int
+test_procparams(int argc, char *argv[])
+{
+
+ PKIX_ProcessingParams *goodObject = NULL;
+ PKIX_ProcessingParams *equalObject = NULL;
+ PKIX_ProcessingParams *diffObject = NULL;
+ PKIX_UInt32 actualMinorVersion;
+ char *dataCentralDir = NULL;
+ PKIX_UInt32 j = 0;
+
+ char *oidAnyPolicy = PKIX_CERTIFICATEPOLICIES_ANYPOLICY_OID;
+ char *oidNist1Policy = "2.16.840.1.101.3.2.1.48.2";
+
+ char *goodInput = "yassir2yassir";
+ char *diffInput = "yassir2bcn";
+
+ char *expectedAscii =
+ "[\n"
+ "\tTrust Anchors: \n"
+ "\t********BEGIN LIST OF TRUST ANCHORS********\n"
+ "\t\t"
+ "([\n"
+ "\tTrusted CA Name: "
+ "CN=yassir,OU=bcn,OU=east,O=sun,C=us\n"
+ "\tTrusted CA PublicKey: ANSI X9.57 DSA Signature\n"
+ "\tInitial Name Constraints:(null)\n"
+ "]\n"
+ ", [\n"
+ "\tTrusted CA Name: OU=bcn,OU=east,O=sun,C=us\n"
+ "\tTrusted CA PublicKey: ANSI X9.57 DSA Signature\n"
+ "\tInitial Name Constraints:(null)\n"
+ "]\n"
+ ")\n"
+ "\t********END LIST OF TRUST ANCHORS********\n"
+ "\tDate: \t\tMon Mar 29 08:48:47 2004\n"
+ "\tTarget Constraints: (null)\n"
+ "\tInitial Policies: (2.5.29.32.0)\n"
+ "\tQualifiers Rejected: FALSE\n"
+ "\tCert Stores: (EMPTY)\n"
+ "\tResource Limits: [\n"
+ "\tMaxTime: 2\n"
+ "\tMaxFanout: 3\n"
+ "\tMaxDepth: 3\n"
+ "]\n\n"
+ "\tCRL Checking Enabled: 0\n"
+ "]\n";
+
+ PKIX_TEST_STD_VARS();
+
+ startTests("ProcessingParams");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ if (argc < 2) {
+ printUsage(argv[0]);
+ return (0);
+ }
+
+ dataCentralDir = argv[j + 1];
+
+ subTest("PKIX_ProcessingParams_Create");
+ goodObject = createProcessingParams(dataCentralDir,
+ goodInput,
+ diffInput,
+ NULL,
+ NULL,
+ PKIX_FALSE,
+ plContext);
+
+ equalObject = createProcessingParams(dataCentralDir,
+ goodInput,
+ diffInput,
+ NULL,
+ NULL,
+ PKIX_FALSE,
+ plContext);
+
+ diffObject = createProcessingParams(dataCentralDir,
+ diffInput,
+ goodInput,
+ NULL,
+ NULL,
+ PKIX_FALSE,
+ plContext);
+
+ testGetAnchors(goodObject, equalObject);
+ testGetSetDate(goodObject, equalObject);
+ testGetSetCertChainCheckers(goodObject, equalObject);
+ testGetSetRevocationCheckers(goodObject, equalObject);
+ testGetSetResourceLimits(goodObject, equalObject);
+
+ /*
+ * XXX testGetSetConstraints(goodObject);
+ */
+
+ testGetSetInitialPolicies(goodObject, oidAnyPolicy);
+ testGetSetInitialPolicies(equalObject, oidAnyPolicy);
+ testGetSetInitialPolicies(diffObject, oidNist1Policy);
+ testGetSetPolicyQualifiersRejected(goodObject, PKIX_FALSE);
+ testGetSetPolicyQualifiersRejected(equalObject, PKIX_FALSE);
+ testGetSetPolicyQualifiersRejected(diffObject, PKIX_TRUE);
+
+ PKIX_TEST_EQ_HASH_TOSTR_DUP(goodObject,
+ equalObject,
+ diffObject,
+ NULL, /* expectedAscii, */
+ ProcessingParams,
+ PKIX_FALSE);
+
+ testDestroy(goodObject, equalObject, diffObject);
+
+cleanup:
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("ProcessingParams");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/params/test_resourcelimits.c b/nss/cmd/libpkix/pkix/params/test_resourcelimits.c
new file mode 100644
index 0000000..f52c3ef
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/params/test_resourcelimits.c
@@ -0,0 +1,99 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_resourcelimits.c
+ *
+ * Test ResourceLimits Type
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+static void
+testDestroy(void *goodObject, void *equalObject, void *diffObject)
+{
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_ResourceLimits_Destroy");
+
+ PKIX_TEST_DECREF_BC(goodObject);
+ PKIX_TEST_DECREF_BC(equalObject);
+ PKIX_TEST_DECREF_BC(diffObject);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+int
+test_resourcelimits(int argc, char *argv[])
+{
+
+ PKIX_ResourceLimits *goodObject = NULL;
+ PKIX_ResourceLimits *equalObject = NULL;
+ PKIX_ResourceLimits *diffObject = NULL;
+ PKIX_UInt32 maxTime = 0;
+ PKIX_UInt32 maxFanout = 0;
+ PKIX_UInt32 maxDepth = 0;
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_UInt32 j = 0;
+ char *expectedAscii =
+ "[\n"
+ "\tMaxTime: 10\n"
+ "\tMaxFanout: 5\n"
+ "\tMaxDepth: 5\n"
+ "]\n";
+
+ PKIX_TEST_STD_VARS();
+
+ startTests("ResourceLimits");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ subTest("PKIX_ResourceLimits_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_Create(&goodObject, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_Create(&diffObject, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_Create(&equalObject, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_SetMaxTime(goodObject, 10, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_GetMaxTime(goodObject, &maxTime, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_SetMaxTime(equalObject, maxTime, plContext));
+ maxTime++;
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_SetMaxTime(diffObject, maxTime, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_SetMaxFanout(goodObject, 5, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_GetMaxFanout(goodObject, &maxFanout, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_SetMaxFanout(equalObject, maxFanout, plContext));
+ maxFanout++;
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_SetMaxFanout(diffObject, maxFanout, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_SetMaxDepth(goodObject, 5, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_GetMaxDepth(goodObject, &maxDepth, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_SetMaxDepth(equalObject, maxDepth, plContext));
+ maxDepth++;
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_SetMaxDepth(diffObject, maxDepth, plContext));
+
+ PKIX_TEST_EQ_HASH_TOSTR_DUP(goodObject,
+ equalObject,
+ diffObject,
+ expectedAscii,
+ ResourceLimits,
+ PKIX_FALSE);
+
+ testDestroy(goodObject, equalObject, diffObject);
+
+cleanup:
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("ResourceLimits");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/params/test_trustanchor.c b/nss/cmd/libpkix/pkix/params/test_trustanchor.c
new file mode 100644
index 0000000..4bd9d17
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/params/test_trustanchor.c
@@ -0,0 +1,251 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_trustanchor.c
+ *
+ * Test TrustAnchor Type
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+static void
+createTrustAnchors(
+ char *dirName,
+ char *goodInput,
+ PKIX_TrustAnchor **goodObject,
+ PKIX_TrustAnchor **equalObject,
+ PKIX_TrustAnchor **diffObject)
+{
+ subTest("PKIX_TrustAnchor_CreateWithNameKeyPair ");
+ *goodObject = createTrustAnchor(dirName, goodInput, PKIX_FALSE, plContext);
+
+ subTest("PKIX_TrustAnchor_CreateWithNameKeyPair ");
+ *equalObject = createTrustAnchor(dirName, goodInput, PKIX_FALSE, plContext);
+
+ subTest("PKIX_TrustAnchor_CreateWithCert ");
+ *diffObject = createTrustAnchor(dirName, goodInput, PKIX_TRUE, plContext);
+}
+
+static void
+testGetCAName(
+ PKIX_PL_Cert *diffCert,
+ PKIX_TrustAnchor *equalObject)
+{
+
+ PKIX_PL_X500Name *diffCAName = NULL;
+ PKIX_PL_X500Name *equalCAName = NULL;
+
+ PKIX_TEST_STD_VARS();
+ subTest("PKIX_TrustAnchor_GetCAName");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetSubject(diffCert, &diffCAName, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_TrustAnchor_GetCAName(equalObject, &equalCAName, plContext));
+
+ testEqualsHelper((PKIX_PL_Object *)diffCAName,
+ (PKIX_PL_Object *)equalCAName,
+ PKIX_TRUE,
+ plContext);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(diffCAName);
+ PKIX_TEST_DECREF_AC(equalCAName);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetCAPublicKey(
+ PKIX_PL_Cert *diffCert,
+ PKIX_TrustAnchor *equalObject)
+{
+
+ PKIX_PL_PublicKey *diffPubKey = NULL;
+ PKIX_PL_PublicKey *equalPubKey = NULL;
+
+ PKIX_TEST_STD_VARS();
+ subTest("PKIX_TrustAnchor_GetCAPublicKey");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetSubjectPublicKey(diffCert, &diffPubKey, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_TrustAnchor_GetCAPublicKey(equalObject, &equalPubKey, plContext));
+
+ testEqualsHelper((PKIX_PL_Object *)diffPubKey,
+ (PKIX_PL_Object *)equalPubKey,
+ PKIX_TRUE,
+ plContext);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(diffPubKey);
+ PKIX_TEST_DECREF_AC(equalPubKey);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetNameConstraints(char *dirName)
+{
+ PKIX_TrustAnchor *goodObject = NULL;
+ PKIX_TrustAnchor *equalObject = NULL;
+ PKIX_TrustAnchor *diffObject = NULL;
+ PKIX_PL_Cert *diffCert;
+ PKIX_PL_CertNameConstraints *diffNC = NULL;
+ PKIX_PL_CertNameConstraints *equalNC = NULL;
+ char *goodInput = "nameConstraintsDN5CACert.crt";
+ char *expectedAscii =
+ "[\n"
+ "\tTrusted CA Name: CN=nameConstraints DN5 CA,"
+ "O=Test Certificates,C=US\n"
+ "\tTrusted CA PublicKey: PKCS #1 RSA Encryption\n"
+ "\tInitial Name Constraints:[\n"
+ "\t\tPermitted Name: (OU=permittedSubtree1,"
+ "O=Test Certificates,C=US)\n"
+ "\t\tExcluded Name: (OU=excludedSubtree1,"
+ "OU=permittedSubtree1,O=Test Certificates,C=US)\n"
+ "\t]\n"
+ "\n"
+ "]\n";
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("Create TrustAnchors and compare");
+
+ createTrustAnchors(dirName, goodInput, &goodObject, &equalObject, &diffObject);
+
+ PKIX_TEST_EQ_HASH_TOSTR_DUP(goodObject,
+ equalObject,
+ diffObject,
+ expectedAscii,
+ TrustAnchor,
+ PKIX_TRUE);
+
+ subTest("PKIX_TrustAnchor_GetTrustedCert");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_TrustAnchor_GetTrustedCert(diffObject, &diffCert, plContext));
+
+ subTest("PKIX_PL_Cert_GetNameConstraints");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetNameConstraints(diffCert, &diffNC, plContext));
+
+ subTest("PKIX_TrustAnchor_GetNameConstraints");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_TrustAnchor_GetNameConstraints(equalObject, &equalNC, plContext));
+
+ testEqualsHelper((PKIX_PL_Object *)diffNC,
+ (PKIX_PL_Object *)equalNC,
+ PKIX_TRUE,
+ plContext);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(diffNC);
+ PKIX_TEST_DECREF_AC(equalNC);
+ PKIX_TEST_DECREF_BC(diffCert);
+ PKIX_TEST_DECREF_BC(goodObject);
+ PKIX_TEST_DECREF_BC(equalObject);
+ PKIX_TEST_DECREF_BC(diffObject);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testDestroy(void *goodObject, void *equalObject, void *diffObject)
+{
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_TrustAnchor_Destroy");
+
+ PKIX_TEST_DECREF_BC(goodObject);
+ PKIX_TEST_DECREF_BC(equalObject);
+ PKIX_TEST_DECREF_BC(diffObject);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+printUsage(void)
+{
+ (void)printf("\nUSAGE:\ttest_trustanchor \n\n");
+}
+
+int
+test_trustanchor(int argc, char *argv[])
+{
+
+ PKIX_TrustAnchor *goodObject = NULL;
+ PKIX_TrustAnchor *equalObject = NULL;
+ PKIX_TrustAnchor *diffObject = NULL;
+ PKIX_PL_Cert *diffCert = NULL;
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_UInt32 j = 0;
+
+ char *goodInput = "yassir2yassir";
+ char *expectedAscii =
+ "[\n"
+ "\tTrusted CA Name: "
+ "CN=yassir,OU=bcn,OU=east,O=sun,C=us\n"
+ "\tTrusted CA PublicKey: ANSI X9.57 DSA Signature\n"
+ "\tInitial Name Constraints:(null)\n"
+ "]\n";
+ char *dirName = NULL;
+ char *dataCentralDir = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ startTests("TrustAnchor");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ if (argc < 3) {
+ printUsage();
+ return (0);
+ }
+
+ dirName = argv[j + 1];
+ dataCentralDir = argv[j + 2];
+
+ createTrustAnchors(dataCentralDir,
+ goodInput,
+ &goodObject,
+ &equalObject,
+ &diffObject);
+
+ PKIX_TEST_EQ_HASH_TOSTR_DUP(goodObject,
+ equalObject,
+ diffObject,
+ expectedAscii,
+ TrustAnchor,
+ PKIX_TRUE);
+
+ subTest("PKIX_TrustAnchor_GetTrustedCert");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_TrustAnchor_GetTrustedCert(diffObject, &diffCert, plContext));
+
+ testGetCAName(diffCert, equalObject);
+ testGetCAPublicKey(diffCert, equalObject);
+
+ testGetNameConstraints(dirName);
+
+ testDestroy(goodObject, equalObject, diffObject);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(diffCert);
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("TrustAnchor");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/params/test_valparams.c b/nss/cmd/libpkix/pkix/params/test_valparams.c
new file mode 100644
index 0000000..6419062
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/params/test_valparams.c
@@ -0,0 +1,261 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_valparams.c
+ *
+ * Test ValidateParams Type
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+static void
+testDestroy(void *goodObject, void *equalObject, void *diffObject)
+{
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_ValidateParams_Destroy");
+
+ PKIX_TEST_DECREF_BC(goodObject);
+ PKIX_TEST_DECREF_BC(equalObject);
+ PKIX_TEST_DECREF_BC(diffObject);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetProcParams(
+ PKIX_ValidateParams *goodObject,
+ PKIX_ValidateParams *equalObject)
+{
+
+ PKIX_ProcessingParams *goodProcParams = NULL;
+ PKIX_ProcessingParams *equalProcParams = NULL;
+
+ PKIX_TEST_STD_VARS();
+ subTest("PKIX_ValidateParams_GetProcessingParams");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateParams_GetProcessingParams(goodObject, &goodProcParams, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateParams_GetProcessingParams(equalObject, &equalProcParams, plContext));
+
+ testEqualsHelper((PKIX_PL_Object *)goodProcParams,
+ (PKIX_PL_Object *)equalProcParams,
+ PKIX_TRUE,
+ plContext);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(goodProcParams);
+ PKIX_TEST_DECREF_AC(equalProcParams);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetCertChain(
+ PKIX_ValidateParams *goodObject,
+ PKIX_ValidateParams *equalObject)
+{
+
+ PKIX_List *goodChain = NULL;
+ PKIX_List *equalChain = NULL;
+
+ PKIX_TEST_STD_VARS();
+ subTest("PKIX_ValidateParams_GetCertChain");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateParams_GetCertChain(goodObject, &goodChain, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateParams_GetCertChain(equalObject, &equalChain, plContext));
+
+ testEqualsHelper((PKIX_PL_Object *)goodChain,
+ (PKIX_PL_Object *)equalChain,
+ PKIX_TRUE,
+ plContext);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(goodChain);
+ PKIX_TEST_DECREF_AC(equalChain);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+printUsage(char *pName)
+{
+ printf("\nUSAGE: %s \n\n", pName);
+}
+
+int
+test_valparams(int argc, char *argv[])
+{
+
+ PKIX_ValidateParams *goodObject = NULL;
+ PKIX_ValidateParams *equalObject = NULL;
+ PKIX_ValidateParams *diffObject = NULL;
+ PKIX_List *chain = NULL;
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_UInt32 j = 0;
+ char *dirName = NULL;
+
+ char *goodInput = "yassir2yassir";
+ char *diffInput = "yassir2bcn";
+
+ char *expectedAscii =
+ "[\n"
+ "\tProcessing Params: \n"
+ "\t********BEGIN PROCESSING PARAMS********\n"
+ "\t\t"
+ "[\n"
+ "\tTrust Anchors: \n"
+ "\t********BEGIN LIST OF TRUST ANCHORS********\n"
+ "\t\t"
+ "([\n"
+ "\tTrusted CA Name: "
+ "CN=yassir,OU=bcn,OU=east,O=sun,C=us\n"
+ "\tTrusted CA PublicKey: ANSI X9.57 DSA Signature\n"
+ "\tInitial Name Constraints:(null)\n"
+ "]\n"
+ ", [\n"
+ "\tTrusted CA Name: OU=bcn,OU=east,O=sun,C=us\n"
+ "\tTrusted CA PublicKey: ANSI X9.57 DSA Signature\n"
+ "\tInitial Name Constraints:(null)\n"
+ "]\n"
+ ")\n"
+ "\t********END LIST OF TRUST ANCHORS********\n"
+ "\tDate: \t\t(null)\n"
+ "\tTarget Constraints: (null)\n"
+ "\tInitial Policies: (null)\n"
+ "\tQualifiers Rejected: FALSE\n"
+ "\tCert Stores: (EMPTY)\n"
+ "\tCRL Checking Enabled: 0\n"
+ "]\n"
+ "\n"
+ "\t********END PROCESSING PARAMS********\n"
+ "\tChain: \t\t"
+ "([\n"
+ "\tVersion: v3\n"
+ "\tSerialNumber: 37bc66ec\n"
+ "\tIssuer: CN=yassir,OU=bcn,OU=east,O=sun,C=us\n"
+ "\tSubject: OU=bcn,OU=east,O=sun,C=us\n"
+ "\tValidity: [From: Thu Aug 19 16:19:56 1999\n"
+ "\t To: Fri Aug 18 16:19:56 2000]\n"
+ "\tSubjectAltNames: (null)\n"
+ "\tAuthorityKeyId: (null)\n"
+ "\tSubjectKeyId: (null)\n"
+ "\tSubjPubKeyAlgId: ANSI X9.57 DSA Signature\n"
+ "\tCritExtOIDs: (2.5.29.15, 2.5.29.19)\n"
+ "\tExtKeyUsages: (null)\n"
+ "\tBasicConstraint: CA(0)\n"
+ "\tCertPolicyInfo: (null)\n"
+ "\tPolicyMappings: (null)\n"
+ "\tExplicitPolicy: -1\n"
+ "\tInhibitMapping: -1\n"
+ "\tInhibitAnyPolicy:-1\n"
+ "\tNameConstraints: (null)\n"
+ "]\n"
+ ", [\n"
+ "\tVersion: v3\n"
+ "\tSerialNumber: 37bc65af\n"
+ "\tIssuer: CN=yassir,OU=bcn,OU=east,O=sun,C=us\n"
+ "\tSubject: CN=yassir,OU=bcn,OU=east,O=sun,C=us\n"
+ "\tValidity: [From: Thu Aug 19 16:14:39 1999\n"
+ "\t To: Fri Aug 18 16:14:39 2000]\n"
+ "\tSubjectAltNames: (null)\n"
+ "\tAuthorityKeyId: (null)\n"
+ "\tSubjectKeyId: (null)\n"
+ "\tSubjPubKeyAlgId: ANSI X9.57 DSA Signature\n"
+ "\tCritExtOIDs: (2.5.29.15, 2.5.29.19)\n"
+ "\tExtKeyUsages: (null)\n"
+ "\tBasicConstraint: CA(0)\n"
+ "\tCertPolicyInfo: (null)\n"
+ "\tPolicyMappings: (null)\n"
+ "\tExplicitPolicy: -1\n"
+ "\tInhibitMapping: -1\n"
+ "\tInhibitAnyPolicy:-1\n"
+ "\tNameConstraints: (null)\n"
+ "]\n"
+ ")\n"
+ "]\n";
+
+ PKIX_TEST_STD_VARS();
+
+ startTests("ValidateParams");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ if (argc < 2) {
+ printUsage(argv[0]);
+ return (0);
+ }
+
+ dirName = argv[j + 1];
+
+ subTest("PKIX_ValidateParams_Create");
+ chain = createCertChain(dirName, diffInput, goodInput, plContext);
+ goodObject = createValidateParams(dirName,
+ goodInput,
+ diffInput,
+ NULL,
+ NULL,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ chain,
+ plContext);
+ equalObject = createValidateParams(dirName,
+ goodInput,
+ diffInput,
+ NULL,
+ NULL,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ chain,
+ plContext);
+ diffObject = createValidateParams(dirName,
+ diffInput,
+ goodInput,
+ NULL,
+ NULL,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ chain,
+ plContext);
+
+ testGetProcParams(goodObject, equalObject);
+ testGetCertChain(goodObject, equalObject);
+
+ PKIX_TEST_EQ_HASH_TOSTR_DUP(goodObject,
+ equalObject,
+ diffObject,
+ NULL, /* expectedAscii, */
+ ValidateParams,
+ PKIX_FALSE);
+
+ testDestroy(goodObject, equalObject, diffObject);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(chain);
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("ValidateParams");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/results/Makefile b/nss/cmd/libpkix/pkix/results/Makefile
new file mode 100755
index 0000000..09ca5f1
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/results/Makefile
@@ -0,0 +1,47 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(PKIX_DEPTH)/config.mk
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platrules.mk
diff --git a/nss/cmd/libpkix/pkix/results/manifest.mn b/nss/cmd/libpkix/pkix/results/manifest.mn
new file mode 100755
index 0000000..5a8b936
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/results/manifest.mn
@@ -0,0 +1,23 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+PKIX_DEPTH = ../..
+PLAT_DEPTH = $(PKIX_DEPTH)/..
+CORE_DEPTH = $(PKIX_DEPTH)/../../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+CSRCS = test_buildresult.c \
+ test_policynode.c \
+ test_verifynode.c \
+ test_valresult.c \
+ $(NULL)
+
+LIBRARY_NAME=pkixtoolresults
+
+SOURCE_LIB_DIR=$(PKIX_DEPTH)/$(OBJDIR)
+
+NO_MD_RELEASE = 1
diff --git a/nss/cmd/libpkix/pkix/results/test_buildresult.c b/nss/cmd/libpkix/pkix/results/test_buildresult.c
new file mode 100644
index 0000000..8b13e8e
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/results/test_buildresult.c
@@ -0,0 +1,212 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_buildresult.c
+ *
+ * Test BuildResult Type
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+static void
+testDestroy(void *goodObject, void *equalObject, void *diffObject)
+{
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_BuildResult_Destroy");
+
+ PKIX_TEST_DECREF_BC(goodObject);
+ PKIX_TEST_DECREF_BC(equalObject);
+ PKIX_TEST_DECREF_BC(diffObject);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetValidateResult(
+ PKIX_BuildResult *goodObject,
+ PKIX_BuildResult *equalObject)
+{
+
+ PKIX_ValidateResult *goodValResult = NULL;
+ PKIX_ValidateResult *equalValResult = NULL;
+
+ PKIX_TEST_STD_VARS();
+ subTest("PKIX_BuildResult_GetValidateResult");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_BuildResult_GetValidateResult(goodObject, &goodValResult, NULL));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_BuildResult_GetValidateResult(equalObject, &equalValResult, NULL));
+
+ testEqualsHelper((PKIX_PL_Object *)goodValResult,
+ (PKIX_PL_Object *)equalValResult,
+ PKIX_TRUE,
+ plContext);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(goodValResult);
+ PKIX_TEST_DECREF_AC(equalValResult);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetCertChain(
+ PKIX_BuildResult *goodObject,
+ PKIX_BuildResult *equalObject)
+{
+
+ PKIX_List *goodChain = NULL;
+ PKIX_List *equalChain = NULL;
+
+ PKIX_TEST_STD_VARS();
+ subTest("PKIX_BuildResult_GetCertChain");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_BuildResult_GetCertChain(goodObject, &goodChain, NULL));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_BuildResult_GetCertChain(equalObject, &equalChain, NULL));
+
+ testEqualsHelper((PKIX_PL_Object *)goodChain,
+ (PKIX_PL_Object *)equalChain,
+ PKIX_TRUE,
+ plContext);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(goodChain);
+ PKIX_TEST_DECREF_AC(equalChain);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+printUsage(char *pName)
+{
+ printf("\nUSAGE: %s \n\n", pName);
+}
+
+int
+test_buildresult(int argc, char *argv[])
+{
+
+ PKIX_BuildResult *goodObject = NULL;
+ PKIX_BuildResult *equalObject = NULL;
+ PKIX_BuildResult *diffObject = NULL;
+ PKIX_UInt32 actualMinorVersion;
+ char *dirName = NULL;
+ PKIX_UInt32 j = 0;
+
+ char *goodInput = "yassir2yassir";
+ char *diffInput = "yassir2bcn";
+
+ char *expectedAscii =
+ "[\n"
+ "\tValidateResult: \t\t"
+ "[\n"
+ "\tTrustAnchor: \t\t"
+ "[\n"
+ "\tTrusted CA Name: "
+ "CN=yassir,OU=bcn,OU=east,O=sun,C=us\n"
+ "\tTrusted CA PublicKey: ANSI X9.57 DSA Signature\n"
+ "\tInitial Name Constraints:(null)\n"
+ "]\n"
+ "\tPubKey: \t\t"
+ "ANSI X9.57 DSA Signature\n"
+ "\tPolicyTree: \t\t(null)\n"
+ "]\n"
+ "\tCertChain: \t\t("
+ "[\n"
+ "\tVersion: v3\n"
+ "\tSerialNumber: 37bc65af\n"
+ "\tIssuer: CN=yassir,OU=bcn,OU=east,O=sun,C=us\n"
+ "\tSubject: CN=yassir,OU=bcn,OU=east,O=sun,C=us\n"
+ "\tValidity: [From: Thu Aug 19 16:14:39 1999\n"
+ "\t To: Fri Aug 18 16:14:39 2000]\n"
+ "\tSubjectAltNames: (null)\n"
+ "\tAuthorityKeyId: (null)\n"
+ "\tSubjectKeyId: (null)\n"
+ "\tSubjPubKeyAlgId: ANSI X9.57 DSA Signature\n"
+ "\tCritExtOIDs: (2.5.29.15, 2.5.29.19)\n"
+ "\tExtKeyUsages: (null)\n"
+ "\tBasicConstraint: CA(0)\n"
+ "\tCertPolicyInfo: (null)\n"
+ "\tPolicyMappings: (null)\n"
+ "\tExplicitPolicy: -1\n"
+ "\tInhibitMapping: -1\n"
+ "\tInhibitAnyPolicy:-1\n"
+ "\tNameConstraints: (null)\n"
+ "]\n"
+ ", [\n"
+ "\tVersion: v3\n"
+ "\tSerialNumber: 37bc66ec\n"
+ "\tIssuer: CN=yassir,OU=bcn,OU=east,O=sun,C=us\n"
+ "\tSubject: OU=bcn,OU=east,O=sun,C=us\n"
+ "\tValidity: [From: Thu Aug 19 16:19:56 1999\n"
+ "\t To: Fri Aug 18 16:19:56 2000]\n"
+ "\tSubjectAltNames: (null)\n"
+ "\tAuthorityKeyId: (null)\n"
+ "\tSubjectKeyId: (null)\n"
+ "\tSubjPubKeyAlgId: ANSI X9.57 DSA Signature\n"
+ "\tCritExtOIDs: (2.5.29.15, 2.5.29.19)\n"
+ "\tExtKeyUsages: (null)\n"
+ "\tBasicConstraint: CA(0)\n"
+ "\tCertPolicyInfo: (null)\n"
+ "\tPolicyMappings: (null)\n"
+ "\tExplicitPolicy: -1\n"
+ "\tInhibitMapping: -1\n"
+ "\tInhibitAnyPolicy:-1\n"
+ "\tNameConstraints: (null)\n"
+ "]\n"
+ ")\n"
+ "]\n";
+
+ PKIX_TEST_STD_VARS();
+
+ startTests("BuildResult");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ if (argc < 2) {
+ printUsage(argv[0]);
+ return (0);
+ }
+
+ dirName = argv[j + 1];
+
+ subTest("pkix_BuildResult_Create");
+
+ goodObject = createBuildResult(dirName, goodInput, diffInput, goodInput, diffInput, plContext);
+ equalObject = createBuildResult(dirName, goodInput, diffInput, goodInput, diffInput, plContext);
+ diffObject = createBuildResult(dirName, diffInput, goodInput, diffInput, goodInput, plContext);
+
+ testGetValidateResult(goodObject, equalObject);
+ testGetCertChain(goodObject, equalObject);
+
+ PKIX_TEST_EQ_HASH_TOSTR_DUP(goodObject,
+ equalObject,
+ diffObject,
+ NULL, /* expectedAscii, */
+ BuildResult,
+ PKIX_FALSE);
+
+ testDestroy(goodObject, equalObject, diffObject);
+
+cleanup:
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("BuildResult");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/results/test_policynode.c b/nss/cmd/libpkix/pkix/results/test_policynode.c
new file mode 100644
index 0000000..38ac1d9
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/results/test_policynode.c
@@ -0,0 +1,612 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_policynode.c
+ *
+ * Test PolicyNode Type
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+static void
+test_GetChildren(
+ PKIX_PolicyNode *goodNode,
+ PKIX_PolicyNode *equalNode,
+ PKIX_PolicyNode *diffNode)
+{
+
+ /*
+ * Caution: be careful where you insert this test. PKIX_PolicyNode_GetChildren
+ * is required by the API to return an immutable List, and it does it by setting
+ * the List immutable. We don't make a copy because the assumption is that
+ * certificate and policy processing have been completed before the user gets at
+ * the public API. So subsequent tests of functions that modify the policy tree,
+ * such as Prune, will fail if called after the execution of this test.
+ */
+
+ PKIX_Boolean isImmutable = PKIX_FALSE;
+ PKIX_List *goodList = NULL;
+ PKIX_List *equalList = NULL;
+ PKIX_List *diffList = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_PolicyNode_GetChildren");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PolicyNode_GetChildren(goodNode, &goodList, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PolicyNode_GetChildren(equalNode, &equalList, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PolicyNode_GetChildren(diffNode, &diffList, plContext));
+
+ PKIX_TEST_EQ_HASH_TOSTR_DUP(goodList, equalList, diffList, NULL, List, NULL);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_IsImmutable(goodList, &isImmutable, plContext));
+
+ if (isImmutable != PKIX_TRUE) {
+ testError("PKIX_PolicyNode_GetChildren returned a mutable List");
+ }
+
+cleanup:
+ PKIX_TEST_DECREF_AC(goodList);
+ PKIX_TEST_DECREF_AC(equalList);
+ PKIX_TEST_DECREF_AC(diffList);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+test_GetParent(
+ PKIX_PolicyNode *goodNode,
+ PKIX_PolicyNode *equalNode,
+ PKIX_PolicyNode *diffNode,
+ char *expectedAscii)
+{
+ PKIX_PolicyNode *goodParent = NULL;
+ PKIX_PolicyNode *equalParent = NULL;
+ PKIX_PolicyNode *diffParent = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_PolicyNode_GetParent");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PolicyNode_GetParent(goodNode, &goodParent, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PolicyNode_GetParent(equalNode, &equalParent, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PolicyNode_GetParent(diffNode, &diffParent, plContext));
+
+ PKIX_TEST_EQ_HASH_TOSTR_DUP(goodParent,
+ equalParent,
+ diffParent,
+ expectedAscii,
+ CertPolicyNode,
+ NULL);
+
+cleanup:
+ PKIX_TEST_DECREF_AC(goodParent);
+ PKIX_TEST_DECREF_AC(equalParent);
+ PKIX_TEST_DECREF_AC(diffParent);
+
+ PKIX_TEST_RETURN();
+}
+
+/*
+ * This test is the same as testDuplicateHelper, except that it
+ * produces a more useful "Actual value" and "Expected value"
+ * in the case of an unexpected mismatch.
+ */
+static void
+test_DuplicateHelper(PKIX_PolicyNode *object, void *plContext)
+{
+ PKIX_PolicyNode *newObject = NULL;
+ PKIX_Boolean cmpResult;
+ PKIX_PL_String *original = NULL;
+ PKIX_PL_String *copy = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("testing pkix_PolicyNode_Duplicate");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Duplicate((PKIX_PL_Object *)object,
+ (PKIX_PL_Object **)&newObject,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)object,
+ (PKIX_PL_Object *)newObject,
+ &cmpResult,
+ plContext));
+
+ if (!cmpResult) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)object, &original, plContext));
+ testError("unexpected mismatch");
+ (void)printf("original value:\t%s\n", original->escAsciiString);
+
+ if (newObject) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)newObject, ©, plContext));
+ (void)printf("copy value:\t%s\n", copy->escAsciiString);
+ } else {
+ (void)printf("copy value:\t(NULL)\n");
+ }
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(newObject);
+ PKIX_TEST_DECREF_AC(original);
+ PKIX_TEST_DECREF_AC(copy);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+test_GetValidPolicy(
+ PKIX_PolicyNode *goodNode,
+ PKIX_PolicyNode *equalNode,
+ PKIX_PolicyNode *diffNode,
+ char *expectedAscii)
+{
+ PKIX_PL_OID *goodPolicy = NULL;
+ PKIX_PL_OID *equalPolicy = NULL;
+ PKIX_PL_OID *diffPolicy = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_PolicyNode_GetValidPolicy");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PolicyNode_GetValidPolicy(goodNode, &goodPolicy, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PolicyNode_GetValidPolicy(equalNode, &equalPolicy, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PolicyNode_GetValidPolicy(diffNode, &diffPolicy, plContext));
+
+ PKIX_TEST_EQ_HASH_TOSTR_DUP(goodPolicy, equalPolicy, diffPolicy, expectedAscii, OID, NULL);
+
+cleanup:
+ PKIX_TEST_DECREF_AC(goodPolicy);
+ PKIX_TEST_DECREF_AC(equalPolicy);
+ PKIX_TEST_DECREF_AC(diffPolicy);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+test_GetPolicyQualifiers(
+ PKIX_PolicyNode *goodNode,
+ PKIX_PolicyNode *equalNode,
+ PKIX_PolicyNode *diffNode,
+ char *expectedAscii)
+{
+ PKIX_Boolean isImmutable = PKIX_FALSE;
+ PKIX_List *goodList = NULL;
+ PKIX_List *equalList = NULL;
+ PKIX_List *diffList = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_PolicyNode_GetPolicyQualifiers");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PolicyNode_GetPolicyQualifiers(goodNode, &goodList, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PolicyNode_GetPolicyQualifiers(equalNode, &equalList, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PolicyNode_GetPolicyQualifiers(diffNode, &diffList, plContext));
+
+ PKIX_TEST_EQ_HASH_TOSTR_DUP(goodList, equalList, diffList, expectedAscii, List, plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_IsImmutable(goodList, &isImmutable, plContext));
+
+ if (isImmutable != PKIX_TRUE) {
+ testError("PKIX_PolicyNode_GetPolicyQualifiers returned a mutable List");
+ }
+cleanup:
+ PKIX_TEST_DECREF_AC(goodList);
+ PKIX_TEST_DECREF_AC(equalList);
+ PKIX_TEST_DECREF_AC(diffList);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+test_GetExpectedPolicies(
+ PKIX_PolicyNode *goodNode,
+ PKIX_PolicyNode *equalNode,
+ PKIX_PolicyNode *diffNode,
+ char *expectedAscii)
+{
+ PKIX_Boolean isImmutable = PKIX_FALSE;
+ PKIX_List *goodList = NULL;
+ PKIX_List *equalList = NULL;
+ PKIX_List *diffList = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_PolicyNode_GetExpectedPolicies");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PolicyNode_GetExpectedPolicies(goodNode, &goodList, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PolicyNode_GetExpectedPolicies(equalNode, &equalList, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PolicyNode_GetExpectedPolicies(diffNode, &diffList, plContext));
+
+ PKIX_TEST_EQ_HASH_TOSTR_DUP(goodList, equalList, diffList, expectedAscii, List, plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_IsImmutable(goodList, &isImmutable, plContext));
+
+ if (isImmutable != PKIX_TRUE) {
+ testError("PKIX_PolicyNode_GetExpectedPolicies returned a mutable List");
+ }
+cleanup:
+ PKIX_TEST_DECREF_AC(goodList);
+ PKIX_TEST_DECREF_AC(equalList);
+ PKIX_TEST_DECREF_AC(diffList);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+test_IsCritical(
+ PKIX_PolicyNode *goodNode,
+ PKIX_PolicyNode *equalNode,
+ PKIX_PolicyNode *diffNode)
+{
+ PKIX_Boolean goodBool = PKIX_FALSE;
+ PKIX_Boolean equalBool = PKIX_FALSE;
+ PKIX_Boolean diffBool = PKIX_FALSE;
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_PolicyNode_IsCritical");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PolicyNode_IsCritical(goodNode, &goodBool, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PolicyNode_IsCritical(equalNode, &equalBool, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PolicyNode_IsCritical(diffNode, &diffBool, plContext));
+
+ if ((!goodBool) || (!equalBool) || (diffBool)) {
+ testError("IsCritical returned unexpected value");
+ }
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+test_GetDepth(
+ PKIX_PolicyNode *depth1Node,
+ PKIX_PolicyNode *depth2Node,
+ PKIX_PolicyNode *depth3Node)
+{
+ PKIX_UInt32 depth1 = 0;
+ PKIX_UInt32 depth2 = 0;
+ PKIX_UInt32 depth3 = 0;
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_PolicyNode_GetDepth");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PolicyNode_GetDepth(depth1Node, &depth1, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PolicyNode_GetDepth(depth2Node, &depth2, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PolicyNode_GetDepth(depth3Node, &depth3, plContext));
+
+ if ((depth1 != 1) || (depth2 != 2) || (depth3 != 3)) {
+ testError("GetDepth returned unexpected value");
+ }
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+printUsage(void)
+{
+ (void)printf("\nUSAGE:\ttest_policynode \n\n");
+}
+
+int
+test_policynode(int argc, char *argv[])
+{
+
+ /*
+ * Create a tree with parent = anyPolicy,
+ * child1 with Nist1+Nist2, child2 with Nist1.
+ * Give each child another child, with policies Nist2
+ * and Nist1, respectively. Pruning with a depth of two
+ * should have no effect. Give one of the children
+ * another child. Then pruning with a depth of three
+ * should reduce the tree to a single strand, as child1
+ * and child3 are removed.
+ *
+ * parent (anyPolicy)
+ * / \
+ * child1(Nist1+Nist2) child2(Nist1)
+ * | |
+ * child3(Nist2) child4(Nist1)
+ * |
+ * child5(Nist1)
+ *
+ */
+ char *asciiAnyPolicy = "2.5.29.32.0";
+ PKIX_PL_Cert *cert = NULL;
+ PKIX_PL_CertPolicyInfo *nist1Policy = NULL;
+ PKIX_PL_CertPolicyInfo *nist2Policy = NULL;
+ PKIX_List *policyQualifierList = NULL;
+ PKIX_PL_OID *oidAnyPolicy = NULL;
+ PKIX_PL_OID *oidNist1Policy = NULL;
+ PKIX_PL_OID *oidNist2Policy = NULL;
+ PKIX_List *expectedAnyList = NULL;
+ PKIX_List *expectedNist1List = NULL;
+ PKIX_List *expectedNist2List = NULL;
+ PKIX_List *expectedNist1Nist2List = NULL;
+ PKIX_List *emptyList = NULL;
+ PKIX_PolicyNode *parentNode = NULL;
+ PKIX_PolicyNode *childNode1 = NULL;
+ PKIX_PolicyNode *childNode2 = NULL;
+ PKIX_PolicyNode *childNode3 = NULL;
+ PKIX_PolicyNode *childNode4 = NULL;
+ PKIX_PolicyNode *childNode5 = NULL;
+ PKIX_PL_String *parentString = NULL;
+ PKIX_Boolean pDelete = PKIX_FALSE;
+ char *expectedParentAscii =
+ "{2.16.840.1.101.3.2.1.48.2,(1.3.6.1.5.5.7.2.2:[30 5C "
+ "1A 5A 71 31 3A 20 20 54 68 69 73 20 69 73 20 74 68 65"
+ " 20 75 73 65 72 20 6E 6F 74 69 63 65 20 66 72 6F 6D 2"
+ "0 71 75 61 6C 69 66 69 65 72 20 31 2E 20 20 54 68 69 "
+ "73 20 63 65 72 74 69 66 69 63 61 74 65 20 69 73 20 66"
+ " 6F 72 20 74 65 73 74 20 70 75 72 70 6F 73 65 73 20 6"
+ "F 6E 6C 79]),Critical,(2.16.840.1.101.3.2.1.48.1[(1.3"
+ ".6.1.5.5.7.2.2:[30 5C 1A 5A 71 31 3A 20 20 54 68 69 7"
+ "3 20 69 73 20 74 68 65 20 75 73 65 72 20 6E 6F 74 69 "
+ "63 65 20 66 72 6F 6D 20 71 75 61 6C 69 66 69 65 72 20"
+ " 31 2E 20 20 54 68 69 73 20 63 65 72 74 69 66 69 63 6"
+ "1 74 65 20 69 73 20 66 6F 72 20 74 65 73 74 20 70 75 "
+ "72 70 6F 73 65 73 20 6F 6E 6C 79])], 2.16.840.1.101.3"
+ ".2.1.48.2[(1.3.6.1.5.5.7.2.2:[30 5A 1A 58 71 32 3A 20"
+ " 20 54 68 69 73 20 69 73 20 74 68 65 20 75 73 65 72 2"
+ "0 6E 6F 74 69 63 65 20 66 72 6F 6D 20 71 75 61 6C 69 "
+ "66 69 65 72 20 32 2E 20 20 54 68 69 73 20 75 73 65 72"
+ " 20 6E 6F 74 69 63 65 20 73 68 6F 75 6C 64 20 6E 6F 7"
+ "4 20 62 65 20 64 69 73 70 6C 61 79 65 64])]),1}\n"
+ ". {2.16.840.1.101.3.2.1.48.2,(1.3.6.1.5.5.7.2.2:[30 5"
+ "C 1A 5A 71 31 3A 20 20 54 68 69 73 20 69 73 20 74 68 "
+ "65 20 75 73 65 72 20 6E 6F 74 69 63 65 20 66 72 6F 6D"
+ " 20 71 75 61 6C 69 66 69 65 72 20 31 2E 20 20 54 68 6"
+ "9 73 20 63 65 72 74 69 66 69 63 61 74 65 20 69 73 20 "
+ "66 6F 72 20 74 65 73 74 20 70 75 72 70 6F 73 65 73 20"
+ " 6F 6E 6C 79]),Critical,(2.16.840.1.101.3.2.1.48.2),2}";
+ char *expectedValidAscii =
+ "2.16.840.1.101.3.2.1.48.2";
+ char *expectedQualifiersAscii =
+ /* "(1.3.6.1.5.5.7.2.2)"; */
+ "(1.3.6.1.5.5.7.2.2:[30 5C 1A 5A 71 31 3A 20 20 54 68 "
+ "69 73 20 69 73 20 74 68 65 20 75 73 65 72 20 6E 6F 74"
+ " 69 63 65 20 66 72 6F 6D 20 71 75 61 6C 69 66 69 65 7"
+ "2 20 31 2E 20 20 54 68 69 73 20 63 65 72 74 69 66 69 "
+ "63 61 74 65 20 69 73 20 66 6F 72 20 74 65 73 74 20 70"
+ " 75 72 70 6F 73 65 73 20 6F 6E 6C 79])";
+ char *expectedPoliciesAscii =
+ "(2.16.840.1.101.3.2.1.48.1)";
+ char *expectedTree =
+ "{2.5.29.32.0,{},Critical,(2.5.29.32.0),0}\n"
+ ". {2.16.840.1.101.3.2.1.48.2,(1.3.6.1.5.5.7.2.2:[30 5"
+ "C 1A 5A 71 31 3A 20 20 54 68 69 73 20 69 73 20 74 68 "
+ "65 20 75 73 65 72 20 6E 6F 74 69 63 65 20 66 72 6F 6D"
+ " 20 71 75 61 6C 69 66 69 65 72 20 31 2E 20 20 54 68 6"
+ "9 73 20 63 65 72 74 69 66 69 63 61 74 65 20 69 73 20 "
+ "66 6F 72 20 74 65 73 74 20 70 75 72 70 6F 73 65 73 20"
+ " 6F 6E 6C 79]),Critical,(2.16.840.1.101.3.2.1.48.1[(1"
+ ".3.6.1.5.5.7.2.2:[30 5C 1A 5A 71 31 3A 20 20 54 68 69"
+ " 73 20 69 73 20 74 68 65 20 75 73 65 72 20 6E 6F 74 6"
+ "9 63 65 20 66 72 6F 6D 20 71 75 61 6C 69 66 69 65 72 "
+ "20 31 2E 20 20 54 68 69 73 20 63 65 72 74 69 66 69 63"
+ " 61 74 65 20 69 73 20 66 6F 72 20 74 65 73 74 20 70 7"
+ "5 72 70 6F 73 65 73 20 6F 6E 6C 79])], 2.16.840.1.101"
+ ".3.2.1.48.2[(1.3.6.1.5.5.7.2.2:[30 5A 1A 58 71 32 3A "
+ "20 20 54 68 69 73 20 69 73 20 74 68 65 20 75 73 65 72"
+ " 20 6E 6F 74 69 63 65 20 66 72 6F 6D 20 71 75 61 6C 6"
+ "9 66 69 65 72 20 32 2E 20 20 54 68 69 73 20 75 73 65 "
+ "72 20 6E 6F 74 69 63 65 20 73 68 6F 75 6C 64 20 6E 6F"
+ " 74 20 62 65 20 64 69 73 70 6C 61 79 65 64])]"
+ "),1}\n"
+ ". . {2.16.840.1.101.3.2.1.48.2,(1.3.6.1.5.5.7.2.2:[30"
+ " 5C 1A 5A 71 31 3A 20 20 54 68 69 73 20 69 73 20 74 6"
+ "8 65 20 75 73 65 72 20 6E 6F 74 69 63 65 20 66 72 6F "
+ "6D 20 71 75 61 6C 69 66 69 65 72 20 31 2E 20 20 54 68"
+ " 69 73 20 63 65 72 74 69 66 69 63 61 74 65 20 69 73 2"
+ "0 66 6F 72 20 74 65 73 74 20 70 75 72 70 6F 73 65 73 "
+ "20 6F 6E 6C 79]),Critical,(2.16.840.1.101.3.2.1.48.2)"
+ ",2}\n"
+ ". {2.16.840.1.101.3.2.1.48.1,(1.3.6.1.5.5.7.2.2:[30 5"
+ "C 1A 5A 71 31 3A 20 20 54 68 69 73 20 69 73 20 74 68 "
+ "65 20 75 73 65 72 20 6E 6F 74 69 63 65 20 66 72 6F 6D"
+ " 20 71 75 61 6C 69 66 69 65 72 20 31 2E 20 20 54 68 6"
+ "9 73 20 63 65 72 74 69 66 69 63 61 74 65 20 69 73 20 "
+ "66 6F 72 20 74 65 73 74 20 70 75 72 70 6F 73 65 73 20"
+ " 6F 6E 6C 79]),Critical,(2.16.840.1.101.3.2.1.48.1),1}\n"
+ ". . {2.16.840.1.101.3.2.1.48.1,(EMPTY),Not Critical,"
+ "(2.16.840.1.101.3.2.1.48.1),2}\n"
+ ". . . {2.16.840.1.101.3.2.1.48.1,{},Critical,(2.16.84"
+ "0.1.101.3.2.1.48.1),3}";
+ char *expectedPrunedTree =
+ "{2.5.29.32.0,{},Critical,(2.5.29.32.0),0}\n"
+ ". {2.16.840.1.101.3.2.1.48.1,(1.3.6.1.5.5.7.2.2:[30 5"
+ "C 1A 5A 71 31 3A 20 20 54 68 69 73 20 69 73 20 74 68 "
+ "65 20 75 73 65 72 20 6E 6F 74 69 63 65 20 66 72 6F 6D"
+ " 20 71 75 61 6C 69 66 69 65 72 20 31 2E 20 20 54 68 6"
+ "9 73 20 63 65 72 74 69 66 69 63 61 74 65 20 69 73 20 "
+ "66 6F 72 20 74 65 73 74 20 70 75 72 70 6F 73 65 73 20"
+ " 6F 6E 6C 79]),Critical,(2.16.840.1.101.3.2.1.48.1),1}\n"
+ ". . {2.16.840.1.101.3.2.1.48.1,(EMPTY),Not Critical,"
+ "(2.16.840.1.101.3.2.1.48.1),2}\n"
+ ". . . {2.16.840.1.101.3.2.1.48.1,{},Critical,(2.16.84"
+ "0.1.101.3.2.1.48.1),3}";
+
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_UInt32 j = 0;
+ char *dirName = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ if (argc < 2) {
+ printUsage();
+ return (0);
+ }
+
+ startTests("PolicyNode");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ dirName = argv[j + 1];
+
+ subTest("Creating OID objects");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create(asciiAnyPolicy, &oidAnyPolicy, plContext));
+
+ /* Read certificates to get real policies, qualifiers */
+
+ cert = createCert(dirName, "UserNoticeQualifierTest16EE.crt", plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetPolicyInformation(cert, &expectedNist1Nist2List, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(expectedNist1Nist2List,
+ 0,
+ (PKIX_PL_Object **)&nist1Policy,
+ plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(expectedNist1Nist2List,
+ 1,
+ (PKIX_PL_Object **)&nist2Policy,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CertPolicyInfo_GetPolQualifiers(nist1Policy, &policyQualifierList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CertPolicyInfo_GetPolicyId(nist1Policy, &oidNist1Policy, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CertPolicyInfo_GetPolicyId(nist2Policy, &oidNist2Policy, plContext));
+
+ subTest("Creating expectedPolicy List objects");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&expectedAnyList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&expectedNist1List, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&expectedNist2List, plContext));
+
+ subTest("Populating expectedPolicy List objects");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(expectedAnyList, (PKIX_PL_Object *)oidAnyPolicy, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(expectedNist1List,
+ (PKIX_PL_Object *)oidNist1Policy,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(expectedNist2List,
+ (PKIX_PL_Object *)oidNist2Policy,
+ plContext));
+
+ subTest("Creating PolicyNode objects");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&emptyList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_Create(oidAnyPolicy,
+ NULL,
+ PKIX_TRUE,
+ expectedAnyList,
+ &parentNode,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_Create(oidNist2Policy,
+ policyQualifierList,
+ PKIX_TRUE,
+ expectedNist1Nist2List,
+ &childNode1,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_Create(oidNist1Policy,
+ policyQualifierList,
+ PKIX_TRUE,
+ expectedNist1List,
+ &childNode2,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_Create(oidNist2Policy,
+ policyQualifierList,
+ PKIX_TRUE,
+ expectedNist2List,
+ &childNode3,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_Create(oidNist1Policy,
+ emptyList,
+ PKIX_FALSE,
+ expectedNist1List,
+ &childNode4,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_Create(oidNist1Policy,
+ NULL,
+ PKIX_TRUE,
+ expectedNist1List,
+ &childNode5,
+ plContext));
+
+ subTest("Creating the PolicyNode tree");
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_AddToParent(parentNode, childNode1, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_AddToParent(parentNode, childNode2, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_AddToParent(childNode1, childNode3, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_AddToParent(childNode2, childNode4, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_AddToParent(childNode4, childNode5, plContext));
+
+ subTest("Displaying PolicyNode objects");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)parentNode, &parentString, plContext));
+ (void)printf("parentNode is\n\t%s\n", parentString->escAsciiString);
+
+ testToStringHelper((PKIX_PL_Object *)parentNode, expectedTree, plContext);
+
+ test_DuplicateHelper(parentNode, plContext);
+
+ test_GetParent(childNode3, childNode3, childNode4, expectedParentAscii);
+ test_GetValidPolicy(childNode1, childNode3, parentNode, expectedValidAscii);
+ test_GetPolicyQualifiers(childNode1, childNode3, childNode4, expectedQualifiersAscii);
+ test_GetExpectedPolicies(childNode2, childNode4, childNode3, expectedPoliciesAscii);
+ test_IsCritical(childNode1, childNode2, childNode4);
+ test_GetDepth(childNode2, childNode4, childNode5);
+
+ subTest("pkix_PolicyNode_Prune");
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_Prune(parentNode, 2, &pDelete, plContext));
+
+ testToStringHelper((PKIX_PL_Object *)parentNode, expectedTree, plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_Prune(parentNode, 3, &pDelete, plContext));
+
+ testToStringHelper((PKIX_PL_Object *)parentNode, expectedPrunedTree, plContext);
+
+ test_GetChildren(parentNode, parentNode, childNode2);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(cert);
+ PKIX_TEST_DECREF_AC(nist1Policy);
+ PKIX_TEST_DECREF_AC(nist2Policy);
+ PKIX_TEST_DECREF_AC(policyQualifierList);
+ PKIX_TEST_DECREF_AC(oidAnyPolicy);
+ PKIX_TEST_DECREF_AC(oidNist1Policy);
+ PKIX_TEST_DECREF_AC(oidNist2Policy);
+ PKIX_TEST_DECREF_AC(expectedAnyList);
+ PKIX_TEST_DECREF_AC(expectedNist1List);
+ PKIX_TEST_DECREF_AC(expectedNist2List);
+ PKIX_TEST_DECREF_AC(expectedNist1Nist2List);
+ PKIX_TEST_DECREF_AC(emptyList);
+ PKIX_TEST_DECREF_AC(parentNode);
+ PKIX_TEST_DECREF_AC(childNode1);
+ PKIX_TEST_DECREF_AC(childNode2);
+ PKIX_TEST_DECREF_AC(childNode3);
+ PKIX_TEST_DECREF_AC(childNode4);
+ PKIX_TEST_DECREF_AC(childNode5);
+ PKIX_TEST_DECREF_AC(parentString);
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("PolicyNode");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/results/test_valresult.c b/nss/cmd/libpkix/pkix/results/test_valresult.c
new file mode 100644
index 0000000..7760a43
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/results/test_valresult.c
@@ -0,0 +1,199 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_valresult.c
+ *
+ * Test ValidateResult Type
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+static void
+testDestroy(void *goodObject, void *equalObject, void *diffObject)
+{
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_ValidateResult_Destroy");
+
+ PKIX_TEST_DECREF_BC(goodObject);
+ PKIX_TEST_DECREF_BC(equalObject);
+ PKIX_TEST_DECREF_BC(diffObject);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetPublicKey(
+ PKIX_ValidateResult *goodObject,
+ PKIX_ValidateResult *equalObject)
+{
+
+ PKIX_PL_PublicKey *goodPubKey = NULL;
+ PKIX_PL_PublicKey *equalPubKey = NULL;
+
+ PKIX_TEST_STD_VARS();
+ subTest("PKIX_ValidateResult_GetPublicKey");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateResult_GetPublicKey(goodObject, &goodPubKey, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateResult_GetPublicKey(equalObject, &equalPubKey, plContext));
+
+ testEqualsHelper((PKIX_PL_Object *)goodPubKey,
+ (PKIX_PL_Object *)equalPubKey,
+ PKIX_TRUE,
+ plContext);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(goodPubKey);
+ PKIX_TEST_DECREF_AC(equalPubKey);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetTrustAnchor(
+ PKIX_ValidateResult *goodObject,
+ PKIX_ValidateResult *equalObject)
+{
+
+ PKIX_TrustAnchor *goodAnchor = NULL;
+ PKIX_TrustAnchor *equalAnchor = NULL;
+
+ PKIX_TEST_STD_VARS();
+ subTest("PKIX_ValidateResult_GetTrustAnchor");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateResult_GetTrustAnchor(goodObject, &goodAnchor, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateResult_GetTrustAnchor(equalObject, &equalAnchor, plContext));
+
+ testEqualsHelper((PKIX_PL_Object *)goodAnchor,
+ (PKIX_PL_Object *)equalAnchor,
+ PKIX_TRUE,
+ plContext);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(goodAnchor);
+ PKIX_TEST_DECREF_AC(equalAnchor);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetPolicyTree(
+ PKIX_ValidateResult *goodObject,
+ PKIX_ValidateResult *equalObject)
+{
+
+ PKIX_PolicyNode *goodTree = NULL;
+ PKIX_PolicyNode *equalTree = NULL;
+
+ PKIX_TEST_STD_VARS();
+ subTest("PKIX_ValidateResult_GetPolicyTree");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateResult_GetPolicyTree(goodObject, &goodTree, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateResult_GetPolicyTree(equalObject, &equalTree, plContext));
+
+ if (goodTree) {
+ testEqualsHelper((PKIX_PL_Object *)goodTree,
+ (PKIX_PL_Object *)equalTree,
+ PKIX_TRUE,
+ plContext);
+ } else if (equalTree) {
+ pkixTestErrorMsg = "Mismatch: NULL and non-NULL Policy Trees";
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(goodTree);
+ PKIX_TEST_DECREF_AC(equalTree);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+printUsage(char *pName)
+{
+ printf("\nUSAGE: %s \n\n", pName);
+}
+
+int
+test_valresult(int argc, char *argv[])
+{
+
+ PKIX_ValidateResult *goodObject = NULL;
+ PKIX_ValidateResult *equalObject = NULL;
+ PKIX_ValidateResult *diffObject = NULL;
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_UInt32 j = 0;
+
+ char *goodInput = "yassir2yassir";
+ char *diffInput = "yassir2bcn";
+ char *dirName = NULL;
+
+ char *expectedAscii =
+ "[\n"
+ "\tTrustAnchor: \t\t"
+ "[\n"
+ "\tTrusted CA Name: "
+ "CN=yassir,OU=bcn,OU=east,O=sun,C=us\n"
+ "\tTrusted CA PublicKey: ANSI X9.57 DSA Signature\n"
+ "\tInitial Name Constraints:(null)\n"
+ "]\n"
+ "\tPubKey: \t\t"
+ "ANSI X9.57 DSA Signature\n"
+ "\tPolicyTree: \t\t(null)\n"
+ "]\n";
+
+ PKIX_TEST_STD_VARS();
+
+ startTests("ValidateResult");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ if (argc < 2) {
+ printUsage(argv[0]);
+ return (0);
+ }
+
+ dirName = argv[j + 1];
+
+ subTest("pkix_ValidateResult_Create");
+
+ goodObject = createValidateResult(dirName, goodInput, diffInput, plContext);
+ equalObject = createValidateResult(dirName, goodInput, diffInput, plContext);
+ diffObject = createValidateResult(dirName, diffInput, goodInput, plContext);
+
+ testGetPublicKey(goodObject, equalObject);
+ testGetTrustAnchor(goodObject, equalObject);
+ testGetPolicyTree(goodObject, equalObject);
+
+ PKIX_TEST_EQ_HASH_TOSTR_DUP(goodObject,
+ equalObject,
+ diffObject,
+ expectedAscii,
+ ValidateResult,
+ PKIX_FALSE);
+
+ testDestroy(goodObject, equalObject, diffObject);
+
+cleanup:
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("ValidateResult");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/results/test_verifynode.c b/nss/cmd/libpkix/pkix/results/test_verifynode.c
new file mode 100644
index 0000000..21c61aa
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/results/test_verifynode.c
@@ -0,0 +1,112 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_verifynode.c
+ *
+ * Test VerifyNode Type
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+static void
+printUsage(void)
+{
+ (void)printf("\nUSAGE:\ttest_verifynode path cert1 cert2 cert3\n\n");
+}
+
+int
+test_verifynode(int argc, char *argv[])
+{
+
+ /*
+ * Create a tree with parent = cert1, child=cert2, grandchild=cert3
+ */
+ PKIX_PL_Cert *cert1 = NULL;
+ PKIX_PL_Cert *cert2 = NULL;
+ PKIX_PL_Cert *cert3 = NULL;
+ PKIX_VerifyNode *parentNode = NULL;
+ PKIX_VerifyNode *childNode = NULL;
+ PKIX_VerifyNode *grandChildNode = NULL;
+ PKIX_PL_String *parentString = NULL;
+
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_UInt32 j = 0;
+ char *dirName = NULL;
+ char *twoNodeAscii = "CERT[Issuer:CN=Trust Anchor,O=Test Cert"
+ "ificates,C=US, Subject:CN=Trust Anchor,O=Test Certif"
+ "icates,C=US], depth=0, error=(null)\n. CERT[Issuer:C"
+ "N=Trust Anchor,O=Test Certificates,C=US, Subject:CN="
+ "Good CA,O=Test Certificates,C=US], depth=1, error=(null)";
+ char *threeNodeAscii = "CERT[Issuer:CN=Trust Anchor,O=Test Ce"
+ "rtificates,C=US, Subject:CN=Trust Anchor,O=Test Cert"
+ "ificates,C=US], depth=0, error=(null)\n. CERT[Issuer"
+ ":CN=Trust Anchor,O=Test Certificates,C=US, Subject:C"
+ "N=Good CA,O=Test Certificates,C=US], depth=1, error="
+ "(null)\n. . CERT[Issuer:CN=Good CA,O=Test Certificat"
+ "es,C=US, Subject:CN=Valid EE Certificate Test1,O=Tes"
+ "t Certificates,C=US], depth=2, error=(null)";
+
+ PKIX_TEST_STD_VARS();
+
+ if (argc < 3) {
+ printUsage();
+ return (0);
+ }
+
+ startTests("VerifyNode");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ dirName = argv[++j];
+
+ subTest("Creating Certs");
+
+ cert1 = createCert(dirName, argv[++j], plContext);
+
+ cert2 = createCert(dirName, argv[++j], plContext);
+
+ cert3 = createCert(dirName, argv[++j], plContext);
+
+ subTest("Creating VerifyNode objects");
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_VerifyNode_Create(cert1, 0, NULL, &parentNode, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_VerifyNode_Create(cert2, 1, NULL, &childNode, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_VerifyNode_Create(cert3, 2, NULL, &grandChildNode, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_VerifyNode_AddToChain(parentNode, childNode, plContext));
+
+ subTest("Creating VerifyNode ToString objects");
+
+ testToStringHelper((PKIX_PL_Object *)parentNode, twoNodeAscii, plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_VerifyNode_AddToChain(parentNode, grandChildNode, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)parentNode, &parentString, plContext));
+ (void)printf("parentNode is\n\t%s\n", parentString->escAsciiString);
+
+ testToStringHelper((PKIX_PL_Object *)parentNode, threeNodeAscii, plContext);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(cert1);
+ PKIX_TEST_DECREF_AC(cert2);
+ PKIX_TEST_DECREF_AC(parentNode);
+ PKIX_TEST_DECREF_AC(childNode);
+ PKIX_TEST_DECREF_AC(parentString);
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("VerifyNode");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/store/Makefile b/nss/cmd/libpkix/pkix/store/Makefile
new file mode 100755
index 0000000..09ca5f1
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/store/Makefile
@@ -0,0 +1,47 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(PKIX_DEPTH)/config.mk
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platrules.mk
diff --git a/nss/cmd/libpkix/pkix/store/manifest.mn b/nss/cmd/libpkix/pkix/store/manifest.mn
new file mode 100755
index 0000000..566a346
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/store/manifest.mn
@@ -0,0 +1,19 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+PKIX_DEPTH = ../..
+PLAT_DEPTH = $(PKIX_DEPTH)/..
+CORE_DEPTH = $(PKIX_DEPTH)/../../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+CSRCS = test_store.c
+
+LIBRARY_NAME=pkixtoolstore
+
+SOURCE_LIB_DIR=$(PKIX_DEPTH)/$(OBJDIR)
+
+NO_MD_RELEASE = 1
diff --git a/nss/cmd/libpkix/pkix/store/test_store.c b/nss/cmd/libpkix/pkix/store/test_store.c
new file mode 100644
index 0000000..59606b8
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/store/test_store.c
@@ -0,0 +1,194 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_certstore.c
+ *
+ * Test CertStore Type
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+static PKIX_Error *
+testCRLCallback(
+ PKIX_CertStore *store,
+ PKIX_CRLSelector *selector,
+ void **pNBIOContext,
+ PKIX_List **pCrls, /* list of PKIX_PL_Crl */
+ void *plContext)
+{
+ return (0);
+}
+
+static PKIX_Error *
+testCRLContinue(
+ PKIX_CertStore *store,
+ PKIX_CRLSelector *selector,
+ void **pNBIOContext,
+ PKIX_List **pCrls, /* list of PKIX_PL_Crl */
+ void *plContext)
+{
+ return (0);
+}
+
+static PKIX_Error *
+testCertCallback(
+ PKIX_CertStore *store,
+ PKIX_CertSelector *selector,
+ void **pNBIOContext,
+ PKIX_List **pCerts, /* list of PKIX_PL_Cert */
+ void *plContext)
+{
+ return (0);
+}
+
+static PKIX_Error *
+testCertContinue(
+ PKIX_CertStore *store,
+ PKIX_CertSelector *selector,
+ void **pNBIOContext,
+ PKIX_List **pCerts, /* list of PKIX_PL_Cert */
+ void *plContext)
+{
+ return (0);
+}
+
+static char *
+catDirName(char *platform, char *dir, void *plContext)
+{
+ char *pathName = NULL;
+ PKIX_UInt32 dirLen;
+ PKIX_UInt32 platformLen;
+
+ PKIX_TEST_STD_VARS();
+
+ dirLen = PL_strlen(dir);
+ platformLen = PL_strlen(platform);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Malloc(platformLen +
+ dirLen +
+ 2,
+ (void **)&pathName, plContext));
+
+ PL_strcpy(pathName, platform);
+ PL_strcat(pathName, "/");
+ PL_strcat(pathName, dir);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+
+ return (pathName);
+}
+
+static void
+testCertStore(char *crlDir)
+{
+ PKIX_PL_String *dirString = NULL;
+ PKIX_CertStore *certStore = NULL;
+ PKIX_PL_Object *getCertStoreContext = NULL;
+ PKIX_CertStore_CertCallback certCallback = NULL;
+ PKIX_CertStore_CRLCallback crlCallback = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII,
+ crlDir,
+ 0,
+ &dirString,
+ plContext));
+
+ subTest("PKIX_CertStore_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertStore_Create(testCertCallback,
+ testCRLCallback,
+ testCertContinue,
+ testCRLContinue,
+ NULL, /* trustCallback */
+ (PKIX_PL_Object *)dirString,
+ PKIX_TRUE, /* cacheFlag */
+ PKIX_TRUE, /* local */
+ &certStore,
+ plContext));
+
+ subTest("PKIX_CertStore_GetCertCallback");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertStore_GetCertCallback(certStore, &certCallback, plContext));
+
+ if (certCallback != testCertCallback) {
+ testError("PKIX_CertStore_GetCertCallback unexpected mismatch");
+ }
+
+ subTest("PKIX_CertStore_GetCRLCallback");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertStore_GetCRLCallback(certStore, &crlCallback, plContext));
+
+ if (crlCallback != testCRLCallback) {
+ testError("PKIX_CertStore_GetCRLCallback unexpected mismatch");
+ }
+
+ subTest("PKIX_CertStore_GetCertStoreContext");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertStore_GetCertStoreContext(certStore, &getCertStoreContext, plContext));
+
+ if ((PKIX_PL_Object *)dirString != getCertStoreContext) {
+ testError("PKIX_CertStore_GetCertStoreContext unexpected mismatch");
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(dirString);
+ PKIX_TEST_DECREF_AC(certStore);
+ PKIX_TEST_DECREF_AC(getCertStoreContext);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+printUsage(char *pName)
+{
+ printf("\nUSAGE: %s testName \n\n", pName);
+}
+
+/* Functional tests for CertStore public functions */
+
+int
+test_store(int argc, char *argv[])
+{
+
+ char *platformDir = NULL;
+ char *dataDir = NULL;
+ char *combinedDir = NULL;
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_UInt32 j = 0;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ if (argc < (3 + j)) {
+ printUsage(argv[0]);
+ return (0);
+ }
+
+ startTests(argv[1 + j]);
+
+ dataDir = argv[2 + j];
+ platformDir = argv[3 + j];
+ combinedDir = catDirName(platformDir, dataDir, plContext);
+
+ testCertStore(combinedDir);
+
+cleanup:
+
+ pkixTestErrorResult = PKIX_PL_Free(combinedDir, plContext);
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("CertStore");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/top/Makefile b/nss/cmd/libpkix/pkix/top/Makefile
new file mode 100755
index 0000000..09ca5f1
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/top/Makefile
@@ -0,0 +1,47 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(PKIX_DEPTH)/config.mk
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platrules.mk
diff --git a/nss/cmd/libpkix/pkix/top/manifest.mn b/nss/cmd/libpkix/pkix/top/manifest.mn
new file mode 100755
index 0000000..a7d997d
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/top/manifest.mn
@@ -0,0 +1,33 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+PKIX_DEPTH = ../..
+PLAT_DEPTH = $(PKIX_DEPTH)/..
+CORE_DEPTH = $(PKIX_DEPTH)/../../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+CSRCS = test_basicchecker.c \
+ test_basicconstraintschecker.c \
+ test_buildchain.c \
+ test_buildchain_uchecker.c \
+ test_buildchain_partialchain.c \
+ test_buildchain_resourcelimits.c \
+ test_customcrlchecker.c \
+ test_defaultcrlchecker2stores.c \
+ test_ocsp.c \
+ test_policychecker.c \
+ test_subjaltnamechecker.c \
+ test_validatechain.c \
+ test_validatechain_bc.c \
+ test_validatechain_NB.c \
+ $(NULL)
+
+LIBRARY_NAME=pkixtooltop
+
+SOURCE_LIB_DIR=$(PKIX_DEPTH)/$(OBJDIR)
+
+NO_MD_RELEASE = 1
diff --git a/nss/cmd/libpkix/pkix/top/test_basicchecker.c b/nss/cmd/libpkix/pkix/top/test_basicchecker.c
new file mode 100644
index 0000000..658bf67
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/top/test_basicchecker.c
@@ -0,0 +1,238 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_basicchecker.c
+ *
+ * Test Basic Checking
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+static void
+testPass(char *dirName, char *goodInput, char *diffInput, char *dateAscii)
+{
+
+ PKIX_List *chain = NULL;
+ PKIX_ValidateParams *valParams = NULL;
+ PKIX_ValidateResult *valResult = NULL;
+ PKIX_VerifyNode *verifyTree = NULL;
+ PKIX_PL_String *verifyString = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("Basic-Common-Fields ");
+ /*
+ * Tests the Expiration, NameChaining, and Signature Checkers
+ */
+
+ chain = createCertChain(dirName, goodInput, diffInput, plContext);
+
+ valParams = createValidateParams(dirName,
+ goodInput,
+ diffInput,
+ dateAscii,
+ NULL,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ chain,
+ plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateChain(valParams, &valResult, &verifyTree, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)verifyTree, &verifyString, plContext));
+ (void)printf("verifyTree is\n%s\n", verifyString->escAsciiString);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(verifyString);
+ PKIX_TEST_DECREF_AC(verifyTree);
+ PKIX_TEST_DECREF_AC(chain);
+ PKIX_TEST_DECREF_AC(valParams);
+ PKIX_TEST_DECREF_AC(valResult);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testNameChainingFail(
+ char *dirName,
+ char *goodInput,
+ char *diffInput,
+ char *dateAscii)
+{
+ PKIX_List *chain = NULL;
+ PKIX_ValidateParams *valParams = NULL;
+ PKIX_ValidateResult *valResult = NULL;
+ PKIX_VerifyNode *verifyTree = NULL;
+ PKIX_PL_String *verifyString = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("NameChaining ");
+
+ chain = createCertChain(dirName, diffInput, goodInput, plContext);
+
+ valParams = createValidateParams(dirName,
+ goodInput,
+ diffInput,
+ dateAscii,
+ NULL,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ chain,
+ plContext);
+
+ PKIX_TEST_EXPECT_ERROR(PKIX_ValidateChain(valParams, &valResult, &verifyTree, plContext));
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(verifyString);
+ PKIX_TEST_DECREF_AC(verifyTree);
+ PKIX_TEST_DECREF_AC(chain);
+ PKIX_TEST_DECREF_AC(valParams);
+ PKIX_TEST_DECREF_AC(valResult);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testDateFail(char *dirName, char *goodInput, char *diffInput)
+{
+
+ PKIX_List *chain = NULL;
+ PKIX_ValidateParams *valParams = NULL;
+ PKIX_ValidateResult *valResult = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ chain = createCertChain(dirName, goodInput, diffInput, plContext);
+
+ subTest("Expiration ");
+ valParams = createValidateParams(dirName,
+ goodInput,
+ diffInput,
+ NULL,
+ NULL,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ chain,
+ plContext);
+
+ PKIX_TEST_EXPECT_ERROR(PKIX_ValidateChain(valParams, &valResult, NULL, plContext));
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(chain);
+ PKIX_TEST_DECREF_AC(valParams);
+ PKIX_TEST_DECREF_AC(valResult);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testSignatureFail(
+ char *dirName,
+ char *goodInput,
+ char *diffInput,
+ char *dateAscii)
+{
+ PKIX_List *chain = NULL;
+ PKIX_ValidateParams *valParams = NULL;
+ PKIX_ValidateResult *valResult = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("Signature ");
+
+ chain = createCertChain(dirName, diffInput, goodInput, plContext);
+
+ valParams = createValidateParams(dirName,
+ goodInput,
+ diffInput,
+ dateAscii,
+ NULL,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ chain,
+ plContext);
+
+ PKIX_TEST_EXPECT_ERROR(PKIX_ValidateChain(valParams, &valResult, NULL, plContext));
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(chain);
+ PKIX_TEST_DECREF_AC(valParams);
+ PKIX_TEST_DECREF_AC(valResult);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+printUsage(char *pName)
+{
+ printf("\nUSAGE: %s \n\n", pName);
+}
+
+int
+test_basicchecker(int argc, char *argv[])
+{
+
+ char *goodInput = "yassir2yassir";
+ char *diffInput = "yassir2bcn";
+ char *dateAscii = "991201000000Z";
+ char *dirName = NULL;
+ PKIX_UInt32 j = 0;
+ PKIX_UInt32 actualMinorVersion;
+
+ PKIX_TEST_STD_VARS();
+
+ startTests("SignatureChecker");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ if (argc < 2) {
+ printUsage(argv[0]);
+ return (0);
+ }
+
+ dirName = argv[j + 1];
+
+ /* The NameChaining, Expiration, and Signature Checkers all pass */
+ testPass(dirName, goodInput, diffInput, dateAscii);
+
+ /* Individual Checkers fail */
+ testNameChainingFail(dirName, goodInput, diffInput, dateAscii);
+ testDateFail(dirName, goodInput, diffInput);
+
+/*
+ * XXX
+ * since the signature check is done last, we need to create
+ * certs whose name chaining passes, but their signatures fail;
+ * we currently don't have any such certs.
+ */
+/* testSignatureFail(goodInput, diffInput, dateAscii); */
+
+cleanup:
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("SignatureChecker");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/top/test_basicconstraintschecker.c b/nss/cmd/libpkix/pkix/top/test_basicconstraintschecker.c
new file mode 100644
index 0000000..eba5153
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/top/test_basicconstraintschecker.c
@@ -0,0 +1,145 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_basicconstraintschecker.c
+ *
+ * Test Basic Constraints Checking
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+#define PKIX_TEST_MAX_CERTS 10
+
+static void *plContext = NULL;
+
+static void
+printUsage1(char *pName)
+{
+ printf("\nUSAGE: %s test-name [ENE|EE] ", pName);
+ printf("cert [certs].\n");
+}
+
+static void
+printUsageMax(PKIX_UInt32 numCerts)
+{
+ printf("\nUSAGE ERROR: number of certs %d exceed maximum %d\n",
+ numCerts, PKIX_TEST_MAX_CERTS);
+}
+
+int
+test_basicconstraintschecker(int argc, char *argv[])
+{
+
+ PKIX_List *chain = NULL;
+ PKIX_ValidateParams *valParams = NULL;
+ PKIX_ValidateResult *valResult = NULL;
+ PKIX_UInt32 actualMinorVersion;
+ char *certNames[PKIX_TEST_MAX_CERTS];
+ PKIX_PL_Cert *certs[PKIX_TEST_MAX_CERTS];
+ PKIX_VerifyNode *verifyTree = NULL;
+ PKIX_PL_String *verifyString = NULL;
+ PKIX_UInt32 chainLength = 0;
+ PKIX_UInt32 i = 0;
+ PKIX_UInt32 j = 0;
+ PKIX_Boolean testValid = PKIX_FALSE;
+ char *dirName = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ if (argc < 4) {
+ printUsage1(argv[0]);
+ return (0);
+ }
+
+ startTests("BasicConstraintsChecker");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ /* ENE = expect no error; EE = expect error */
+ if (PORT_Strcmp(argv[2 + j], "ENE") == 0) {
+ testValid = PKIX_TRUE;
+ } else if (PORT_Strcmp(argv[2 + j], "EE") == 0) {
+ testValid = PKIX_FALSE;
+ } else {
+ printUsage1(argv[0]);
+ return (0);
+ }
+
+ dirName = argv[3 + j];
+
+ chainLength = (argc - j) - 4;
+ if (chainLength > PKIX_TEST_MAX_CERTS) {
+ printUsageMax(chainLength);
+ }
+
+ for (i = 0; i < chainLength; i++) {
+ certNames[i] = argv[(4 + j) + i];
+ certs[i] = NULL;
+ }
+
+ subTest(argv[1 + j]);
+
+ subTest("Basic-Constraints - Create Cert Chain");
+
+ chain = createCertChainPlus(dirName, certNames, certs, chainLength, plContext);
+
+ /*
+ * Error occurs when creating Cert, this is critical and test
+ * should not continue. Since we expect error, we assume this
+ * error is the one that is expected, so undo the error count.
+ *
+ * This work needs future enhancement. We will introduce another
+ * flag ESE, in addition to the existing EE(expect validation
+ * error) and ENE(expect no validation error). ESE stands for
+ * "expect setup error". When running with ESE, if any of the setup
+ * calls such creating Cert Chain fails, the test can end and
+ * considered to be successful.
+ */
+ if (testValid == PKIX_FALSE && chain == NULL) {
+ testErrorUndo("Cert Error - Create failed");
+ goto cleanup;
+ }
+
+ subTest("Basic-Constraints - Create Params");
+
+ valParams = createValidateParams(dirName,
+ argv[4 +
+ j],
+ NULL,
+ NULL,
+ NULL,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ chain,
+ plContext);
+
+ subTest("Basic-Constraints - Validate Chain");
+
+ if (testValid == PKIX_TRUE) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateChain(valParams, &valResult, &verifyTree, plContext));
+ } else {
+ PKIX_TEST_EXPECT_ERROR(PKIX_ValidateChain(valParams, &valResult, &verifyTree, plContext));
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(verifyString);
+ PKIX_TEST_DECREF_AC(verifyTree);
+ PKIX_TEST_DECREF_AC(chain);
+ PKIX_TEST_DECREF_AC(valParams);
+ PKIX_TEST_DECREF_AC(valResult);
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("BasicConstraintsChecker");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/top/test_buildchain.c b/nss/cmd/libpkix/pkix/top/test_buildchain.c
new file mode 100644
index 0000000..5c9ec59
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/top/test_buildchain.c
@@ -0,0 +1,418 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_buildchain.c
+ *
+ * Test BuildChain function
+ *
+ */
+
+/* #define debuggingWithoutRevocation */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+#define LDAP_PORT 389
+static PKIX_Boolean usebind = PKIX_FALSE;
+static PKIX_Boolean useLDAP = PKIX_FALSE;
+static char buf[PR_NETDB_BUF_SIZE];
+static char *serverName = NULL;
+static char *sepPtr = NULL;
+static PRNetAddr netAddr;
+static PRHostEnt hostent;
+static PKIX_UInt32 portNum = 0;
+static PRIntn hostenum = 0;
+static PRStatus prstatus = PR_FAILURE;
+static void *ipaddr = NULL;
+
+static void *plContext = NULL;
+
+static void
+printUsage(void)
+{
+ (void)printf("\nUSAGE:\ttest_buildchain [-arenas] [usebind] "
+ "servername[:port] [ENE|EE]\n"
+ "\t "
+ " \n\n");
+ (void)printf("Builds a chain of certificates from to \n"
+ "using the certs and CRLs in . "
+ "servername[:port] gives\n"
+ "the address of an LDAP server. If port is not"
+ " specified, port 389 is used. \"-\" means no LDAP server.\n"
+ "If ENE is specified, then an Error is Not Expected. "
+ "EE indicates an Error is Expected.\n");
+}
+
+static PKIX_Error *
+createLdapCertStore(
+ char *hostname,
+ PRIntervalTime timeout,
+ PKIX_CertStore **pLdapCertStore,
+ void *plContext)
+{
+ PRIntn backlog = 0;
+
+ char *bindname = "";
+ char *auth = "";
+
+ LDAPBindAPI bindAPI;
+ LDAPBindAPI *bindPtr = NULL;
+ PKIX_PL_LdapDefaultClient *ldapClient = NULL;
+ PKIX_CertStore *ldapCertStore = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ if (usebind) {
+ bindPtr = &bindAPI;
+ bindAPI.selector = SIMPLE_AUTH;
+ bindAPI.chooser.simple.bindName = bindname;
+ bindAPI.chooser.simple.authentication = auth;
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_LdapDefaultClient_CreateByName(hostname, timeout, bindPtr, &ldapClient, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_LdapCertStore_Create((PKIX_PL_LdapClient *)ldapClient,
+ &ldapCertStore,
+ plContext));
+
+ *pLdapCertStore = ldapCertStore;
+cleanup:
+
+ PKIX_TEST_DECREF_AC(ldapClient);
+
+ PKIX_TEST_RETURN();
+
+ return (pkixTestErrorResult);
+}
+
+int
+test_buildchain(int argc, char *argv[])
+{
+ PKIX_BuildResult *buildResult = NULL;
+ PKIX_ComCertSelParams *certSelParams = NULL;
+ PKIX_CertSelector *certSelector = NULL;
+ PKIX_TrustAnchor *anchor = NULL;
+ PKIX_PL_PublicKey *trustedPubKey = NULL;
+ PKIX_List *anchors = NULL;
+ PKIX_List *certs = NULL;
+ PKIX_RevocationChecker *revChecker = NULL;
+ PKIX_PL_Cert *cert = NULL;
+ PKIX_ProcessingParams *procParams = NULL;
+ char *dirName = NULL;
+ PKIX_PL_String *dirNameString = NULL;
+ PKIX_PL_Cert *trustedCert = NULL;
+ PKIX_PL_Cert *targetCert = NULL;
+ PKIX_UInt32 actualMinorVersion = 0;
+ PKIX_UInt32 numCerts = 0;
+ PKIX_UInt32 i = 0;
+ PKIX_UInt32 j = 0;
+ PKIX_UInt32 k = 0;
+ PKIX_CertStore *ldapCertStore = NULL;
+ PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT; /* blocking */
+ /* PRIntervalTime timeout = PR_INTERVAL_NO_WAIT; =0 for non-blocking */
+ PKIX_CertStore *certStore = NULL;
+ PKIX_List *certStores = NULL;
+ PKIX_List *revCheckers = NULL;
+ char *asciiResult = NULL;
+ PKIX_Boolean result = PKIX_FALSE;
+ PKIX_Boolean testValid = PKIX_TRUE;
+ PKIX_List *expectedCerts = NULL;
+ PKIX_PL_Cert *dirCert = NULL;
+ PKIX_VerifyNode *verifyTree = NULL;
+ PKIX_PL_String *verifyString = NULL;
+ PKIX_PL_String *actualCertsString = NULL;
+ PKIX_PL_String *expectedCertsString = NULL;
+ void *state = NULL;
+ char *actualCertsAscii = NULL;
+ char *expectedCertsAscii = NULL;
+ PRPollDesc *pollDesc = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ if (argc < 5) {
+ printUsage();
+ return (0);
+ }
+
+ startTests("BuildChain");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ /*
+ * arguments:
+ * [optional] -arenas
+ * [optional] usebind
+ * servername or servername:port ( - for no server)
+ * testname
+ * EE or ENE
+ * cert directory
+ * target cert (end entity)
+ * intermediate certs
+ * trust anchor
+ */
+
+ /* optional argument "usebind" for Ldap CertStore */
+ if (argv[j + 1]) {
+ if (PORT_Strcmp(argv[j + 1], "usebind") == 0) {
+ usebind = PKIX_TRUE;
+ j++;
+ }
+ }
+
+ if (PORT_Strcmp(argv[++j], "-") == 0) {
+ useLDAP = PKIX_FALSE;
+ } else {
+ serverName = argv[j];
+ useLDAP = PKIX_TRUE;
+ }
+
+ subTest(argv[++j]);
+
+ /* ENE = expect no error; EE = expect error */
+ if (PORT_Strcmp(argv[++j], "ENE") == 0) {
+ testValid = PKIX_TRUE;
+ } else if (PORT_Strcmp(argv[j], "EE") == 0) {
+ testValid = PKIX_FALSE;
+ } else {
+ printUsage();
+ return (0);
+ }
+
+ dirName = argv[++j];
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&expectedCerts, plContext));
+
+ for (k = ++j; k < (PKIX_UInt32)argc; k++) {
+
+ dirCert = createCert(dirName, argv[k], plContext);
+
+ if (k == (PKIX_UInt32)(argc - 1)) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_IncRef((PKIX_PL_Object *)dirCert, plContext));
+ trustedCert = dirCert;
+ } else {
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(expectedCerts,
+ (PKIX_PL_Object *)dirCert,
+ plContext));
+
+ if (k == j) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_IncRef((PKIX_PL_Object *)dirCert, plContext));
+ targetCert = dirCert;
+ }
+ }
+
+ PKIX_TEST_DECREF_BC(dirCert);
+ }
+
+ /* create processing params with list of trust anchors */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_TrustAnchor_CreateWithCert(trustedCert, &anchor, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&anchors, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(anchors, (PKIX_PL_Object *)anchor, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_Create(anchors, &procParams, plContext));
+
+ /* create CertSelector with target certificate in params */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&certSelParams, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetCertificate(certSelParams, targetCert, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, certSelParams, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetTargetCertConstraints(procParams, certSelector, plContext));
+
+ /* create CertStores */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII, dirName, 0, &dirNameString, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&certStores, plContext));
+
+ if (useLDAP == PKIX_TRUE) {
+ PKIX_TEST_EXPECT_NO_ERROR(createLdapCertStore(serverName, timeout, &ldapCertStore, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(certStores,
+ (PKIX_PL_Object *)ldapCertStore,
+ plContext));
+ } else {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CollectionCertStore_Create(dirNameString, &certStore, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(certStores, (PKIX_PL_Object *)certStore, plContext));
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetCertStores(procParams, certStores, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&revCheckers, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetSubjectPublicKey(trustedCert, &trustedPubKey, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(expectedCerts, &numCerts, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_DefaultRevChecker_Initialize(certStores,
+ NULL, /* testDate, may be NULL */
+ trustedPubKey,
+ numCerts,
+ &revChecker,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(revCheckers, (PKIX_PL_Object *)revChecker, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetRevocationCheckers(procParams, revCheckers, plContext));
+
+#ifdef debuggingWithoutRevocation
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetRevocationEnabled(procParams, PKIX_FALSE, plContext));
+#endif
+
+ /* build cert chain using processing params and return buildResult */
+
+ pkixTestErrorResult = PKIX_BuildChain(procParams,
+ (void **)&pollDesc,
+ &state,
+ &buildResult,
+ &verifyTree,
+ plContext);
+
+ while (pollDesc != NULL) {
+
+ if (PR_Poll(pollDesc, 1, 0) < 0) {
+ testError("PR_Poll failed");
+ }
+
+ pkixTestErrorResult = PKIX_BuildChain(procParams,
+ (void **)&pollDesc,
+ &state,
+ &buildResult,
+ &verifyTree,
+ plContext);
+ }
+
+ if (pkixTestErrorResult) {
+ if (testValid == PKIX_FALSE) { /* EE */
+ (void)printf("EXPECTED ERROR RECEIVED!\n");
+ } else { /* ENE */
+ testError("UNEXPECTED ERROR RECEIVED");
+ }
+ } else {
+ if (testValid == PKIX_TRUE) { /* ENE */
+ (void)printf("EXPECTED NON-ERROR RECEIVED!\n");
+ } else { /* EE */
+ (void)printf("UNEXPECTED NON-ERROR RECEIVED!\n");
+ }
+ }
+
+ subTest("Displaying VerifyNode objects");
+
+ if (verifyTree == NULL) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII, "(null)", 0, &verifyString, plContext));
+ } else {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)verifyTree, &verifyString, plContext));
+ }
+
+ (void)printf("verifyTree is\n%s\n", verifyString->escAsciiString);
+
+ if (pkixTestErrorResult) {
+ PKIX_TEST_DECREF_BC(pkixTestErrorResult);
+ goto cleanup;
+ }
+
+ if (buildResult) {
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_BuildResult_GetCertChain(buildResult, &certs, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certs, &numCerts, plContext));
+
+ printf("\n");
+
+ for (i = 0; i < numCerts; i++) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certs,
+ i,
+ (PKIX_PL_Object **)&cert,
+ plContext));
+
+ asciiResult = PKIX_Cert2ASCII(cert);
+
+ printf("CERT[%d]:\n%s\n", i, asciiResult);
+
+ /* PKIX_Cert2ASCII used PKIX_PL_Malloc(...,,NULL) */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(asciiResult, NULL));
+ asciiResult = NULL;
+
+ PKIX_TEST_DECREF_BC(cert);
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)certs,
+ (PKIX_PL_Object *)expectedCerts,
+ &result,
+ plContext));
+
+ if (!result) {
+ testError("BUILT CERTCHAIN IS "
+ "NOT THE ONE THAT WAS EXPECTED");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)certs,
+ &actualCertsString,
+ plContext));
+
+ actualCertsAscii = PKIX_String2ASCII(actualCertsString, plContext);
+ if (actualCertsAscii == NULL) {
+ pkixTestErrorMsg = "PKIX_String2ASCII Failed";
+ goto cleanup;
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)expectedCerts,
+ &expectedCertsString,
+ plContext));
+
+ expectedCertsAscii = PKIX_String2ASCII(expectedCertsString, plContext);
+ if (expectedCertsAscii == NULL) {
+ pkixTestErrorMsg = "PKIX_String2ASCII Failed";
+ goto cleanup;
+ }
+
+ (void)printf("Actual value:\t%s\n", actualCertsAscii);
+ (void)printf("Expected value:\t%s\n",
+ expectedCertsAscii);
+ }
+ }
+
+cleanup:
+ PKIX_TEST_DECREF_AC(verifyString);
+ PKIX_TEST_DECREF_AC(verifyTree);
+
+ PKIX_PL_Free(asciiResult, NULL);
+ PKIX_PL_Free(actualCertsAscii, plContext);
+ PKIX_PL_Free(expectedCertsAscii, plContext);
+
+ PKIX_TEST_DECREF_AC(state);
+ PKIX_TEST_DECREF_AC(actualCertsString);
+ PKIX_TEST_DECREF_AC(expectedCertsString);
+ PKIX_TEST_DECREF_AC(expectedCerts);
+ PKIX_TEST_DECREF_AC(buildResult);
+ PKIX_TEST_DECREF_AC(procParams);
+ PKIX_TEST_DECREF_AC(certStores);
+ PKIX_TEST_DECREF_AC(revCheckers);
+ PKIX_TEST_DECREF_AC(revChecker);
+ PKIX_TEST_DECREF_AC(ldapCertStore);
+ PKIX_TEST_DECREF_AC(certStore);
+ PKIX_TEST_DECREF_AC(dirNameString);
+ PKIX_TEST_DECREF_AC(certSelParams);
+ PKIX_TEST_DECREF_AC(certSelector);
+ PKIX_TEST_DECREF_AC(anchors);
+ PKIX_TEST_DECREF_AC(anchor);
+ PKIX_TEST_DECREF_AC(trustedCert);
+ PKIX_TEST_DECREF_AC(trustedPubKey);
+
+ PKIX_TEST_DECREF_AC(certs);
+ PKIX_TEST_DECREF_AC(cert);
+ PKIX_TEST_DECREF_AC(targetCert);
+
+ PKIX_TEST_RETURN();
+
+ PKIX_Shutdown(plContext);
+
+ endTests("BuildChain");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/top/test_buildchain_partialchain.c b/nss/cmd/libpkix/pkix/top/test_buildchain_partialchain.c
new file mode 100644
index 0000000..4861a8e
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/top/test_buildchain_partialchain.c
@@ -0,0 +1,725 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_buildchain_partialchain.c
+ *
+ * Test BuildChain function
+ *
+ */
+
+#define debuggingWithoutRevocation
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+#define LDAP_PORT 389
+static PKIX_Boolean usebind = PKIX_FALSE;
+static PKIX_Boolean useLDAP = PKIX_FALSE;
+static char buf[PR_NETDB_BUF_SIZE];
+static char *serverName = NULL;
+static char *sepPtr = NULL;
+static PRNetAddr netAddr;
+static PRHostEnt hostent;
+static PKIX_UInt32 portNum = 0;
+static PRIntn hostenum = 0;
+static PRStatus prstatus = PR_FAILURE;
+static void *ipaddr = NULL;
+
+static void *plContext = NULL;
+
+static void
+printUsage(void)
+{
+ (void)printf("\nUSAGE:\ttest_buildchain [-arenas] [usebind] "
+ "servername[:port] [ENE|EE]\n"
+ "\t "
+ " \n\n");
+ (void)printf("Builds a chain of certificates from to \n"
+ "using the certs and CRLs in . "
+ "servername[:port] gives\n"
+ "the address of an LDAP server. If port is not"
+ " specified, port 389 is used. \"-\" means no LDAP server.\n"
+ "If ENE is specified, then an Error is Not Expected. "
+ "EE indicates an Error is Expected.\n");
+}
+
+static PKIX_Error *
+createLdapCertStore(
+ char *hostname,
+ PRIntervalTime timeout,
+ PKIX_CertStore **pLdapCertStore,
+ void *plContext)
+{
+ PRIntn backlog = 0;
+
+ char *bindname = "";
+ char *auth = "";
+
+ LDAPBindAPI bindAPI;
+ LDAPBindAPI *bindPtr = NULL;
+ PKIX_PL_LdapDefaultClient *ldapClient = NULL;
+ PKIX_CertStore *ldapCertStore = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ if (usebind) {
+ bindPtr = &bindAPI;
+ bindAPI.selector = SIMPLE_AUTH;
+ bindAPI.chooser.simple.bindName = bindname;
+ bindAPI.chooser.simple.authentication = auth;
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_LdapDefaultClient_CreateByName(hostname, timeout, bindPtr, &ldapClient, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_LdapCertStore_Create((PKIX_PL_LdapClient *)ldapClient,
+ &ldapCertStore,
+ plContext));
+
+ *pLdapCertStore = ldapCertStore;
+cleanup:
+
+ PKIX_TEST_DECREF_AC(ldapClient);
+
+ PKIX_TEST_RETURN();
+
+ return (pkixTestErrorResult);
+}
+
+/* Test with all Certs in the partial list, no leaf */
+static PKIX_Error *
+testWithNoLeaf(
+ PKIX_PL_Cert *trustedCert,
+ PKIX_List *listOfCerts,
+ PKIX_PL_Cert *targetCert,
+ PKIX_List *certStores,
+ PKIX_Boolean testValid,
+ void *plContext)
+{
+ PKIX_UInt32 numCerts = 0;
+ PKIX_UInt32 i = 0;
+ PKIX_TrustAnchor *anchor = NULL;
+ PKIX_List *anchors = NULL;
+ PKIX_List *hintCerts = NULL;
+ PKIX_List *revCheckers = NULL;
+ PKIX_List *certs = NULL;
+ PKIX_PL_Cert *cert = NULL;
+ PKIX_ProcessingParams *procParams = NULL;
+ PKIX_ComCertSelParams *certSelParams = NULL;
+ PKIX_CertSelector *certSelector = NULL;
+ PKIX_PL_PublicKey *trustedPubKey = NULL;
+ PKIX_RevocationChecker *revChecker = NULL;
+ PKIX_BuildResult *buildResult = NULL;
+ PRPollDesc *pollDesc = NULL;
+ void *state = NULL;
+ char *asciiResult = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ /* create processing params with list of trust anchors */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_TrustAnchor_CreateWithCert(trustedCert, &anchor, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&anchors, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(anchors, (PKIX_PL_Object *)anchor, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_Create(anchors, &procParams, plContext));
+
+ /* create CertSelector with no target certificate in params */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&certSelParams, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, certSelParams, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetTargetCertConstraints(procParams, certSelector, plContext));
+
+ /* create hintCerts */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Duplicate((PKIX_PL_Object *)listOfCerts,
+ (PKIX_PL_Object **)&hintCerts,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetHintCerts(procParams, hintCerts, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetCertStores(procParams, certStores, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&revCheckers, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetSubjectPublicKey(trustedCert, &trustedPubKey, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(listOfCerts, &numCerts, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_DefaultRevChecker_Initialize(certStores,
+ NULL, /* testDate, may be NULL */
+ trustedPubKey,
+ numCerts,
+ &revChecker,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(revCheckers, (PKIX_PL_Object *)revChecker, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetRevocationCheckers(procParams, revCheckers, plContext));
+
+#ifdef debuggingWithoutRevocation
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetRevocationEnabled(procParams, PKIX_FALSE, plContext));
+#endif
+
+ /* build cert chain using processing params and return buildResult */
+
+ pkixTestErrorResult = PKIX_BuildChain(procParams,
+ (void **)&pollDesc,
+ &state,
+ &buildResult,
+ NULL,
+ plContext);
+
+ while (pollDesc != NULL) {
+
+ if (PR_Poll(pollDesc, 1, 0) < 0) {
+ testError("PR_Poll failed");
+ }
+
+ pkixTestErrorResult = PKIX_BuildChain(procParams,
+ (void **)&pollDesc,
+ &state,
+ &buildResult,
+ NULL,
+ plContext);
+ }
+
+ if (pkixTestErrorResult) {
+ if (testValid == PKIX_FALSE) { /* EE */
+ (void)printf("EXPECTED ERROR RECEIVED!\n");
+ } else { /* ENE */
+ testError("UNEXPECTED ERROR RECEIVED");
+ }
+ PKIX_TEST_DECREF_BC(pkixTestErrorResult);
+ goto cleanup;
+ }
+
+ if (testValid == PKIX_TRUE) { /* ENE */
+ (void)printf("EXPECTED NON-ERROR RECEIVED!\n");
+ } else { /* EE */
+ (void)printf("UNEXPECTED NON-ERROR RECEIVED!\n");
+ }
+
+ if (buildResult) {
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_BuildResult_GetCertChain(buildResult, &certs, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certs, &numCerts, plContext));
+
+ printf("\n");
+
+ for (i = 0; i < numCerts; i++) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certs,
+ i,
+ (PKIX_PL_Object **)&cert,
+ plContext));
+
+ asciiResult = PKIX_Cert2ASCII(cert);
+
+ printf("CERT[%d]:\n%s\n", i, asciiResult);
+
+ /* PKIX_Cert2ASCII used PKIX_PL_Malloc(...,,NULL) */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(asciiResult, NULL));
+ asciiResult = NULL;
+
+ PKIX_TEST_DECREF_BC(cert);
+ }
+ }
+
+cleanup:
+ PKIX_PL_Free(asciiResult, NULL);
+
+ PKIX_TEST_DECREF_AC(state);
+ PKIX_TEST_DECREF_AC(buildResult);
+ PKIX_TEST_DECREF_AC(procParams);
+ PKIX_TEST_DECREF_AC(revCheckers);
+ PKIX_TEST_DECREF_AC(revChecker);
+ PKIX_TEST_DECREF_AC(certSelParams);
+ PKIX_TEST_DECREF_AC(certSelector);
+ PKIX_TEST_DECREF_AC(anchors);
+ PKIX_TEST_DECREF_AC(anchor);
+ PKIX_TEST_DECREF_AC(hintCerts);
+ PKIX_TEST_DECREF_AC(trustedPubKey);
+ PKIX_TEST_DECREF_AC(certs);
+ PKIX_TEST_DECREF_AC(cert);
+ PKIX_TEST_RETURN();
+
+ return (pkixTestErrorResult);
+}
+
+/* Test with all Certs in the partial list, leaf duplicates the first one */
+static PKIX_Error *
+testWithDuplicateLeaf(
+ PKIX_PL_Cert *trustedCert,
+ PKIX_List *listOfCerts,
+ PKIX_PL_Cert *targetCert,
+ PKIX_List *certStores,
+ PKIX_Boolean testValid,
+ void *plContext)
+{
+ PKIX_UInt32 numCerts = 0;
+ PKIX_UInt32 i = 0;
+ PKIX_TrustAnchor *anchor = NULL;
+ PKIX_List *anchors = NULL;
+ PKIX_List *hintCerts = NULL;
+ PKIX_List *revCheckers = NULL;
+ PKIX_List *certs = NULL;
+ PKIX_PL_Cert *cert = NULL;
+ PKIX_ProcessingParams *procParams = NULL;
+ PKIX_ComCertSelParams *certSelParams = NULL;
+ PKIX_CertSelector *certSelector = NULL;
+ PKIX_PL_PublicKey *trustedPubKey = NULL;
+ PKIX_RevocationChecker *revChecker = NULL;
+ PKIX_BuildResult *buildResult = NULL;
+ PRPollDesc *pollDesc = NULL;
+ void *state = NULL;
+ char *asciiResult = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ /* create processing params with list of trust anchors */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_TrustAnchor_CreateWithCert(trustedCert, &anchor, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&anchors, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(anchors, (PKIX_PL_Object *)anchor, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_Create(anchors, &procParams, plContext));
+
+ /* create CertSelector with target certificate in params */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&certSelParams, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetCertificate(certSelParams, targetCert, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, certSelParams, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetTargetCertConstraints(procParams, certSelector, plContext));
+
+ /* create hintCerts */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Duplicate((PKIX_PL_Object *)listOfCerts,
+ (PKIX_PL_Object **)&hintCerts,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetHintCerts(procParams, hintCerts, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetCertStores(procParams, certStores, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&revCheckers, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetSubjectPublicKey(trustedCert, &trustedPubKey, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(listOfCerts, &numCerts, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_DefaultRevChecker_Initialize(certStores,
+ NULL, /* testDate, may be NULL */
+ trustedPubKey,
+ numCerts,
+ &revChecker,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(revCheckers, (PKIX_PL_Object *)revChecker, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetRevocationCheckers(procParams, revCheckers, plContext));
+
+#ifdef debuggingWithoutRevocation
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetRevocationEnabled(procParams, PKIX_FALSE, plContext));
+#endif
+
+ /* build cert chain using processing params and return buildResult */
+
+ pkixTestErrorResult = PKIX_BuildChain(procParams,
+ (void **)&pollDesc,
+ &state,
+ &buildResult,
+ NULL,
+ plContext);
+
+ while (pollDesc != NULL) {
+
+ if (PR_Poll(pollDesc, 1, 0) < 0) {
+ testError("PR_Poll failed");
+ }
+
+ pkixTestErrorResult = PKIX_BuildChain(procParams,
+ (void **)&pollDesc,
+ &state,
+ &buildResult,
+ NULL,
+ plContext);
+ }
+
+ if (pkixTestErrorResult) {
+ if (testValid == PKIX_FALSE) { /* EE */
+ (void)printf("EXPECTED ERROR RECEIVED!\n");
+ } else { /* ENE */
+ testError("UNEXPECTED ERROR RECEIVED");
+ }
+ PKIX_TEST_DECREF_BC(pkixTestErrorResult);
+ goto cleanup;
+ }
+
+ if (testValid == PKIX_TRUE) { /* ENE */
+ (void)printf("EXPECTED NON-ERROR RECEIVED!\n");
+ } else { /* EE */
+ (void)printf("UNEXPECTED NON-ERROR RECEIVED!\n");
+ }
+
+ if (buildResult) {
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_BuildResult_GetCertChain(buildResult, &certs, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certs, &numCerts, plContext));
+
+ printf("\n");
+
+ for (i = 0; i < numCerts; i++) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certs,
+ i,
+ (PKIX_PL_Object **)&cert,
+ plContext));
+
+ asciiResult = PKIX_Cert2ASCII(cert);
+
+ printf("CERT[%d]:\n%s\n", i, asciiResult);
+
+ /* PKIX_Cert2ASCII used PKIX_PL_Malloc(...,,NULL) */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(asciiResult, NULL));
+ asciiResult = NULL;
+
+ PKIX_TEST_DECREF_BC(cert);
+ }
+ }
+
+cleanup:
+ PKIX_PL_Free(asciiResult, NULL);
+
+ PKIX_TEST_DECREF_AC(state);
+ PKIX_TEST_DECREF_AC(buildResult);
+ PKIX_TEST_DECREF_AC(procParams);
+ PKIX_TEST_DECREF_AC(revCheckers);
+ PKIX_TEST_DECREF_AC(revChecker);
+ PKIX_TEST_DECREF_AC(certSelParams);
+ PKIX_TEST_DECREF_AC(certSelector);
+ PKIX_TEST_DECREF_AC(anchors);
+ PKIX_TEST_DECREF_AC(anchor);
+ PKIX_TEST_DECREF_AC(hintCerts);
+ PKIX_TEST_DECREF_AC(trustedPubKey);
+ PKIX_TEST_DECREF_AC(certs);
+ PKIX_TEST_DECREF_AC(cert);
+ PKIX_TEST_RETURN();
+
+ return (pkixTestErrorResult);
+}
+
+/* Test with all Certs except the leaf in the partial list */
+static PKIX_Error *
+testWithLeafAndChain(
+ PKIX_PL_Cert *trustedCert,
+ PKIX_List *listOfCerts,
+ PKIX_PL_Cert *targetCert,
+ PKIX_List *certStores,
+ PKIX_Boolean testValid,
+ void *plContext)
+{
+ PKIX_UInt32 numCerts = 0;
+ PKIX_UInt32 i = 0;
+ PKIX_TrustAnchor *anchor = NULL;
+ PKIX_List *anchors = NULL;
+ PKIX_List *hintCerts = NULL;
+ PKIX_List *revCheckers = NULL;
+ PKIX_List *certs = NULL;
+ PKIX_PL_Cert *cert = NULL;
+ PKIX_ProcessingParams *procParams = NULL;
+ PKIX_ComCertSelParams *certSelParams = NULL;
+ PKIX_CertSelector *certSelector = NULL;
+ PKIX_PL_PublicKey *trustedPubKey = NULL;
+ PKIX_RevocationChecker *revChecker = NULL;
+ PKIX_BuildResult *buildResult = NULL;
+ PRPollDesc *pollDesc = NULL;
+ void *state = NULL;
+ char *asciiResult = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ /* create processing params with list of trust anchors */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_TrustAnchor_CreateWithCert(trustedCert, &anchor, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&anchors, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(anchors, (PKIX_PL_Object *)anchor, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_Create(anchors, &procParams, plContext));
+
+ /* create CertSelector with target certificate in params */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&certSelParams, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetCertificate(certSelParams, targetCert, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, certSelParams, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetTargetCertConstraints(procParams, certSelector, plContext));
+
+ /* create hintCerts */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Duplicate((PKIX_PL_Object *)listOfCerts,
+ (PKIX_PL_Object **)&hintCerts,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_DeleteItem(hintCerts, 0, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetHintCerts(procParams, hintCerts, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetCertStores(procParams, certStores, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&revCheckers, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetSubjectPublicKey(trustedCert, &trustedPubKey, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(listOfCerts, &numCerts, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_DefaultRevChecker_Initialize(certStores,
+ NULL, /* testDate, may be NULL */
+ trustedPubKey,
+ numCerts,
+ &revChecker,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(revCheckers, (PKIX_PL_Object *)revChecker, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetRevocationCheckers(procParams, revCheckers, plContext));
+
+#ifdef debuggingWithoutRevocation
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetRevocationEnabled(procParams, PKIX_FALSE, plContext));
+#endif
+
+ /* build cert chain using processing params and return buildResult */
+
+ pkixTestErrorResult = PKIX_BuildChain(procParams,
+ (void **)&pollDesc,
+ &state,
+ &buildResult,
+ NULL,
+ plContext);
+
+ while (pollDesc != NULL) {
+
+ if (PR_Poll(pollDesc, 1, 0) < 0) {
+ testError("PR_Poll failed");
+ }
+
+ pkixTestErrorResult = PKIX_BuildChain(procParams,
+ (void **)&pollDesc,
+ &state,
+ &buildResult,
+ NULL,
+ plContext);
+ }
+
+ if (pkixTestErrorResult) {
+ if (testValid == PKIX_FALSE) { /* EE */
+ (void)printf("EXPECTED ERROR RECEIVED!\n");
+ } else { /* ENE */
+ testError("UNEXPECTED ERROR RECEIVED");
+ }
+ PKIX_TEST_DECREF_BC(pkixTestErrorResult);
+ goto cleanup;
+ }
+
+ if (testValid == PKIX_TRUE) { /* ENE */
+ (void)printf("EXPECTED NON-ERROR RECEIVED!\n");
+ } else { /* EE */
+ (void)printf("UNEXPECTED NON-ERROR RECEIVED!\n");
+ }
+
+ if (buildResult) {
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_BuildResult_GetCertChain(buildResult, &certs, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certs, &numCerts, plContext));
+
+ printf("\n");
+
+ for (i = 0; i < numCerts; i++) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certs,
+ i,
+ (PKIX_PL_Object **)&cert,
+ plContext));
+
+ asciiResult = PKIX_Cert2ASCII(cert);
+
+ printf("CERT[%d]:\n%s\n", i, asciiResult);
+
+ /* PKIX_Cert2ASCII used PKIX_PL_Malloc(...,,NULL) */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(asciiResult, NULL));
+ asciiResult = NULL;
+
+ PKIX_TEST_DECREF_BC(cert);
+ }
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(state);
+ PKIX_TEST_DECREF_AC(buildResult);
+ PKIX_TEST_DECREF_AC(procParams);
+ PKIX_TEST_DECREF_AC(revCheckers);
+ PKIX_TEST_DECREF_AC(revChecker);
+ PKIX_TEST_DECREF_AC(certSelParams);
+ PKIX_TEST_DECREF_AC(certSelector);
+ PKIX_TEST_DECREF_AC(anchors);
+ PKIX_TEST_DECREF_AC(anchor);
+ PKIX_TEST_DECREF_AC(hintCerts);
+ PKIX_TEST_DECREF_AC(trustedPubKey);
+ PKIX_TEST_DECREF_AC(certs);
+ PKIX_TEST_DECREF_AC(cert);
+
+ PKIX_TEST_RETURN();
+
+ return (pkixTestErrorResult);
+}
+
+int
+test_buildchain_partialchain(int argc, char *argv[])
+{
+ PKIX_UInt32 actualMinorVersion = 0;
+ PKIX_UInt32 j = 0;
+ PKIX_UInt32 k = 0;
+ PKIX_Boolean ene = PKIX_TRUE; /* expect no error */
+ PKIX_List *listOfCerts = NULL;
+ PKIX_List *certStores = NULL;
+ PKIX_PL_Cert *dirCert = NULL;
+ PKIX_PL_Cert *trusted = NULL;
+ PKIX_PL_Cert *target = NULL;
+ PKIX_CertStore *ldapCertStore = NULL;
+ PKIX_CertStore *certStore = NULL;
+ PKIX_PL_String *dirNameString = NULL;
+ char *dirName = NULL;
+
+ PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT; /* blocking */
+ /* PRIntervalTime timeout = PR_INTERVAL_NO_WAIT; =0 for non-blocking */
+
+ PKIX_TEST_STD_VARS();
+
+ if (argc < 5) {
+ printUsage();
+ return (0);
+ }
+
+ startTests("BuildChain");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ /*
+ * arguments:
+ * [optional] -arenas
+ * [optional] usebind
+ * servername or servername:port ( - for no server)
+ * testname
+ * EE or ENE
+ * cert directory
+ * target cert (end entity)
+ * intermediate certs
+ * trust anchor
+ */
+
+ /* optional argument "usebind" for Ldap CertStore */
+ if (argv[j + 1]) {
+ if (PORT_Strcmp(argv[j + 1], "usebind") == 0) {
+ usebind = PKIX_TRUE;
+ j++;
+ }
+ }
+
+ if (PORT_Strcmp(argv[++j], "-") == 0) {
+ useLDAP = PKIX_FALSE;
+ } else {
+ serverName = argv[j];
+ useLDAP = PKIX_TRUE;
+ }
+
+ subTest(argv[++j]);
+
+ /* ENE = expect no error; EE = expect error */
+ if (PORT_Strcmp(argv[++j], "ENE") == 0) {
+ ene = PKIX_TRUE;
+ } else if (PORT_Strcmp(argv[j], "EE") == 0) {
+ ene = PKIX_FALSE;
+ } else {
+ printUsage();
+ return (0);
+ }
+
+ dirName = argv[++j];
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&listOfCerts, plContext));
+
+ for (k = ++j; k < ((PKIX_UInt32)argc); k++) {
+
+ dirCert = createCert(dirName, argv[k], plContext);
+
+ if (k == ((PKIX_UInt32)(argc - 1))) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_IncRef((PKIX_PL_Object *)dirCert, plContext));
+ trusted = dirCert;
+ } else {
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(listOfCerts,
+ (PKIX_PL_Object *)dirCert,
+ plContext));
+
+ if (k == j) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_IncRef((PKIX_PL_Object *)dirCert, plContext));
+ target = dirCert;
+ }
+ }
+
+ PKIX_TEST_DECREF_BC(dirCert);
+ }
+
+ /* create CertStores */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII, dirName, 0, &dirNameString, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&certStores, plContext));
+
+ if (useLDAP == PKIX_TRUE) {
+ PKIX_TEST_EXPECT_NO_ERROR(createLdapCertStore(serverName, timeout, &ldapCertStore, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(certStores,
+ (PKIX_PL_Object *)ldapCertStore,
+ plContext));
+ } else {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CollectionCertStore_Create(dirNameString, &certStore, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(certStores, (PKIX_PL_Object *)certStore, plContext));
+ }
+
+ subTest("testWithNoLeaf");
+ PKIX_TEST_EXPECT_NO_ERROR(testWithNoLeaf(trusted, listOfCerts, target, certStores, ene, plContext));
+
+ subTest("testWithDuplicateLeaf");
+ PKIX_TEST_EXPECT_NO_ERROR(testWithDuplicateLeaf(trusted, listOfCerts, target, certStores, ene, plContext));
+
+ subTest("testWithLeafAndChain");
+ PKIX_TEST_EXPECT_NO_ERROR(testWithLeafAndChain(trusted, listOfCerts, target, certStores, ene, plContext));
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(listOfCerts);
+ PKIX_TEST_DECREF_AC(certStores);
+ PKIX_TEST_DECREF_AC(ldapCertStore);
+ PKIX_TEST_DECREF_AC(certStore);
+ PKIX_TEST_DECREF_AC(dirNameString);
+ PKIX_TEST_DECREF_AC(trusted);
+ PKIX_TEST_DECREF_AC(target);
+
+ PKIX_TEST_RETURN();
+
+ PKIX_Shutdown(plContext);
+
+ endTests("BuildChain");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/top/test_buildchain_resourcelimits.c b/nss/cmd/libpkix/pkix/top/test_buildchain_resourcelimits.c
new file mode 100644
index 0000000..1b28435
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/top/test_buildchain_resourcelimits.c
@@ -0,0 +1,438 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_buildchain_resourcelimits.c
+ *
+ * Test BuildChain function with constraints on resources
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+#define PKIX_TESTUSERCHECKER_TYPE (PKIX_NUMTYPES + 30)
+
+static void *plContext = NULL;
+static PKIX_Boolean usebind = PKIX_FALSE;
+static PKIX_Boolean useLDAP = PKIX_FALSE;
+static char buf[PR_NETDB_BUF_SIZE];
+static char *serverName = NULL;
+
+static void
+printUsage(void)
+{
+ (void)printf("\nUSAGE:\ttest_buildchain_resourcelimits [-arenas] "
+ "[usebind] servername[:port]\\\n\t\t [ENE|EE]"
+ " \\\n\t\t"
+ " \n\n");
+ (void)printf("Builds a chain of certificates from to \n"
+ "using the certs and CRLs in . "
+ "servername[:port] gives\n"
+ "the address of an LDAP server. If port is not"
+ " specified, port 389 is used.\n\"-\" means no LDAP server.\n\n"
+ "If ENE is specified, then an Error is Not Expected.\n"
+ "EE indicates an Error is Expected.\n");
+}
+
+static PKIX_Error *
+createLdapCertStore(
+ char *hostname,
+ PRIntervalTime timeout,
+ PKIX_CertStore **pLdapCertStore,
+ void *plContext)
+{
+ PRIntn backlog = 0;
+
+ char *bindname = "";
+ char *auth = "";
+
+ LDAPBindAPI bindAPI;
+ LDAPBindAPI *bindPtr = NULL;
+ PKIX_PL_LdapDefaultClient *ldapClient = NULL;
+ PKIX_CertStore *ldapCertStore = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ if (usebind) {
+ bindPtr = &bindAPI;
+ bindAPI.selector = SIMPLE_AUTH;
+ bindAPI.chooser.simple.bindName = bindname;
+ bindAPI.chooser.simple.authentication = auth;
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_LdapDefaultClient_CreateByName(hostname, timeout, bindPtr, &ldapClient, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_LdapCertStore_Create((PKIX_PL_LdapClient *)ldapClient, &ldapCertStore, plContext));
+
+ *pLdapCertStore = ldapCertStore;
+cleanup:
+
+ PKIX_TEST_DECREF_AC(ldapClient);
+
+ PKIX_TEST_RETURN();
+
+ return (pkixTestErrorResult);
+}
+
+static void
+Test_BuildResult(
+ PKIX_ProcessingParams *procParams,
+ PKIX_Boolean testValid,
+ PKIX_List *expectedCerts,
+ void *plContext)
+{
+ PKIX_PL_Cert *cert = NULL;
+ PKIX_List *certs = NULL;
+ PKIX_PL_String *actualCertsString = NULL;
+ PKIX_PL_String *expectedCertsString = NULL;
+ PKIX_BuildResult *buildResult = NULL;
+ PKIX_Boolean result;
+ PKIX_Boolean supportForward = PKIX_FALSE;
+ PKIX_UInt32 numCerts, i;
+ char *asciiResult = NULL;
+ char *actualCertsAscii = NULL;
+ char *expectedCertsAscii = NULL;
+ void *state = NULL;
+ PRPollDesc *pollDesc = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ pkixTestErrorResult = PKIX_BuildChain(procParams,
+ (void **)&pollDesc,
+ &state,
+ &buildResult,
+ NULL,
+ plContext);
+
+ while (pollDesc != NULL) {
+
+ if (PR_Poll(pollDesc, 1, 0) < 0) {
+ testError("PR_Poll failed");
+ }
+
+ pkixTestErrorResult = PKIX_BuildChain(procParams,
+ (void **)&pollDesc,
+ &state,
+ &buildResult,
+ NULL,
+ plContext);
+ }
+
+ if (pkixTestErrorResult) {
+ if (testValid == PKIX_FALSE) { /* EE */
+ (void)printf("EXPECTED ERROR RECEIVED!\n");
+ } else { /* ENE */
+ testError("UNEXPECTED ERROR RECEIVED!\n");
+ }
+ PKIX_TEST_DECREF_BC(pkixTestErrorResult);
+ goto cleanup;
+ }
+
+ if (testValid == PKIX_TRUE) { /* ENE */
+ (void)printf("EXPECTED NON-ERROR RECEIVED!\n");
+ } else { /* EE */
+ testError("UNEXPECTED NON-ERROR RECEIVED!\n");
+ }
+
+ if (buildResult) {
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_BuildResult_GetCertChain(buildResult, &certs, NULL));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certs, &numCerts, plContext));
+
+ printf("\n");
+
+ for (i = 0; i < numCerts; i++) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certs,
+ i,
+ (PKIX_PL_Object **)&cert,
+ plContext));
+
+ asciiResult = PKIX_Cert2ASCII(cert);
+
+ printf("CERT[%d]:\n%s\n", i, asciiResult);
+
+ /* PKIX_Cert2ASCII used PKIX_PL_Malloc(...,,NULL) */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(asciiResult, NULL));
+ asciiResult = NULL;
+
+ PKIX_TEST_DECREF_BC(cert);
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)certs,
+ (PKIX_PL_Object *)expectedCerts,
+ &result,
+ plContext));
+
+ if (!result) {
+ testError("BUILT CERTCHAIN IS "
+ "NOT THE ONE THAT WAS EXPECTED");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)certs,
+ &actualCertsString,
+ plContext));
+
+ actualCertsAscii = PKIX_String2ASCII(actualCertsString, plContext);
+ if (actualCertsAscii == NULL) {
+ pkixTestErrorMsg = "PKIX_String2ASCII Failed";
+ goto cleanup;
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)expectedCerts,
+ &expectedCertsString,
+ plContext));
+
+ expectedCertsAscii = PKIX_String2ASCII(expectedCertsString, plContext);
+ if (expectedCertsAscii == NULL) {
+ pkixTestErrorMsg = "PKIX_String2ASCII Failed";
+ goto cleanup;
+ }
+
+ (void)printf("Actual value:\t%s\n", actualCertsAscii);
+ (void)printf("Expected value:\t%s\n",
+ expectedCertsAscii);
+ }
+ }
+
+cleanup:
+
+ PKIX_PL_Free(asciiResult, NULL);
+ PKIX_PL_Free(actualCertsAscii, plContext);
+ PKIX_PL_Free(expectedCertsAscii, plContext);
+ PKIX_TEST_DECREF_AC(state);
+ PKIX_TEST_DECREF_AC(buildResult);
+ PKIX_TEST_DECREF_AC(certs);
+ PKIX_TEST_DECREF_AC(cert);
+ PKIX_TEST_DECREF_AC(actualCertsString);
+ PKIX_TEST_DECREF_AC(expectedCertsString);
+
+ PKIX_TEST_RETURN();
+}
+
+int
+test_buildchain_resourcelimits(int argc, char *argv[])
+{
+ PKIX_ComCertSelParams *certSelParams = NULL;
+ PKIX_CertSelector *certSelector = NULL;
+ PKIX_TrustAnchor *anchor = NULL;
+ PKIX_List *anchors = NULL;
+ PKIX_ProcessingParams *procParams = NULL;
+ PKIX_CertChainChecker *checker = NULL;
+ PKIX_ResourceLimits *resourceLimits = NULL;
+ char *dirName = NULL;
+ PKIX_PL_String *dirNameString = NULL;
+ PKIX_PL_Cert *trustedCert = NULL;
+ PKIX_PL_Cert *targetCert = NULL;
+ PKIX_PL_Cert *dirCert = NULL;
+ PKIX_UInt32 actualMinorVersion = 0;
+ PKIX_UInt32 j = 0;
+ PKIX_UInt32 k = 0;
+ PKIX_CertStore *ldapCertStore = NULL;
+ PRIntervalTime timeout = 0; /* 0 for non-blocking */
+ PKIX_CertStore *certStore = NULL;
+ PKIX_List *certStores = NULL;
+ PKIX_List *expectedCerts = NULL;
+ PKIX_Boolean testValid = PKIX_FALSE;
+ PKIX_Boolean usebind = PKIX_FALSE;
+ PKIX_Boolean useLDAP = PKIX_FALSE;
+
+ PKIX_TEST_STD_VARS();
+
+ if (argc < 5) {
+ printUsage();
+ return (0);
+ }
+
+ startTests("BuildChain_ResourceLimits");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ /*
+ * arguments:
+ * [optional] -arenas
+ * [optional] usebind
+ * servername or servername:port ( - for no server)
+ * testname
+ * EE or ENE
+ * cert directory
+ * target cert (end entity)
+ * intermediate certs
+ * trust anchor
+ */
+
+ /* optional argument "usebind" for Ldap CertStore */
+ if (argv[j + 1]) {
+ if (PORT_Strcmp(argv[j + 1], "usebind") == 0) {
+ usebind = PKIX_TRUE;
+ j++;
+ }
+ }
+
+ if (PORT_Strcmp(argv[++j], "-") == 0) {
+ useLDAP = PKIX_FALSE;
+ } else {
+ serverName = argv[j];
+ }
+
+ subTest(argv[++j]);
+
+ /* ENE = expect no error; EE = expect error */
+ if (PORT_Strcmp(argv[++j], "ENE") == 0) {
+ testValid = PKIX_TRUE;
+ } else if (PORT_Strcmp(argv[j], "EE") == 0) {
+ testValid = PKIX_FALSE;
+ } else {
+ printUsage();
+ return (0);
+ }
+
+ dirName = argv[++j];
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&expectedCerts, plContext));
+
+ for (k = ++j; k < argc; k++) {
+
+ dirCert = createCert(dirName, argv[k], plContext);
+
+ if (k == (argc - 1)) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_IncRef((PKIX_PL_Object *)dirCert, plContext));
+ trustedCert = dirCert;
+ } else {
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(expectedCerts,
+ (PKIX_PL_Object *)dirCert,
+ plContext));
+
+ if (k == j) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_IncRef((PKIX_PL_Object *)dirCert, plContext));
+ targetCert = dirCert;
+ }
+ }
+
+ PKIX_TEST_DECREF_BC(dirCert);
+ }
+
+ /* create processing params with list of trust anchors */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_TrustAnchor_CreateWithCert(trustedCert, &anchor, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&anchors, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(anchors, (PKIX_PL_Object *)anchor, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_Create(anchors, &procParams, plContext));
+
+ /* create CertSelector with target certificate in params */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&certSelParams, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetCertificate(certSelParams, targetCert, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, certSelParams, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetTargetCertConstraints(procParams, certSelector, plContext));
+
+ /* create CertStores */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII,
+ dirName,
+ 0,
+ &dirNameString,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CollectionCertStore_Create(dirNameString, &certStore, plContext));
+
+#if 0
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Pk11CertStore_Create
+ (&certStore, plContext));
+#endif
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&certStores, plContext));
+
+ if (useLDAP == PKIX_TRUE) {
+ PKIX_TEST_EXPECT_NO_ERROR(createLdapCertStore(serverName, timeout, &ldapCertStore, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(certStores,
+ (PKIX_PL_Object *)ldapCertStore,
+ plContext));
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(certStores, (PKIX_PL_Object *)certStore, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetCertStores(procParams, certStores, plContext));
+
+ /* set resource limits */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_Create(&resourceLimits, plContext));
+
+ /* need longer time when running dbx for memory leak checking */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_SetMaxTime(resourceLimits, 60, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_SetMaxFanout(resourceLimits, 2, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_SetMaxDepth(resourceLimits, 2, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetResourceLimits(procParams, resourceLimits, plContext));
+
+ /* build cert chain using processing params and return buildResult */
+
+ subTest("Testing ResourceLimits MaxFanout & MaxDepth - ");
+ Test_BuildResult(procParams,
+ testValid,
+ expectedCerts,
+ plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_SetMaxFanout(resourceLimits, 1, plContext));
+
+ subTest("Testing ResourceLimits MaxFanout - ");
+ Test_BuildResult(procParams,
+ PKIX_FALSE,
+ expectedCerts,
+ plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_SetMaxFanout(resourceLimits, 2, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_SetMaxDepth(resourceLimits, 1, plContext));
+
+ subTest("Testing ResourceLimits MaxDepth - ");
+ Test_BuildResult(procParams,
+ PKIX_FALSE,
+ expectedCerts,
+ plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_SetMaxFanout(resourceLimits, 0, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_SetMaxDepth(resourceLimits, 0, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ResourceLimits_SetMaxTime(resourceLimits, 0, plContext));
+
+ subTest("Testing ResourceLimits No checking - ");
+ Test_BuildResult(procParams,
+ testValid,
+ expectedCerts,
+ plContext);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(expectedCerts);
+ PKIX_TEST_DECREF_AC(procParams);
+ PKIX_TEST_DECREF_AC(procParams);
+ PKIX_TEST_DECREF_AC(certStores);
+ PKIX_TEST_DECREF_AC(certStore);
+ PKIX_TEST_DECREF_AC(ldapCertStore);
+ PKIX_TEST_DECREF_AC(dirNameString);
+ PKIX_TEST_DECREF_AC(trustedCert);
+ PKIX_TEST_DECREF_AC(targetCert);
+ PKIX_TEST_DECREF_AC(anchors);
+ PKIX_TEST_DECREF_AC(anchor);
+ PKIX_TEST_DECREF_AC(certSelParams);
+ PKIX_TEST_DECREF_AC(certSelector);
+ PKIX_TEST_DECREF_AC(checker);
+ PKIX_TEST_DECREF_AC(resourceLimits);
+
+ PKIX_TEST_RETURN();
+
+ PKIX_Shutdown(plContext);
+
+ endTests("BuildChain_UserChecker");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/top/test_buildchain_uchecker.c b/nss/cmd/libpkix/pkix/top/test_buildchain_uchecker.c
new file mode 100644
index 0000000..43f06ec
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/top/test_buildchain_uchecker.c
@@ -0,0 +1,327 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_buildchain_uchecker.c
+ *
+ * Test BuildChain User Checker function
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+static PKIX_UInt32 numUserCheckerCalled = 0;
+
+static void
+printUsage(void)
+{
+ (void)printf("\nUSAGE:\ttest_buildchain_uchecker [ENE|EE] "
+ "[-|[F]] "
+ " \n\n");
+ (void)printf("Builds a chain of certificates between "
+ " and \n"
+ "using the certs and CRLs in .\n"
+ "If is not an empty string, its value is used as\n"
+ "user defined checker's critical extension OID.\n"
+ "A - for is no OID and F is for supportingForward.\n"
+ "If ENE is specified, then an Error is Not Expected.\n"
+ "If EE is specified, an Error is Expected.\n");
+}
+
+static PKIX_Error *
+testUserChecker(
+ PKIX_CertChainChecker *checker,
+ PKIX_PL_Cert *cert,
+ PKIX_List *unresExtOIDs,
+ void **pNBIOContext,
+ void *plContext)
+{
+ numUserCheckerCalled++;
+ return (0);
+}
+
+int
+test_buildchain_uchecker(int argc, char *argv[])
+{
+ PKIX_BuildResult *buildResult = NULL;
+ PKIX_ComCertSelParams *certSelParams = NULL;
+ PKIX_CertSelector *certSelector = NULL;
+ PKIX_TrustAnchor *anchor = NULL;
+ PKIX_List *anchors = NULL;
+ PKIX_List *certs = NULL;
+ PKIX_PL_Cert *cert = NULL;
+ PKIX_ProcessingParams *procParams = NULL;
+ PKIX_CertChainChecker *checker = NULL;
+ char *dirName = NULL;
+ PKIX_PL_String *dirNameString = NULL;
+ PKIX_PL_Cert *trustedCert = NULL;
+ PKIX_PL_Cert *targetCert = NULL;
+ PKIX_UInt32 numCerts = 0;
+ PKIX_UInt32 i = 0;
+ PKIX_UInt32 j = 0;
+ PKIX_UInt32 k = 0;
+ PKIX_UInt32 chainLength = 0;
+ PKIX_CertStore *certStore = NULL;
+ PKIX_List *certStores = NULL;
+ char *asciiResult = NULL;
+ PKIX_Boolean result;
+ PKIX_Boolean testValid = PKIX_TRUE;
+ PKIX_Boolean supportForward = PKIX_FALSE;
+ PKIX_List *expectedCerts = NULL;
+ PKIX_List *userOIDs = NULL;
+ PKIX_PL_OID *oid = NULL;
+ PKIX_PL_Cert *dirCert = NULL;
+ PKIX_PL_String *actualCertsString = NULL;
+ PKIX_PL_String *expectedCertsString = NULL;
+ char *actualCertsAscii = NULL;
+ char *expectedCertsAscii = NULL;
+ char *oidString = NULL;
+ void *buildState = NULL; /* needed by pkix_build for non-blocking I/O */
+ void *nbioContext = NULL; /* needed by pkix_build for non-blocking I/O */
+
+ PKIX_TEST_STD_VARS();
+
+ if (argc < 5) {
+ printUsage();
+ return (0);
+ }
+
+ startTests("BuildChain_UserChecker");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ /* ENE = expect no error; EE = expect error */
+ if (PORT_Strcmp(argv[2 + j], "ENE") == 0) {
+ testValid = PKIX_TRUE;
+ } else if (PORT_Strcmp(argv[2 + j], "EE") == 0) {
+ testValid = PKIX_FALSE;
+ } else {
+ printUsage();
+ return (0);
+ }
+
+ /* OID specified at argv[3+j] */
+
+ if (*argv[3 + j] != '-') {
+
+ if (*argv[3 + j] == 'F') {
+ supportForward = PKIX_TRUE;
+ oidString = argv[3 + j] + 1;
+ } else {
+ oidString = argv[3 + j];
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&userOIDs, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create(oidString, &oid, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(userOIDs, (PKIX_PL_Object *)oid, plContext));
+ PKIX_TEST_DECREF_BC(oid);
+ }
+
+ subTest(argv[1 + j]);
+
+ dirName = argv[4 + j];
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&expectedCerts, plContext));
+
+ chainLength = argc - j - 5;
+
+ for (k = 0; k < chainLength; k++) {
+
+ dirCert = createCert(dirName, argv[5 + k + j], plContext);
+
+ if (k == (chainLength - 1)) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_IncRef((PKIX_PL_Object *)dirCert, plContext));
+ trustedCert = dirCert;
+ } else {
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(expectedCerts,
+ (PKIX_PL_Object *)dirCert,
+ plContext));
+
+ if (k == 0) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_IncRef((PKIX_PL_Object *)dirCert,
+ plContext));
+ targetCert = dirCert;
+ }
+ }
+
+ PKIX_TEST_DECREF_BC(dirCert);
+ }
+
+ /* create processing params with list of trust anchors */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_TrustAnchor_CreateWithCert(trustedCert, &anchor, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&anchors, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(anchors, (PKIX_PL_Object *)anchor, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_Create(anchors, &procParams, plContext));
+
+ /* create CertSelector with target certificate in params */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&certSelParams, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetCertificate(certSelParams, targetCert, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, certSelParams, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetTargetCertConstraints(procParams, certSelector, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertChainChecker_Create(testUserChecker,
+ supportForward,
+ PKIX_FALSE,
+ userOIDs,
+ NULL,
+ &checker,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_AddCertChainChecker(procParams, checker, plContext));
+
+ /* create CertStores */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII,
+ dirName,
+ 0,
+ &dirNameString,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CollectionCertStore_Create(dirNameString, &certStore, plContext));
+
+#if 0
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Pk11CertStore_Create
+ (&certStore, plContext));
+#endif
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&certStores, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(certStores, (PKIX_PL_Object *)certStore, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetCertStores(procParams, certStores, plContext));
+
+ /* build cert chain using processing params and return buildResult */
+
+ pkixTestErrorResult = PKIX_BuildChain(procParams,
+ &nbioContext,
+ &buildState,
+ &buildResult,
+ NULL,
+ plContext);
+
+ if (testValid == PKIX_TRUE) { /* ENE */
+ if (pkixTestErrorResult) {
+ (void)printf("UNEXPECTED RESULT RECEIVED!\n");
+ } else {
+ (void)printf("EXPECTED RESULT RECEIVED!\n");
+ PKIX_TEST_DECREF_BC(pkixTestErrorResult);
+ }
+ } else { /* EE */
+ if (pkixTestErrorResult) {
+ (void)printf("EXPECTED RESULT RECEIVED!\n");
+ PKIX_TEST_DECREF_BC(pkixTestErrorResult);
+ } else {
+ testError("UNEXPECTED RESULT RECEIVED");
+ }
+ }
+
+ if (buildResult) {
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_BuildResult_GetCertChain(buildResult, &certs, NULL));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certs, &numCerts, plContext));
+
+ printf("\n");
+
+ for (i = 0; i < numCerts; i++) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certs,
+ i,
+ (PKIX_PL_Object **)&cert,
+ plContext));
+
+ asciiResult = PKIX_Cert2ASCII(cert);
+
+ printf("CERT[%d]:\n%s\n", i, asciiResult);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(asciiResult, plContext));
+ asciiResult = NULL;
+
+ PKIX_TEST_DECREF_BC(cert);
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)certs,
+ (PKIX_PL_Object *)expectedCerts,
+ &result,
+ plContext));
+
+ if (!result) {
+ testError("BUILT CERTCHAIN IS "
+ "NOT THE ONE THAT WAS EXPECTED");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)certs,
+ &actualCertsString,
+ plContext));
+
+ actualCertsAscii = PKIX_String2ASCII(actualCertsString, plContext);
+ if (actualCertsAscii == NULL) {
+ pkixTestErrorMsg = "PKIX_String2ASCII Failed";
+ goto cleanup;
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)expectedCerts,
+ &expectedCertsString,
+ plContext));
+
+ expectedCertsAscii = PKIX_String2ASCII(expectedCertsString, plContext);
+ if (expectedCertsAscii == NULL) {
+ pkixTestErrorMsg = "PKIX_String2ASCII Failed";
+ goto cleanup;
+ }
+
+ (void)printf("Actual value:\t%s\n", actualCertsAscii);
+ (void)printf("Expected value:\t%s\n",
+ expectedCertsAscii);
+
+ if (chainLength - 1 != numUserCheckerCalled) {
+ pkixTestErrorMsg =
+ "PKIX user defined checker not called";
+ }
+
+ goto cleanup;
+ }
+ }
+
+cleanup:
+ PKIX_PL_Free(asciiResult, plContext);
+ PKIX_PL_Free(actualCertsAscii, plContext);
+ PKIX_PL_Free(expectedCertsAscii, plContext);
+
+ PKIX_TEST_DECREF_AC(actualCertsString);
+ PKIX_TEST_DECREF_AC(expectedCertsString);
+ PKIX_TEST_DECREF_AC(expectedCerts);
+ PKIX_TEST_DECREF_AC(certs);
+ PKIX_TEST_DECREF_AC(cert);
+ PKIX_TEST_DECREF_AC(certStore);
+ PKIX_TEST_DECREF_AC(certStores);
+ PKIX_TEST_DECREF_AC(dirNameString);
+ PKIX_TEST_DECREF_AC(trustedCert);
+ PKIX_TEST_DECREF_AC(targetCert);
+ PKIX_TEST_DECREF_AC(anchor);
+ PKIX_TEST_DECREF_AC(anchors);
+ PKIX_TEST_DECREF_AC(procParams);
+ PKIX_TEST_DECREF_AC(certSelParams);
+ PKIX_TEST_DECREF_AC(certSelector);
+ PKIX_TEST_DECREF_AC(buildResult);
+ PKIX_TEST_DECREF_AC(procParams);
+ PKIX_TEST_DECREF_AC(userOIDs);
+ PKIX_TEST_DECREF_AC(checker);
+
+ PKIX_TEST_RETURN();
+
+ PKIX_Shutdown(plContext);
+
+ endTests("BuildChain_UserChecker");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/top/test_customcrlchecker.c b/nss/cmd/libpkix/pkix/top/test_customcrlchecker.c
new file mode 100644
index 0000000..d2c667a
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/top/test_customcrlchecker.c
@@ -0,0 +1,435 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_customcrlchecker.c
+ *
+ * Test Custom CRL Checking
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+#define PKIX_TEST_MAX_CERTS 10
+#define PKIX_TEST_COLLECTIONCERTSTORE_NUM_CRLS 5
+
+static void *plContext = NULL;
+char *dirName = NULL; /* also used in callback */
+
+static void
+printUsage1(char *pName)
+{
+ printf("\nUSAGE: %s test-purpose [ENE|EE] ", pName);
+ printf("cert [certs].\n");
+}
+
+static void
+printUsageMax(PKIX_UInt32 numCerts)
+{
+ printf("\nUSAGE ERROR: number of certs %d exceed maximum %d\n",
+ numCerts, PKIX_TEST_MAX_CERTS);
+}
+
+static PKIX_Error *
+getCRLCallback(
+ PKIX_CertStore *store,
+ PKIX_CRLSelector *crlSelector,
+ void **pNBIOContext,
+ PKIX_List **pCrlList,
+ void *plContext)
+{
+ char *crlFileNames[] = { "chem.crl",
+ "phys.crl",
+ "prof.crl",
+ "sci.crl",
+ "test.crl",
+ 0 };
+ PKIX_PL_CRL *crl = NULL;
+ PKIX_List *crlList = NULL;
+ PKIX_UInt32 i = 0;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&crlList, plContext));
+
+ while (crlFileNames[i]) {
+
+ crl = createCRL(dirName, crlFileNames[i++], plContext);
+
+ if (crl != NULL) {
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(crlList, (PKIX_PL_Object *)crl, plContext));
+
+ PKIX_TEST_DECREF_BC(crl);
+ }
+ }
+
+ *pCrlList = crlList;
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+
+ return (0); /* this function is called by libpkix */
+}
+
+static PKIX_Error *
+getCRLContinue(
+ PKIX_CertStore *store,
+ PKIX_CRLSelector *crlSelector,
+ void **pNBIOContext,
+ PKIX_List **pCrlList,
+ void *plContext)
+{
+ return (NULL);
+}
+
+static PKIX_Error *
+getCertCallback(
+ PKIX_CertStore *store,
+ PKIX_CertSelector *certSelector,
+ void **pNBIOContext,
+ PKIX_List **pCerts,
+ void *plContext)
+{
+ return (NULL);
+}
+
+static PKIX_Error *
+getCertContinue(
+ PKIX_CertStore *store,
+ PKIX_CertSelector *certSelector,
+ void **pNBIOContext,
+ PKIX_List **pCerts,
+ void *plContext)
+{
+ return (NULL);
+}
+
+static PKIX_Error *
+testCRLSelectorMatchCallback(
+ PKIX_CRLSelector *selector,
+ PKIX_PL_CRL *crl,
+ void *plContext)
+{
+ PKIX_ComCRLSelParams *comCrlSelParams = NULL;
+ PKIX_List *issuerList = NULL;
+ PKIX_PL_X500Name *issuer = NULL;
+ PKIX_PL_X500Name *crlIssuer = NULL;
+ PKIX_UInt32 numIssuers = 0;
+ PKIX_UInt32 i = 0;
+ PKIX_Boolean result = PKIX_FALSE;
+ PKIX_Error *error = NULL;
+ char *errorText = "Not an error, CRL Select mismatch";
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("Custom_Selector_MatchCallback");
+
+ if (selector != NULL) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CRLSelector_GetCommonCRLSelectorParams(selector, &comCrlSelParams, plContext));
+ }
+
+ if (crl != NULL) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CRL_GetIssuer(crl, &crlIssuer, plContext));
+ }
+
+ if (comCrlSelParams != NULL) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_GetIssuerNames(comCrlSelParams, &issuerList, plContext));
+ }
+
+ if (issuerList != NULL) {
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(issuerList, &numIssuers, plContext));
+
+ for (i = 0; i < numIssuers; i++) {
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(issuerList,
+ i, (PKIX_PL_Object **)&issuer,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)crlIssuer,
+ (PKIX_PL_Object *)issuer,
+ &result,
+ plContext));
+
+ if (result != PKIX_TRUE) {
+ break;
+ }
+
+ if (i == numIssuers - 1) {
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Error_Create(0,
+ NULL,
+ NULL,
+ PKIX_TESTNOTANERRORCRLSELECTMISMATCH,
+ &error,
+ plContext));
+
+ PKIX_TEST_DECREF_AC(issuer);
+ issuer = NULL;
+ break;
+ }
+
+ PKIX_TEST_DECREF_AC(issuer);
+ }
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(comCrlSelParams);
+ PKIX_TEST_DECREF_AC(crlIssuer);
+ PKIX_TEST_DECREF_AC(issuer);
+ PKIX_TEST_DECREF_AC(issuerList);
+
+ PKIX_TEST_RETURN();
+
+ return (error);
+}
+
+static PKIX_Error *
+testAddIssuerName(PKIX_ComCRLSelParams *comCrlSelParams, char *issuerName)
+{
+ PKIX_PL_String *issuerString = NULL;
+ PKIX_PL_X500Name *issuer = NULL;
+ PKIX_UInt32 length = 0;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_ComCRLSelParams_AddIssuerName");
+
+ length = PL_strlen(issuerName);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_UTF8,
+ issuerName,
+ length,
+ &issuerString,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_X500Name_Create(issuerString,
+ &issuer,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_AddIssuerName(comCrlSelParams, issuer, plContext));
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(issuerString);
+ PKIX_TEST_DECREF_AC(issuer);
+
+ PKIX_TEST_RETURN();
+
+ return (0);
+}
+
+static PKIX_Error *
+testCustomCertStore(PKIX_ValidateParams *valParams)
+{
+ PKIX_CertStore_CRLCallback crlCallback;
+ PKIX_CertStore *certStore = NULL;
+ PKIX_ProcessingParams *procParams = NULL;
+ char *issuerName1 = "cn=science,o=mit,c=us";
+ char *issuerName2 = "cn=physics,o=mit,c=us";
+ char *issuerName3 = "cn=prof noall,o=mit,c=us";
+ char *issuerName4 = "cn=testing CRL,o=test,c=us";
+ PKIX_ComCRLSelParams *comCrlSelParams = NULL;
+ PKIX_CRLSelector *crlSelector = NULL;
+ PKIX_List *crlList = NULL;
+ PKIX_UInt32 numCrl = 0;
+ void *nbioContext = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_PL_CollectionCertStore_Create");
+
+ /* Create CRLSelector, link in CollectionCertStore */
+
+ subTest("PKIX_ComCRLSelParams_AddIssuerNames");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_Create(&comCrlSelParams, plContext));
+
+ testAddIssuerName(comCrlSelParams, issuerName1);
+ testAddIssuerName(comCrlSelParams, issuerName2);
+ testAddIssuerName(comCrlSelParams, issuerName3);
+ testAddIssuerName(comCrlSelParams, issuerName4);
+
+ subTest("PKIX_CRLSelector_SetCommonCRLSelectorParams");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CRLSelector_Create(testCRLSelectorMatchCallback,
+ NULL,
+ &crlSelector,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CRLSelector_SetCommonCRLSelectorParams(crlSelector, comCrlSelParams, plContext));
+
+ /* Create CertStore, link in CRLSelector */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateParams_GetProcessingParams(valParams, &procParams, plContext));
+
+ subTest("PKIX_CertStore_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertStore_Create(getCertCallback,
+ getCRLCallback,
+ getCertContinue,
+ getCRLContinue,
+ NULL, /* trustCallback */
+ (PKIX_PL_Object *)crlSelector, /* fake */
+ PKIX_FALSE, /* cacheFlag */
+ PKIX_TRUE, /* localFlag */
+ &certStore,
+ plContext));
+
+ subTest("PKIX_ProcessingParams_AddCertStore");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_AddCertStore(procParams, certStore, plContext));
+
+ subTest("PKIX_ProcessingParams_SetRevocationEnabled");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetRevocationEnabled(procParams, PKIX_TRUE, plContext));
+
+ subTest("PKIX_CertStore_GetCRLCallback");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertStore_GetCRLCallback(certStore,
+ &crlCallback,
+ NULL));
+
+ subTest("Getting CRL by CRL Callback");
+ PKIX_TEST_EXPECT_NO_ERROR(crlCallback(certStore,
+ crlSelector,
+ &nbioContext,
+ &crlList,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(crlList,
+ &numCrl,
+ plContext));
+
+ if (numCrl != PKIX_TEST_COLLECTIONCERTSTORE_NUM_CRLS) {
+ pkixTestErrorMsg = "unexpected CRL number mismatch";
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(crlList);
+ PKIX_TEST_DECREF_AC(comCrlSelParams);
+ PKIX_TEST_DECREF_AC(crlSelector);
+ PKIX_TEST_DECREF_AC(procParams);
+ PKIX_TEST_DECREF_AC(certStore);
+
+ PKIX_TEST_RETURN();
+
+ return (0);
+}
+
+/*
+ * Validate Certificate Chain with Certificate Revocation List
+ * Certificate Chain is built based on input certs' sequence.
+ * CRL is fetched from the directory specified in CollectionCertStore.
+ * while CollectionCertStore is linked in CertStore Object which then
+ * linked in ProcessParam. During validation, CRLChecker will invoke
+ * the crlCallback (this test uses PKIX_PL_CollectionCertStore_GetCRL)
+ * to get CRL data for revocation check.
+ * This test set criteria in CRLSelector which is linked in
+ * CommonCRLSelectorParam. When CRL data is fetched into cache for
+ * revocation check, CRL's are filtered based on the criteria set.
+ */
+
+int
+test_customcrlchecker(int argc, char *argv[])
+{
+
+ PKIX_List *chain = NULL;
+ PKIX_ValidateParams *valParams = NULL;
+ PKIX_ValidateResult *valResult = NULL;
+ PKIX_UInt32 actualMinorVersion;
+ char *certNames[PKIX_TEST_MAX_CERTS];
+ PKIX_PL_Cert *certs[PKIX_TEST_MAX_CERTS];
+ PKIX_VerifyNode *verifyTree = NULL;
+ PKIX_PL_String *verifyString = NULL;
+ PKIX_UInt32 chainLength = 0;
+ PKIX_UInt32 i = 0;
+ PKIX_UInt32 j = 0;
+ PKIX_Boolean testValid = PKIX_TRUE;
+ char *anchorName = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ if (argc < 5) {
+ printUsage1(argv[0]);
+ return (0);
+ }
+
+ startTests("CRL Checker");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ /* ENE = expect no error; EE = expect error */
+ if (PORT_Strcmp(argv[2 + j], "ENE") == 0) {
+ testValid = PKIX_TRUE;
+ } else if (PORT_Strcmp(argv[2 + j], "EE") == 0) {
+ testValid = PKIX_FALSE;
+ } else {
+ printUsage1(argv[0]);
+ return (0);
+ }
+
+ chainLength = (argc - j) - 5;
+ if (chainLength > PKIX_TEST_MAX_CERTS) {
+ printUsageMax(chainLength);
+ }
+
+ for (i = 0; i < chainLength; i++) {
+
+ certNames[i] = argv[(5 + j) + i];
+ certs[i] = NULL;
+ }
+
+ dirName = argv[3 + j];
+
+ subTest(argv[1 + j]);
+
+ subTest("Custom-CRL-Checker - Create Cert Chain");
+
+ chain = createCertChainPlus(dirName, certNames, certs, chainLength, plContext);
+
+ subTest("Custom-CRL-Checker - Create Params");
+
+ anchorName = argv[4 + j];
+
+ valParams = createValidateParams(dirName,
+ anchorName,
+ NULL,
+ NULL,
+ NULL,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ chain,
+ plContext);
+
+ subTest("Custom-CRL-Checker - Set Processing Params for CertStore");
+
+ testCustomCertStore(valParams);
+
+ subTest("Custom-CRL-Checker - Validate Chain");
+
+ if (testValid == PKIX_TRUE) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateChain(valParams, &valResult, &verifyTree, plContext));
+ } else {
+ PKIX_TEST_EXPECT_ERROR(PKIX_ValidateChain(valParams, &valResult, &verifyTree, plContext));
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(verifyString);
+ PKIX_TEST_DECREF_AC(verifyTree);
+ PKIX_TEST_DECREF_AC(chain);
+ PKIX_TEST_DECREF_AC(valParams);
+ PKIX_TEST_DECREF_AC(valResult);
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("CRL Checker");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/top/test_defaultcrlchecker2stores.c b/nss/cmd/libpkix/pkix/top/test_defaultcrlchecker2stores.c
new file mode 100644
index 0000000..3ce4513
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/top/test_defaultcrlchecker2stores.c
@@ -0,0 +1,230 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_defaultcrlchecker2stores.c
+ *
+ * Test Default CRL with multiple CertStore Checking
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+#define PKIX_TEST_MAX_CERTS 10
+
+static void *plContext = NULL;
+
+static void
+printUsage1(char *pName)
+{
+ printf("\nUSAGE: %s test-purpose [ENE|EE] ", pName);
+ printf("crl-directory cert [certs].\n");
+}
+
+static void
+printUsageMax(PKIX_UInt32 numCerts)
+{
+ printf("\nUSAGE ERROR: number of certs %d exceed maximum %d\n",
+ numCerts, PKIX_TEST_MAX_CERTS);
+}
+
+static PKIX_Error *
+getCertCallback(
+ PKIX_CertStore *store,
+ PKIX_CertSelector *certSelector,
+ PKIX_List **pCerts,
+ void *plContext)
+{
+ return (NULL);
+}
+
+static PKIX_Error *
+testDefaultMultipleCertStores(PKIX_ValidateParams *valParams,
+ char *crlDir1,
+ char *crlDir2)
+{
+ PKIX_PL_String *dirString1 = NULL;
+ PKIX_PL_String *dirString2 = NULL;
+ PKIX_CertStore *certStore1 = NULL;
+ PKIX_CertStore *certStore2 = NULL;
+ PKIX_List *certStoreList = NULL;
+ PKIX_ProcessingParams *procParams = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_PL_CollectionCertStore_Create");
+
+ /* Create CollectionCertStore */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII,
+ crlDir1,
+ 0,
+ &dirString1,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CollectionCertStore_Create(dirString1,
+ &certStore1,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII,
+ crlDir2,
+ 0,
+ &dirString2,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CollectionCertStore_Create(dirString2,
+ &certStore2,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateParams_GetProcessingParams(valParams, &procParams, plContext));
+
+ /* Add multiple CollectionCertStores */
+
+ subTest("PKIX_ProcessingParams_SetCertStores");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&certStoreList, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(certStoreList, (PKIX_PL_Object *)certStore1, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetCertStores(procParams, certStoreList, plContext));
+
+ subTest("PKIX_ProcessingParams_AddCertStore");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_AddCertStore(procParams, certStore2, plContext));
+
+ subTest("PKIX_ProcessingParams_SetRevocationEnabled");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetRevocationEnabled(procParams, PKIX_TRUE, plContext));
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(dirString1);
+ PKIX_TEST_DECREF_AC(dirString2);
+ PKIX_TEST_DECREF_AC(certStore1);
+ PKIX_TEST_DECREF_AC(certStore2);
+ PKIX_TEST_DECREF_AC(certStoreList);
+ PKIX_TEST_DECREF_AC(procParams);
+
+ PKIX_TEST_RETURN();
+
+ return (0);
+}
+
+/*
+ * Validate Certificate Chain with Certificate Revocation List
+ * Certificate Chain is build based on input certs' sequence.
+ * CRL is fetched from the directory specified in CollectionCertStore.
+ * while CollectionCertStore is linked in CertStore Object which then
+ * linked in ProcessParam. During validation, CRLChecker will invoke
+ * the crlCallback (this test uses PKIX_PL_CollectionCertStore_GetCRL)
+ * to get CRL data for revocation check.
+ * This test gets CRL's from two CertStores, each has a valid CRL
+ * required for revocation check to pass.
+ */
+
+int
+test_defaultcrlchecker2stores(int argc, char *argv[])
+{
+
+ PKIX_List *chain = NULL;
+ PKIX_ValidateParams *valParams = NULL;
+ PKIX_ValidateResult *valResult = NULL;
+ PKIX_UInt32 actualMinorVersion;
+ char *certNames[PKIX_TEST_MAX_CERTS];
+ PKIX_PL_Cert *certs[PKIX_TEST_MAX_CERTS];
+ PKIX_VerifyNode *verifyTree = NULL;
+ PKIX_PL_String *verifyString = NULL;
+ PKIX_UInt32 chainLength = 0;
+ PKIX_UInt32 i = 0;
+ PKIX_UInt32 j = 0;
+ PKIX_Boolean testValid = PKIX_TRUE;
+ char *dirName = NULL;
+ char *anchorName = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ if (argc < 6) {
+ printUsage1(argv[0]);
+ return (0);
+ }
+
+ startTests("CRL Checker");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ /* ENE = expect no error; EE = expect error */
+ if (PORT_Strcmp(argv[2 + j], "ENE") == 0) {
+ testValid = PKIX_TRUE;
+ } else if (PORT_Strcmp(argv[2 + j], "EE") == 0) {
+ testValid = PKIX_FALSE;
+ } else {
+ printUsage1(argv[0]);
+ return (0);
+ }
+
+ chainLength = (argc - j) - 7;
+ if (chainLength > PKIX_TEST_MAX_CERTS) {
+ printUsageMax(chainLength);
+ }
+
+ for (i = 0; i < chainLength; i++) {
+
+ certNames[i] = argv[(7 + j) + i];
+ certs[i] = NULL;
+ }
+
+ subTest(argv[1 + j]);
+
+ subTest("Default-CRL-Checker");
+
+ subTest("Default-CRL-Checker - Create Cert Chain");
+
+ dirName = argv[3 + j];
+
+ chain = createCertChainPlus(dirName, certNames, certs, chainLength, plContext);
+
+ subTest("Default-CRL-Checker - Create Params");
+
+ anchorName = argv[6 + j];
+
+ valParams = createValidateParams(dirName,
+ anchorName,
+ NULL,
+ NULL,
+ NULL,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ chain,
+ plContext);
+
+ subTest("Multiple-CertStores");
+
+ testDefaultMultipleCertStores(valParams, argv[4 + j], argv[5 + j]);
+
+ subTest("Default-CRL-Checker - Validate Chain");
+
+ if (testValid == PKIX_TRUE) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateChain(valParams, &valResult, &verifyTree, plContext));
+ } else {
+ PKIX_TEST_EXPECT_ERROR(PKIX_ValidateChain(valParams, &valResult, &verifyTree, plContext));
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)verifyTree, &verifyString, plContext));
+ (void)printf("verifyTree is\n%s\n", verifyString->escAsciiString);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(verifyString);
+ PKIX_TEST_DECREF_AC(verifyTree);
+
+ PKIX_TEST_DECREF_AC(valParams);
+ PKIX_TEST_DECREF_AC(valResult);
+ PKIX_TEST_DECREF_AC(chain);
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("CRL Checker");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/top/test_ocsp.c b/nss/cmd/libpkix/pkix/top/test_ocsp.c
new file mode 100644
index 0000000..e97e570
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/top/test_ocsp.c
@@ -0,0 +1,288 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_ocspchecker.c
+ *
+ * Test OcspChecker function
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+static void
+printUsage(void)
+{
+ (void)printf("\nUSAGE:\nOcspChecker -d TestName "
+ "[ENE|EE] "
+ "\n\n");
+ (void)printf("Validates a chain of certificates between "
+ " and \n"
+ "using the certs and CRLs in and "
+ "pkcs11 db from . "
+ "If ENE is specified,\n"
+ "then an Error is Not Expected. "
+ "If EE is specified, an Error is Expected.\n");
+}
+
+static char *
+createFullPathName(
+ char *dirName,
+ char *certFile,
+ void *plContext)
+{
+ PKIX_UInt32 certFileLen;
+ PKIX_UInt32 dirNameLen;
+ char *certPathName = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ certFileLen = PL_strlen(certFile);
+ dirNameLen = PL_strlen(dirName);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Malloc(dirNameLen +
+ certFileLen +
+ 2,
+ (void **)&certPathName,
+ plContext));
+
+ PL_strcpy(certPathName, dirName);
+ PL_strcat(certPathName, "/");
+ PL_strcat(certPathName, certFile);
+ printf("certPathName = %s\n", certPathName);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+
+ return (certPathName);
+}
+
+static PKIX_Error *
+testDefaultCertStore(PKIX_ValidateParams *valParams, char *crlDir)
+{
+ PKIX_PL_String *dirString = NULL;
+ PKIX_CertStore *certStore = NULL;
+ PKIX_ProcessingParams *procParams = NULL;
+ PKIX_PL_Date *validity = NULL;
+ PKIX_List *revCheckers = NULL;
+ PKIX_RevocationChecker *revChecker = NULL;
+ PKIX_PL_Object *revCheckerContext = NULL;
+ PKIX_OcspChecker *ocspChecker = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_PL_CollectionCertStoreContext_Create");
+
+ /* Create CollectionCertStore */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII, crlDir, 0, &dirString, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CollectionCertStore_Create(dirString, &certStore, plContext));
+
+ /* Create CertStore */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateParams_GetProcessingParams(valParams, &procParams, plContext));
+
+ subTest("PKIX_ProcessingParams_AddCertStore");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_AddCertStore(procParams, certStore, plContext));
+
+ subTest("PKIX_ProcessingParams_SetRevocationEnabled");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetRevocationEnabled(procParams, PKIX_FALSE, plContext));
+
+ /* create current Date */
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_pl_Date_CreateFromPRTime(PR_Now(), &validity, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&revCheckers, plContext));
+
+ /* create revChecker */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_OcspChecker_Initialize(validity,
+ NULL, /* pwArg */
+ NULL, /* Use default responder */
+ &revChecker,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_RevocationChecker_GetRevCheckerContext(revChecker, &revCheckerContext, plContext));
+
+ /* Check that this object is a ocsp checker */
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_CheckType(revCheckerContext, PKIX_OCSPCHECKER_TYPE, plContext));
+
+ ocspChecker = (PKIX_OcspChecker *)revCheckerContext;
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_OcspChecker_SetVerifyFcn(ocspChecker,
+ PKIX_PL_OcspResponse_UseBuildChain,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(revCheckers, (PKIX_PL_Object *)revChecker, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetRevocationCheckers(procParams, revCheckers, plContext));
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(dirString);
+ PKIX_TEST_DECREF_AC(procParams);
+ PKIX_TEST_DECREF_AC(certStore);
+ PKIX_TEST_DECREF_AC(revCheckers);
+ PKIX_TEST_DECREF_AC(revChecker);
+ PKIX_TEST_DECREF_AC(ocspChecker);
+ PKIX_TEST_DECREF_AC(validity);
+
+ PKIX_TEST_RETURN();
+
+ return (0);
+}
+
+int
+test_ocsp(int argc, char *argv[])
+{
+
+ PKIX_ValidateParams *valParams = NULL;
+ PKIX_ProcessingParams *procParams = NULL;
+ PKIX_ComCertSelParams *certSelParams = NULL;
+ PKIX_CertSelector *certSelector = NULL;
+ PKIX_ValidateResult *valResult = NULL;
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_UInt32 j = 0;
+ PKIX_UInt32 k = 0;
+ PKIX_UInt32 chainLength = 0;
+ PKIX_Boolean testValid = PKIX_TRUE;
+ PKIX_List *chainCerts = NULL;
+ PKIX_VerifyNode *verifyTree = NULL;
+ PKIX_PL_String *verifyString = NULL;
+ PKIX_PL_Cert *dirCert = NULL;
+ PKIX_PL_Cert *trustedCert = NULL;
+ PKIX_PL_Cert *targetCert = NULL;
+ PKIX_TrustAnchor *anchor = NULL;
+ PKIX_List *anchors = NULL;
+ char *dirCertName = NULL;
+ char *anchorCertName = NULL;
+ char *dirName = NULL;
+ char *databaseDir = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ if (argc < 5) {
+ printUsage();
+ return (0);
+ }
+
+ startTests("OcspChecker");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ /* ENE = expect no error; EE = expect error */
+ if (PORT_Strcmp(argv[2 + j], "ENE") == 0) {
+ testValid = PKIX_TRUE;
+ } else if (PORT_Strcmp(argv[2 + j], "EE") == 0) {
+ testValid = PKIX_FALSE;
+ } else {
+ printUsage();
+ return (0);
+ }
+
+ subTest(argv[1 + j]);
+
+ dirName = argv[3 + j];
+
+ chainLength = argc - j - 5;
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&chainCerts, plContext));
+
+ for (k = 0; k < chainLength; k++) {
+
+ dirCert = createCert(dirName, argv[5 + k + j], plContext);
+
+ if (k == 0) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_IncRef((PKIX_PL_Object *)dirCert, plContext));
+ targetCert = dirCert;
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(chainCerts, (PKIX_PL_Object *)dirCert, plContext));
+
+ PKIX_TEST_DECREF_BC(dirCert);
+ }
+
+ /* create processing params with list of trust anchors */
+
+ anchorCertName = argv[4 + j];
+ trustedCert = createCert(dirName, anchorCertName, plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_TrustAnchor_CreateWithCert(trustedCert, &anchor, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&anchors, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(anchors, (PKIX_PL_Object *)anchor, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_Create(anchors, &procParams, plContext));
+
+ /* create CertSelector with target certificate in params */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&certSelParams, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetCertificate(certSelParams, targetCert, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, certSelParams, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetTargetCertConstraints(procParams, certSelector, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateParams_Create(procParams, chainCerts, &valParams, plContext));
+
+ testDefaultCertStore(valParams, dirName);
+
+ pkixTestErrorResult = PKIX_ValidateChain(valParams, &valResult, &verifyTree, plContext);
+
+ if (pkixTestErrorResult) {
+ if (testValid == PKIX_FALSE) { /* EE */
+ (void)printf("EXPECTED ERROR RECEIVED!\n");
+ } else { /* ENE */
+ testError("UNEXPECTED ERROR RECEIVED");
+ }
+ PKIX_TEST_DECREF_BC(pkixTestErrorResult);
+ } else {
+ if (testValid == PKIX_TRUE) { /* ENE */
+ (void)printf("EXPECTED SUCCESSFUL VALIDATION!\n");
+ } else { /* EE */
+ (void)printf("UNEXPECTED SUCCESSFUL VALIDATION!\n");
+ }
+ }
+
+ subTest("Displaying VerifyTree");
+
+ if (verifyTree == NULL) {
+ (void)printf("VerifyTree is NULL\n");
+ } else {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)verifyTree, &verifyString, plContext));
+ (void)printf("verifyTree is\n%s\n",
+ verifyString->escAsciiString);
+ PKIX_TEST_DECREF_BC(verifyString);
+ PKIX_TEST_DECREF_BC(verifyTree);
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(valParams);
+ PKIX_TEST_DECREF_AC(procParams);
+ PKIX_TEST_DECREF_AC(certSelParams);
+ PKIX_TEST_DECREF_AC(certSelector);
+ PKIX_TEST_DECREF_AC(chainCerts);
+ PKIX_TEST_DECREF_AC(anchors);
+ PKIX_TEST_DECREF_AC(anchor);
+ PKIX_TEST_DECREF_AC(trustedCert);
+ PKIX_TEST_DECREF_AC(targetCert);
+ PKIX_TEST_DECREF_AC(valResult);
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("OcspChecker");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/top/test_policychecker.c b/nss/cmd/libpkix/pkix/top/test_policychecker.c
new file mode 100644
index 0000000..1318f13
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/top/test_policychecker.c
@@ -0,0 +1,535 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_policychecker.c
+ *
+ * Test Policy Checking
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+#define PKIX_TEST_MAX_CERTS 10
+
+static void *plContext = NULL;
+
+static void
+printUsage(char *testname)
+{
+ char *fmt =
+ "USAGE: %s testname"
+ " [ENE|EE] \"{OID[:OID]*}\" [A|E|P] cert [cert]*\n"
+ "(The quotes are needed around the OID argument for dbx.)\n"
+ "(The optional arg A indicates initialAnyPolicyInhibit.)\n"
+ "(The optional arg E indicates initialExplicitPolicy.)\n"
+ "(The optional arg P indicates initialPolicyMappingInhibit.)\n";
+ printf(fmt, testname);
+}
+
+static void
+printUsageMax(PKIX_UInt32 numCerts)
+{
+ printf("\nUSAGE ERROR: number of certs %d exceed maximum %d\n",
+ numCerts, PKIX_TEST_MAX_CERTS);
+}
+
+static PKIX_List *
+policySetParse(char *policyString)
+{
+ char *p = NULL;
+ char *oid = NULL;
+ char c = '\0';
+ PKIX_Boolean validString = PKIX_FALSE;
+ PKIX_PL_OID *plOID = NULL;
+ PKIX_List *policySet = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ p = policyString;
+
+ /*
+ * There may or may not be quotes around the initial-policy-set
+ * string. If they are omitted, dbx will strip off the curly braces.
+ * If they are included, dbx will strip off the quotes, but if you
+ * are running directly from a script, without dbx, the quotes will
+ * not be stripped. We need to be able to handle both cases.
+ */
+ if (*p == '"') {
+ p++;
+ }
+
+ if ('{' != *p++) {
+ return (NULL);
+ }
+ oid = p;
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&policySet, plContext));
+
+ /* scan to the end of policyString */
+ while (!validString) {
+ /* scan to the end of the current OID string */
+ c = *oid;
+ while ((c != '\0') && (c != ':') && (c != '}')) {
+ c = *++oid;
+ }
+
+ if ((c != ':') || (c != '}')) {
+ *oid = '\0'; /* store a null terminator */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create(p, &plOID, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(policySet,
+ (PKIX_PL_Object *)plOID,
+ plContext));
+
+ PKIX_TEST_DECREF_BC(plOID);
+ plOID = NULL;
+ if (c == '}') {
+ /*
+ * Any exit but this one means
+ * we were given a badly-formed string.
+ */
+ validString = PKIX_TRUE;
+ }
+ p = ++oid;
+ }
+ }
+
+cleanup:
+ if (!validString) {
+ PKIX_TEST_DECREF_AC(plOID);
+ PKIX_TEST_DECREF_AC(policySet);
+ policySet = NULL;
+ }
+
+ PKIX_TEST_RETURN();
+
+ return (policySet);
+}
+
+/*
+ * FUNCTION: treeToStringHelper
+ * This function obtains the string representation of a PolicyNode
+ * Tree and compares it to the expected value.
+ * PARAMETERS:
+ * "parent" - a PolicyNode, the root of a PolicyNodeTree;
+ * must be non-NULL.
+ * "expected" - the desired string.
+ * THREAD SAFETY:
+ * Thread Safe
+ *
+ * Multiple threads can safely call this function without worrying
+ * about conflicts, even if they're operating on the same object.
+ * RETURNS:
+ * Nothing.
+ */
+static void
+treeToStringHelper(PKIX_PolicyNode *parent, char *expected)
+{
+ PKIX_PL_String *stringRep = NULL;
+ char *actual = NULL;
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)parent, &stringRep, plContext));
+
+ actual = PKIX_String2ASCII(stringRep, plContext);
+ if (actual == NULL) {
+ pkixTestErrorMsg = "PKIX_String2ASCII Failed";
+ goto cleanup;
+ }
+
+ if (PL_strcmp(actual, expected) != 0) {
+ testError("unexpected mismatch");
+ (void)printf("Actual value:\t%s\n", actual);
+ (void)printf("Expected value:\t%s\n", expected);
+ }
+
+cleanup:
+
+ PKIX_PL_Free(actual, plContext);
+
+ PKIX_TEST_DECREF_AC(stringRep);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testPass(char *dirName, char *goodInput, char *diffInput, char *dateAscii)
+{
+
+ PKIX_List *chain = NULL;
+ PKIX_ValidateParams *valParams = NULL;
+ PKIX_ValidateResult *valResult = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("Basic-Common-Fields ");
+ /*
+ * Tests the Expiration, NameChaining, and Signature Checkers
+ */
+
+ chain = createCertChain(dirName, goodInput, diffInput, plContext);
+
+ valParams = createValidateParams(dirName,
+ goodInput,
+ diffInput,
+ dateAscii,
+ NULL,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ chain,
+ plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateChain(valParams, &valResult, NULL, plContext));
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(chain);
+ PKIX_TEST_DECREF_AC(valParams);
+ PKIX_TEST_DECREF_AC(valResult);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testNistTest1(char *dirName)
+{
+#define PKIX_TEST_NUM_CERTS 2
+ char *trustAnchor =
+ "TrustAnchorRootCertificate.crt";
+ char *intermediateCert =
+ "GoodCACert.crt";
+ char *endEntityCert =
+ "ValidCertificatePathTest1EE.crt";
+ char *certNames[PKIX_TEST_NUM_CERTS];
+ char *asciiAnyPolicy = "2.5.29.32.0";
+ PKIX_PL_Cert *certs[PKIX_TEST_NUM_CERTS] = { NULL, NULL };
+
+ PKIX_ValidateParams *valParams = NULL;
+ PKIX_ValidateResult *valResult = NULL;
+ PKIX_List *chain = NULL;
+ PKIX_PL_OID *anyPolicyOID = NULL;
+ PKIX_List *initialPolicies = NULL;
+ char *anchorName = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("testNistTest1: Creating the cert chain");
+ /*
+ * Create a chain, but don't include the first certName.
+ * That's the anchor, and is supplied separately from
+ * the chain.
+ */
+ certNames[0] = intermediateCert;
+ certNames[1] = endEntityCert;
+ chain = createCertChainPlus(dirName, certNames, certs, PKIX_TEST_NUM_CERTS, plContext);
+
+ subTest("testNistTest1: Creating the Validate Parameters");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create(asciiAnyPolicy, &anyPolicyOID, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&initialPolicies, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(initialPolicies, (PKIX_PL_Object *)anyPolicyOID, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetImmutable(initialPolicies, plContext));
+
+ valParams = createValidateParams(dirName,
+ trustAnchor,
+ NULL,
+ NULL,
+ initialPolicies,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ chain,
+ plContext);
+
+ subTest("testNistTest1: Validating the chain");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateChain(valParams, &valResult, NULL, plContext));
+
+cleanup:
+
+ PKIX_PL_Free(anchorName, plContext);
+
+ PKIX_TEST_DECREF_AC(anyPolicyOID);
+ PKIX_TEST_DECREF_AC(initialPolicies);
+ PKIX_TEST_DECREF_AC(valParams);
+ PKIX_TEST_DECREF_AC(valResult);
+ PKIX_TEST_DECREF_AC(chain);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testNistTest2(char *dirName)
+{
+#define PKIX_TEST_NUM_CERTS 2
+ char *trustAnchor =
+ "TrustAnchorRootCertificate.crt";
+ char *intermediateCert =
+ "GoodCACert.crt";
+ char *endEntityCert =
+ "ValidCertificatePathTest1EE.crt";
+ char *certNames[PKIX_TEST_NUM_CERTS];
+ char *asciiNist1Policy = "2.16.840.1.101.3.2.1.48.1";
+ PKIX_PL_Cert *certs[PKIX_TEST_NUM_CERTS] = { NULL, NULL };
+
+ PKIX_ValidateParams *valParams = NULL;
+ PKIX_ValidateResult *valResult = NULL;
+ PKIX_List *chain = NULL;
+ PKIX_PL_OID *Nist1PolicyOID = NULL;
+ PKIX_List *initialPolicies = NULL;
+ char *anchorName = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("testNistTest2: Creating the cert chain");
+ /*
+ * Create a chain, but don't include the first certName.
+ * That's the anchor, and is supplied separately from
+ * the chain.
+ */
+ certNames[0] = intermediateCert;
+ certNames[1] = endEntityCert;
+ chain = createCertChainPlus(dirName, certNames, certs, PKIX_TEST_NUM_CERTS, plContext);
+
+ subTest("testNistTest2: Creating the Validate Parameters");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create(asciiNist1Policy, &Nist1PolicyOID, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&initialPolicies, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(initialPolicies, (PKIX_PL_Object *)Nist1PolicyOID, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetImmutable(initialPolicies, plContext));
+
+ valParams = createValidateParams(dirName,
+ trustAnchor,
+ NULL,
+ NULL,
+ initialPolicies,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ chain,
+ plContext);
+
+ subTest("testNistTest2: Validating the chain");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateChain(valParams, &valResult, NULL, plContext));
+
+cleanup:
+
+ PKIX_PL_Free(anchorName, plContext);
+
+ PKIX_TEST_DECREF_AC(Nist1PolicyOID);
+ PKIX_TEST_DECREF_AC(initialPolicies);
+ PKIX_TEST_DECREF_AC(valParams);
+ PKIX_TEST_DECREF_AC(valResult);
+ PKIX_TEST_DECREF_AC(chain);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+printValidPolicyTree(PKIX_ValidateResult *valResult)
+{
+ PKIX_PolicyNode *validPolicyTree = NULL;
+ PKIX_PL_String *treeString = NULL;
+
+ PKIX_TEST_STD_VARS();
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateResult_GetPolicyTree(valResult, &validPolicyTree, plContext));
+ if (validPolicyTree) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)validPolicyTree,
+ &treeString,
+ plContext));
+ (void)printf("validPolicyTree is\n\t%s\n",
+ treeString->escAsciiString);
+ } else {
+ (void)printf("validPolicyTree is NULL\n");
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(validPolicyTree);
+ PKIX_TEST_DECREF_AC(treeString);
+
+ PKIX_TEST_RETURN();
+}
+
+int
+test_policychecker(int argc, char *argv[])
+{
+
+ PKIX_Boolean initialPolicyMappingInhibit = PKIX_FALSE;
+ PKIX_Boolean initialAnyPolicyInhibit = PKIX_FALSE;
+ PKIX_Boolean initialExplicitPolicy = PKIX_FALSE;
+ PKIX_Boolean expectedResult = PKIX_FALSE;
+ PKIX_UInt32 chainLength = 0;
+ PKIX_UInt32 initArgs = 0;
+ PKIX_UInt32 firstCert = 0;
+ PKIX_UInt32 i = 0;
+ PKIX_Int32 j = 0;
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_ProcessingParams *procParams = NULL;
+ char *firstTrustAnchor = "yassir2yassir";
+ char *secondTrustAnchor = "yassir2bcn";
+ char *dateAscii = "991201000000Z";
+ PKIX_ValidateParams *valParams = NULL;
+ PKIX_ValidateResult *valResult = NULL;
+ PKIX_List *userInitialPolicySet = NULL; /* List of PKIX_PL_OID */
+ char *certNames[PKIX_TEST_MAX_CERTS];
+ PKIX_PL_Cert *certs[PKIX_TEST_MAX_CERTS];
+ PKIX_List *chain = NULL;
+ PKIX_Error *validationError = NULL;
+ PKIX_VerifyNode *verifyTree = NULL;
+ PKIX_PL_String *verifyString = NULL;
+ char *dirName = NULL;
+ char *dataCentralDir = NULL;
+ char *anchorName = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ /*
+ * Perform hard-coded tests if no command line args.
+ * If command line args are provided, they must be:
+ * arg[1]: test name
+ * arg[2]: "ENE" or "EE", for "expect no error" or "expect error"
+ * arg[3]: directory for certificates
+ * arg[4]: user-initial-policy-set, consisting of braces
+ * containing zero or more OID sequences, separated by commas
+ * arg[5]: (optional) "E", indicating initialExplicitPolicy
+ * arg[firstCert]: the path and filename of the trust anchor certificate
+ * arg[firstCert+1..(n-1)]: successive certificates in the chain
+ * arg[n]: the end entity certificate
+ *
+ * Example: test_policychecker test1EE ENE
+ * {2.5.29.32.0,2.5.29.32.3.6} Anchor CA EndEntity
+ */
+
+ dirName = argv[3 + j];
+ dataCentralDir = argv[4 + j];
+
+ if (argc <= 5 || ((6 == argc) && (j))) {
+
+ testPass(dataCentralDir,
+ firstTrustAnchor,
+ secondTrustAnchor,
+ dateAscii);
+
+ testNistTest1(dirName);
+
+ testNistTest2(dirName);
+
+ goto cleanup;
+ }
+
+ if (argc < (7 + j)) {
+ printUsage(argv[0]);
+ pkixTestErrorMsg = "Invalid command line arguments.";
+ goto cleanup;
+ }
+
+ if (PORT_Strcmp(argv[2 + j], "ENE") == 0) {
+ expectedResult = PKIX_TRUE;
+ } else if (PORT_Strcmp(argv[2 + j], "EE") == 0) {
+ expectedResult = PKIX_FALSE;
+ } else {
+ printUsage(argv[0]);
+ pkixTestErrorMsg = "Invalid command line arguments.";
+ goto cleanup;
+ }
+
+ userInitialPolicySet = policySetParse(argv[5 + j]);
+ if (!userInitialPolicySet) {
+ printUsage(argv[0]);
+ pkixTestErrorMsg = "Invalid command line arguments.";
+ goto cleanup;
+ }
+
+ for (initArgs = 0; initArgs < 3; initArgs++) {
+ if (PORT_Strcmp(argv[6 + j + initArgs], "A") == 0) {
+ initialAnyPolicyInhibit = PKIX_TRUE;
+ } else if (PORT_Strcmp(argv[6 + j + initArgs], "E") == 0) {
+ initialExplicitPolicy = PKIX_TRUE;
+ } else if (PORT_Strcmp(argv[6 + j + initArgs], "P") == 0) {
+ initialPolicyMappingInhibit = PKIX_TRUE;
+ } else {
+ break;
+ }
+ }
+
+ firstCert = initArgs + j + 6;
+ chainLength = argc - (firstCert + 1);
+ if (chainLength > PKIX_TEST_MAX_CERTS) {
+ printUsageMax(chainLength);
+ pkixTestErrorMsg = "Invalid command line arguments.";
+ goto cleanup;
+ }
+
+ /*
+ * Create a chain, but don't include the first certName.
+ * That's the anchor, and is supplied separately from
+ * the chain.
+ */
+ for (i = 0; i < chainLength; i++) {
+
+ certNames[i] = argv[i + (firstCert + 1)];
+ certs[i] = NULL;
+ }
+ chain = createCertChainPlus(dirName, certNames, certs, chainLength, plContext);
+
+ subTest(argv[1 + j]);
+
+ valParams = createValidateParams(dirName,
+ argv[firstCert],
+ NULL,
+ NULL,
+ userInitialPolicySet,
+ initialPolicyMappingInhibit,
+ initialAnyPolicyInhibit,
+ initialExplicitPolicy,
+ PKIX_FALSE,
+ chain,
+ plContext);
+
+ if (expectedResult == PKIX_TRUE) {
+ subTest(" (expecting successful validation)");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateChain(valParams, &valResult, &verifyTree, plContext));
+
+ printValidPolicyTree(valResult);
+
+ } else {
+ subTest(" (expecting validation to fail)");
+ validationError = PKIX_ValidateChain(valParams, &valResult, &verifyTree, plContext);
+ if (!validationError) {
+ printValidPolicyTree(valResult);
+ pkixTestErrorMsg = "Should have thrown an error here.";
+ }
+ PKIX_TEST_DECREF_BC(validationError);
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)verifyTree, &verifyString, plContext));
+ (void)printf("verifyTree is\n%s\n", verifyString->escAsciiString);
+
+cleanup:
+
+ PKIX_PL_Free(anchorName, plContext);
+
+ PKIX_TEST_DECREF_AC(verifyString);
+ PKIX_TEST_DECREF_AC(verifyTree);
+ PKIX_TEST_DECREF_AC(userInitialPolicySet);
+ PKIX_TEST_DECREF_AC(chain);
+ PKIX_TEST_DECREF_AC(valParams);
+ PKIX_TEST_DECREF_AC(valResult);
+ PKIX_TEST_DECREF_AC(validationError);
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("PolicyChecker");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/top/test_subjaltnamechecker.c b/nss/cmd/libpkix/pkix/top/test_subjaltnamechecker.c
new file mode 100644
index 0000000..3f9711e
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/top/test_subjaltnamechecker.c
@@ -0,0 +1,261 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_subjaltnamechecker.c
+ *
+ * Test Subject Alternative Name Checking
+ *
+ */
+
+/*
+ * There is no subjaltnamechecker. Instead, targetcertchecker is doing
+ * the job for checking subject alternative names' validity. For testing,
+ * in order to enter names with various type, we create this test excutable
+ * to parse different scenario.
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+#define PKIX_TEST_MAX_CERTS 10
+
+static void *plContext = NULL;
+
+static void
+printUsage1(char *pName)
+{
+ printf("\nUSAGE: %s test-name [ENE|EE] ", pName);
+ printf("cert [certs].\n");
+}
+
+static void
+printUsage2(char *name)
+{
+ printf("\ninvalid test-name syntax - %s", name);
+ printf("\ntest-name syntax: [01][DNORU]:+...");
+ printf("\n [01] 1 - match all; 0 - match one");
+ printf("\n name - type can be specified as");
+ printf("\n [DNORU] D-Directory name");
+ printf("\n N-DNS name");
+ printf("\n O-OID name");
+ printf("\n R-RFC822 name");
+ printf("\n U-URI name");
+ printf("\n + separator for more names\n\n");
+}
+
+static void
+printUsageMax(PKIX_UInt32 numCerts)
+{
+ printf("\nUSAGE ERROR: number of certs %d exceed maximum %d\n",
+ numCerts, PKIX_TEST_MAX_CERTS);
+}
+
+static PKIX_UInt32
+getNameType(char *name)
+{
+ PKIX_UInt32 nameType;
+
+ PKIX_TEST_STD_VARS();
+
+ switch (*name) {
+ case 'D':
+ nameType = PKIX_DIRECTORY_NAME;
+ break;
+ case 'N':
+ nameType = PKIX_DNS_NAME;
+ break;
+ case 'O':
+ nameType = PKIX_OID_NAME;
+ break;
+ case 'R':
+ nameType = PKIX_RFC822_NAME;
+ break;
+ case 'U':
+ nameType = PKIX_URI_NAME;
+ break;
+ default:
+ printUsage2(name);
+ nameType = 0xFFFF;
+ }
+
+ goto cleanup;
+
+cleanup:
+ PKIX_TEST_RETURN();
+ return (nameType);
+}
+
+int
+test_subjaltnamechecker(int argc, char *argv[])
+{
+
+ PKIX_List *chain = NULL;
+ PKIX_ValidateParams *valParams = NULL;
+ PKIX_ValidateResult *valResult = NULL;
+ PKIX_CertSelector *selector = NULL;
+ PKIX_ComCertSelParams *selParams = NULL;
+ PKIX_ProcessingParams *procParams = NULL;
+ PKIX_PL_GeneralName *name = NULL;
+ PKIX_UInt32 actualMinorVersion;
+ char *certNames[PKIX_TEST_MAX_CERTS];
+ PKIX_PL_Cert *certs[PKIX_TEST_MAX_CERTS];
+ PKIX_UInt32 chainLength = 0;
+ PKIX_UInt32 i = 0;
+ PKIX_UInt32 j = 0;
+ char *nameStr;
+ char *nameEnd;
+ char *names[PKIX_TEST_MAX_CERTS];
+ PKIX_UInt32 numNames = 0;
+ PKIX_UInt32 nameType;
+ PKIX_Boolean matchAll = PKIX_TRUE;
+ PKIX_Boolean testValid = PKIX_TRUE;
+ char *dirName = NULL;
+ char *anchorName = NULL;
+ PKIX_VerifyNode *verifyTree = NULL;
+ PKIX_PL_String *verifyString = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ if (argc < 5) {
+ printUsage1(argv[0]);
+ return (0);
+ }
+
+ startTests("SubjAltNameConstraintChecker");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ j++; /* skip test-purpose string */
+
+ /* ENE = expect no error; EE = expect error */
+ if (PORT_Strcmp(argv[2 + j], "ENE") == 0) {
+ testValid = PKIX_TRUE;
+ } else if (PORT_Strcmp(argv[2 + j], "EE") == 0) {
+ testValid = PKIX_FALSE;
+ } else {
+ printUsage1(argv[0]);
+ return (0);
+ }
+
+ /* taking out leading and trailing ", if any */
+ nameStr = argv[1 + j];
+ subTest(nameStr);
+ if (*nameStr == '"') {
+ nameStr++;
+ nameEnd = nameStr;
+ while (*nameEnd != '"' && *nameEnd != '\0') {
+ nameEnd++;
+ }
+ *nameEnd = '\0';
+ }
+
+ /* extract first [0|1] inidcating matchAll or not */
+ matchAll = (*nameStr == '0') ? PKIX_FALSE : PKIX_TRUE;
+ nameStr++;
+
+ numNames = 0;
+ while (*nameStr != '\0') {
+ names[numNames++] = nameStr;
+ while (*nameStr != '+' && *nameStr != '\0') {
+ nameStr++;
+ }
+ if (*nameStr == '+') {
+ *nameStr = '\0';
+ nameStr++;
+ }
+ }
+
+ chainLength = (argc - j) - 4;
+ if (chainLength > PKIX_TEST_MAX_CERTS) {
+ printUsageMax(chainLength);
+ }
+
+ for (i = 0; i < chainLength; i++) {
+ certNames[i] = argv[(4 + j) + i];
+ certs[i] = NULL;
+ }
+
+ /* SubjAltName for validation */
+
+ subTest("Add Subject Alt Name for NameConstraint checking");
+
+ subTest("Create Selector and ComCertSelParams");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &selector, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&selParams, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, selParams, plContext));
+
+ subTest("PKIX_ComCertSelParams_SetMatchAllSubjAltNames");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetMatchAllSubjAltNames(selParams, matchAll, plContext));
+
+ subTest("PKIX_ComCertSelParams_AddSubjAltName(s)");
+ for (i = 0; i < numNames; i++) {
+ nameType = getNameType(names[i]);
+ if (nameType == 0xFFFF) {
+ return (0);
+ }
+ nameStr = names[i] + 2;
+ name = createGeneralName(nameType, nameStr, plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_AddSubjAltName(selParams, name, plContext));
+ PKIX_TEST_DECREF_BC(name);
+ }
+
+ subTest("SubjAltName-Constraints - Create Cert Chain");
+
+ dirName = argv[3 + j];
+
+ chain = createCertChainPlus(dirName, certNames, certs, chainLength, plContext);
+
+ subTest("SubjAltName-Constraints - Create Params");
+
+ valParams = createValidateParams(dirName,
+ argv[4 +
+ j],
+ NULL,
+ NULL,
+ NULL,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ chain,
+ plContext);
+
+ subTest("PKIX_ValidateParams_getProcessingParams");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateParams_GetProcessingParams(valParams, &procParams, plContext));
+
+ subTest("PKIX_ProcessingParams_SetTargetCertConstraints");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetTargetCertConstraints(procParams, selector, plContext));
+
+ subTest("Subject Alt Name - Validate Chain");
+
+ if (testValid == PKIX_TRUE) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateChain(valParams, &valResult, &verifyTree, plContext));
+ } else {
+ PKIX_TEST_EXPECT_ERROR(PKIX_ValidateChain(valParams, &valResult, &verifyTree, plContext));
+ }
+
+cleanup:
+
+ PKIX_PL_Free(anchorName, plContext);
+
+ PKIX_TEST_DECREF_AC(verifyString);
+ PKIX_TEST_DECREF_AC(verifyTree);
+ PKIX_TEST_DECREF_AC(chain);
+ PKIX_TEST_DECREF_AC(valParams);
+ PKIX_TEST_DECREF_AC(valResult);
+ PKIX_TEST_DECREF_AC(selector);
+ PKIX_TEST_DECREF_AC(selParams);
+ PKIX_TEST_DECREF_AC(procParams);
+ PKIX_TEST_DECREF_AC(name);
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("SubjAltNameConstraintsChecker");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/top/test_validatechain.c b/nss/cmd/libpkix/pkix/top/test_validatechain.c
new file mode 100644
index 0000000..98cb7b0
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/top/test_validatechain.c
@@ -0,0 +1,221 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_validatechain.c
+ *
+ * Test ValidateChain function
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+static void
+printUsage(void)
+{
+ (void)printf("\nUSAGE:\nvalidateChain TestName [ENE|EE] "
+ " \n\n");
+ (void)printf("Validates a chain of certificates between "
+ " and \n"
+ "using the certs and CRLs in . "
+ "If ENE is specified,\n"
+ "then an Error is Not Expected. "
+ "If EE is specified, an Error is Expected.\n");
+}
+
+static char *
+createFullPathName(
+ char *dirName,
+ char *certFile,
+ void *plContext)
+{
+ PKIX_UInt32 certFileLen;
+ PKIX_UInt32 dirNameLen;
+ char *certPathName = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ certFileLen = PL_strlen(certFile);
+ dirNameLen = PL_strlen(dirName);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Malloc(dirNameLen +
+ certFileLen +
+ 2,
+ (void **)&certPathName,
+ plContext));
+
+ PL_strcpy(certPathName, dirName);
+ PL_strcat(certPathName, "/");
+ PL_strcat(certPathName, certFile);
+ printf("certPathName = %s\n", certPathName);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+
+ return (certPathName);
+}
+
+static PKIX_Error *
+testDefaultCertStore(PKIX_ValidateParams *valParams, char *crlDir)
+{
+ PKIX_PL_String *dirString = NULL;
+ PKIX_CertStore *certStore = NULL;
+ PKIX_ProcessingParams *procParams = NULL;
+ PKIX_PL_Date *validity = NULL;
+ PKIX_List *revCheckers = NULL;
+ PKIX_RevocationChecker *ocspChecker = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_PL_CollectionCertStoreContext_Create");
+
+ /* Create CollectionCertStore */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII, crlDir, 0, &dirString, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CollectionCertStore_Create(dirString, &certStore, plContext));
+
+ /* Create CertStore */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateParams_GetProcessingParams(valParams, &procParams, plContext));
+
+ subTest("PKIX_ProcessingParams_AddCertStore");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_AddCertStore(procParams, certStore, plContext));
+
+ subTest("PKIX_ProcessingParams_SetRevocationEnabled");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetRevocationEnabled(procParams, PKIX_TRUE, plContext));
+
+ /* create current Date */
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_pl_Date_CreateFromPRTime(PR_Now(), &validity, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&revCheckers, plContext));
+
+ /* create revChecker */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_OcspChecker_Initialize(validity,
+ NULL, /* pwArg */
+ NULL, /* Use default responder */
+ &ocspChecker,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(revCheckers, (PKIX_PL_Object *)ocspChecker, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetRevocationCheckers(procParams, revCheckers, plContext));
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(dirString);
+ PKIX_TEST_DECREF_AC(procParams);
+ PKIX_TEST_DECREF_AC(certStore);
+ PKIX_TEST_DECREF_AC(revCheckers);
+ PKIX_TEST_DECREF_AC(ocspChecker);
+
+ PKIX_TEST_RETURN();
+
+ return (0);
+}
+
+int
+test_validatechain(int argc, char *argv[])
+{
+
+ PKIX_ValidateParams *valParams = NULL;
+ PKIX_ValidateResult *valResult = NULL;
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_UInt32 j = 0;
+ PKIX_UInt32 k = 0;
+ PKIX_UInt32 chainLength = 0;
+ PKIX_Boolean testValid = PKIX_TRUE;
+ PKIX_List *chainCerts = NULL;
+ PKIX_PL_Cert *dirCert = NULL;
+ PKIX_VerifyNode *verifyTree = NULL;
+ PKIX_PL_String *verifyString = NULL;
+ char *dirCertName = NULL;
+ char *anchorCertName = NULL;
+ char *dirName = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ if (argc < 5) {
+ printUsage();
+ return (0);
+ }
+
+ startTests("ValidateChain");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ /* ENE = expect no error; EE = expect error */
+ if (PORT_Strcmp(argv[2 + j], "ENE") == 0) {
+ testValid = PKIX_TRUE;
+ } else if (PORT_Strcmp(argv[2 + j], "EE") == 0) {
+ testValid = PKIX_FALSE;
+ } else {
+ printUsage();
+ return (0);
+ }
+
+ subTest(argv[1 + j]);
+
+ dirName = argv[3 + j];
+
+ chainLength = argc - j - 5;
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&chainCerts, plContext));
+
+ for (k = 0; k < chainLength; k++) {
+
+ dirCert = createCert(dirName, argv[5 + k + j], plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(chainCerts, (PKIX_PL_Object *)dirCert, plContext));
+
+ PKIX_TEST_DECREF_BC(dirCert);
+ }
+
+ valParams = createValidateParams(dirName,
+ argv[4 +
+ j],
+ NULL,
+ NULL,
+ NULL,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ chainCerts,
+ plContext);
+
+ testDefaultCertStore(valParams, dirName);
+
+ if (testValid == PKIX_TRUE) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateChain(valParams, &valResult, &verifyTree, plContext));
+ } else {
+ PKIX_TEST_EXPECT_ERROR(PKIX_ValidateChain(valParams, &valResult, &verifyTree, plContext));
+ }
+
+ subTest("Displaying VerifyNode objects");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)verifyTree, &verifyString, plContext));
+ (void)printf("verifyTree is\n%s\n", verifyString->escAsciiString);
+
+cleanup:
+ PKIX_TEST_DECREF_AC(verifyString);
+ PKIX_TEST_DECREF_AC(verifyTree);
+
+ PKIX_TEST_DECREF_AC(chainCerts);
+ PKIX_TEST_DECREF_AC(valParams);
+ PKIX_TEST_DECREF_AC(valResult);
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("ValidateChain");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/top/test_validatechain_NB.c b/nss/cmd/libpkix/pkix/top/test_validatechain_NB.c
new file mode 100644
index 0000000..ad73a5d
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/top/test_validatechain_NB.c
@@ -0,0 +1,351 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_validatechain_NB.c
+ *
+ * Test ValidateChain (nonblocking I/O) function
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+static void
+printUsage(void)
+{
+ (void)printf("\nUSAGE:\ntest_validateChain_NB TestName [ENE|EE] "
+ " \n\n");
+ (void)printf("Validates a chain of certificates between "
+ " and \n"
+ "using the certs and CRLs in . "
+ "If ENE is specified,\n"
+ "then an Error is Not Expected. "
+ "If EE is specified, an Error is Expected.\n");
+}
+
+static char *
+createFullPathName(
+ char *dirName,
+ char *certFile,
+ void *plContext)
+{
+ PKIX_UInt32 certFileLen;
+ PKIX_UInt32 dirNameLen;
+ char *certPathName = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ certFileLen = PL_strlen(certFile);
+ dirNameLen = PL_strlen(dirName);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Malloc(dirNameLen +
+ certFileLen +
+ 2,
+ (void **)&certPathName,
+ plContext));
+
+ PL_strcpy(certPathName, dirName);
+ PL_strcat(certPathName, "/");
+ PL_strcat(certPathName, certFile);
+ printf("certPathName = %s\n", certPathName);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+
+ return (certPathName);
+}
+
+static PKIX_Error *
+testSetupCertStore(PKIX_ValidateParams *valParams, char *ldapName)
+{
+ PKIX_PL_String *dirString = NULL;
+ PKIX_CertStore *certStore = NULL;
+ PKIX_ProcessingParams *procParams = NULL;
+ PKIX_PL_LdapDefaultClient *ldapClient = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_PL_CollectionCertStoreContext_Create");
+
+ /* Create LDAPCertStore */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_LdapDefaultClient_CreateByName(ldapName,
+ 0, /* timeout */
+ NULL, /* bindPtr */
+ &ldapClient,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_LdapCertStore_Create((PKIX_PL_LdapClient *)ldapClient,
+ &certStore,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateParams_GetProcessingParams(valParams, &procParams, plContext));
+
+ subTest("PKIX_ProcessingParams_AddCertStore");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_AddCertStore(procParams, certStore, plContext));
+
+ subTest("PKIX_ProcessingParams_SetRevocationEnabled");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetRevocationEnabled(procParams, PKIX_TRUE, plContext));
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(dirString);
+ PKIX_TEST_DECREF_AC(procParams);
+ PKIX_TEST_DECREF_AC(certStore);
+ PKIX_TEST_DECREF_AC(ldapClient);
+
+ PKIX_TEST_RETURN();
+
+ return (0);
+}
+
+static char *levels[] = {
+ "None", "Fatal Error", "Error", "Warning", "Debug", "Trace"
+};
+
+static PKIX_Error *
+loggerCallback(
+ PKIX_Logger *logger,
+ PKIX_PL_String *message,
+ PKIX_UInt32 logLevel,
+ PKIX_ERRORCLASS logComponent,
+ void *plContext)
+{
+#define resultSize 150
+ char *msg = NULL;
+ char result[resultSize];
+
+ PKIX_TEST_STD_VARS();
+
+ msg = PKIX_String2ASCII(message, plContext);
+ PR_snprintf(result, resultSize,
+ "Logging %s (%s): %s",
+ levels[logLevel],
+ PKIX_ERRORCLASSNAMES[logComponent],
+ msg);
+ subTest(result);
+
+cleanup:
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(msg, plContext));
+ PKIX_TEST_RETURN();
+}
+
+static void
+testLogErrors(
+ PKIX_ERRORCLASS module,
+ PKIX_UInt32 loggingLevel,
+ PKIX_List *loggers,
+ void *plContext)
+{
+ PKIX_Logger *logger = NULL;
+ PKIX_PL_String *component = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Logger_Create(loggerCallback, NULL, &logger, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Logger_SetLoggingComponent(logger, module, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Logger_SetMaxLoggingLevel(logger, loggingLevel, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(loggers, (PKIX_PL_Object *)logger, plContext));
+
+cleanup:
+ PKIX_TEST_DECREF_AC(logger);
+ PKIX_TEST_DECREF_AC(component);
+
+ PKIX_TEST_RETURN();
+}
+
+int
+test_validatechain_NB(int argc, char *argv[])
+{
+
+ PKIX_ValidateParams *valParams = NULL;
+ PKIX_ValidateResult *valResult = NULL;
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_UInt32 j = 0;
+ PKIX_UInt32 k = 0;
+ PKIX_UInt32 chainLength = 0;
+ PKIX_Boolean testValid = PKIX_TRUE;
+ PKIX_List *chainCerts = NULL;
+ PKIX_PL_Cert *dirCert = NULL;
+ char *dirCertName = NULL;
+ char *anchorCertName = NULL;
+ char *dirName = NULL;
+ PKIX_UInt32 certIndex = 0;
+ PKIX_UInt32 anchorIndex = 0;
+ PKIX_UInt32 checkerIndex = 0;
+ PKIX_Boolean revChecking = PKIX_FALSE;
+ PKIX_List *checkers = NULL;
+ PRPollDesc *pollDesc = NULL;
+ PRErrorCode errorCode = 0;
+ PKIX_PL_Socket *socket = NULL;
+ char *ldapName = NULL;
+ PKIX_VerifyNode *verifyTree = NULL;
+ PKIX_PL_String *verifyString = NULL;
+
+ PKIX_List *loggers = NULL;
+ PKIX_Logger *logger = NULL;
+ char *logging = NULL;
+ PKIX_PL_String *component = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ if (argc < 5) {
+ printUsage();
+ return (0);
+ }
+
+ startTests("ValidateChain_NB");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ /* ENE = expect no error; EE = expect error */
+ if (PORT_Strcmp(argv[2 + j], "ENE") == 0) {
+ testValid = PKIX_TRUE;
+ } else if (PORT_Strcmp(argv[2 + j], "EE") == 0) {
+ testValid = PKIX_FALSE;
+ } else {
+ printUsage();
+ return (0);
+ }
+
+ subTest(argv[1 + j]);
+
+ dirName = argv[3 + j];
+
+ chainLength = argc - j - 5;
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&chainCerts, plContext));
+
+ for (k = 0; k < chainLength; k++) {
+
+ dirCert = createCert(dirName, argv[5 + k + j], plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(chainCerts, (PKIX_PL_Object *)dirCert, plContext));
+
+ PKIX_TEST_DECREF_BC(dirCert);
+ }
+
+ valParams = createValidateParams(dirName,
+ argv[4 +
+ j],
+ NULL,
+ NULL,
+ NULL,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ chainCerts,
+ plContext);
+
+ ldapName = PR_GetEnvSecure("LDAP");
+ /* Is LDAP set in the environment? */
+ if ((ldapName == NULL) || (*ldapName == '\0')) {
+ testError("LDAP not set in environment");
+ goto cleanup;
+ }
+
+ pkixTestErrorResult = pkix_pl_Socket_CreateByName(PKIX_FALSE, /* isServer */
+ PR_SecondsToInterval(30), /* try 30 secs for connect */
+ ldapName,
+ &errorCode,
+ &socket,
+ plContext);
+
+ if (pkixTestErrorResult != NULL) {
+ PKIX_PL_Object_DecRef((PKIX_PL_Object *)pkixTestErrorResult, plContext);
+ pkixTestErrorResult = NULL;
+ testError("Unable to connect to LDAP Server");
+ goto cleanup;
+ }
+
+ PKIX_TEST_DECREF_BC(socket);
+
+ testSetupCertStore(valParams, ldapName);
+
+ logging = PR_GetEnvSecure("LOGGING");
+ /* Is LOGGING set in the environment? */
+ if ((logging != NULL) && (*logging != '\0')) {
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&loggers, plContext));
+
+ testLogErrors(PKIX_VALIDATE_ERROR, 2, loggers, plContext);
+ testLogErrors(PKIX_CERTCHAINCHECKER_ERROR, 2, loggers, plContext);
+ testLogErrors(PKIX_LDAPDEFAULTCLIENT_ERROR, 2, loggers, plContext);
+ testLogErrors(PKIX_CERTSTORE_ERROR, 2, loggers, plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_SetLoggers(loggers, plContext));
+ }
+
+ pkixTestErrorResult = PKIX_ValidateChain_NB(valParams,
+ &certIndex,
+ &anchorIndex,
+ &checkerIndex,
+ &revChecking,
+ &checkers,
+ (void **)&pollDesc,
+ &valResult,
+ &verifyTree,
+ plContext);
+
+ while (pollDesc != NULL) {
+
+ if (PR_Poll(pollDesc, 1, 0) < 0) {
+ testError("PR_Poll failed");
+ }
+
+ pkixTestErrorResult = PKIX_ValidateChain_NB(valParams,
+ &certIndex,
+ &anchorIndex,
+ &checkerIndex,
+ &revChecking,
+ &checkers,
+ (void **)&pollDesc,
+ &valResult,
+ &verifyTree,
+ plContext);
+ }
+
+ if (pkixTestErrorResult) {
+ if (testValid == PKIX_FALSE) { /* EE */
+ (void)printf("EXPECTED ERROR RECEIVED!\n");
+ } else { /* ENE */
+ testError("UNEXPECTED ERROR RECEIVED");
+ }
+ PKIX_TEST_DECREF_BC(pkixTestErrorResult);
+ } else {
+
+ if (testValid == PKIX_TRUE) { /* ENE */
+ (void)printf("EXPECTED NON-ERROR RECEIVED!\n");
+ } else { /* EE */
+ (void)printf("UNEXPECTED NON-ERROR RECEIVED!\n");
+ }
+ }
+
+cleanup:
+
+ if (verifyTree) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)verifyTree, &verifyString, plContext));
+ (void)printf("verifyTree is\n%s\n",
+ verifyString->escAsciiString);
+ }
+
+ PKIX_TEST_DECREF_AC(verifyString);
+ PKIX_TEST_DECREF_AC(verifyTree);
+ PKIX_TEST_DECREF_AC(checkers);
+ PKIX_TEST_DECREF_AC(chainCerts);
+ PKIX_TEST_DECREF_AC(valParams);
+ PKIX_TEST_DECREF_AC(valResult);
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("ValidateChain_NB");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/top/test_validatechain_bc.c b/nss/cmd/libpkix/pkix/top/test_validatechain_bc.c
new file mode 100644
index 0000000..480ec26
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/top/test_validatechain_bc.c
@@ -0,0 +1,233 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * validateChainBasicConstraints.c
+ *
+ * Tests Cert Chain Validation
+ *
+ */
+
+#include
+#include
+#include
+
+#include "pkix_pl_generalname.h"
+#include "pkix_pl_cert.h"
+#include "pkix.h"
+#include "testutil.h"
+#include "prlong.h"
+#include "plstr.h"
+#include "prthread.h"
+#include "nspr.h"
+#include "prtypes.h"
+#include "prtime.h"
+#include "pk11func.h"
+#include "secasn1.h"
+#include "cert.h"
+#include "cryptohi.h"
+#include "secoid.h"
+#include "certdb.h"
+#include "secitem.h"
+#include "keythi.h"
+#include "nss.h"
+
+static void *plContext = NULL;
+
+static void
+printUsage(void)
+{
+ printf("\nUSAGE: incorrect.\n");
+}
+
+static PKIX_PL_Cert *
+createCert(char *inFileName)
+{
+ PKIX_PL_ByteArray *byteArray = NULL;
+ void *buf = NULL;
+ PRFileDesc *inFile = NULL;
+ PKIX_UInt32 len;
+ SECItem certDER;
+ SECStatus rv;
+ /* default: NULL cert (failure case) */
+ PKIX_PL_Cert *cert = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ certDER.data = NULL;
+
+ inFile = PR_Open(inFileName, PR_RDONLY, 0);
+
+ if (!inFile) {
+ pkixTestErrorMsg = "Unable to open cert file";
+ goto cleanup;
+ } else {
+ rv = SECU_ReadDERFromFile(&certDER, inFile, PR_FALSE, PR_FALSE);
+ if (!rv) {
+ buf = (void *)certDER.data;
+ len = certDER.len;
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_ByteArray_Create(buf, len, &byteArray, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_Create(byteArray, &cert, plContext));
+
+ SECITEM_FreeItem(&certDER, PR_FALSE);
+ } else {
+ pkixTestErrorMsg = "Unable to read DER from cert file";
+ goto cleanup;
+ }
+ }
+
+cleanup:
+
+ if (inFile) {
+ PR_Close(inFile);
+ }
+
+ if (PKIX_TEST_ERROR_RECEIVED) {
+ SECITEM_FreeItem(&certDER, PR_FALSE);
+ }
+
+ PKIX_TEST_DECREF_AC(byteArray);
+
+ PKIX_TEST_RETURN();
+
+ return (cert);
+}
+
+int
+test_validatechain_bc(int argc, char *argv[])
+{
+
+ PKIX_TrustAnchor *anchor = NULL;
+ PKIX_List *anchors = NULL;
+ PKIX_List *certs = NULL;
+ PKIX_ProcessingParams *procParams = NULL;
+ PKIX_ValidateParams *valParams = NULL;
+ PKIX_ValidateResult *valResult = NULL;
+ PKIX_PL_X500Name *subject = NULL;
+ PKIX_ComCertSelParams *certSelParams = NULL;
+ PKIX_CertSelector *certSelector = NULL;
+
+ char *trustedCertFile = NULL;
+ char *chainCertFile = NULL;
+ PKIX_PL_Cert *trustedCert = NULL;
+ PKIX_PL_Cert *chainCert = NULL;
+ PKIX_UInt32 chainLength = 0;
+ PKIX_UInt32 i = 0;
+ PKIX_UInt32 j = 0;
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_VerifyNode *verifyTree = NULL;
+ PKIX_PL_String *verifyString = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ if (argc < 3) {
+ printUsage();
+ return (0);
+ }
+
+ startTests("ValidateChainBasicConstraints");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ chainLength = (argc - j) - 2;
+
+ /* create processing params with list of trust anchors */
+ trustedCertFile = argv[1 + j];
+ trustedCert = createCert(trustedCertFile);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetSubject(trustedCert, &subject, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&certSelParams, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetBasicConstraints(certSelParams, -1, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, certSelParams, plContext));
+
+ PKIX_TEST_DECREF_BC(subject);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_TrustAnchor_CreateWithCert(trustedCert, &anchor, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&anchors, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(anchors, (PKIX_PL_Object *)anchor, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_Create(anchors, &procParams, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetRevocationEnabled(procParams, PKIX_FALSE, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetTargetCertConstraints(procParams, certSelector, plContext));
+
+ PKIX_TEST_DECREF_BC(certSelector);
+
+ /* create cert chain */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&certs, plContext));
+ for (i = 0; i < chainLength; i++) {
+ chainCertFile = argv[i + (2 + j)];
+ chainCert = createCert(chainCertFile);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(certs, (PKIX_PL_Object *)chainCert, plContext));
+
+ PKIX_TEST_DECREF_BC(chainCert);
+ }
+
+ /* create validate params with processing params and cert chain */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateParams_Create(procParams, certs, &valParams, plContext));
+
+ /* validate cert chain using processing params and return valResult */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateChain(valParams, &valResult, &verifyTree, plContext));
+
+ if (valResult != NULL) {
+ printf("SUCCESSFULLY VALIDATED with Basic Constraint ");
+ printf("Cert Selector minimum path length to be -1\n");
+ PKIX_TEST_DECREF_BC(valResult);
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)verifyTree, &verifyString, plContext));
+ (void)printf("verifyTree is\n%s\n", verifyString->escAsciiString);
+ PKIX_TEST_DECREF_BC(verifyString);
+ PKIX_TEST_DECREF_BC(verifyTree);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetBasicConstraints(certSelParams, 6, plContext));
+
+ /* validate cert chain using processing params and return valResult */
+
+ PKIX_TEST_EXPECT_ERROR(PKIX_ValidateChain(valParams, &valResult, &verifyTree, plContext));
+
+ if (valResult != NULL) {
+ printf("SUCCESSFULLY VALIDATED with Basic Constraint ");
+ printf("Cert Selector minimum path length to be 6\n");
+ }
+
+ PKIX_TEST_DECREF_BC(trustedCert);
+ PKIX_TEST_DECREF_BC(anchor);
+ PKIX_TEST_DECREF_BC(anchors);
+ PKIX_TEST_DECREF_BC(certs);
+ PKIX_TEST_DECREF_BC(procParams);
+
+cleanup:
+
+ if (PKIX_TEST_ERROR_RECEIVED) {
+ printf("FAILED TO VALIDATE\n");
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)verifyTree, &verifyString, plContext));
+ (void)printf("verifyTree is\n%s\n", verifyString->escAsciiString);
+ PKIX_TEST_DECREF_AC(verifyString);
+ PKIX_TEST_DECREF_AC(verifyTree);
+
+ PKIX_TEST_DECREF_AC(certSelParams);
+ PKIX_TEST_DECREF_AC(valResult);
+ PKIX_TEST_DECREF_AC(valParams);
+
+ PKIX_TEST_RETURN();
+
+ PKIX_Shutdown(plContext);
+
+ endTests("ValidateChainBasicConstraints");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/util/Makefile b/nss/cmd/libpkix/pkix/util/Makefile
new file mode 100755
index 0000000..09ca5f1
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/util/Makefile
@@ -0,0 +1,47 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(PKIX_DEPTH)/config.mk
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platrules.mk
diff --git a/nss/cmd/libpkix/pkix/util/manifest.mn b/nss/cmd/libpkix/pkix/util/manifest.mn
new file mode 100755
index 0000000..7dbeb6d
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/util/manifest.mn
@@ -0,0 +1,23 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+PKIX_DEPTH = ../..
+PLAT_DEPTH = $(PKIX_DEPTH)/..
+CORE_DEPTH = $(PKIX_DEPTH)/../../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+CSRCS = test_error.c \
+ test_list.c \
+ test_list2.c \
+ test_logger.c \
+ $(NULL)
+
+LIBRARY_NAME=pkixtoolutil
+
+SOURCE_LIB_DIR=$(PKIX_DEPTH)/$(OBJDIR)
+
+NO_MD_RELEASE = 1
diff --git a/nss/cmd/libpkix/pkix/util/test_error.c b/nss/cmd/libpkix/pkix/util/test_error.c
new file mode 100644
index 0000000..9cddecc
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/util/test_error.c
@@ -0,0 +1,385 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_error.c
+ *
+ * Tests Error Object Creation, ToString, Callbacks and Destroy
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+static void
+createErrors(
+ PKIX_Error **error,
+ PKIX_Error **error2,
+ PKIX_Error **error3,
+ PKIX_Error **error5,
+ PKIX_Error **error6,
+ PKIX_Error **error7,
+ char *infoChar)
+
+{
+ PKIX_PL_String *infoString = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(
+ PKIX_ESCASCII,
+ infoChar,
+ PL_strlen(infoChar),
+ &infoString,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Error_Create(PKIX_MEM_ERROR,
+ NULL,
+ NULL,
+ PKIX_TESTANOTHERERRORMESSAGE,
+ error2,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Error_Create(PKIX_OBJECT_ERROR,
+ *error2,
+ (PKIX_PL_Object *)infoString,
+ PKIX_TESTERRORMESSAGE,
+ error,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Error_Create(PKIX_OBJECT_ERROR,
+ *error2,
+ (PKIX_PL_Object *)infoString,
+ PKIX_TESTERRORMESSAGE,
+ error3,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Error_Create(PKIX_OBJECT_ERROR,
+ NULL,
+ (PKIX_PL_Object *)infoString,
+ 0,
+ error5,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Error_Create(PKIX_MEM_ERROR,
+ *error5,
+ (PKIX_PL_Object *)infoString,
+ 0,
+ error6,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Error_Create(PKIX_OBJECT_ERROR,
+ *error6,
+ (PKIX_PL_Object *)infoString,
+ 0,
+ error7,
+ plContext));
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(infoString);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetErrorClass(PKIX_Error *error, PKIX_Error *error2)
+{
+ PKIX_ERRORCLASS errClass;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Error_GetErrorClass(error, &errClass, plContext));
+
+ if (errClass != PKIX_OBJECT_ERROR) {
+ testError("Incorrect Class Returned");
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Error_GetErrorClass(error2, &errClass, plContext));
+
+ if (errClass != PKIX_MEM_ERROR) {
+ testError("Incorrect Class Returned");
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Error_GetErrorClass(PKIX_ALLOC_ERROR(),
+ &errClass, plContext));
+ if (errClass != PKIX_FATAL_ERROR) {
+ testError("Incorrect Class Returned");
+ }
+
+cleanup:
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetDescription(
+ PKIX_Error *error,
+ PKIX_Error *error2,
+ PKIX_Error *error3,
+ char *descChar,
+ char *descChar2)
+{
+
+ PKIX_PL_String *targetString = NULL;
+ char *temp = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Error_GetDescription(error, &targetString, plContext));
+ temp = PKIX_String2ASCII(targetString, plContext);
+ PKIX_TEST_DECREF_BC(targetString);
+
+ if (temp) {
+ if (PL_strcmp(temp, descChar) != 0) {
+ testError("Incorrect description returned");
+ }
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Error_GetDescription(error2, &targetString, plContext));
+ temp = PKIX_String2ASCII(targetString, plContext);
+ PKIX_TEST_DECREF_BC(targetString);
+
+ if (temp) {
+ if (PL_strcmp(temp, descChar2) != 0) {
+ testError("Incorrect description returned");
+ }
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Error_GetDescription(error3, &targetString, plContext));
+ temp = PKIX_String2ASCII(targetString, plContext);
+ PKIX_TEST_DECREF_BC(targetString);
+
+ if (temp) {
+ if (PL_strcmp(temp, descChar) != 0) {
+ testError("Incorrect description returned");
+ }
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetCause(PKIX_Error *error, PKIX_Error *error2, PKIX_Error *error3)
+{
+
+ PKIX_Error *error4 = NULL;
+ PKIX_PL_String *targetString = NULL;
+ char *temp = NULL;
+ PKIX_Boolean boolResult;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Error_GetCause(error, &error4, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)error2,
+ (PKIX_PL_Object *)error4,
+ &boolResult, plContext));
+ if (!boolResult)
+ testError("Incorrect Cause returned");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)error4,
+ &targetString, plContext));
+
+ temp = PKIX_String2ASCII(targetString, plContext);
+ if (temp) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+
+ PKIX_TEST_DECREF_BC(targetString);
+ PKIX_TEST_DECREF_BC(error4);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Error_GetCause(error3, &error4, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)error2,
+ (PKIX_PL_Object *)error4,
+ &boolResult, plContext));
+ if (!boolResult)
+ testError("Incorrect Cause returned");
+
+ PKIX_TEST_DECREF_BC(error4);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetSupplementaryInfo(PKIX_Error *error, char *infoChar)
+{
+
+ PKIX_PL_Object *targetString = NULL;
+ char *temp = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Error_GetSupplementaryInfo(error, &targetString, plContext));
+ temp = PKIX_String2ASCII((PKIX_PL_String *)targetString, plContext);
+ PKIX_TEST_DECREF_BC(targetString);
+
+ if (temp) {
+ if (PL_strcmp(temp, infoChar) != 0) {
+ testError("Incorrect info returned");
+ }
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testPrimitiveError(void)
+{
+ PKIX_PL_String *targetString = NULL;
+ PKIX_PL_String *targetStringCopy = NULL;
+ char *temp = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)PKIX_ALLOC_ERROR(),
+ &targetString, plContext));
+
+ temp = PKIX_String2ASCII(targetString, plContext);
+ if (temp) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+
+ targetStringCopy = targetString;
+
+ PKIX_TEST_DECREF_BC(targetString);
+
+ /*
+ * We need to DECREF twice, b/c the PKIX_ALLOC_ERROR object
+ * which holds a cached copy of the stringRep can never be DECREF'd
+ */
+ PKIX_TEST_DECREF_BC(targetStringCopy);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testChaining(PKIX_Error *error7)
+{
+ PKIX_PL_String *targetString = NULL;
+ PKIX_Error *tempError = NULL;
+ char *temp = NULL;
+ PKIX_UInt32 i;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)error7,
+ &targetString, plContext));
+
+ temp = PKIX_String2ASCII(targetString, plContext);
+ if (temp) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+
+ for (i = 0, tempError = error7; i < 2; i++) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Error_GetCause(tempError, &tempError, plContext));
+ if (tempError == NULL) {
+ testError("Unexpected end to error chain");
+ break;
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_DecRef((PKIX_PL_Object *)tempError, plContext));
+ }
+
+ PKIX_TEST_DECREF_BC(targetString);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testDestroy(PKIX_Error *error)
+{
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_DECREF_BC(error);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+int
+test_error(int argc, char *argv[])
+{
+
+ PKIX_Error *error, *error2, *error3, *error5, *error6, *error7;
+ char *descChar = "Error Message";
+ char *descChar2 = "Another Error Message";
+ char *infoChar = "Auxiliary Info";
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_UInt32 j = 0;
+
+ PKIX_TEST_STD_VARS();
+
+ startTests("Errors");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ subTest("PKIX_Error_Create");
+ createErrors(&error,
+ &error2,
+ &error3,
+ &error5,
+ &error6,
+ &error7,
+ infoChar);
+
+ PKIX_TEST_EQ_HASH_TOSTR_DUP(error,
+ error,
+ error2,
+ NULL,
+ Error,
+ PKIX_TRUE);
+
+ subTest("PKIX_Error_GetErrorClass");
+ testGetErrorClass(error, error2);
+
+ subTest("PKIX_Error_GetDescription");
+ testGetDescription(error, error2, error3, descChar, descChar2);
+
+ subTest("PKIX_Error_GetCause");
+ testGetCause(error, error2, error3);
+
+ subTest("PKIX_Error_GetSupplementaryInfo");
+ testGetSupplementaryInfo(error, infoChar);
+
+ subTest("Primitive Error Type");
+ testPrimitiveError();
+
+ subTest("Error Chaining");
+ testChaining(error7);
+
+ subTest("PKIX_Error_Destroy");
+ testDestroy(error);
+ testDestroy(error2);
+ testDestroy(error3);
+ testDestroy(error5);
+ testDestroy(error6);
+ testDestroy(error7);
+
+cleanup:
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("Errors");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/util/test_list.c b/nss/cmd/libpkix/pkix/util/test_list.c
new file mode 100644
index 0000000..e5e6e50
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/util/test_list.c
@@ -0,0 +1,765 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_list.c
+ *
+ * Tests List Objects
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+static void
+createLists(PKIX_List **list, PKIX_List **list2)
+{
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(list, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(list2, plContext));
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testReverseList(void)
+{
+ PKIX_List *firstList = NULL;
+ PKIX_List *reverseList = NULL;
+ PKIX_UInt32 length, i;
+ char *testItemString = "one";
+ char *testItemString2 = "two";
+ PKIX_PL_String *testItem = NULL;
+ PKIX_PL_String *testItem2 = NULL;
+ PKIX_PL_Object *retrievedItem1 = NULL;
+ PKIX_PL_Object *retrievedItem2 = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&firstList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_ReverseList(firstList, &reverseList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(reverseList, &length, plContext));
+ if (length != 0) {
+ testError("Incorrect Length returned");
+ }
+
+ PKIX_TEST_DECREF_BC(reverseList);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII,
+ testItemString,
+ 0,
+ &testItem,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII,
+ testItemString2,
+ 0,
+ &testItem2,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(firstList,
+ (PKIX_PL_Object *)testItem,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_ReverseList(firstList, &reverseList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(reverseList, &length, plContext));
+ if (length != 1) {
+ testError("Incorrect Length returned");
+ }
+
+ PKIX_TEST_DECREF_BC(reverseList);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(firstList,
+ (PKIX_PL_Object *)testItem2,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(firstList,
+ (PKIX_PL_Object *)testItem,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(firstList,
+ (PKIX_PL_Object *)testItem2,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_ReverseList(firstList, &reverseList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(reverseList, &length, plContext));
+ if (length != 4) {
+ testError("Incorrect Length returned");
+ }
+
+ for (i = 0; i < length; i++) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(firstList,
+ i,
+ &retrievedItem1,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(reverseList,
+ (length - 1) - i,
+ &retrievedItem2,
+ plContext));
+
+ testEqualsHelper(retrievedItem1, retrievedItem2, PKIX_TRUE, plContext);
+
+ PKIX_TEST_DECREF_BC(retrievedItem1);
+ PKIX_TEST_DECREF_BC(retrievedItem2);
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(firstList);
+ PKIX_TEST_DECREF_AC(reverseList);
+
+ PKIX_TEST_DECREF_AC(testItem);
+ PKIX_TEST_DECREF_AC(testItem2);
+
+ PKIX_TEST_DECREF_AC(retrievedItem1);
+ PKIX_TEST_DECREF_AC(retrievedItem2);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testZeroLengthList(PKIX_List *list)
+{
+ PKIX_UInt32 length;
+ PKIX_Boolean empty;
+ char *testItemString = "hello";
+ PKIX_PL_String *testItem = NULL;
+ PKIX_PL_String *retrievedItem = NULL;
+ PKIX_List *diffList = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&diffList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(list, &length, plContext));
+
+ if (length != 0) {
+ testError("Incorrect Length returned");
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_IsEmpty(list, &empty, plContext));
+ if (!empty) {
+ testError("Incorrect result for PKIX_List_IsEmpty");
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII,
+ testItemString,
+ 0,
+ &testItem,
+ plContext));
+
+ PKIX_TEST_EXPECT_ERROR(PKIX_List_InsertItem(list, 0, (PKIX_PL_Object *)testItem, plContext));
+
+ PKIX_TEST_EXPECT_ERROR(PKIX_List_SetItem(list, 0, (PKIX_PL_Object *)testItem, plContext));
+
+ PKIX_TEST_EXPECT_ERROR(PKIX_List_GetItem(list,
+ 0,
+ (PKIX_PL_Object **)&retrievedItem,
+ plContext));
+
+ PKIX_TEST_EXPECT_ERROR(PKIX_List_DeleteItem(list, 0, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(diffList,
+ (PKIX_PL_Object *)testItem,
+ plContext));
+
+ testDuplicateHelper((PKIX_PL_Object *)diffList, plContext);
+
+ PKIX_TEST_EQ_HASH_TOSTR_DUP(list, list, diffList, "(EMPTY)", List, PKIX_TRUE);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(diffList, &length, plContext));
+ if (length != 1) {
+ testError("Incorrect Length returned");
+ }
+
+ PKIX_TEST_EXPECT_ERROR(PKIX_List_DeleteItem(list, 1, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_DeleteItem(diffList, 0, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(diffList, &length, plContext));
+ if (length != 0) {
+ testError("Incorrect Length returned");
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(testItem);
+ PKIX_TEST_DECREF_AC(diffList);
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetLength(PKIX_List *list)
+{
+ PKIX_UInt32 length;
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(list, &length, plContext));
+
+ if (length != 3) {
+ testError("Incorrect Length returned");
+ }
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetSetItem(
+ PKIX_List *list,
+ char *testItemString,
+ char *testItemString2,
+ char *testItemString3,
+ PKIX_PL_String **testItem,
+ PKIX_PL_String **testItem2,
+ PKIX_PL_String **testItem3)
+{
+ PKIX_PL_Object *tempItem = NULL;
+ char *temp = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII,
+ testItemString,
+ PL_strlen(testItemString),
+ testItem,
+ plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII,
+ testItemString2,
+ PL_strlen(testItemString2),
+ testItem2,
+ plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII,
+ testItemString3,
+ PL_strlen(testItemString3),
+ testItem3,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(list, (PKIX_PL_Object *)*testItem, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(list, (PKIX_PL_Object *)*testItem, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(list, (PKIX_PL_Object *)*testItem, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetItem(list, 0, (PKIX_PL_Object *)*testItem, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetItem(list, 1, (PKIX_PL_Object *)*testItem2, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetItem(list, 2, (PKIX_PL_Object *)*testItem3, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(list, 0, &tempItem, plContext));
+
+ temp = PKIX_String2ASCII((PKIX_PL_String *)tempItem, plContext);
+ if (temp) {
+ if (PL_strcmp(testItemString, temp) != 0)
+ testError("GetItem from list is incorrect");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+
+ PKIX_TEST_DECREF_BC(tempItem);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(list, 1, &tempItem, plContext));
+
+ temp = PKIX_String2ASCII((PKIX_PL_String *)tempItem, plContext);
+ if (temp) {
+ if (PL_strcmp(testItemString2, temp) != 0)
+ testError("GetItem from list is incorrect");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+ PKIX_TEST_DECREF_BC(tempItem);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(list, 2, &tempItem, plContext));
+
+ temp = PKIX_String2ASCII((PKIX_PL_String *)tempItem, plContext);
+ if (temp) {
+ if (PL_strcmp(testItemString3, temp) != 0)
+ testError("GetItem from list is incorrect");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+ PKIX_TEST_DECREF_BC(tempItem);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetItem(list, 0, (PKIX_PL_Object *)*testItem3, plContext));
+ temp = PKIX_String2ASCII(*testItem3, plContext);
+ if (temp) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(list, 0, &tempItem, plContext));
+
+ temp = PKIX_String2ASCII((PKIX_PL_String *)tempItem, plContext);
+ if (temp) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+
+ temp = PKIX_String2ASCII((PKIX_PL_String *)tempItem, plContext);
+ if (temp) {
+ if (PL_strcmp(testItemString3, temp) != 0)
+ testError("GetItem from list is incorrect");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+ PKIX_TEST_DECREF_BC(tempItem);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testInsertItem(
+ PKIX_List *list,
+ PKIX_PL_String *testItem,
+ char *testItemString)
+{
+ PKIX_PL_Object *tempItem = NULL;
+ PKIX_PL_String *outputString = NULL;
+ char *temp = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_InsertItem(list, 0, (PKIX_PL_Object *)testItem, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(list, 0, &tempItem, plContext));
+
+ temp = PKIX_String2ASCII((PKIX_PL_String *)tempItem, plContext);
+ if (temp) {
+ if (PL_strcmp(testItemString, temp) != 0)
+ testError("GetItem from list is incorrect");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+ PKIX_TEST_DECREF_BC(tempItem);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)list,
+ &outputString,
+ plContext));
+
+ temp = PKIX_String2ASCII(outputString, plContext);
+ if (temp) {
+ if (PL_strcmp("(a, c, b, c)", temp) != 0)
+ testError("List toString is Incorrect");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+
+ PKIX_TEST_DECREF_BC(outputString);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testAppendItem(PKIX_List *list, PKIX_PL_String *testItem)
+{
+ PKIX_UInt32 length2;
+ PKIX_PL_String *outputString = NULL;
+ char *temp = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(list, &length2, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(list,
+ (PKIX_PL_Object *)testItem,
+ plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)list,
+ &outputString,
+ plContext));
+
+ temp = PKIX_String2ASCII(outputString, plContext);
+ if (temp) {
+ if (PL_strcmp("(a, c, b, c, a)", temp) != 0)
+ testError("List toString is Incorrect");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+
+ PKIX_TEST_DECREF_BC(outputString);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testNestedLists(
+ PKIX_List *list,
+ PKIX_List *list2,
+ PKIX_PL_String *testItem,
+ PKIX_PL_String *testItem2)
+{
+ PKIX_PL_String *outputString = NULL;
+ char *temp = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(list2, (PKIX_PL_Object *)testItem, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(list2,
+ (PKIX_PL_Object *)NULL,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(list2,
+ (PKIX_PL_Object *)testItem,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)list2,
+ &outputString,
+ plContext));
+
+ temp = PKIX_String2ASCII(outputString, plContext);
+ if (temp) {
+ if (PL_strcmp("(a, (null), a)", temp) != 0)
+ testError("List toString is Incorrect");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+ PKIX_TEST_DECREF_BC(outputString);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_InsertItem(list, 1,
+ (PKIX_PL_Object *)list2,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)list,
+ &outputString,
+ plContext));
+
+ temp = PKIX_String2ASCII(outputString, plContext);
+ if (temp) {
+ if (PL_strcmp("(a, (a, (null), a), c, b, c, a)", temp) != 0)
+ testError("List toString is Incorrect");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+ PKIX_TEST_DECREF_BC(outputString);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testDeleteItem(
+ PKIX_List *list,
+ PKIX_List *list2,
+ PKIX_PL_String *testItem2,
+ PKIX_PL_String *testItem3)
+{
+ PKIX_PL_String *outputString = NULL;
+ char *temp = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_DeleteItem(list, 5, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)list,
+ &outputString,
+ plContext));
+
+ temp = PKIX_String2ASCII(outputString, plContext);
+ if (temp) {
+ if (PL_strcmp("(a, (a, (null), a), c, b, c)", temp) != 0)
+ testError("List toString is Incorrect");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+ PKIX_TEST_DECREF_BC(outputString);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_DeleteItem(list, 1, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)list,
+ &outputString,
+ plContext));
+
+ temp = PKIX_String2ASCII(outputString, plContext);
+ if (temp) {
+ if (PL_strcmp("(a, c, b, c)", temp) != 0)
+ testError("List toString is Incorrect");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+ PKIX_TEST_DECREF_BC(outputString);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_DeleteItem(list, 0, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)list,
+ &outputString,
+ plContext));
+
+ temp = PKIX_String2ASCII(outputString, plContext);
+ if (temp) {
+ if (PL_strcmp("(c, b, c)", temp) != 0)
+ testError("List toString is Incorrect");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+ PKIX_TEST_DECREF_BC(outputString);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_DeleteItem(list2, 1, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)list2,
+ &outputString,
+ plContext));
+ temp = PKIX_String2ASCII(outputString, plContext);
+ if (temp) {
+ if (PL_strcmp("(a, a)", temp) != 0)
+ testError("List toString is Incorrect");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+ PKIX_TEST_DECREF_BC(outputString);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(list2,
+ (PKIX_PL_Object *)testItem2,
+ plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)list2,
+ &outputString,
+ plContext));
+
+ temp = PKIX_String2ASCII(outputString, plContext);
+ if (temp) {
+ if (PL_strcmp("(a, a, b)", temp) != 0)
+ testError("List toString is Incorrect");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+ PKIX_TEST_DECREF_BC(outputString);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_DeleteItem(list2, 2, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)list2,
+ &outputString,
+ plContext));
+
+ temp = PKIX_String2ASCII(outputString, plContext);
+ if (temp) {
+ if (PL_strcmp("(a, a)", temp) != 0)
+ testError("List toString is Incorrect");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+ PKIX_TEST_DECREF_BC(outputString);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(list2,
+ (PKIX_PL_Object *)testItem3,
+ plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)list2,
+ &outputString,
+ plContext));
+ temp = PKIX_String2ASCII(outputString, plContext);
+ if (temp) {
+ if (PL_strcmp("(a, a, c)", temp) != 0)
+ testError("List toString is Incorrect");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+ PKIX_TEST_DECREF_BC(outputString);
+
+ PKIX_TEST_DECREF_BC(list2);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+#if testContainsFunction
+/* This test requires pkix_List_Contains to be in nss.def */
+static void
+testContains(void)
+{
+
+ PKIX_List *list;
+ PKIX_PL_String *testItem, *testItem2, *testItem3, *testItem4;
+ char *testItemString = "a";
+ char *testItemString2 = "b";
+ char *testItemString3 = "c";
+ char *testItemString4 = "d";
+ PKIX_Boolean found = PKIX_FALSE;
+
+ PKIX_TEST_STD_VARS();
+ subTest("pkix_ListContains");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII,
+ testItemString,
+ PL_strlen(testItemString),
+ &testItem,
+ plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII,
+ testItemString2,
+ PL_strlen(testItemString2),
+ &testItem2,
+ plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII,
+ testItemString3,
+ PL_strlen(testItemString3),
+ &testItem3,
+ plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII,
+ testItemString4,
+ PL_strlen(testItemString4),
+ &testItem4,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&list, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(list, (PKIX_PL_Object *)testItem, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(list, (PKIX_PL_Object *)testItem2, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(list, (PKIX_PL_Object *)testItem3, plContext));
+
+ subTest("pkix_List_Contains ");
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_List_Contains(list, (PKIX_PL_Object *)testItem4, &found, plContext));
+
+ if (found) {
+ testError("Contains found item that wasn't there!");
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(list, (PKIX_PL_Object *)testItem4, plContext));
+
+ subTest("pkix_List_Contains ");
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_List_Contains(list, (PKIX_PL_Object *)testItem4, &found, plContext));
+
+ if (!found) {
+ testError("Contains missed item that was present!");
+ }
+
+ PKIX_TEST_DECREF_BC(list);
+ PKIX_TEST_DECREF_BC(testItem);
+ PKIX_TEST_DECREF_BC(testItem2);
+ PKIX_TEST_DECREF_BC(testItem3);
+ PKIX_TEST_DECREF_BC(testItem4);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+#endif
+
+static void
+testErrorHandling(void)
+{
+ PKIX_List *emptylist = NULL;
+ PKIX_List *list = NULL;
+ PKIX_PL_Object *tempItem = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&list, plContext));
+
+ PKIX_TEST_EXPECT_ERROR(PKIX_List_GetItem(list, 4, &tempItem, plContext));
+
+ PKIX_TEST_EXPECT_ERROR(PKIX_List_GetItem(list, 1, NULL, plContext));
+ PKIX_TEST_EXPECT_ERROR(PKIX_List_SetItem(list, 4, tempItem, plContext));
+ PKIX_TEST_EXPECT_ERROR(PKIX_List_SetItem(NULL, 1, tempItem, plContext));
+ PKIX_TEST_EXPECT_ERROR(PKIX_List_InsertItem(list, 4, tempItem, plContext));
+
+ PKIX_TEST_EXPECT_ERROR(PKIX_List_InsertItem(NULL, 1, tempItem, plContext));
+
+ PKIX_TEST_EXPECT_ERROR(PKIX_List_AppendItem(NULL, tempItem, plContext));
+ PKIX_TEST_EXPECT_ERROR(PKIX_List_DeleteItem(list, 5, plContext));
+ PKIX_TEST_EXPECT_ERROR(PKIX_List_DeleteItem(NULL, 1, plContext));
+ PKIX_TEST_EXPECT_ERROR(PKIX_List_GetLength(list, NULL, plContext));
+
+ PKIX_TEST_DECREF_BC(list);
+ PKIX_TEST_DECREF_BC(emptylist);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testDestroy(PKIX_List *list)
+{
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_DECREF_BC(list);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+int
+test_list(int argc, char *argv[])
+{
+
+ PKIX_List *list, *list2;
+ PKIX_PL_String *testItem, *testItem2, *testItem3;
+ char *testItemString = "a";
+ char *testItemString2 = "b";
+ char *testItemString3 = "c";
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_UInt32 j = 0;
+
+ PKIX_TEST_STD_VARS();
+
+ startTests("Lists");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ subTest("PKIX_List_Create");
+ createLists(&list, &list2);
+
+ subTest("pkix_List_ReverseList");
+ testReverseList();
+
+ subTest("Zero-length List");
+ testZeroLengthList(list);
+
+ subTest("PKIX_List_Get/SetItem");
+ testGetSetItem(list,
+ testItemString,
+ testItemString2,
+ testItemString3,
+ &testItem,
+ &testItem2,
+ &testItem3);
+
+ subTest("PKIX_List_GetLength");
+ testGetLength(list);
+
+ PKIX_TEST_EQ_HASH_TOSTR_DUP(list,
+ list,
+ list2,
+ "(c, b, c)",
+ List,
+ PKIX_TRUE);
+
+ subTest("PKIX_List_InsertItem");
+ testInsertItem(list, testItem, testItemString);
+
+ subTest("PKIX_List_AppendItem");
+ testAppendItem(list, testItem);
+
+ subTest("Nested Lists");
+ testNestedLists(list, list2, testItem, testItem2);
+
+ subTest("PKIX_List_DeleteItem");
+ testDeleteItem(list, list2, testItem2, testItem3);
+
+ PKIX_TEST_DECREF_BC(testItem);
+ PKIX_TEST_DECREF_BC(testItem2);
+ PKIX_TEST_DECREF_BC(testItem3);
+
+#if testContainsFunction
+ /* This test requires pkix_List_Contains to be in nss.def */
+ testContains();
+#endif
+
+ subTest("PKIX_List Error Handling");
+ testErrorHandling();
+
+ subTest("PKIX_List_Destroy");
+ testDestroy(list);
+
+cleanup:
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("Lists");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/util/test_list2.c b/nss/cmd/libpkix/pkix/util/test_list2.c
new file mode 100644
index 0000000..7e4114e
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/util/test_list2.c
@@ -0,0 +1,120 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_list2.c
+ *
+ * Performs an in-place sort on a list
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+int
+test_list2(int argc, char *argv[])
+{
+
+ PKIX_List *list;
+ char *temp;
+ PKIX_UInt32 i = 0;
+ PKIX_UInt32 j = 0;
+ PKIX_Int32 cmpResult;
+ PKIX_PL_OID *testOID;
+ PKIX_PL_String *testString;
+ PKIX_PL_Object *obj, *obj2;
+ PKIX_UInt32 size = 10;
+ char *testOIDString[10] = {
+ "2.9.999.1.20",
+ "1.2.3.4.5.6.7",
+ "0.1",
+ "1.2.3.5",
+ "0.39",
+ "1.2.3.4.7",
+ "1.2.3.4.6",
+ "0.39.1",
+ "1.2.3.4.5",
+ "0.39.1.300"
+ };
+ PKIX_UInt32 actualMinorVersion;
+
+ PKIX_TEST_STD_VARS();
+
+ startTests("List Sorting");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ subTest("Creating Unsorted Lists");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&list, plContext));
+ for (i = 0; i < size; i++) {
+ /* Create a new OID object */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create(
+ testOIDString[i],
+ &testOID,
+ plContext));
+ /* Insert it into the list */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(list, (PKIX_PL_Object *)testOID, plContext));
+ /* Decref the string object */
+ PKIX_TEST_DECREF_BC(testOID);
+ }
+
+ subTest("Outputting Unsorted List");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)list,
+ &testString,
+ plContext));
+ temp = PKIX_String2ASCII(testString, plContext);
+ if (temp) {
+ (void)printf("%s \n", temp);
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+ PKIX_TEST_DECREF_BC(testString);
+
+ subTest("Performing Bubble Sort");
+
+ for (i = 0; i < size; i++)
+ for (j = 9; j > i; j--) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(list, j, &obj, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(list, j -
+ 1,
+ &obj2, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Compare(obj, obj2, &cmpResult, plContext));
+ if (cmpResult < 0) {
+ /* Exchange the items */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetItem(list, j, obj2, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetItem(list, j -
+ 1,
+ obj, plContext));
+ }
+ /* DecRef objects */
+ PKIX_TEST_DECREF_BC(obj);
+ PKIX_TEST_DECREF_BC(obj2);
+ }
+
+ subTest("Outputting Sorted List");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)list,
+ &testString,
+ plContext));
+ temp = PKIX_String2ASCII(testString, plContext);
+ if (temp) {
+ (void)printf("%s \n", temp);
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(testString);
+ PKIX_TEST_DECREF_AC(list);
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("List Sorting");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix/util/test_logger.c b/nss/cmd/libpkix/pkix/util/test_logger.c
new file mode 100644
index 0000000..3b7e516
--- /dev/null
+++ b/nss/cmd/libpkix/pkix/util/test_logger.c
@@ -0,0 +1,314 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_logger.c
+ *
+ * Tests Logger Objects
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+static char *levels[] = {
+ "None",
+ "Fatal Error",
+ "Error",
+ "Warning",
+ "Debug",
+ "Trace"
+};
+
+static PKIX_Error *
+testLoggerCallback(
+ PKIX_Logger *logger,
+ PKIX_PL_String *message,
+ PKIX_UInt32 logLevel,
+ PKIX_ERRORCLASS logComponent,
+ void *plContext)
+{
+ char *comp = NULL;
+ char *msg = NULL;
+ char result[100];
+ static int callCount = 0;
+
+ PKIX_TEST_STD_VARS();
+
+ msg = PKIX_String2ASCII(message, plContext);
+ PR_snprintf(result, 100, "Logging %s (%s): %s",
+ levels[logLevel], PKIX_ERRORCLASSNAMES[logComponent], msg);
+ subTest(result);
+
+ callCount++;
+ if (callCount > 1) {
+ testError("Incorrect number of Logger Callback ");
+ }
+
+cleanup:
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(msg, plContext));
+ PKIX_TEST_RETURN();
+}
+
+static PKIX_Error *
+testLoggerCallback2(
+ PKIX_Logger *logger,
+ PKIX_PL_String *message,
+ PKIX_UInt32 logLevel,
+ PKIX_ERRORCLASS logComponent,
+ void *plContext)
+{
+ char *comp = NULL;
+ char *msg = NULL;
+ char result[100];
+
+ PKIX_TEST_STD_VARS();
+
+ msg = PKIX_String2ASCII(message, plContext);
+ PR_snprintf(result, 100, "Logging %s (%s): %s",
+ levels[logLevel], PKIX_ERRORCLASSNAMES[logComponent], msg);
+ subTest(result);
+
+cleanup:
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(msg, plContext));
+ PKIX_TEST_RETURN();
+}
+
+static void
+createLogger(PKIX_Logger **logger,
+ PKIX_PL_Object *context,
+ PKIX_Logger_LogCallback cb)
+{
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Logger_Create(cb, context, logger, plContext));
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testContextCallback(PKIX_Logger *logger, PKIX_Logger *logger2)
+{
+ PKIX_Logger_LogCallback cb = NULL;
+ PKIX_PL_Object *context = NULL;
+ PKIX_Boolean cmpResult = PKIX_FALSE;
+ PKIX_UInt32 length;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_Logger_GetLoggerContext");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Logger_GetLoggerContext(logger2, &context, plContext));
+
+ testEqualsHelper((PKIX_PL_Object *)logger, context, PKIX_TRUE, plContext);
+
+ subTest("PKIX_Logger_GetLogCallback");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Logger_GetLogCallback(logger, &cb, plContext));
+
+ if (cb != testLoggerCallback) {
+ testError("Incorrect Logger Callback returned");
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(context);
+ PKIX_TEST_RETURN();
+}
+
+static void
+testComponent(PKIX_Logger *logger)
+{
+ PKIX_ERRORCLASS compName = (PKIX_ERRORCLASS)NULL;
+ PKIX_ERRORCLASS compNameReturn = (PKIX_ERRORCLASS)NULL;
+ PKIX_Boolean cmpResult = PKIX_FALSE;
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_Logger_GetLoggingComponent");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Logger_GetLoggingComponent(logger, &compName, plContext));
+
+ if (compName != (PKIX_ERRORCLASS)NULL) {
+ testError("Incorrect Logger Component returned. expect ");
+ }
+
+ subTest("PKIX_Logger_SetLoggingComponent");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Logger_SetLoggingComponent(logger, PKIX_LIST_ERROR, plContext));
+
+ subTest("PKIX_Logger_GetLoggingComponent");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Logger_GetLoggingComponent(logger, &compNameReturn, plContext));
+
+ if (compNameReturn != PKIX_LIST_ERROR) {
+ testError("Incorrect Logger Component returned.");
+ }
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testMaxLoggingLevel(PKIX_Logger *logger)
+{
+ PKIX_UInt32 level = 0;
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_Logger_GetMaxLoggingLevel");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Logger_GetMaxLoggingLevel(logger, &level, plContext));
+
+ if (level != 0) {
+ testError("Incorrect Logger MaxLoggingLevel returned");
+ }
+
+ subTest("PKIX_Logger_SetMaxLoggingLevel");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Logger_SetMaxLoggingLevel(logger, 3, plContext));
+
+ subTest("PKIX_Logger_GetMaxLoggingLevel");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Logger_GetMaxLoggingLevel(logger, &level, plContext));
+
+ if (level != 3) {
+ testError("Incorrect Logger MaxLoggingLevel returned");
+ }
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testLogger(PKIX_Logger *logger, PKIX_Logger *logger2)
+{
+ PKIX_List *loggerList = NULL;
+ PKIX_List *checkList = NULL;
+ PKIX_UInt32 length;
+ PKIX_Boolean cmpResult = PKIX_FALSE;
+ char *expectedAscii = "[\n"
+ "\tLogger: \n"
+ "\tContext: (null)\n"
+ "\tMaximum Level: 3\n"
+ "\tComponent Name: LIST\n"
+ "]\n";
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_GetLoggers");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_GetLoggers(&loggerList, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(loggerList, &length, plContext));
+ if (length != 0) {
+ testError("Incorrect Logger List returned");
+ }
+ PKIX_TEST_DECREF_BC(loggerList);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&loggerList, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(loggerList, (PKIX_PL_Object *)logger, plContext));
+
+ subTest("PKIX_SetLoggers");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_SetLoggers(loggerList, plContext));
+
+ subTest("PKIX_Logger_SetLoggingComponent");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Logger_SetLoggingComponent(logger2, PKIX_MUTEX_ERROR, plContext));
+
+ subTest("PKIX_Logger_SetMaxLoggingLevel");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_Logger_SetMaxLoggingLevel(logger2, 5, plContext));
+
+ subTest("PKIX_AddLogger");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_AddLogger(logger2, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&checkList, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(checkList, (PKIX_PL_Object *)logger, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(checkList, (PKIX_PL_Object *)logger2, plContext));
+
+ PKIX_TEST_DECREF_BC(loggerList);
+
+ subTest("PKIX_GetLoggers");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_GetLoggers(&loggerList, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(loggerList, &length, plContext));
+
+ subTest("pkix_Loggers_Equals");
+ testEqualsHelper((PKIX_PL_Object *)loggerList,
+ (PKIX_PL_Object *)checkList,
+ PKIX_TRUE,
+ plContext);
+
+ subTest("pkix_Loggers_Duplicate");
+ testDuplicateHelper((PKIX_PL_Object *)logger, plContext);
+
+ subTest("pkix_Loggers_Hashcode");
+ testHashcodeHelper((PKIX_PL_Object *)logger,
+ (PKIX_PL_Object *)logger,
+ PKIX_TRUE,
+ plContext);
+
+ subTest("pkix_Loggers_ToString");
+ testToStringHelper((PKIX_PL_Object *)logger, expectedAscii, plContext);
+
+ subTest("PKIX Logger Callback");
+ subTest("Expect to have ***Fatal Error (List): Null argument*** once");
+ PKIX_TEST_EXPECT_ERROR(PKIX_List_AppendItem(NULL, (PKIX_PL_Object *)NULL, plContext));
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(loggerList);
+ PKIX_TEST_DECREF_AC(checkList);
+ PKIX_TEST_RETURN();
+}
+
+static void
+testDestroy(PKIX_Logger *logger)
+{
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_DECREF_BC(logger);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+}
+
+int
+test_logger(int argc, char *argv[])
+{
+
+ PKIX_Logger *logger, *logger2;
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_UInt32 j = 0;
+
+ PKIX_TEST_STD_VARS();
+
+ startTests("Loggers");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ subTest("PKIX_Logger_Create");
+ createLogger(&logger, NULL, testLoggerCallback);
+ createLogger(&logger2, (PKIX_PL_Object *)logger, testLoggerCallback2);
+
+ subTest("Logger Context and Callback");
+ testContextCallback(logger, logger2);
+
+ subTest("Logger Component");
+ testComponent(logger);
+
+ subTest("Logger MaxLoggingLevel");
+ testMaxLoggingLevel(logger);
+
+ subTest("Logger List operations");
+ testLogger(logger, logger2);
+
+ subTest("PKIX_Logger_Destroy");
+ testDestroy(logger);
+ testDestroy(logger2);
+
+cleanup:
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("Loggers");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix_pl/Makefile b/nss/cmd/libpkix/pkix_pl/Makefile
new file mode 100755
index 0000000..ab4ffbd
--- /dev/null
+++ b/nss/cmd/libpkix/pkix_pl/Makefile
@@ -0,0 +1,48 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(PKIX_DEPTH)/config.mk
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platrules.mk
+
diff --git a/nss/cmd/libpkix/pkix_pl/manifest.mn b/nss/cmd/libpkix/pkix_pl/manifest.mn
new file mode 100755
index 0000000..84997cb
--- /dev/null
+++ b/nss/cmd/libpkix/pkix_pl/manifest.mn
@@ -0,0 +1,11 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+PKIX_DEPTH = ./..
+PLAT_DEPTH = $(PKIX_DEPTH)/..
+CORE_DEPTH = $(PKIX_DEPTH)/../../..
+
+DIRS = module pki system \
+ $(NULL)
diff --git a/nss/cmd/libpkix/pkix_pl/module/Makefile b/nss/cmd/libpkix/pkix_pl/module/Makefile
new file mode 100755
index 0000000..09ca5f1
--- /dev/null
+++ b/nss/cmd/libpkix/pkix_pl/module/Makefile
@@ -0,0 +1,47 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(PKIX_DEPTH)/config.mk
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platrules.mk
diff --git a/nss/cmd/libpkix/pkix_pl/module/manifest.mn b/nss/cmd/libpkix/pkix_pl/module/manifest.mn
new file mode 100755
index 0000000..eedc934
--- /dev/null
+++ b/nss/cmd/libpkix/pkix_pl/module/manifest.mn
@@ -0,0 +1,24 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+PKIX_DEPTH = ../..
+PLAT_DEPTH = $(PKIX_DEPTH)/..
+CORE_DEPTH = $(PKIX_DEPTH)/../../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+CSRCS = test_colcertstore.c \
+ test_ekuchecker.c \
+ test_pk11certstore.c \
+ test_socket.c \
+ test_httpcertstore.c \
+ $(NULL)
+
+LIBRARY_NAME=pkixtoolmodule
+
+SOURCE_LIB_DIR=$(PKIX_DEPTH)/$(OBJDIR)
+
+NO_MD_RELEASE = 1
diff --git a/nss/cmd/libpkix/pkix_pl/module/test_colcertstore.c b/nss/cmd/libpkix/pkix_pl/module/test_colcertstore.c
new file mode 100644
index 0000000..37169d6
--- /dev/null
+++ b/nss/cmd/libpkix/pkix_pl/module/test_colcertstore.c
@@ -0,0 +1,247 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_colcertstore.c
+ *
+ * Test CollectionCertStore Type
+ *
+ */
+
+#include "testutil.h"
+
+#include "testutil_nss.h"
+
+/* When CRL IDP is supported, change NUM_CRLS to 9 */
+#define PKIX_TEST_COLLECTIONCERTSTORE_NUM_CRLS 4
+#define PKIX_TEST_COLLECTIONCERTSTORE_NUM_CERTS 15
+
+static void *plContext = NULL;
+
+static PKIX_Error *
+testCRLSelectorMatchCallback(
+ PKIX_CRLSelector *selector,
+ PKIX_PL_CRL *crl,
+ PKIX_Boolean *pMatch,
+ void *plContext)
+{
+ *pMatch = PKIX_TRUE;
+
+ return (0);
+}
+
+static PKIX_Error *
+testCertSelectorMatchCallback(
+ PKIX_CertSelector *selector,
+ PKIX_PL_Cert *cert,
+ PKIX_Boolean *pResult,
+ void *plContext)
+{
+ *pResult = PKIX_TRUE;
+
+ return (0);
+}
+
+static PKIX_Error *
+getCertCallback(
+ PKIX_CertStore *store,
+ PKIX_CertSelector *certSelector,
+ PKIX_List **pCerts,
+ void *plContext)
+{
+ return (0);
+}
+
+static char *
+catDirName(char *platform, char *dir, void *plContext)
+{
+ char *pathName = NULL;
+ PKIX_UInt32 dirLen;
+ PKIX_UInt32 platformLen;
+
+ PKIX_TEST_STD_VARS();
+
+ dirLen = PL_strlen(dir);
+ platformLen = PL_strlen(platform);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Malloc(platformLen +
+ dirLen +
+ 2,
+ (void **)&pathName, plContext));
+
+ PL_strcpy(pathName, platform);
+ PL_strcat(pathName, "/");
+ PL_strcat(pathName, dir);
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+
+ return (pathName);
+}
+
+static void
+testGetCRL(char *crlDir)
+{
+ PKIX_PL_String *dirString = NULL;
+ PKIX_CertStore_CRLCallback crlCallback;
+ PKIX_CertStore *certStore = NULL;
+ PKIX_CRLSelector *crlSelector = NULL;
+ PKIX_List *crlList = NULL;
+ PKIX_UInt32 numCrl = 0;
+ void *nbioContext = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII,
+ crlDir,
+ 0,
+ &dirString,
+ plContext));
+
+ subTest("PKIX_PL_CollectionCertStore_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CollectionCertStore_Create(dirString,
+ &certStore,
+ plContext));
+
+ subTest("PKIX_CRLSelector_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CRLSelector_Create(testCRLSelectorMatchCallback,
+ NULL,
+ &crlSelector,
+ plContext));
+
+ subTest("PKIX_CertStore_GetCRLCallback");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertStore_GetCRLCallback(certStore, &crlCallback, NULL));
+
+ subTest("Getting data from CRL Callback");
+ PKIX_TEST_EXPECT_NO_ERROR(crlCallback(certStore,
+ crlSelector,
+ &nbioContext,
+ &crlList,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(crlList,
+ &numCrl,
+ plContext));
+
+ if (numCrl != PKIX_TEST_COLLECTIONCERTSTORE_NUM_CRLS) {
+ pkixTestErrorMsg = "unexpected CRL number mismatch";
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(dirString);
+ PKIX_TEST_DECREF_AC(crlList);
+ PKIX_TEST_DECREF_AC(crlSelector);
+ PKIX_TEST_DECREF_AC(certStore);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+testGetCert(char *certDir)
+{
+ PKIX_PL_String *dirString = NULL;
+ PKIX_CertStore_CertCallback certCallback;
+ PKIX_CertStore *certStore = NULL;
+ PKIX_CertSelector *certSelector = NULL;
+ PKIX_List *certList = NULL;
+ PKIX_UInt32 numCert = 0;
+ void *nbioContext = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII,
+ certDir,
+ 0,
+ &dirString,
+ plContext));
+
+ subTest("PKIX_PL_CollectionCertStore_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CollectionCertStore_Create(dirString,
+ &certStore,
+ plContext));
+
+ subTest("PKIX_CertSelector_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(testCertSelectorMatchCallback,
+ NULL,
+ &certSelector,
+ plContext));
+
+ subTest("PKIX_CertStore_GetCertCallback");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertStore_GetCertCallback(certStore, &certCallback, NULL));
+
+ subTest("Getting data from Cert Callback");
+ PKIX_TEST_EXPECT_NO_ERROR(certCallback(certStore,
+ certSelector,
+ &nbioContext,
+ &certList,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certList,
+ &numCert,
+ plContext));
+
+ if (numCert != PKIX_TEST_COLLECTIONCERTSTORE_NUM_CERTS) {
+ pkixTestErrorMsg = "unexpected Cert number mismatch";
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(dirString);
+ PKIX_TEST_DECREF_AC(certList);
+ PKIX_TEST_DECREF_AC(certSelector);
+ PKIX_TEST_DECREF_AC(certStore);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+printUsage(char *pName)
+{
+ printf("\nUSAGE: %s test-purpose \n\n", pName);
+}
+
+/* Functional tests for CollectionCertStore public functions */
+
+int
+test_colcertstore(int argc, char *argv[])
+{
+
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_UInt32 j = 0;
+ char *platformDir = NULL;
+ char *dataDir = NULL;
+ char *combinedDir = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ startTests("CollectionCertStore");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ if (argc < (3 + j)) {
+ printUsage(argv[0]);
+ return (0);
+ }
+
+ dataDir = argv[2 + j];
+ platformDir = argv[3 + j];
+ combinedDir = catDirName(platformDir, dataDir, plContext);
+
+ testGetCRL(combinedDir);
+ testGetCert(combinedDir);
+
+cleanup:
+
+ pkixTestErrorResult = PKIX_PL_Free(combinedDir, plContext);
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("CollectionCertStore");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix_pl/module/test_ekuchecker.c b/nss/cmd/libpkix/pkix_pl/module/test_ekuchecker.c
new file mode 100644
index 0000000..ccd05a5
--- /dev/null
+++ b/nss/cmd/libpkix/pkix_pl/module/test_ekuchecker.c
@@ -0,0 +1,275 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_ekuchecker.c
+ *
+ * Test Extend Key Usage Checker
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+#define PKIX_TEST_MAX_CERTS 10
+
+static void *plContext = NULL;
+
+static void
+printUsage1(char *pName)
+{
+ printf("\nUSAGE: %s test-purpose [ENE|EE] ", pName);
+ printf("[E]oid[,oid]* cert [certs].\n");
+}
+
+static void
+printUsageMax(PKIX_UInt32 numCerts)
+{
+ printf("\nUSAGE ERROR: number of certs %d exceed maximum %d\n",
+ numCerts, PKIX_TEST_MAX_CERTS);
+}
+
+static PKIX_Error *
+testCertSelectorMatchCallback(
+ PKIX_CertSelector *selector,
+ PKIX_PL_Cert *cert,
+ PKIX_Boolean *pResult,
+ void *plContext)
+{
+ *pResult = PKIX_TRUE;
+
+ return (0);
+}
+
+static PKIX_Error *
+testEkuSetup(
+ PKIX_ValidateParams *valParams,
+ char *ekuOidString,
+ PKIX_Boolean *only4EE)
+{
+ PKIX_ProcessingParams *procParams = NULL;
+ PKIX_List *ekuList = NULL;
+ PKIX_PL_OID *ekuOid = NULL;
+ PKIX_ComCertSelParams *selParams = NULL;
+ PKIX_CertSelector *certSelector = NULL;
+ PKIX_Boolean last_token = PKIX_FALSE;
+ PKIX_UInt32 i, tokeni;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("PKIX_ValidateParams_GetProcessingParams");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateParams_GetProcessingParams(valParams, &procParams, plContext));
+
+ /* Get extended key usage OID(s) from command line, separated by "," */
+
+ if (ekuOidString[0] == '"') {
+ /* erase doble quotes, if any */
+ i = 1;
+ while (ekuOidString[i] != '"' && ekuOidString[i] != '\0') {
+ ekuOidString[i - 1] = ekuOidString[i];
+ i++;
+ }
+ ekuOidString[i - 1] = '\0';
+ }
+
+ if (ekuOidString[0] == '\0') {
+ ekuList = NULL;
+ } else {
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&ekuList, plContext));
+
+ /* if OID string start with E, only check for last cert */
+ if (ekuOidString[0] == 'E') {
+ *only4EE = PKIX_TRUE;
+ tokeni = 2;
+ i = 1;
+ } else {
+ *only4EE = PKIX_FALSE;
+ tokeni = 1;
+ i = 0;
+ }
+
+ while (last_token != PKIX_TRUE) {
+ while (ekuOidString[tokeni] != ',' &&
+ ekuOidString[tokeni] != '\0') {
+ tokeni++;
+ }
+ if (ekuOidString[tokeni] == '\0') {
+ last_token = PKIX_TRUE;
+ } else {
+ ekuOidString[tokeni] = '\0';
+ tokeni++;
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create(&ekuOidString[i], &ekuOid, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(ekuList, (PKIX_PL_Object *)ekuOid, plContext));
+
+ PKIX_TEST_DECREF_BC(ekuOid);
+ i = tokeni;
+ }
+ }
+
+ /* Set extended key usage link to processing params */
+
+ subTest("PKIX_ComCertSelParams_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&selParams, plContext));
+
+ subTest("PKIX_ComCertSelParams_SetExtendedKeyUsage");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetExtendedKeyUsage(selParams, ekuList, plContext));
+
+ subTest("PKIX_CertSelector_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(testCertSelectorMatchCallback,
+ NULL,
+ &certSelector,
+ plContext));
+
+ subTest("PKIX_CertSelector_SetCommonCertSelectorParams");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, selParams, plContext));
+
+ subTest("PKIX_ProcessingParams_SetTargetCertConstraints");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetTargetCertConstraints(procParams, certSelector, plContext));
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(selParams);
+ PKIX_TEST_DECREF_AC(certSelector);
+ PKIX_TEST_DECREF_AC(procParams);
+ PKIX_TEST_DECREF_AC(ekuOid);
+ PKIX_TEST_DECREF_AC(ekuList);
+
+ PKIX_TEST_RETURN();
+
+ return (0);
+}
+
+static PKIX_Error *
+testEkuChecker(
+ PKIX_ValidateParams *valParams,
+ PKIX_Boolean only4EE)
+{
+ PKIX_ProcessingParams *procParams = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateParams_GetProcessingParams(valParams, &procParams, plContext));
+
+ subTest("PKIX_ProcessingParams_SetRevocationEnabled - disable");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetRevocationEnabled(procParams, PKIX_FALSE, plContext));
+
+ if (only4EE == PKIX_FALSE) {
+ subTest("PKIX_PL_EkuChecker_Create");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_EkuChecker_Create(procParams, plContext));
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(procParams);
+
+ PKIX_TEST_RETURN();
+
+ return (0);
+}
+
+int
+test_ekuchecker(int argc, char *argv[])
+{
+ PKIX_List *chain = NULL;
+ PKIX_ValidateParams *valParams = NULL;
+ PKIX_ValidateResult *valResult = NULL;
+ PKIX_UInt32 actualMinorVersion;
+ char *certNames[PKIX_TEST_MAX_CERTS];
+ char *dirName = NULL;
+ PKIX_PL_Cert *certs[PKIX_TEST_MAX_CERTS];
+ PKIX_UInt32 chainLength = 0;
+ PKIX_UInt32 i = 0;
+ PKIX_UInt32 j = 0;
+ PKIX_Boolean testValid = PKIX_FALSE;
+ PKIX_Boolean only4EE = PKIX_FALSE;
+
+ PKIX_TEST_STD_VARS();
+
+ if (argc < 5) {
+ printUsage1(argv[0]);
+ return (0);
+ }
+
+ startTests("EKU Checker");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ /* ENE = expect no error; EE = expect error */
+ if (PORT_Strcmp(argv[2 + j], "ENE") == 0) {
+ testValid = PKIX_TRUE;
+ } else if (PORT_Strcmp(argv[2 + j], "EE") == 0) {
+ testValid = PKIX_FALSE;
+ } else {
+ printUsage1(argv[0]);
+ return (0);
+ }
+
+ dirName = argv[4 + j];
+
+ chainLength = (argc - j) - 6;
+ if (chainLength > PKIX_TEST_MAX_CERTS) {
+ printUsageMax(chainLength);
+ }
+
+ for (i = 0; i < chainLength; i++) {
+
+ certNames[i] = argv[6 + i + j];
+ certs[i] = NULL;
+ }
+
+ subTest(argv[1 + j]);
+
+ subTest("Extended-Key-Usage-Checker");
+
+ subTest("Extended-Key-Usage-Checker - Create Cert Chain");
+
+ chain = createCertChainPlus(dirName, certNames, certs, chainLength, plContext);
+
+ subTest("Extended-Key-Usage-Checker - Create Params");
+
+ valParams = createValidateParams(dirName,
+ argv[5 +
+ j],
+ NULL,
+ NULL,
+ NULL,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ PKIX_FALSE,
+ chain,
+ plContext);
+
+ subTest("Default CertStore");
+
+ testEkuSetup(valParams, argv[3 + j], &only4EE);
+
+ testEkuChecker(valParams, only4EE);
+
+ subTest("Extended-Key-Usage-Checker - Validate Chain");
+
+ if (testValid == PKIX_TRUE) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateChain(valParams, &valResult, NULL, plContext));
+ } else {
+ PKIX_TEST_EXPECT_ERROR(PKIX_ValidateChain(valParams, &valResult, NULL, plContext));
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(chain);
+ PKIX_TEST_DECREF_AC(valParams);
+ PKIX_TEST_DECREF_AC(valResult);
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("EKU Checker");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix_pl/module/test_httpcertstore.c b/nss/cmd/libpkix/pkix_pl/module/test_httpcertstore.c
new file mode 100644
index 0000000..62f8630
--- /dev/null
+++ b/nss/cmd/libpkix/pkix_pl/module/test_httpcertstore.c
@@ -0,0 +1,300 @@
+/*
+ * test_httpcertstore.c
+ *
+ * Test Httpcertstore Type
+ *
+ * Copyright 2004-2005 Sun Microsystems, Inc. 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. Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistribution 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.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
+ * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
+ * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use in
+ * the design, construction, operation or maintenance of any nuclear facility.
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+#include "pkix_pl_common.h"
+
+static void *plContext = NULL;
+
+static void
+printUsage(char *testname)
+{
+ char *fmt =
+ "USAGE: %s [-arenas] certDir certName\n";
+ printf(fmt, "test_httpcertstore");
+}
+
+/* Functional tests for Socket public functions */
+static void
+do_other_work(void)
+{ /* while waiting for nonblocking I/O to complete */
+ (void)PR_Sleep(2 * 60);
+}
+
+PKIX_Error *
+PKIX_PL_HttpCertStore_Create(
+ PKIX_PL_HttpClient *client, /* if NULL, use default Client */
+ PKIX_PL_GeneralName *location,
+ PKIX_CertStore **pCertStore,
+ void *plContext);
+
+PKIX_Error *
+pkix_pl_HttpCertStore_CreateWithAsciiName(
+ PKIX_PL_HttpClient *client, /* if NULL, use default Client */
+ char *location,
+ PKIX_CertStore **pCertStore,
+ void *plContext);
+
+static PKIX_Error *
+getLocation(
+ PKIX_PL_Cert *certWithAia,
+ PKIX_PL_GeneralName **pLocation,
+ void *plContext)
+{
+ PKIX_List *aiaList = NULL;
+ PKIX_UInt32 size = 0;
+ PKIX_PL_InfoAccess *aia = NULL;
+ PKIX_UInt32 iaType = PKIX_INFOACCESS_LOCATION_UNKNOWN;
+ PKIX_PL_GeneralName *location = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("Getting Authority Info Access");
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetAuthorityInfoAccess(certWithAia, &aiaList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(aiaList, &size, plContext));
+
+ if (size != 1) {
+ pkixTestErrorMsg = "unexpected number of AIA";
+ goto cleanup;
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(aiaList, 0, (PKIX_PL_Object **)&aia, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_InfoAccess_GetLocationType(aia, &iaType, plContext));
+
+ if (iaType != PKIX_INFOACCESS_LOCATION_HTTP) {
+ pkixTestErrorMsg = "unexpected location type in AIA";
+ goto cleanup;
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_InfoAccess_GetLocation(aia, &location, plContext));
+
+ *pLocation = location;
+
+cleanup:
+ PKIX_TEST_DECREF_AC(aiaList);
+ PKIX_TEST_DECREF_AC(aia);
+
+ PKIX_TEST_RETURN();
+
+ return (NULL);
+}
+
+int
+test_httpcertstore(int argc, char *argv[])
+{
+
+ PKIX_UInt32 i = 0;
+ PKIX_UInt32 numCerts = 0;
+ PKIX_UInt32 numCrls = 0;
+ int j = 0;
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_UInt32 length = 0;
+
+ char *certName = NULL;
+ char *certDir = NULL;
+ PKIX_PL_Cert *cmdLineCert = NULL;
+ PKIX_PL_Cert *cert = NULL;
+ PKIX_CertSelector *certSelector = NULL;
+ PKIX_CertStore *certStore = NULL;
+ PKIX_CertStore *crlStore = NULL;
+ PKIX_PL_GeneralName *location = NULL;
+ PKIX_CertStore_CertCallback getCerts = NULL;
+ PKIX_List *certs = NULL;
+ char *asciiResult = NULL;
+ void *nbio = NULL;
+
+ PKIX_PL_CRL *crl = NULL;
+ PKIX_CRLSelector *crlSelector = NULL;
+ char *crlLocation = "http://betty.nist.gov/pathdiscoverytestsuite/CRL"
+ "files/BasicHTTPURIPeer2CACRL.crl";
+ PKIX_CertStore_CRLCallback getCrls = NULL;
+ PKIX_List *crls = NULL;
+ PKIX_PL_String *crlString = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ startTests("HttpCertStore");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ if (argc != (j + 3)) {
+ printUsage(argv[0]);
+ pkixTestErrorMsg = "Missing command line argument.";
+ goto cleanup;
+ }
+
+ certDir = argv[++j];
+ certName = argv[++j];
+
+ cmdLineCert = createCert(certDir, certName, plContext);
+ if (cmdLineCert == NULL) {
+ pkixTestErrorMsg = "Unable to create Cert";
+ goto cleanup;
+ }
+
+ /* muster arguments to create HttpCertStore */
+ PKIX_TEST_EXPECT_NO_ERROR(getLocation(cmdLineCert, &location, plContext));
+
+ if (location == NULL) {
+ pkixTestErrorMsg = "Give me a cert with an HTTP URI!";
+ goto cleanup;
+ }
+
+ /* create HttpCertStore */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_HttpCertStore_Create(NULL, location, &certStore, plContext));
+
+ /* get the GetCerts callback */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertStore_GetCertCallback(certStore, &getCerts, plContext));
+
+ /* create a CertSelector */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext));
+
+ /* Get the certs */
+ PKIX_TEST_EXPECT_NO_ERROR(getCerts(certStore, certSelector, &nbio, &certs, plContext));
+
+ while (nbio != NULL) {
+ /* poll for a completion */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertStore_CertContinue(certStore, certSelector, &nbio, &certs, plContext));
+ }
+
+ if (certs) {
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certs, &numCerts, plContext));
+
+ if (numCerts == 0) {
+ printf("HttpCertStore returned an empty Cert list\n");
+ goto cleanup;
+ }
+
+ for (i = 0; i < numCerts; i++) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(certs,
+ i,
+ (PKIX_PL_Object **)&cert,
+ plContext));
+
+ asciiResult = PKIX_Cert2ASCII(cert);
+
+ printf("CERT[%d]:\n%s\n", i, asciiResult);
+
+ /* PKIX_Cert2ASCII used PKIX_PL_Malloc(...,,NULL) */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(asciiResult, NULL));
+ asciiResult = NULL;
+
+ PKIX_TEST_DECREF_BC(cert);
+ }
+ } else {
+ printf("HttpCertStore returned a NULL Cert list\n");
+ }
+
+ /* create HttpCertStore */
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_pl_HttpCertStore_CreateWithAsciiName(NULL, crlLocation, &crlStore, plContext));
+
+ /* get the GetCrls callback */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertStore_GetCRLCallback(crlStore, &getCrls, plContext));
+
+ /* create a CrlSelector */
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CRLSelector_Create(NULL, NULL, &crlSelector, plContext));
+
+ /* Get the crls */
+ PKIX_TEST_EXPECT_NO_ERROR(getCrls(crlStore, crlSelector, &nbio, &crls, plContext));
+
+ while (nbio != NULL) {
+ /* poll for a completion */
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertStore_CrlContinue(crlStore, crlSelector, &nbio, &crls, plContext));
+ }
+
+ if (crls) {
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(crls, &numCrls, plContext));
+
+ if (numCrls == 0) {
+ printf("HttpCertStore returned an empty CRL list\n");
+ goto cleanup;
+ }
+
+ for (i = 0; i < numCrls; i++) {
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(crls,
+ i,
+ (PKIX_PL_Object **)&crl,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString(
+ (PKIX_PL_Object *)crl,
+ &crlString,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_GetEncoded(crlString,
+ PKIX_ESCASCII,
+ (void **)&asciiResult,
+ &length,
+ plContext));
+
+ printf("CRL[%d]:\n%s\n", i, asciiResult);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(asciiResult, plContext));
+ PKIX_TEST_DECREF_BC(crlString);
+ PKIX_TEST_DECREF_BC(crl);
+ }
+ } else {
+ printf("HttpCertStore returned a NULL CRL list\n");
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(cert);
+ PKIX_TEST_DECREF_AC(cmdLineCert);
+ PKIX_TEST_DECREF_AC(certStore);
+ PKIX_TEST_DECREF_AC(crlStore);
+ PKIX_TEST_DECREF_AC(location);
+ PKIX_TEST_DECREF_AC(certs);
+ PKIX_TEST_DECREF_AC(crl);
+ PKIX_TEST_DECREF_AC(crlString);
+ PKIX_TEST_DECREF_AC(crls);
+
+ PKIX_TEST_RETURN();
+
+ endTests("HttpDefaultClient");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix_pl/module/test_pk11certstore.c b/nss/cmd/libpkix/pkix_pl/module/test_pk11certstore.c
new file mode 100644
index 0000000..58fceb1
--- /dev/null
+++ b/nss/cmd/libpkix/pkix_pl/module/test_pk11certstore.c
@@ -0,0 +1,580 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_pk11certstore.c
+ *
+ * Test Pk11CertStore Type
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+/*
+ * This function creates a certSelector with ComCertSelParams set up to
+ * select entries whose Subject Name matches that in the given Cert and
+ * whose validity window includes the Date specified by "validityDate".
+ */
+static void
+test_makeSubjectCertSelector(
+ PKIX_PL_Cert *certNameToMatch,
+ PKIX_PL_Date *validityDate,
+ PKIX_CertSelector **pSelector,
+ void *plContext)
+{
+ PKIX_CertSelector *selector = NULL;
+ PKIX_ComCertSelParams *subjParams = NULL;
+ PKIX_PL_X500Name *subjectName = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &selector, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&subjParams, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetSubject(certNameToMatch, &subjectName, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetSubject(subjParams, subjectName, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetCertificateValid(subjParams, validityDate, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, subjParams, plContext));
+ *pSelector = selector;
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(subjParams);
+ PKIX_TEST_DECREF_AC(subjectName);
+
+ PKIX_TEST_RETURN();
+}
+
+/*
+ * This function creates a certSelector with ComCertSelParams set up to
+ * select entries containing a Basic Constraints extension with a path
+ * length of at least the specified "minPathLength".
+ */
+static void
+test_makePathCertSelector(
+ PKIX_Int32 minPathLength,
+ PKIX_CertSelector **pSelector,
+ void *plContext)
+{
+ PKIX_CertSelector *selector = NULL;
+ PKIX_ComCertSelParams *pathParams = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create(NULL, NULL, &selector, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&pathParams, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetBasicConstraints(pathParams, minPathLength, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams(selector, pathParams, plContext));
+ *pSelector = selector;
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(pathParams);
+
+ PKIX_TEST_RETURN();
+}
+
+/*
+ * This function reads a directory-file cert specified by "desiredSubjectCert",
+ * and decodes the SubjectName. It uses that name to set up the CertSelector
+ * for a Subject Name match, and then queries the database for matching entries.
+ * It is intended to test a "smart" database query.
+ */
+static void
+testMatchCertSubject(
+ char *crlDir,
+ char *desiredSubjectCert,
+ char *expectedAscii,
+ PKIX_PL_Date *validityDate,
+ void *plContext)
+{
+ PKIX_UInt32 numCert = 0;
+ PKIX_PL_Cert *certWithDesiredSubject = NULL;
+ PKIX_CertStore *certStore = NULL;
+ PKIX_CertSelector *certSelector = NULL;
+ PKIX_List *certList = NULL;
+ PKIX_CertStore_CertCallback getCert = NULL;
+ void *nbioContext = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ certWithDesiredSubject = createCert(crlDir, desiredSubjectCert, plContext);
+
+ test_makeSubjectCertSelector(certWithDesiredSubject,
+ validityDate,
+ &certSelector,
+ plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Pk11CertStore_Create(&certStore, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertStore_GetCertCallback(certStore, &getCert, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(getCert(certStore,
+ certSelector,
+ &nbioContext,
+ &certList,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(certList, &numCert, plContext));
+
+ if (numCert > 0) {
+ /* List should be immutable */
+ PKIX_TEST_EXPECT_ERROR(PKIX_List_DeleteItem(certList, 0, plContext));
+ }
+
+ if (expectedAscii) {
+ testToStringHelper((PKIX_PL_Object *)certList, expectedAscii, plContext);
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(certWithDesiredSubject);
+ PKIX_TEST_DECREF_AC(certStore);
+ PKIX_TEST_DECREF_AC(certSelector);
+ PKIX_TEST_DECREF_AC(certList);
+
+ PKIX_TEST_RETURN();
+}
+
+/*
+ * This function uses the minimum path length specified by "minPath" to set up
+ * a CertSelector for a BasicConstraints match, and then queries the database
+ * for matching entries. It is intended to test the case where there
+ * is no "smart" database query, so the database will be asked for all
+ * available certs and the filtering will be done by the interaction of the
+ * certstore and the selector.
+ */
+static void
+testMatchCertMinPath(
+ PKIX_Int32 minPath,
+ char *expectedAscii,
+ void *plContext)
+{
+ PKIX_CertStore *certStore = NULL;
+ PKIX_CertSelector *certSelector = NULL;
+ PKIX_List *certList = NULL;
+ PKIX_CertStore_CertCallback getCert = NULL;
+ void *nbioContext = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("Searching Certs for minPath");
+
+ test_makePathCertSelector(minPath, &certSelector, plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Pk11CertStore_Create(&certStore, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertStore_GetCertCallback(certStore, &getCert, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(getCert(certStore,
+ certSelector,
+ &nbioContext,
+ &certList,
+ plContext));
+
+ if (expectedAscii) {
+ testToStringHelper((PKIX_PL_Object *)certList, expectedAscii, plContext);
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(certStore);
+ PKIX_TEST_DECREF_AC(certSelector);
+ PKIX_TEST_DECREF_AC(certList);
+
+ PKIX_TEST_RETURN();
+}
+
+/*
+ * This function creates a crlSelector with ComCrlSelParams set up to
+ * select entries whose Issuer Name matches that in the given Crl.
+ */
+static void
+test_makeIssuerCRLSelector(
+ PKIX_PL_CRL *crlNameToMatch,
+ PKIX_CRLSelector **pSelector,
+ void *plContext)
+{
+ PKIX_CRLSelector *selector = NULL;
+ PKIX_ComCRLSelParams *issuerParams = NULL;
+ PKIX_PL_X500Name *issuerName = NULL;
+ PKIX_List *names = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CRLSelector_Create(NULL, NULL, &selector, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_Create(&issuerParams, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CRL_GetIssuer(crlNameToMatch, &issuerName, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&names, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(names, (PKIX_PL_Object *)issuerName, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_SetIssuerNames(issuerParams, names, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CRLSelector_SetCommonCRLSelectorParams(selector, issuerParams, plContext));
+ *pSelector = selector;
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(issuerParams);
+ PKIX_TEST_DECREF_AC(issuerName);
+ PKIX_TEST_DECREF_AC(names);
+
+ PKIX_TEST_RETURN();
+}
+
+/*
+ * This function creates a crlSelector with ComCrlSelParams set up to
+ * select entries that would be valid at the Date specified by the Date
+ * criterion.
+ */
+static void
+test_makeDateCRLSelector(
+ PKIX_PL_Date *dateToMatch,
+ PKIX_CRLSelector **pSelector,
+ void *plContext)
+{
+ PKIX_CRLSelector *selector = NULL;
+ PKIX_ComCRLSelParams *dateParams = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CRLSelector_Create(NULL, NULL, &selector, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_Create(&dateParams, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCRLSelParams_SetDateAndTime(dateParams, dateToMatch, plContext));
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CRLSelector_SetCommonCRLSelectorParams(selector, dateParams, plContext));
+ *pSelector = selector;
+
+cleanup:
+ PKIX_TEST_DECREF_AC(dateParams);
+
+ PKIX_TEST_RETURN();
+}
+
+/*
+ * This function reads a directory-file crl specified by "desiredIssuerCrl",
+ * and decodes the IssuerName. It uses that name to set up the CrlSelector
+ * for a Issuer Name match, and then queries the database for matching entries.
+ * It is intended to test the case of a "smart" database query.
+ */
+static void
+testMatchCrlIssuer(
+ char *crlDir,
+ char *desiredIssuerCrl,
+ char *expectedAscii,
+ void *plContext)
+{
+ PKIX_UInt32 numCrl = 0;
+ PKIX_PL_CRL *crlWithDesiredIssuer = NULL;
+ PKIX_CertStore *crlStore = NULL;
+ PKIX_CRLSelector *crlSelector = NULL;
+ PKIX_List *crlList = NULL;
+ PKIX_CertStore_CRLCallback getCrl = NULL;
+ void *nbioContext = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("Searching CRLs for matching Issuer");
+
+ crlWithDesiredIssuer = createCRL(crlDir, desiredIssuerCrl, plContext);
+
+ test_makeIssuerCRLSelector(crlWithDesiredIssuer, &crlSelector, plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Pk11CertStore_Create(&crlStore, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertStore_GetCRLCallback(crlStore, &getCrl, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(getCrl(crlStore,
+ crlSelector,
+ &nbioContext,
+ &crlList,
+ plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(crlList, &numCrl, plContext));
+
+ if (numCrl > 0) {
+ /* List should be immutable */
+ PKIX_TEST_EXPECT_ERROR(PKIX_List_DeleteItem(crlList, 0, plContext));
+ }
+
+ if (expectedAscii) {
+ testToStringHelper((PKIX_PL_Object *)crlList, expectedAscii, plContext);
+ }
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(crlWithDesiredIssuer);
+ PKIX_TEST_DECREF_AC(crlStore);
+ PKIX_TEST_DECREF_AC(crlSelector);
+ PKIX_TEST_DECREF_AC(crlList);
+
+ PKIX_TEST_RETURN();
+}
+
+/*
+ * This function uses the date specified by "matchDate" to set up the
+ * CrlSelector for a Date match. It is intended to test the case where there
+ * is no "smart" database query, so the CertStore should throw an error
+ * rather than ask the database for all available CRLs and then filter the
+ * results using the selector.
+ */
+static void
+testMatchCrlDate(
+ char *dateMatch,
+ char *expectedAscii,
+ void *plContext)
+{
+ PKIX_PL_Date *dateCriterion = NULL;
+ PKIX_CertStore *crlStore = NULL;
+ PKIX_CRLSelector *crlSelector = NULL;
+ PKIX_List *crlList = NULL;
+ PKIX_CertStore_CRLCallback getCrl = NULL;
+
+ PKIX_TEST_STD_VARS();
+
+ subTest("Searching CRLs for matching Date");
+
+ dateCriterion = createDate(dateMatch, plContext);
+ test_makeDateCRLSelector(dateCriterion, &crlSelector, plContext);
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Pk11CertStore_Create(&crlStore, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertStore_GetCRLCallback(crlStore, &getCrl, plContext));
+
+ PKIX_TEST_EXPECT_ERROR(getCrl(crlStore, crlSelector, NULL, &crlList, plContext));
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(dateCriterion);
+ PKIX_TEST_DECREF_AC(crlStore);
+ PKIX_TEST_DECREF_AC(crlSelector);
+ PKIX_TEST_DECREF_AC(crlList);
+
+ PKIX_TEST_RETURN();
+}
+
+static void
+printUsage(char *pName)
+{
+ printf("\nUSAGE: %s <-d data-dir> \n\n", pName);
+}
+
+/* Functional tests for Pk11CertStore public functions */
+
+int
+test_pk11certstore(int argc, char *argv[])
+{
+
+ PKIX_UInt32 j = 0;
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_PL_Date *validityDate = NULL;
+ PKIX_PL_Date *betweenDate = NULL;
+ char *crlDir = NULL;
+ char *expectedProfAscii = "([\n"
+ "\tVersion: v3\n"
+ "\tSerialNumber: 00ca\n"
+ "\tIssuer: CN=chemistry,O=mit,C=us\n"
+ "\tSubject: CN=prof noall,O=mit,C=us\n"
+ "\tValidity: [From: Fri Feb 11 14:14:06 2005\n"
+ "\t To: Mon Jan 18, 2105]\n"
+ "\tSubjectAltNames: (null)\n"
+ "\tAuthorityKeyId: (null)\n"
+ "\tSubjectKeyId: (null)\n"
+ "\tSubjPubKeyAlgId: ANSI X9.57 DSA Signature\n"
+ "\tCritExtOIDs: (2.5.29.15, 2.5.29.19)\n"
+ "\tExtKeyUsages: (null)\n"
+ "\tBasicConstraint: CA(6)\n"
+ "\tCertPolicyInfo: (null)\n"
+ "\tPolicyMappings: (null)\n"
+ "\tExplicitPolicy: -1\n"
+ "\tInhibitMapping: -1\n"
+ "\tInhibitAnyPolicy:-1\n"
+ "\tNameConstraints: (null)\n"
+ "]\n"
+ ", [\n"
+ "\tVersion: v3\n"
+ "\tSerialNumber: 03\n"
+ "\tIssuer: CN=physics,O=mit,C=us\n"
+ "\tSubject: CN=prof noall,O=mit,C=us\n"
+ "\tValidity: [From: Fri Feb 11 12:52:26 2005\n"
+ "\t To: Mon Jan 18, 2105]\n"
+ "\tSubjectAltNames: (null)\n"
+ "\tAuthorityKeyId: (null)\n"
+ "\tSubjectKeyId: (null)\n"
+ "\tSubjPubKeyAlgId: ANSI X9.57 DSA Signature\n"
+ "\tCritExtOIDs: (2.5.29.15, 2.5.29.19)\n"
+ "\tExtKeyUsages: (null)\n"
+ "\tBasicConstraint: CA(0)\n"
+ "\tCertPolicyInfo: (null)\n"
+ "\tPolicyMappings: (null)\n"
+ "\tExplicitPolicy: -1\n"
+ "\tInhibitMapping: -1\n"
+ "\tInhibitAnyPolicy:-1\n"
+ "\tNameConstraints: (null)\n"
+ "]\n"
+ ")";
+ char *expectedValidityAscii = "([\n"
+ "\tVersion: v3\n"
+ "\tSerialNumber: 03\n"
+ "\tIssuer: CN=physics,O=mit,C=us\n"
+ "\tSubject: CN=prof noall,O=mit,C=us\n"
+ "\tValidity: [From: Fri Feb 11 12:52:26 2005\n"
+ "\t To: Mon Jan 18, 2105]\n"
+ "\tSubjectAltNames: (null)\n"
+ "\tAuthorityKeyId: (null)\n"
+ "\tSubjectKeyId: (null)\n"
+ "\tSubjPubKeyAlgId: ANSI X9.57 DSA Signature\n"
+ "\tCritExtOIDs: (2.5.29.15, 2.5.29.19)\n"
+ "\tExtKeyUsages: (null)\n"
+ "\tBasicConstraint: CA(0)\n"
+ "\tCertPolicyInfo: (null)\n"
+ "\tPolicyMappings: (null)\n"
+ "\tExplicitPolicy: -1\n"
+ "\tInhibitMapping: -1\n"
+ "\tInhibitAnyPolicy:-1\n"
+ "\tNameConstraints: (null)\n"
+ "]\n"
+ ")";
+ char *expectedMinPathAscii = "([\n"
+ "\tVersion: v3\n"
+ "\tSerialNumber: 01\n"
+ "\tIssuer: CN=science,O=mit,C=us\n"
+ "\tSubject: CN=science,O=mit,C=us\n"
+ "\tValidity: [From: Fri Feb 11 12:47:58 2005\n"
+ "\t To: Mon Jan 18, 2105]\n"
+ "\tSubjectAltNames: (null)\n"
+ "\tAuthorityKeyId: (null)\n"
+ "\tSubjectKeyId: (null)\n"
+ "\tSubjPubKeyAlgId: ANSI X9.57 DSA Signature\n"
+ "\tCritExtOIDs: (2.5.29.15, 2.5.29.19)\n"
+ "\tExtKeyUsages: (null)\n"
+ "\tBasicConstraint: CA(10)\n"
+ "\tCertPolicyInfo: (null)\n"
+ "\tPolicyMappings: (null)\n"
+ "\tExplicitPolicy: -1\n"
+ "\tInhibitMapping: -1\n"
+ "\tInhibitAnyPolicy:-1\n"
+ "\tNameConstraints: (null)\n"
+ "]\n"
+ ")";
+ char *expectedIssuerAscii = "([\n"
+ "\tVersion: v2\n"
+ "\tIssuer: CN=physics,O=mit,C=us\n"
+ "\tUpdate: [Last: Fri Feb 11 13:51:38 2005\n"
+ "\t Next: Mon Jan 18, 2105]\n"
+ "\tSignatureAlgId: 1.2.840.10040.4.3\n"
+ "\tCRL Number : (null)\n"
+ "\n"
+ "\tEntry List: (\n"
+ "\t[\n"
+ "\tSerialNumber: 67\n"
+ "\tReasonCode: 257\n"
+ "\tRevocationDate: Fri Feb 11 13:51:38 2005\n"
+ "\tCritExtOIDs: (EMPTY)\n"
+ "\t]\n"
+ "\t)\n"
+ "\n"
+ "\tCritExtOIDs: (EMPTY)\n"
+ "]\n"
+ ")";
+ char *expectedDateAscii = "([\n"
+ "\tVersion: v2\n"
+ "\tIssuer: CN=science,O=mit,C=us\n"
+ "\tUpdate: [Last: Fri Feb 11 13:34:40 2005\n"
+ "\t Next: Mon Jan 18, 2105]\n"
+ "\tSignatureAlgId: 1.2.840.10040.4.3\n"
+ "\tCRL Number : (null)\n"
+ "\n"
+ "\tEntry List: (\n"
+ "\t[\n"
+ "\tSerialNumber: 65\n"
+ "\tReasonCode: 260\n"
+ "\tRevocationDate: Fri Feb 11 13:34:40 2005\n"
+ "\tCritExtOIDs: (EMPTY)\n"
+ "\t]\n"
+ "\t)\n"
+ "\n"
+ "\tCritExtOIDs: (EMPTY)\n"
+ "]\n"
+ ", [\n"
+ "\tVersion: v2\n"
+ "\tIssuer: CN=testing CRL,O=test,C=us\n"
+ "\tUpdate: [Last: Fri Feb 11 13:14:38 2005\n"
+ "\t Next: Mon Jan 18, 2105]\n"
+ "\tSignatureAlgId: 1.2.840.10040.4.3\n"
+ "\tCRL Number : (null)\n"
+ "\n"
+ "\tEntry List: (\n"
+ "\t[\n"
+ "\tSerialNumber: 67\n"
+ "\tReasonCode: 258\n"
+ "\tRevocationDate: Fri Feb 11 13:14:38 2005\n"
+ "\tCritExtOIDs: (EMPTY)\n"
+ "\t]\n"
+ "\t)\n"
+ "\n"
+ "\tCritExtOIDs: (EMPTY)\n"
+ "]\n"
+ ")";
+
+ PKIX_TEST_STD_VARS();
+
+ startTests("Pk11CertStore");
+
+ if (argc < 3) {
+ printUsage(argv[0]);
+ return (0);
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ crlDir = argv[j + 2];
+
+ /* Two certs for prof should be valid now */
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_pl_Date_CreateFromPRTime(PR_Now(), &validityDate, plContext));
+
+ subTest("Searching Certs for Subject");
+
+ testMatchCertSubject(crlDir,
+ "phy2prof.crt",
+ NULL, /* expectedProfAscii, */
+ validityDate,
+ plContext);
+
+ /* One of the certs was not yet valid at this time. */
+ betweenDate = createDate("050210184000Z", plContext);
+
+ subTest("Searching Certs for Subject and Validity");
+
+ testMatchCertSubject(crlDir,
+ "phy2prof.crt",
+ NULL, /* expectedValidityAscii, */
+ betweenDate,
+ plContext);
+
+ testMatchCertMinPath(9,
+ NULL, /* expectedMinPathAscii, */
+ plContext);
+
+ testMatchCrlIssuer(crlDir,
+ "phys.crl",
+ NULL, /* expectedIssuerAscii, */
+ plContext);
+
+ testMatchCrlDate("050211184000Z",
+ NULL, /* expectedDateAscii, */
+ plContext);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(validityDate);
+ PKIX_TEST_DECREF_AC(betweenDate);
+
+ PKIX_TEST_RETURN();
+
+ endTests("Pk11CertStore");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix_pl/module/test_socket.c b/nss/cmd/libpkix/pkix_pl/module/test_socket.c
new file mode 100644
index 0000000..8940025
--- /dev/null
+++ b/nss/cmd/libpkix/pkix_pl/module/test_socket.c
@@ -0,0 +1,571 @@
+/*
+ * test_socket.c
+ *
+ * Test Socket Type
+ *
+ * Copyright 2004-2005 Sun Microsystems, Inc. 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. Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistribution 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.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
+ * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
+ * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use in
+ * the design, construction, operation or maintenance of any nuclear facility.
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+#include "pkix_pl_common.h"
+
+#define LDAP_PORT 389
+
+static void *plContext = NULL;
+
+typedef enum {
+ SERVER_LISTENING,
+ SERVER_RECV1,
+ SERVER_POLL1,
+ SERVER_SEND2,
+ SERVER_POLL2,
+ SERVER_RECV3,
+ SERVER_POLL3,
+ SERVER_SEND4,
+ SERVER_POLL4,
+ SERVER_DONE,
+ SERVER_FAILED
+} SERVER_STATE;
+
+typedef enum {
+ CLIENT_WAITFORCONNECT,
+ CLIENT_SEND1,
+ CLIENT_POLL1,
+ CLIENT_RECV2,
+ CLIENT_POLL2,
+ CLIENT_SEND3,
+ CLIENT_POLL3,
+ CLIENT_RECV4,
+ CLIENT_POLL4,
+ CLIENT_DONE,
+ CLIENT_FAILED
+} CLIENT_STATE;
+
+SERVER_STATE serverState;
+CLIENT_STATE clientState;
+PKIX_PL_Socket *sSock = NULL;
+PKIX_PL_Socket *cSock = NULL;
+PKIX_PL_Socket *rendezvousSock = NULL;
+PKIX_PL_Socket_Callback *sCallbackList;
+PKIX_PL_Socket_Callback *cCallbackList;
+PKIX_PL_Socket_Callback *rvCallbackList;
+PRNetAddr serverNetAddr;
+PRNetAddr clientNetAddr;
+PRIntn backlog = 0;
+PRIntervalTime timeout = 0;
+char *sendBuf1 = "Hello, world!";
+char *sendBuf2 = "Ack";
+char *sendBuf3 = "What do you mean, \"Ack\"?";
+char *sendBuf4 = "What do you mean, \"What do you mean, \'Ack\'?\"?";
+char rcvBuf1[100];
+char rcvBuf2[100];
+
+static void
+printUsage(char *testname)
+{
+ char *fmt = "USAGE: %s [-arenas] server:port\n";
+ printf(fmt, testname);
+}
+
+/* Functional tests for Socket public functions */
+static void
+do_other_work(void)
+{ /* while waiting for nonblocking I/O to complete */
+ (void)PR_Sleep(2 * 60);
+}
+
+static PKIX_Boolean
+server()
+{
+ PKIX_Int32 bytesRead = 0;
+ PKIX_Int32 bytesWritten = 0;
+ PKIX_Boolean keepGoing = PKIX_FALSE;
+
+ PKIX_TEST_STD_VARS();
+
+ switch (serverState) {
+ case SERVER_LISTENING:
+ subTest("SERVER_LISTENING");
+ PKIX_TEST_EXPECT_NO_ERROR(sCallbackList->acceptCallback(sSock, &rendezvousSock, plContext));
+ if (rendezvousSock) {
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_pl_Socket_GetCallbackList(rendezvousSock, &rvCallbackList, plContext));
+
+ serverState = SERVER_RECV1;
+ }
+ break;
+ case SERVER_RECV1:
+ subTest("SERVER_RECV1");
+ PKIX_TEST_EXPECT_NO_ERROR(rvCallbackList->recvCallback(rendezvousSock,
+ rcvBuf1,
+ sizeof(rcvBuf1),
+ &bytesRead,
+ plContext));
+
+ if (bytesRead > 0) {
+ /* confirm that rcvBuf1 = sendBuf1 */
+ if ((bytesRead != (PRInt32)PL_strlen(sendBuf1) + 1) ||
+ (strncmp(sendBuf1, rcvBuf1, bytesRead) != 0)) {
+ testError("Receive buffer mismatch\n");
+ }
+
+ serverState = SERVER_SEND2;
+ keepGoing = PKIX_TRUE;
+ } else {
+ serverState = SERVER_POLL1;
+ }
+ break;
+ case SERVER_POLL1:
+ subTest("SERVER_POLL1");
+ PKIX_TEST_EXPECT_NO_ERROR(rvCallbackList->pollCallback(rendezvousSock, NULL, &bytesRead, plContext));
+
+ if (bytesRead > 0) {
+ /* confirm that rcvBuf1 = sendBuf1 */
+ if ((bytesRead != (PRInt32)PL_strlen(sendBuf1) + 1) ||
+ (strncmp(sendBuf1, rcvBuf1, bytesRead) != 0)) {
+ testError("Receive buffer mismatch\n");
+ }
+
+ serverState = SERVER_SEND2;
+ keepGoing = PKIX_TRUE;
+ }
+ break;
+ case SERVER_SEND2:
+ subTest("SERVER_SEND2");
+ PKIX_TEST_EXPECT_NO_ERROR(rvCallbackList->sendCallback(rendezvousSock,
+ sendBuf2,
+ strlen(sendBuf2) +
+ 1,
+ &bytesWritten,
+ plContext));
+ if (bytesWritten > 0) {
+ serverState = SERVER_RECV3;
+ } else {
+ serverState = SERVER_POLL2;
+ }
+ break;
+ case SERVER_POLL2:
+ subTest("SERVER_POLL2");
+ PKIX_TEST_EXPECT_NO_ERROR(rvCallbackList->pollCallback(rendezvousSock, &bytesWritten, NULL, plContext));
+ if (bytesWritten > 0) {
+ serverState = SERVER_RECV3;
+ }
+ break;
+ case SERVER_RECV3:
+ subTest("SERVER_RECV3");
+ PKIX_TEST_EXPECT_NO_ERROR(rvCallbackList->recvCallback(rendezvousSock,
+ rcvBuf1,
+ sizeof(rcvBuf1),
+ &bytesRead,
+ plContext));
+
+ if (bytesRead > 0) {
+ serverState = SERVER_SEND4;
+ keepGoing = PKIX_TRUE;
+ } else {
+ serverState = SERVER_POLL3;
+ }
+ break;
+ case SERVER_POLL3:
+ subTest("SERVER_POLL3");
+ PKIX_TEST_EXPECT_NO_ERROR(rvCallbackList->pollCallback(rendezvousSock, NULL, &bytesRead, plContext));
+ if (bytesRead > 0) {
+ serverState = SERVER_SEND4;
+ keepGoing = PKIX_TRUE;
+ }
+ break;
+ case SERVER_SEND4:
+ subTest("SERVER_SEND4");
+ PKIX_TEST_EXPECT_NO_ERROR(rvCallbackList->sendCallback(rendezvousSock,
+ sendBuf4,
+ strlen(sendBuf4) +
+ 1,
+ &bytesWritten,
+ plContext));
+
+ if (bytesWritten > 0) {
+ PKIX_TEST_EXPECT_NO_ERROR(rvCallbackList->shutdownCallback(rendezvousSock, plContext));
+ PKIX_TEST_DECREF_BC(sSock);
+ PKIX_TEST_DECREF_BC(rendezvousSock);
+ serverState = SERVER_DONE;
+ } else {
+ serverState = SERVER_POLL4;
+ }
+ break;
+ case SERVER_POLL4:
+ subTest("SERVER_POLL4");
+ PKIX_TEST_EXPECT_NO_ERROR(rvCallbackList->pollCallback(rendezvousSock, &bytesWritten, NULL, plContext));
+ if (bytesWritten > 0) {
+ PKIX_TEST_EXPECT_NO_ERROR(rvCallbackList->shutdownCallback(rendezvousSock, plContext));
+ PKIX_TEST_DECREF_BC(sSock);
+ PKIX_TEST_DECREF_BC(rendezvousSock);
+ serverState = SERVER_DONE;
+ }
+ break;
+ case SERVER_DONE:
+ default:
+ subTest("SERVER_DONE");
+ break;
+ }
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+
+ return (keepGoing);
+}
+
+static PKIX_Boolean
+client()
+{
+ PKIX_Boolean keepGoing = PKIX_FALSE;
+ PKIX_Int32 bytesRead = 0;
+ PKIX_Int32 bytesWritten = 0;
+ PRErrorCode cStat = 0;
+
+ /* At 2 seconds each cycle, this should suffice! */
+ PKIX_UInt32 giveUpCount = 10;
+
+ PKIX_TEST_STD_VARS();
+
+ switch (clientState) {
+ case CLIENT_WAITFORCONNECT:
+ subTest("CLIENT_WAITFORCONNECT");
+ clientState = CLIENT_FAILED;
+ PKIX_TEST_EXPECT_NO_ERROR(cCallbackList->connectcontinueCallback(cSock, &cStat, plContext));
+ if (cStat == 0) {
+ clientState = CLIENT_SEND1;
+ keepGoing = PKIX_TRUE;
+ } else {
+ clientState = CLIENT_WAITFORCONNECT;
+ if (--giveUpCount == 0) {
+ testError("Client unable to connect");
+ }
+ }
+ break;
+ case CLIENT_SEND1:
+ subTest("CLIENT_SEND1");
+ clientState = CLIENT_FAILED;
+ PKIX_TEST_EXPECT_NO_ERROR(cCallbackList->sendCallback(cSock,
+ sendBuf1,
+ strlen(sendBuf1) +
+ 1,
+ &bytesWritten,
+ plContext));
+ if (bytesWritten > 0) {
+ clientState = CLIENT_RECV2;
+ } else {
+ clientState = CLIENT_POLL1;
+ }
+ break;
+ case CLIENT_POLL1:
+ subTest("CLIENT_POLL1");
+ clientState = CLIENT_FAILED;
+ PKIX_TEST_EXPECT_NO_ERROR(cCallbackList->pollCallback(cSock, &bytesWritten, NULL, plContext));
+ if (bytesWritten > 0) {
+ clientState = CLIENT_RECV2;
+ } else {
+ clientState = CLIENT_POLL1;
+ }
+ break;
+ case CLIENT_RECV2:
+ subTest("CLIENT_RECV2");
+ clientState = CLIENT_FAILED;
+ PKIX_TEST_EXPECT_NO_ERROR(cCallbackList->recvCallback(cSock,
+ rcvBuf2,
+ sizeof(rcvBuf2),
+ &bytesRead,
+ plContext));
+
+ if (bytesRead > 0) {
+ /* confirm that rcvBuf2 = sendBuf2 */
+ if ((bytesRead != (PRInt32)PL_strlen(sendBuf2) + 1) ||
+ (strncmp(sendBuf2, rcvBuf2, bytesRead) != 0)) {
+ testError("Receive buffer mismatch\n");
+ }
+ clientState = CLIENT_SEND3;
+ keepGoing = PKIX_TRUE;
+ } else {
+ clientState = CLIENT_POLL2;
+ }
+ break;
+ case CLIENT_POLL2:
+ subTest("CLIENT_POLL2");
+ clientState = CLIENT_FAILED;
+ PKIX_TEST_EXPECT_NO_ERROR(cCallbackList->pollCallback(cSock, NULL, &bytesRead, plContext));
+ if (bytesRead > 0) {
+ /* confirm that rcvBuf2 = sendBuf2 */
+ if ((bytesRead != (PRInt32)PL_strlen(sendBuf2) + 1) ||
+ (strncmp(sendBuf2, rcvBuf2, bytesRead) != 0)) {
+ testError("Receive buffer mismatch\n");
+ }
+ clientState = CLIENT_SEND3;
+ } else {
+ clientState = CLIENT_POLL2;
+ }
+ break;
+ case CLIENT_SEND3:
+ subTest("CLIENT_SEND3");
+ clientState = CLIENT_FAILED;
+ PKIX_TEST_EXPECT_NO_ERROR(cCallbackList->sendCallback(cSock,
+ sendBuf3,
+ strlen(sendBuf3) +
+ 1,
+ &bytesWritten,
+ plContext));
+
+ if (bytesWritten > 0) {
+ clientState = CLIENT_RECV4;
+ } else {
+ clientState = CLIENT_POLL3;
+ }
+ break;
+ case CLIENT_POLL3:
+ subTest("CLIENT_POLL3");
+ clientState = CLIENT_FAILED;
+ PKIX_TEST_EXPECT_NO_ERROR(cCallbackList->pollCallback(cSock, &bytesWritten, NULL, plContext));
+ if (bytesWritten > 0) {
+ clientState = CLIENT_RECV4;
+ } else {
+ clientState = CLIENT_POLL3;
+ }
+ break;
+ case CLIENT_RECV4:
+ subTest("CLIENT_RECV4");
+ clientState = CLIENT_FAILED;
+ PKIX_TEST_EXPECT_NO_ERROR(cCallbackList->recvCallback(cSock,
+ rcvBuf2,
+ sizeof(rcvBuf2),
+ &bytesRead,
+ plContext));
+
+ if (bytesRead > 0) {
+ PKIX_TEST_EXPECT_NO_ERROR(cCallbackList->shutdownCallback(cSock, plContext));
+ PKIX_TEST_DECREF_BC(cSock);
+ clientState = CLIENT_DONE;
+ } else {
+ clientState = CLIENT_POLL4;
+ }
+ break;
+ case CLIENT_POLL4:
+ subTest("CLIENT_POLL4");
+ clientState = CLIENT_FAILED;
+ PKIX_TEST_EXPECT_NO_ERROR(cCallbackList->pollCallback(cSock, NULL, &bytesRead, plContext));
+ if (bytesRead > 0) {
+ PKIX_TEST_EXPECT_NO_ERROR(cCallbackList->shutdownCallback(cSock, plContext));
+ PKIX_TEST_DECREF_BC(cSock);
+ clientState = CLIENT_DONE;
+ } else {
+ clientState = CLIENT_POLL4;
+ }
+ break;
+ case CLIENT_DONE:
+ default:
+ subTest("CLIENT_DONE");
+ break;
+ }
+
+cleanup:
+
+ PKIX_TEST_RETURN();
+
+ return (keepGoing);
+}
+
+static void
+dispatcher()
+{
+ PKIX_Boolean keepGoing = PKIX_FALSE;
+
+ PKIX_TEST_STD_VARS();
+
+ do {
+ if (serverState < SERVER_DONE) {
+ do {
+ keepGoing = server();
+ } while (keepGoing == PKIX_TRUE);
+ }
+ if (clientState < CLIENT_DONE) {
+ do {
+ keepGoing = client();
+ } while (keepGoing == PKIX_TRUE);
+ }
+ do_other_work();
+
+ } while ((serverState < SERVER_DONE) || (clientState < CLIENT_DONE));
+
+ PKIX_TEST_RETURN();
+}
+
+int
+test_socket(int argc, char *argv[])
+{
+
+ int j = 0;
+ PKIX_UInt32 actualMinorVersion;
+ char buf[PR_NETDB_BUF_SIZE];
+ char *serverName = NULL;
+ char *sepPtr = NULL;
+ PRHostEnt hostent;
+ PRUint16 portNum = 0;
+ PRStatus prstatus = PR_FAILURE;
+ PRErrorCode cStat = 0;
+ void *ipaddr = NULL;
+ PKIX_Error *bindError = NULL;
+ PRIntn hostenum;
+
+ PKIX_TEST_STD_VARS();
+
+ startTests("Socket");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ if (argc != (j + 2)) {
+ printUsage(argv[0]);
+ pkixTestErrorMsg = "Missing command line argument.";
+ goto cleanup;
+ }
+
+ serverName = argv[j + 1];
+
+ subTest("Using pkix_pl_Socket_CreateByName");
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_pl_Socket_CreateByName(PKIX_TRUE, timeout, serverName, &cStat, &sSock, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_pl_Socket_GetCallbackList(sSock, &sCallbackList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(sCallbackList->listenCallback(sSock, backlog, plContext));
+
+ serverState = SERVER_LISTENING;
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_pl_Socket_CreateByName(PKIX_FALSE, timeout, serverName, &cStat, &cSock, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_pl_Socket_GetCallbackList(cSock, &cCallbackList, plContext));
+
+ if ((timeout == 0) && (cStat == PR_IN_PROGRESS_ERROR)) {
+ clientState = CLIENT_WAITFORCONNECT;
+ } else {
+ clientState = CLIENT_SEND1;
+ }
+
+ dispatcher();
+
+ subTest("Using pkix_pl_Socket_Create");
+
+ sepPtr = strchr(serverName, ':');
+ /* First strip off the portnum, if present, from the end of the name */
+ if (sepPtr) {
+ *sepPtr++ = '\0';
+ portNum = (PRUint16)atoi(sepPtr);
+ } else {
+ portNum = (PRUint16)LDAP_PORT;
+ }
+ /*
+ * The hostname may be a fully-qualified name. Just
+ * use the leftmost component in our lookup.
+ */
+ sepPtr = strchr(serverName, '.');
+ if (sepPtr) {
+ *sepPtr++ = '\0';
+ }
+ prstatus = PR_GetHostByName(serverName, buf, sizeof(buf), &hostent);
+
+ if ((prstatus != PR_SUCCESS) || (hostent.h_length != 4)) {
+ printUsage(argv[0]);
+ pkixTestErrorMsg =
+ "PR_GetHostByName rejects command line argument.";
+ goto cleanup;
+ }
+
+ serverNetAddr.inet.family = PR_AF_INET;
+ serverNetAddr.inet.port = PR_htons(portNum);
+ serverNetAddr.inet.ip = PR_INADDR_ANY;
+
+ hostenum = PR_EnumerateHostEnt(0, &hostent, portNum, &clientNetAddr);
+ if (hostenum == -1) {
+ pkixTestErrorMsg =
+ "PR_EnumerateHostEnt failed.";
+ goto cleanup;
+ }
+
+ backlog = 5;
+
+ /* timeout = PR_INTERVAL_NO_TIMEOUT; */
+ /* timeout = 0; nonblocking */
+ timeout = 0;
+
+ bindError = pkix_pl_Socket_Create(PKIX_TRUE, timeout, &serverNetAddr, &cStat, &sSock, plContext);
+
+ /* If PR_Bind can't handle INADDR_ANY, try it with the real name */
+ if (bindError) {
+ PKIX_TEST_DECREF_BC(bindError);
+ serverNetAddr.inet.ip = PR_htonl(*(PRUint32 *)ipaddr);
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_pl_Socket_Create(PKIX_TRUE,
+ timeout,
+ &serverNetAddr,
+ &cStat,
+ &sSock,
+ plContext));
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_pl_Socket_GetCallbackList(sSock, &sCallbackList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(sCallbackList->listenCallback(sSock, backlog, plContext));
+
+ serverState = SERVER_LISTENING;
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_pl_Socket_Create(PKIX_FALSE, timeout, &clientNetAddr, &cStat, &cSock, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(pkix_pl_Socket_GetCallbackList(cSock, &cCallbackList, plContext));
+
+ if ((timeout == 0) && (cStat == PR_IN_PROGRESS_ERROR)) {
+ clientState = CLIENT_WAITFORCONNECT;
+ } else {
+ clientState = CLIENT_SEND1;
+ }
+
+ dispatcher();
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(sSock);
+ PKIX_TEST_DECREF_AC(cSock);
+ PKIX_TEST_DECREF_AC(rendezvousSock);
+
+ PKIX_TEST_RETURN();
+
+ endTests("Socket");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix_pl/pki/Makefile b/nss/cmd/libpkix/pkix_pl/pki/Makefile
new file mode 100755
index 0000000..09ca5f1
--- /dev/null
+++ b/nss/cmd/libpkix/pkix_pl/pki/Makefile
@@ -0,0 +1,47 @@
+#! gmake
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(PKIX_DEPTH)/config.mk
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+include $(PLAT_DEPTH)/platrules.mk
diff --git a/nss/cmd/libpkix/pkix_pl/pki/manifest.mn b/nss/cmd/libpkix/pkix_pl/pki/manifest.mn
new file mode 100755
index 0000000..7c6e0a7
--- /dev/null
+++ b/nss/cmd/libpkix/pkix_pl/pki/manifest.mn
@@ -0,0 +1,28 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+PKIX_DEPTH = ../..
+PLAT_DEPTH = $(PKIX_DEPTH)/..
+CORE_DEPTH = $(PKIX_DEPTH)/../../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+CSRCS = test_cert.c \
+ test_crl.c \
+ test_crlentry.c \
+ test_date.c \
+ test_generalname.c \
+ test_nameconstraints.c \
+ test_x500name.c \
+ test_authorityinfoaccess.c \
+ test_subjectinfoaccess.c \
+ $(NULL)
+
+LIBRARY_NAME=pkixtoolpki
+
+SOURCE_LIB_DIR=$(PKIX_DEPTH)/$(OBJDIR)
+
+NO_MD_RELEASE = 1
diff --git a/nss/cmd/libpkix/pkix_pl/pki/test_authorityinfoaccess.c b/nss/cmd/libpkix/pkix_pl/pki/test_authorityinfoaccess.c
new file mode 100644
index 0000000..156b440
--- /dev/null
+++ b/nss/cmd/libpkix/pkix_pl/pki/test_authorityinfoaccess.c
@@ -0,0 +1,105 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_authorityinfoaccess.c
+ *
+ * Test Authority InfoAccess Type
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static void *plContext = NULL;
+
+int
+test_authorityinfoaccess(int argc, char *argv[])
+{
+
+ PKIX_PL_Cert *cert = NULL;
+ PKIX_PL_Cert *certDiff = NULL;
+ PKIX_List *aiaList = NULL;
+ PKIX_List *siaList = NULL;
+ PKIX_PL_InfoAccess *aia = NULL;
+ PKIX_PL_InfoAccess *aiaDup = NULL;
+ PKIX_PL_InfoAccess *aiaDiff = NULL;
+ char *certPathName = NULL;
+ char *dirName = NULL;
+ PKIX_UInt32 actualMinorVersion;
+ PKIX_UInt32 size, i;
+ PKIX_UInt32 j = 0;
+ char *expectedAscii = "[method:caIssuers, location:ldap:"
+ "//betty.nist.gov/cn=CA,ou=Basic%20LDAP%20URI%20OU1,"
+ "o=Test%20Certificates,c=US?cACertificate;binary,"
+ "crossCertificatePair;binary]";
+
+ PKIX_TEST_STD_VARS();
+
+ startTests("AuthorityInfoAccess");
+
+ PKIX_TEST_EXPECT_NO_ERROR(
+ PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
+
+ if (argc < 5 + j) {
+ printf("Usage: %s \n", argv[0]);
+ }
+
+ dirName = argv[2 + j];
+ certPathName = argv[3 + j];
+
+ subTest("Creating Cert with Authority Info Access");
+ cert = createCert(dirName, certPathName, plContext);
+
+ certPathName = argv[4 + j];
+
+ subTest("Creating Cert with Subject Info Access");
+ certDiff = createCert(dirName, certPathName, plContext);
+
+ subTest("Getting Authority Info Access");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetAuthorityInfoAccess(cert, &aiaList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(aiaList, &size, plContext));
+
+ if (size != 1) {
+ pkixTestErrorMsg = "unexpected number of AIA";
+ goto cleanup;
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(aiaList, 0, (PKIX_PL_Object **)&aia, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(aiaList, 0, (PKIX_PL_Object **)&aiaDup, plContext));
+
+ subTest("Getting Subject Info Access as difference comparison");
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetSubjectInfoAccess(certDiff, &siaList, plContext));
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetLength(siaList, &size, plContext));
+
+ if (size != 1) {
+ pkixTestErrorMsg = "unexpected number of AIA";
+ goto cleanup;
+ }
+
+ PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(siaList, 0, (PKIX_PL_Object **)&aiaDiff, plContext));
+
+ subTest("Checking: Equal, Hash and ToString");
+ PKIX_TEST_EQ_HASH_TOSTR_DUP(aia, aiaDup, aiaDiff, expectedAscii, InfoAccess, PKIX_FALSE);
+
+cleanup:
+
+ PKIX_TEST_DECREF_AC(aia);
+ PKIX_TEST_DECREF_AC(aiaDup);
+ PKIX_TEST_DECREF_AC(aiaDiff);
+ PKIX_TEST_DECREF_AC(aiaList);
+ PKIX_TEST_DECREF_AC(siaList);
+ PKIX_TEST_DECREF_AC(cert);
+ PKIX_TEST_DECREF_AC(certDiff);
+
+ PKIX_Shutdown(plContext);
+
+ PKIX_TEST_RETURN();
+
+ endTests("Authorityinfoaccess");
+
+ return (0);
+}
diff --git a/nss/cmd/libpkix/pkix_pl/pki/test_cert.c b/nss/cmd/libpkix/pkix_pl/pki/test_cert.c
new file mode 100644
index 0000000..274f818
--- /dev/null
+++ b/nss/cmd/libpkix/pkix_pl/pki/test_cert.c
@@ -0,0 +1,2088 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * test_cert.c
+ *
+ * Test Cert Type
+ *
+ */
+
+#include "testutil.h"
+#include "testutil_nss.h"
+
+static PKIX_PL_Cert *altNameNoneCert = NULL;
+static PKIX_PL_Cert *altNameOtherCert = NULL;
+static PKIX_PL_Cert *altNameOtherCert_diff = NULL;
+static PKIX_PL_Cert *altNameRfc822Cert = NULL;
+static PKIX_PL_Cert *altNameRfc822Cert_diff = NULL;
+static PKIX_PL_Cert *altNameDnsCert = NULL;
+static PKIX_PL_Cert *altNameDnsCert_diff = NULL;
+static PKIX_PL_Cert *altNameX400Cert = NULL;
+static PKIX_PL_Cert *altNameX400Cert_diff = NULL;
+static PKIX_PL_Cert *altNameDnCert = NULL;
+static PKIX_PL_Cert *altNameDnCert_diff = NULL;
+static PKIX_PL_Cert *altNameEdiCert = NULL;
+static PKIX_PL_Cert *altNameEdiCert_diff = NULL;
+static PKIX_PL_Cert *altNameUriCert = NULL;
+static PKIX_PL_Cert *altNameUriCert_diff = NULL;
+static PKIX_PL_Cert *altNameIpCert = NULL;
+static PKIX_PL_Cert *altNameIpCert_diff = NULL;
+static PKIX_PL_Cert *altNameOidCert = NULL;
+static PKIX_PL_Cert *altNameOidCert_diff = NULL;
+static PKIX_PL_Cert *altNameMultipleCert = NULL;
+
+static void *plContext = NULL;
+
+static void
+createCerts(
+ char *dataCentralDir,
+ char *goodInput,
+ char *diffInput,
+ PKIX_PL_Cert **goodObject,
+ PKIX_PL_Cert **equalObject,
+ PKIX_PL_Cert **diffObject)
+{
+ subTest("PKIX_PL_Cert_Create ");
+ *goodObject = createCert(dataCentralDir, goodInput, plContext);
+
+ subTest("PKIX_PL_Cert_Create ");
+ *equalObject = createCert(dataCentralDir, goodInput, plContext);
+
+ subTest("PKIX_PL_Cert_Create ");
+ *diffObject = createCert(dataCentralDir, diffInput, plContext);
+}
+
+static void
+createCertsWithSubjectAltNames(char *dataCentralDir)
+{
+ subTest("PKIX_PL_Cert_Create ");
+ altNameDnsCert = createCert(dataCentralDir, "generalName/altNameDnsCert", plContext);
+
+ subTest("PKIX_PL_Cert_Create ");
+ altNameDnsCert_diff = createCert(dataCentralDir, "generalName/altNameDnsCert_diff", plContext);
+
+ subTest("PKIX_PL_Cert_Create ");
+ altNameRfc822Cert = createCert(dataCentralDir, "generalName/altNameRfc822Cert", plContext);
+
+ subTest("PKIX_PL_Cert_Create ");
+ altNameRfc822Cert_diff = createCert(dataCentralDir, "generalName/altNameRfc822Cert_diff", plContext);
+
+ subTest("PKIX_PL_Cert_Create ");
+ altNameX400Cert = createCert(dataCentralDir, "generalName/altNameX400Cert", plContext);
+
+ subTest("PKIX_PL_Cert_Create ");
+ altNameX400Cert_diff = createCert(dataCentralDir, "generalName/altNameX400Cert_diff", plContext);
+
+ subTest("PKIX_PL_Cert_Create ");
+ altNameDnCert = createCert(dataCentralDir, "generalName/altNameDnCert", plContext);
+
+ subTest("PKIX_PL_Cert_Create ");
+ altNameDnCert_diff = createCert(dataCentralDir, "generalName/altNameDnCert_diff", plContext);
+
+ subTest("PKIX_PL_Cert_Create ");
+ altNameEdiCert = createCert(dataCentralDir, "generalName/altNameEdiCert", plContext);
+
+ subTest("PKIX_PL_Cert_Create ");
+ altNameEdiCert_diff = createCert(dataCentralDir, "generalName/altNameEdiCert_diff", plContext);
+
+ subTest("PKIX_PL_Cert_Create ");
+ altNameUriCert = createCert(dataCentralDir, "generalName/altNameUriCert", plContext);
+
+ subTest("PKIX_PL_Cert_Create ");
+ altNameUriCert_diff = createCert(dataCentralDir, "generalName/altNameUriCert_diff", plContext);
+
+ subTest("PKIX_PL_Cert_Create ");
+ altNameIpCert = createCert(dataCentralDir, "generalName/altNameIpCert", plContext);
+
+ subTest("PKIX_PL_Cert_Create ");
+ altNameIpCert_diff = createCert(dataCentralDir, "generalName/altNameIpCert_diff", plContext);
+
+ subTest("PKIX_PL_Cert_Create ");
+ altNameOidCert = createCert(dataCentralDir, "generalName/altNameOidCert", plContext);
+
+ subTest("PKIX_PL_Cert_Create ");
+ altNameOidCert_diff = createCert(dataCentralDir, "generalName/altNameOidCert_diff", plContext);
+
+ subTest("PKIX_PL_Cert_Create ");
+ altNameOtherCert = createCert(dataCentralDir, "generalName/altNameOtherCert", plContext);
+
+ subTest("PKIX_PL_Cert_Create