2577df0caa9e27f32f18e9f6b21859c6237e6df1
[openssl.git] / doc / internal / man7 / DERlib.pod
1 =pod
2
3 =head1 NAME
4
5 DERlib - internal OpenSSL DER library
6
7 =head1 DESCRIPTION
8
9 OpenSSL contains an internal small DER reading and writing library,
10 as an alternative to the publicly known i2d and d2i functions.  It's
11 solely constituted of functions that work as building blocks to create
12 more similar functions to encode and decode larger structures.
13
14 All these functions have similar function signatures (C<something>
15 will vary depending on what the function will encode):
16
17     int DER_w_something(WPACKET *pkt, int tag, ...);
18
19 =begin comment
20
21 When readers are added, add this:
22
23     int DER_r_something(PACKET *pkt, int tag, ...);
24
25 =end comment
26
27 I<pkt> is the packet context used, and I<tag> should be the
28 context-specific tag value of the element being handled, or -1 if there
29 is no tag number for that element (you may use the convenience macro
30 B<DER_NO_CONTEXT> instead of -1).  Any argument following is the C
31 variable that's being encoded or decoded.
32
33 =head2 DER writers / encoders
34
35 DER writers are based in L<WPACKET(3)>, a generic packet writing
36 library, so before using any of them, I<pkt> must be initialized
37 using L<WPACKET_init_der(3)> or L<WPACKET_init_null_der(3)>
38
39 DER writers must be used in reverse order, except for the wrapping
40 functions that implement a constructed element.  The latter are easily
41 recognised by their function name including the words C<begin> and
42 C<end>.  As an example, we can look at the DSA signature structure,
43 which is defined like this in ASN.1 terms:
44
45     -- Copied from RFC 3279, section 2.2.2
46     Dss-Sig-Value  ::=  SEQUENCE  {
47             r       INTEGER,
48             s       INTEGER  }
49
50 With the DER library, this is the corresponding code, given two OpenSSL
51 B<BIGNUM>s I<r> and I<s>:
52
53     int ok = DER_w_begin_sequence(pkt, -1)
54           && DER_w_bn(pkg, -1, s)
55           && DER_w_bn(pkg, -1, r)
56           && DER_w_end_sequence(pkt, -1);
57
58 As an example of the use of I<tag>, an ASN.1 element like this:
59
60     v [1] INTEGER OPTIONAL
61
62 Would be encoded like this:
63
64     DER_w_bn(pkt, 1, v)
65
66 =begin comment
67
68 =head2 DER readers / decoders
69
70 TBA
71
72 =end comment
73
74 =head1 EXAMPLES
75
76 A more complex example, encoding the AlgorithmIdentifier with
77 RSASSA-PSS values.
78
79 As a reminder, the AlgorithmIdentifier is specified like this:
80
81     -- From RFC 3280, section 4.1.1.2
82     AlgorithmIdentifier  ::=  SEQUENCE  {
83          algorithm               OBJECT IDENTIFIER,
84          parameters              ANY DEFINED BY algorithm OPTIONAL  }    
85
86 And the RSASSA-PSS OID and parameters are specified like this:
87
88     -- From RFC 3279, section 3.1
89     id-RSASSA-PSS  OBJECT IDENTIFIER  ::=  { pkcs-1 10 }
90
91     RSASSA-PSS-params  ::=  SEQUENCE  {
92        hashAlgorithm      [0] HashAlgorithm DEFAULT
93                                  sha1Identifier,
94        maskGenAlgorithm   [1] MaskGenAlgorithm DEFAULT
95                                  mgf1SHA1Identifier,
96        saltLength         [2] INTEGER DEFAULT 20,
97        trailerField       [3] INTEGER DEFAULT 1  }
98
99 The value we want to encode, written in ASN.1 syntax:
100
101     {
102         algorithm               id-RSASSA-PSS,
103         parameters {
104             hashAlgorithm       sha256Identifier,
105             maskGenAlgorithm    mgf1SHA256Identifier,
106             saltLength          20  -- unnecessarily explicit
107         }
108     }
109
110 Assuming that we have precompiled constants for C<id-RSASSA-PSS>,
111 C<sha256Identifier> and C<mgf1SHA256Identifier>, the DER writing code
112 looks as follows. This is a complete function to write that specific
113 value:
114
115     int DER_w_AlgorithmIdentifier_RSASSA_PSS_special(WPACKET *pkt,
116                                                      int tag,
117                                                      RSA *rsa)
118     {
119         return DER_w_begin_sequence(pkt, tag)
120             && (DER_w_begin_sequence(pkt, DER_NO_CONTEXT)
121                 && DER_w_ulong(pkt, 2, 20)
122                 && DER_w_precompiled(pkt, 1,
123                                      der_mgf1SHA256Identifier,
124                                      sizeof(der_mgf1SHA256Identifier))
125                 && DER_w_precompiled(pkt, 0,
126                                      der_sha256Identifier,
127                                      sizeof(der_sha256Identifier))
128                 && DER_w_end_sequence(pkt, DER_NO_CONTEXT))
129             && DER_w_precompiled(pkt, DER_NO_CONTEXT,
130                                  der_id_RSASSA_PSS,
131                                  sizeof(der_id_RSASSA_PSS))
132             && DER_w_end_sequence(pkt, tag);
133     }
134
135 =head1 SEE ALSO
136
137 L<DER_w_bn(3)>, L<DER_w_begin_sequence(3)>, L<DER_w_precompiled(3)>
138
139 =head1 COPYRIGHT
140
141 Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
142
143 Licensed under the Apache License 2.0 (the "License").  You may not use
144 this file except in compliance with the License.  You can obtain a copy
145 in the file LICENSE in the source distribution or at
146 L<https://www.openssl.org/source/license.html>.
147
148 =cut