mirror of
https://github.com/openssl/openssl.git
synced 2024-12-15 06:01:37 +08:00
6a2b8ff392
This has us switch from the 'structure' "pkcs8" to "PrivateKeyInfo", which is sensible considering we already have "SubjectPublicKeyInfo". We also add "EncryptedPrivateKeyInfo", and use it for a special decoder that detects and decrypts an EncryptedPrivateKeyInfo structured DER blob into a PrivateKeyInfo structured DER blob and passes that on to the next decoder implementation. The result of this change is that PKCS#8 decryption should only happen once per decoding instead of once for every expected key type. Furthermore, this new decoder implementation sets the data type to the OID of the algorithmIdentifier field, thus reducing how many decoder implementations are tentativaly run further down the call chain. Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/15498)
134 lines
4.1 KiB
Plaintext
134 lines
4.1 KiB
Plaintext
=pod
|
|
|
|
=head1 NAME
|
|
|
|
OSSL_ENCODER_to_data,
|
|
OSSL_ENCODER_to_bio,
|
|
OSSL_ENCODER_to_fp
|
|
- Routines to perform an encoding
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
#include <openssl/encoder.h>
|
|
|
|
int OSSL_ENCODER_to_data(OSSL_ENCODER_CTX *ctx, unsigned char **pdata,
|
|
size_t *pdata_len);
|
|
int OSSL_ENCODER_to_bio(OSSL_ENCODER_CTX *ctx, BIO *out);
|
|
int OSSL_ENCODER_to_fp(OSSL_ENCODER_CTX *ctx, FILE *fp);
|
|
|
|
Feature availability macros:
|
|
|
|
=over 4
|
|
|
|
=item OSSL_ENCODER_to_fp() is only available when B<OPENSSL_NO_STDIO>
|
|
is undefined.
|
|
|
|
=back
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
OSSL_ENCODER_to_data() runs the encoding process for the context I<ctx>,
|
|
with the output going to the I<*pdata> and I<*pdata_len>.
|
|
If I<*pdata> is NULL when OSSL_ENCODER_to_data() is called, a buffer will be
|
|
allocated using L<OPENSSL_zalloc(3)>, and I<*pdata> will be set to point at
|
|
the start of that buffer, and I<*pdata_len> will be assigned its length when
|
|
OSSL_ENCODER_to_data() returns.
|
|
If I<*pdata> is non-NULL when OSSL_ENCODER_to_data() is called, I<*pdata_len>
|
|
is assumed to have its size. In this case, I<*pdata> will be set to point
|
|
after the encoded bytes, and I<*pdata_len> will be assigned the number of
|
|
remaining bytes.
|
|
|
|
OSSL_ENCODER_to_bio() runs the encoding process for the context I<ctx>, with
|
|
the output going to the B<BIO> I<out>.
|
|
|
|
OSSL_ENCODER_to_fp() does the same thing as OSSL_ENCODER_to_bio(), except
|
|
that the output is going to the B<FILE> I<fp>.
|
|
|
|
=for comment Know your encoder!
|
|
|
|
For OSSL_ENCODER_to_bio() and OSSL_ENCODER_to_fp(), the application is
|
|
required to set up the B<BIO> or B<FILE> properly, for example to have
|
|
it in text or binary mode as is appropriate for the encoder output type.
|
|
|
|
=head1 RETURN VALUES
|
|
|
|
OSSL_ENCODER_to_bio(), OSSL_ENCODER_to_fp() and OSSL_ENCODER_to_data()
|
|
return 1 on success, or 0 on failure.
|
|
|
|
=head1 EXAMPLES
|
|
|
|
To encode a pkey as PKCS#8 with PEM format into a bio:
|
|
|
|
OSSL_ENCODER_CTX *ectx;
|
|
const char *format = "PEM";
|
|
const char *structure = "PrivateKeyInfo"; /* 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 = "PrivateKeyInfo"; /* 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
|
|
|
|
L<provider(7)>, L<OSSL_ENCODER_CTX(3)>
|
|
|
|
=head1 HISTORY
|
|
|
|
The functions described here were added in OpenSSL 3.0.
|
|
|
|
=head1 COPYRIGHT
|
|
|
|
Copyright 2019-2021 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
|