|  | =pod | 
|  |  | 
|  | =head1 NAME | 
|  |  | 
|  | DERlib - internal OpenSSL DER library | 
|  |  | 
|  | =head1 DESCRIPTION | 
|  |  | 
|  | OpenSSL contains an internal small DER reading and writing library, | 
|  | as an alternative to the publicly known i2d and d2i functions.  It's | 
|  | solely constituted of functions that work as building blocks to create | 
|  | more similar functions to encode and decode larger structures. | 
|  |  | 
|  | All these functions have similar function signatures (C<something> | 
|  | will vary depending on what the function will encode): | 
|  |  | 
|  | int DER_w_something(WPACKET *pkt, int tag, ...); | 
|  |  | 
|  | =begin comment | 
|  |  | 
|  | When readers are added, add this: | 
|  |  | 
|  | int DER_r_something(PACKET *pkt, int tag, ...); | 
|  |  | 
|  | =end comment | 
|  |  | 
|  | I<pkt> is the packet context used, and I<tag> should be the | 
|  | context-specific tag value of the element being handled, or -1 if there | 
|  | is no tag number for that element (you may use the convenience macro | 
|  | B<DER_NO_CONTEXT> instead of -1).  Any argument following is the C | 
|  | variable that's being encoded or decoded. | 
|  |  | 
|  | =head2 DER writers / encoders | 
|  |  | 
|  | DER writers are based in L<WPACKET(3)>, a generic packet writing | 
|  | library, so before using any of them, I<pkt> must be initialized | 
|  | using L<WPACKET_init_der(3)> or L<WPACKET_init_null_der(3)> | 
|  |  | 
|  | DER writers must be used in reverse order, except for the wrapping | 
|  | functions that implement a constructed element.  The latter are easily | 
|  | recognised by their function name including the words C<begin> and | 
|  | C<end>.  As an example, we can look at the DSA signature structure, | 
|  | which is defined like this in ASN.1 terms: | 
|  |  | 
|  | -- Copied from RFC 3279, section 2.2.2 | 
|  | Dss-Sig-Value  ::=  SEQUENCE  { | 
|  | r       INTEGER, | 
|  | s       INTEGER  } | 
|  |  | 
|  | With the DER library, this is the corresponding code, given two OpenSSL | 
|  | B<BIGNUM>s I<r> and I<s>: | 
|  |  | 
|  | int ok = DER_w_begin_sequence(pkt, -1) | 
|  | && DER_w_bn(pkg, -1, s) | 
|  | && DER_w_bn(pkg, -1, r) | 
|  | && DER_w_end_sequence(pkt, -1); | 
|  |  | 
|  | As an example of the use of I<tag>, an ASN.1 element like this: | 
|  |  | 
|  | v [1] INTEGER OPTIONAL | 
|  |  | 
|  | Would be encoded like this: | 
|  |  | 
|  | DER_w_bn(pkt, 1, v) | 
|  |  | 
|  | =begin comment | 
|  |  | 
|  | =head2 DER readers / decoders | 
|  |  | 
|  | TBA | 
|  |  | 
|  | =end comment | 
|  |  | 
|  | =head1 EXAMPLES | 
|  |  | 
|  | A more complex example, encoding the AlgorithmIdentifier with | 
|  | RSASSA-PSS values. | 
|  |  | 
|  | As a reminder, the AlgorithmIdentifier is specified like this: | 
|  |  | 
|  | -- From RFC 3280, section 4.1.1.2 | 
|  | AlgorithmIdentifier  ::=  SEQUENCE  { | 
|  | algorithm               OBJECT IDENTIFIER, | 
|  | parameters              ANY DEFINED BY algorithm OPTIONAL  } | 
|  |  | 
|  | And the RSASSA-PSS OID and parameters are specified like this: | 
|  |  | 
|  | -- From RFC 3279, section 3.1 | 
|  | id-RSASSA-PSS  OBJECT IDENTIFIER  ::=  { pkcs-1 10 } | 
|  |  | 
|  | RSASSA-PSS-params  ::=  SEQUENCE  { | 
|  | hashAlgorithm      [0] HashAlgorithm DEFAULT | 
|  | sha1Identifier, | 
|  | maskGenAlgorithm   [1] MaskGenAlgorithm DEFAULT | 
|  | mgf1SHA1Identifier, | 
|  | saltLength         [2] INTEGER DEFAULT 20, | 
|  | trailerField       [3] INTEGER DEFAULT 1  } | 
|  |  | 
|  | The value we want to encode, written in ASN.1 syntax: | 
|  |  | 
|  | { | 
|  | algorithm               id-RSASSA-PSS, | 
|  | parameters { | 
|  | hashAlgorithm       sha256Identifier, | 
|  | maskGenAlgorithm    mgf1SHA256Identifier, | 
|  | saltLength          20  -- unnecessarily explicit | 
|  | } | 
|  | } | 
|  |  | 
|  | Assuming that we have precompiled constants for C<id-RSASSA-PSS>, | 
|  | C<sha256Identifier> and C<mgf1SHA256Identifier>, the DER writing code | 
|  | looks as follows. This is a complete function to write that specific | 
|  | value: | 
|  |  | 
|  | int DER_w_AlgorithmIdentifier_RSASSA_PSS_special(WPACKET *pkt, | 
|  | int tag, | 
|  | RSA *rsa) | 
|  | { | 
|  | return DER_w_begin_sequence(pkt, tag) | 
|  | && (DER_w_begin_sequence(pkt, DER_NO_CONTEXT) | 
|  | && DER_w_ulong(pkt, 2, 20) | 
|  | && DER_w_precompiled(pkt, 1, | 
|  | der_mgf1SHA256Identifier, | 
|  | sizeof(der_mgf1SHA256Identifier)) | 
|  | && DER_w_precompiled(pkt, 0, | 
|  | der_sha256Identifier, | 
|  | sizeof(der_sha256Identifier)) | 
|  | && DER_w_end_sequence(pkt, DER_NO_CONTEXT)) | 
|  | && DER_w_precompiled(pkt, DER_NO_CONTEXT, | 
|  | der_id_RSASSA_PSS, | 
|  | sizeof(der_id_RSASSA_PSS)) | 
|  | && DER_w_end_sequence(pkt, tag); | 
|  | } | 
|  |  | 
|  | =head1 SEE ALSO | 
|  |  | 
|  | L<DER_w_bn(3)>, L<DER_w_begin_sequence(3)>, L<DER_w_precompiled(3)> | 
|  |  | 
|  | =head1 COPYRIGHT | 
|  |  | 
|  | Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. | 
|  |  | 
|  | Licensed under the Apache License 2.0 (the "License").  You may not use | 
|  | this file except in compliance with the License.  You can obtain a copy | 
|  | in the file LICENSE in the source distribution or at | 
|  | L<https://www.openssl.org/source/license.html>. | 
|  |  | 
|  | =cut |