1=pod
2
3=head1 NAME
4
5DERlib - internal OpenSSL DER library
6
7=head1 DESCRIPTION
8
9OpenSSL contains an internal small DER reading and writing library,
10as an alternative to the publicly known i2d and d2i functions.  It's
11solely constituted of functions that work as building blocks to create
12more similar functions to encode and decode larger structures.
13
14All these functions have similar function signatures (C<something>
15will vary depending on what the function will encode):
16
17    int DER_w_something(WPACKET *pkt, int tag, ...);
18
19=begin comment
20
21When readers are added, add this:
22
23    int DER_r_something(PACKET *pkt, int tag, ...);
24
25=end comment
26
27I<pkt> is the packet context used, and I<tag> should be the
28context-specific tag value of the element being handled, or -1 if there
29is no tag number for that element (you may use the convenience macro
30B<DER_NO_CONTEXT> instead of -1).  Any argument following is the C
31variable that's being encoded or decoded.
32
33=head2 DER writers / encoders
34
35DER writers are based in L<WPACKET(3)>, a generic packet writing
36library, so before using any of them, I<pkt> must be initialized
37using L<WPACKET_init_der(3)> or L<WPACKET_init_null_der(3)>
38
39DER writers must be used in reverse order, except for the wrapping
40functions that implement a constructed element.  The latter are easily
41recognised by their function name including the words C<begin> and
42C<end>.  As an example, we can look at the DSA signature structure,
43which 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
50With the DER library, this is the corresponding code, given two OpenSSL
51B<BIGNUM>s I<r> and I<s>:
52
53    int ok = ossl_DER_w_begin_sequence(pkt, -1)
54          && ossl_DER_w_bn(pkg, -1, s)
55          && ossl_DER_w_bn(pkg, -1, r)
56          && ossl_DER_w_end_sequence(pkt, -1);
57
58As an example of the use of I<tag>, an ASN.1 element like this:
59
60    v [1] INTEGER OPTIONAL
61
62Would be encoded like this:
63
64    ossl_DER_w_bn(pkt, 1, v)
65
66=begin comment
67
68=head2 DER readers / decoders
69
70TBA
71
72=end comment
73
74=head1 EXAMPLES
75
76A more complex example, encoding the AlgorithmIdentifier with
77RSASSA-PSS values.
78
79As 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
86And 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
99The 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
110Assuming that we have precompiled constants for C<id-RSASSA-PSS>,
111C<sha256Identifier> and C<mgf1SHA256Identifier>, the DER writing code
112looks as follows. This is a complete function to write that specific
113value:
114
115    int DER_w_AlgorithmIdentifier_RSASSA_PSS_special(WPACKET *pkt,
116                                                     int tag,
117                                                     RSA *rsa)
118    {
119        return ossl_DER_w_begin_sequence(pkt, tag)
120            && (ossl_DER_w_begin_sequence(pkt, DER_NO_CONTEXT)
121                && ossl_DER_w_uint32(pkt, 2, 20)
122                && ossl_DER_w_precompiled(pkt, 1,
123                                          der_mgf1SHA256Identifier,
124                                          sizeof(der_mgf1SHA256Identifier))
125                && ossl_DER_w_precompiled(pkt, 0,
126                                          der_sha256Identifier,
127                                          sizeof(der_sha256Identifier))
128                && ossl_DER_w_end_sequence(pkt, DER_NO_CONTEXT))
129            && ossl_DER_w_precompiled(pkt, DER_NO_CONTEXT,
130                                      der_id_RSASSA_PSS,
131                                      sizeof(der_id_RSASSA_PSS))
132            && ossl_DER_w_end_sequence(pkt, tag);
133    }
134
135=head1 SEE ALSO
136
137L<ossl_DER_w_bn(3)>, L<ossl_DER_w_begin_sequence(3)>,
138L<ossl_DER_w_precompiled(3)>
139
140=head1 COPYRIGHT
141
142Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved.
143
144Licensed under the Apache License 2.0 (the "License").  You may not use
145this file except in compliance with the License.  You can obtain a copy
146in the file LICENSE in the source distribution or at
147L<https://www.openssl.org/source/license.html>.
148
149=cut
150