]>
Commit | Line | Data |
---|---|---|
1d39620b RL |
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 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. | |
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 correspoding 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 |