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