]> git.ipfire.org Git - thirdparty/openssl.git/blobdiff - doc/internal/man7/DERlib.pod
PROV: Add the beginning of a DER writing library
[thirdparty/openssl.git] / doc / internal / man7 / DERlib.pod
diff --git a/doc/internal/man7/DERlib.pod b/doc/internal/man7/DERlib.pod
new file mode 100644 (file)
index 0000000..7b0e722
--- /dev/null
@@ -0,0 +1,148 @@
+=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 publically 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 correspoding 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