Add some encoder and decoder code examples
authorTomas Mraz <tomas@openssl.org>
Mon, 15 Mar 2021 17:31:34 +0000 (18:31 +0100)
committerPauli <ppzgs1@gmail.com>
Wed, 17 Mar 2021 00:17:48 +0000 (10:17 +1000)
Fixes #14373

Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14557)

doc/man3/OSSL_DECODER.pod
doc/man3/OSSL_DECODER_from_bio.pod
doc/man3/OSSL_ENCODER_to_bio.pod

index d12dede535649223617889d8cfe96454578b7516..289cf1bd84b652ab4ddf0b224de4552dab39414c 100644 (file)
@@ -116,13 +116,46 @@ OSSL_DECODER_fetch() may be called implicitly by other fetching
 functions, using the same library context and properties.
 Any other API that uses keys will typically do this.
 
-=begin comment TODO(3.0) Add examples!
-
 =head1 EXAMPLES
 
-Text, because pod2xxx doesn't like empty sections
+To list all decoders in a provider to a bio_out:
+
+ static void collect_decoders(OSSL_DECODER *decoder, void *stack)
+ {
+     STACK_OF(OSSL_DECODER) *decoder_stack = stack;
+
+     sk_OSSL_DECODER_push(decoder_stack, decoder);
+     OSSL_DECODER_up_ref(decoder);
+ }
+
+ void print_name(const char *name, void *vdata)
+ {
+     BIO *bio = vdata;
+
+     BIO_printf(bio, "%s ", name);
+ }
+
+
+ STACK_OF(OSSL_DECODER) *decoders;
+ int i;
+
+ decoders = sk_OSSL_DECODER_new_null();
+
+ BIO_printf(bio_out, "DECODERs provided by %s:\n", provider);
+ OSSL_DECODER_do_all_provided(NULL, collect_decoders,
+                              decoders);
+
+ for (i = 0; i < sk_OSSL_DECODER_num(decoders); i++) {
+     OSSL_DECODER *decoder = sk_OSSL_DECODER_value(decoders, i);
+
+     if (strcmp(OSSL_PROVIDER_name(OSSL_DECODER_provider(decoder)),
+                provider) != 0)
+         continue;
 
-=end comment
+     if (OSSL_DECODER_names_do_all(decoder, print_name, bio_out))
+            BIO_printf(bio_out, "\n");
+ }
+ sk_OSSL_DECODER_pop_free(decoders, OSSL_DECODER_free);
 
 =head1 SEE ALSO
 
index 3bd43200d3da5e605ccd8d7007f44888edf1cfde..1d329c66d627facc28dc2792d6044acc1ce811b2 100644 (file)
@@ -45,13 +45,60 @@ except that the input is coming from the B<FILE> I<fp>.
 OSSL_DECODER_from_bio() and OSSL_DECODER_from_fp() return 1 on success, or 0
 on failure.
 
-=begin comment TODO(3.0) Add examples!
-
 =head1 EXAMPLES
 
