5 DERlib - internal OpenSSL DER library
9 OpenSSL contains an internal small DER reading and writing library,
10 as an alternative to the publically 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.
14 All these functions have similar function signatures (C<something>
15 will vary depending on what the function will encode):
17 int DER_w_something(WPACKET *pkt, int tag, ...);
21 When readers are added, add this:
23 int DER_r_something(PACKET *pkt, int tag, ...);
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.
33 =head2 DER writers / encoders
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)>
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:
45 -- Copied from RFC 3279, section 2.2.2
46 Dss-Sig-Value ::= SEQUENCE {
50 With the DER library, this is the correspoding code, given two OpenSSL
51 B<BIGNUM>s I<r> and I<s>:
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);
58 As an example of the use of I<tag>, an ASN.1 element like this:
60 v [1] INTEGER OPTIONAL
62 Would be encoded like this:
68 =head2 DER readers / decoders
76 A more complex example, encoding the AlgorithmIdentifier with
79 As a reminder, the AlgorithmIdentifier is specified like this:
81 -- From RFC 3280, section 4.1.1.2
82 AlgorithmIdentifier ::= SEQUENCE {
83 algorithm OBJECT IDENTIFIER,
84 parameters ANY DEFINED BY algorithm OPTIONAL }
86 And the RSASSA-PSS OID and parameters are specified like this:
88 -- From RFC 3279, section 3.1
89 id-RSASSA-PSS OBJECT IDENTIFIER ::= { pkcs-1 10 }
91 RSASSA-PSS-params ::= SEQUENCE {
92 hashAlgorithm [0] HashAlgorithm DEFAULT
94 maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT
96 saltLength [2] INTEGER DEFAULT 20,
97 trailerField [3] INTEGER DEFAULT 1 }
99 The value we want to encode, written in ASN.1 syntax:
102 algorithm id-RSASSA-PSS,
104 hashAlgorithm sha256Identifier,
105 maskGenAlgorithm mgf1SHA256Identifier,
106 saltLength 20 -- unnecessarily explicit
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
115 int DER_w_AlgorithmIdentifier_RSASSA_PSS_special(WPACKET *pkt,
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,
131 sizeof(der_id_RSASSA_PSS))
132 && DER_w_end_sequence(pkt, tag);
137 L<DER_w_bn(3)>, L<DER_w_begin_sequence(3)>, L<DER_w_precompiled(3)>
141 Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
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>.