aboutsummaryrefslogtreecommitdiff
path: root/openssl/agent/pkcs11/private-key.test.cxx
blob: 5e68186f6b4332769a60b0fc1ae8906e95a0e33b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// file      : openssl/agent/pkcs11/private-key.test.cxx -*- C++ -*-
// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
// license   : MIT; see accompanying LICENSE file

#include <iostream>

#include <openssl/agent/pkcs11/url.hxx>
#include <openssl/agent/pkcs11/private-key.hxx>

// Usage: argv[0] <pkcs11-url>
//
// Create private_key object referenced by the <pkcs11-url>. Read data from
// stdin, sign it with the private key, and print the signature to stdout.
//
int
main (int argc, char* argv[])
{
  using namespace std;
  using namespace openssl::agent::pkcs11;

  if (argc != 2)
  {
    cerr << "usage: " << argv[0] << " <pkcs11-url>" << endl;
    return 1;
  }

  cin.exceptions  (ios::badbit);
  cout.exceptions (ios::failbit | ios::badbit);

  try
  {
    url      u   (argv[1]);
    identity idn (u);
    access   acc (u);

    vector<char> data ((istreambuf_iterator<char> (cin)),
                       istreambuf_iterator<char> ());

    vector<char> signature;

    // Stress the API a bit recreating, reusing and having concurrent keys.
    //
    for (size_t i (0); i < 5; ++i)
    {
      private_key key1 (idn, acc, nullptr /* secure_pin */);
      private_key key2 (idn, acc, nullptr /* secure_pin */);

      for (size_t i (0); i < 10; ++i)
      {
        vector<char> sign ((i % 2 == 0 ? key1 : key2).sign (data));

        if (signature.empty ())
          signature = move (sign);
        else if (sign != signature)
          throw runtime_error ("sign operation is unreliable");
      }
    }

    cout.write (signature.data (), signature.size ());
    return 0;
  }
  catch (const invalid_argument& e)
  {
    cerr << e << endl;
    return 1;
  }
  catch (const runtime_error& e)
  {
    cerr << e << endl;
    return 1;
  }
}