-Text, because pod2xxx doesn't like empty sections
-
-=end comment
+To decode an RSA key encoded with PEM from a bio:
+
+ OSSL_DECODER_CTX *dctx;
+ EVP_PKEY *pkey = NULL;
+ const char *format = "PEM";   /* NULL for any format */
+ const char *structure = NULL; /* any structure */
+ const char *keytype = "RSA";  /* NULL for any key */
+ const unsigned char *pass = "my password";
+
+ dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, format, structure,
+                                      keytype,
+                                      OSSL_KEYMGMT_SELECT_KEYPAIR,
+                                      NULL, NULL);
+ if (dctx == NULL) {
+     /* error: no suitable potential decoders found */
+ }
+ if (pass != NULL)
+     OSSL_DECODER_CTX_set_passphrase(dctx, pass, strlen(pass));
+ if (OSSL_DECODER_from_bio(dctx, bio)) {
+     /* pkey is created with the decoded data from the bio */
+ } else {
+     /* decoding failure */
+ }
+ OSSL_DECODER_CTX_free(dctx);
+
+To decode an EC key encoded with DER from a buffer:
+
+ OSSL_DECODER_CTX *dctx;
+ EVP_PKEY *pkey = NULL;
+ const char *format = "DER";   /* NULL for any format */
+ const char *structure = NULL; /* any structure */
+ const char *keytype = "EC";   /* NULL for any key */
+ const unsigned char *pass = NULL
+ const unsigned char *data = buffer;
+ size_t datalen = sizeof(buffer);
+
+ dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, format, structure,
+                                      keytype,
+                                      OSSL_KEYMGMT_SELECT_KEYPAIR
+                                      | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                                      NULL, NULL);
+ if (dctx == NULL) {
+     /* error: no suitable potential decoders found */
+ }
+ if (pass != NULL)
+     OSSL_DECODER_CTX_set_passphrase(dctx, pass, strlen(pass));
+ if (OSSL_DECODER_from_data(dctx, &data, &datalen)) {
+     /* pkey is created with the decoded data from the buffer */
+ } else {
+     /* decoding failure */
+ }
+ OSSL_DECODER_CTX_free(dctx);
 
 =head1 SEE ALSO
 
index f28228bf10b24c4b08f58265e3b40c7735c0ec0c..c0059c07b81fa08f6b90d3f7bc4c667d47057978 100644 (file)
@@ -55,13 +55,63 @@ it in text or binary mode as is appropriate for the encoder output type.
 OSSL_ENCODER_to_bio(), OSSL_ENCODER_to_fp() and OSSL_ENCODER_to_data()
 return 1 on success, or 0 on failure.
 
-=begin comment TODO(3.0) Add examples!
-
 =head1 EXAMPLES
 
-Text, because pod2xxx doesn't like empty sections
-
-=end comment
+To encode a pkey as PKCS#8 with PEM format into a bio:
+
+ OSSL_ENCODER_CTX *ectx;
+ const char *format = "PEM";
+ const char *structure = "pkcs8"; /* PKCS#8 structure */
+ const unsigned char *pass = "my password";
+
+ ectx = OSSL_ENCODER_CTX_new_for_pkey(pkey,
+                                      OSSL_KEYMGMT_SELECT_KEYPAIR
+                                      | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                                      format, structure,
+                                      NULL);
+ if (ectx == NULL) {
+     /* error: no suitable potential encoders found */
+ }
+ if (pass != NULL)
+     OSSL_ENCODER_CTX_set_passphrase(ectx, pass, strlen(pass));
+ if (OSSL_ENCODER_to_bio(ectx, bio)) {
+     /* pkey was successfully encoded into the bio */
+ } else {
+     /* encoding failure */
+ }
+ OSSL_ENCODER_CTX_free(ectx);
+
+To encode a pkey as PKCS#8 with DER format encrypted with
+AES-256-CBC into a buffer:
+
+ OSSL_ENCODER_CTX *ectx;
+ const char *format = "DER";
+ const char *structure = "pkcs8"; /* PKCS#8 structure */
+ const unsigned char *pass = "my password";
+ unsigned char *data = NULL;
+ size_t datalen;
+
+ ectx = OSSL_ENCODER_CTX_new_for_pkey(pkey,
+                                      OSSL_KEYMGMT_SELECT_KEYPAIR,
+                                      | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                                      format, structure,
+                                      NULL);
+ if (ectx == NULL) {
+     /* error: no suitable potential encoders found */
+ }
+ if (pass != NULL) {
+     OSSL_ENCODER_CTX_set_passphrase(ectx, pass, strlen(pass));
+     OSSL_ENCODER_CTX_set_cipher(ctx, "AES-256-CBC", NULL);
+ }
+ if (OSSL_ENCODER_to_data(ectx, &data, &datalen)) {
+     /*
+      * pkey was successfully encoded into a newly allocated
+      * data buffer
+      */
+ } else {
+     /* encoding failure */
+ }
+ OSSL_ENCODER_CTX_free(ectx);
 
 =head1 SEE ALSO