aboutsummaryrefslogtreecommitdiffstats
path: root/lib/crypto/doc/src/engine_keys.xml
blob: 64d1e6c2a3666adcc86521d92caec7608f5f5ca1 (plain) (blame)
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">

<chapter>
  <header>
    <copyright>
      <year>2017</year><year>2017</year>
      <holder>Ericsson AB. All Rights Reserved.</holder>
    </copyright>
    <legalnotice>
      The contents of this file are subject to the Erlang Public License,
      Version 1.1, (the "License"); you may not use this file except in
      compliance with the License. You should have received a copy of the
      Erlang Public License along with this software. If not, it can be
      retrieved online at http://www.erlang.org/.

      Software distributed under the License is distributed on an "AS IS"
      basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
      the License for the specific language governing rights and limitations
      under the License.
    </legalnotice>
    <title>Engine Stored Keys</title>
    <prepared>Hans Nilsson</prepared>
    <date>2017-11-10</date>
    <file>engine_keys.xml</file>
  </header>
  <p>
    <marker id="engine_key"></marker>
    This chapter describes the support in the crypto application for using public and private keys stored in encryption engines.
  </p>

  <section>
    <title>Background</title>
    <p>
      <url href="https://www.openssl.org/">OpenSSL</url> exposes an Engine API, which makes 
      it possible to plug in alternative implementations for some of the cryptographic
      operations implemented by OpenSSL.
      See the chapter <seealso marker="crypto:engine_load#engine_load">Engine Load</seealso>
      for details and how to load an Engine.
    </p>
    <p>
      In addition to provide alternative cryptographic implementations, an engine could provide a storage for
      private or public keys. Such a storage could be made safer than the normal file system. Such techniques are not 
      described in this User's Guide.  Here we concentrate on how to use private or public keys stored in
      such an engine.
    </p>
    <p>
      The storage engine must call <c>ENGINE_set_load_privkey_function</c> and <c>ENGINE_set_load_pubkey_function</c>.
      See the OpenSSL cryptolib's <url href="https://www.openssl.org/docs/manpages.html">manpages</url>.
    </p>
    <p>
      OTP/Crypto requires that the user provides two or three items of information about the key. The application used
      by the user is usually on a higher level, for example <seealso marker="ssl:ssl_app#application">SSL</seealso>. If using
      the crypto application directly, it is required that:
    </p>
    <list>
      <item>an Engine is loaded, see the chapter on <seealso marker="crypto:engine_load#engine_load">Engine Load</seealso>
      or the <seealso marker="crypto:crypto#engine_load-3">Reference Manual</seealso>
      </item>
      <item>a reference to a key in the Engine is available. This should be an Erlang string or binary and depends
      on the Engine loaded
      </item>
      <item>an Erlang map is constructed with the Engine reference, the key reference and possibly a key passphrase if
      needed by the Engine. See the <seealso marker="crypto:crypto#engine_key_ref_type">Reference Manual</seealso> for
      details of the map.
      </item>
    </list>
  </section>

  <section>
    <title>Use Cases</title>
    <section>
      <title>Sign with an engine stored private key</title>
      <p>
	This example shows how to construct a key reference that is used in a sign operation.
	The actual key is stored in the engine that is loaded at prompt 1.
      </p>
      <code>
1> {ok, EngineRef} = crypto:engine_load(....).
...
{ok,#Ref&lt;0.2399045421.3028942852.173962>}
2> PrivKey = #{engine => EngineRef,
               key_id => "id of the private key in Engine"}.
...
3> Signature = crypto:sign(rsa, sha, &lt;&lt;"The message">>, PrivKey).
&lt;&lt;65,6,125,254,54,233,84,77,83,63,168,28,169,214,121,76,
  207,177,124,183,156,185,160,243,36,79,125,230,231,...>>
      </code>
    </section>

    <section>
      <title>Verify with an engine stored public key</title>
      <p>
	Here the signature and message in the last example is verifyed using the public key.
	The public key is stored in an engine, only to exemplify that it is possible. The public
	key could of course be handled openly as usual.
      </p>
      <code>
4> PublicKey = #{engine => EngineRef,
                 key_id => "id of the public key in Engine"}.
...
5> crypto:verify(rsa, sha, &lt;&lt;"The message">>, Signature, PublicKey).
true
6> 
      </code>
    </section>

    <section>
      <title>Using a password protected private key</title>
      <p>
	The same example as the first sign example, except that a password protects the key down in the Engine.
      </p>
      <code>
6> PrivKeyPwd = #{engine => EngineRef,
                  key_id => "id of the pwd protected private key in Engine",
		  password => "password"}.
...
7> crypto:sign(rsa, sha, &lt;&lt;"The message">>, PrivKeyPwd).
&lt;&lt;140,80,168,101,234,211,146,183,231,190,160,82,85,163,
  175,106,77,241,141,120,72,149,181,181,194,154,175,76,
  223,...>>
8> 
      </code>

    </section>

  </section>
</chapter>