Various RT doc fixes

RT1556: doc/crypto/threads.pod
RT2024: Missing pages mentioned in crypto.pod
RT2890: Wrong size in ERR_string_error description.
RT3461: Better description of PEM Encryption
        (Jeffrey Walton <noloader@gmail.com>)
        Also, fix up formatting and removed some code examples
        that encourage unsafe patterns, like unencrypted private
        keys (Rich Salz)
RT4240: Document some speed flags (Tomas Mraz <tmraz@redhat.com>)
RT4260: Fix return value doc for X509_REQ_sign and X509_sign
        (Laetitia Baudoin <lbaudoin@google.com>)

Reviewed-by: Emilia Käsper <emilia@openssl.org>
This commit is contained in:
Rich Salz 2016-02-01 15:15:06 -05:00 committed by Rich Salz
parent e51511ce49
commit a047435774
6 changed files with 144 additions and 205 deletions

View File

@ -8,6 +8,9 @@ speed - test library performance
B<openssl speed>
[B<-engine id>]
[B<-elapsed>]
[B<-evp algo>]
[B<-decrypt>]
[B<md2>]
[B<mdc2>]
[B<md5>]
@ -49,6 +52,19 @@ to attempt to obtain a functional reference to the specified engine,
thus initialising it if needed. The engine will then be set as the default
for all available algorithms.
=item B<-elapsed>
Measure time in real time instead of CPU time. It can be useful when testing
speed of hardware engines.
=item B<-evp algo>
Use the specified cipher or message digest algorithm via the EVP interface.
=item B<-decrypt>
Time the decryption instead of encryption. Affects only the EVP testing.
=item B<[zero or more test algorithms]>
If any options are given, B<speed> tests those algorithms, otherwise all of

View File

@ -20,9 +20,12 @@ error message
=head1 DESCRIPTION
ERR_error_string() generates a human-readable string representing the
error code I<e>, and places it at I<buf>. I<buf> must be at least 120
error code I<e>, and places it at I<buf>. I<buf> must be at least 256
bytes long. If I<buf> is B<NULL>, the error string is placed in a
static buffer.
Note that this function is not thread-safe and does no checks on the size
of the buffer; use ERR_error_string_n() instead.
ERR_error_string_n() is a variant of ERR_error_string() that writes
at most I<len> characters (including the terminating 0)
and truncates the string if necessary.

View File

@ -52,8 +52,8 @@ signature and signing will always update the encoding.
=head1 RETURN VALUES
X509_sign(), X509_sign_ctx(), X509_REQ_sign(), X509_REQ_sign_ctx(),
X509_CRL_sign() and X509_CRL_sign_ctx() return 1 for success and 0
for failure.
X509_CRL_sign() and X509_CRL_sign_ctx() return the size of the signature
in bytes for success and zero for failure.
X509_verify(), X509_REQ_verify() and X509_CRL_verify() return 1 if the
signature is valid and 0 if the signature check fails. If the signature

View File

@ -21,46 +21,10 @@ individual algorithms.
The functionality includes symmetric encryption, public key
cryptography and key agreement, certificate handling, cryptographic
hash functions and a cryptographic pseudo-random number generator.
hash functions, cryptographic pseudo-random number generator, and
various utilities.
=over 4
=item SYMMETRIC CIPHERS
L<blowfish(3)>, L<cast(3)>, L<des(3)>,
L<idea(3)>, L<rc2(3)>, L<rc4(3)>, L<rc5(3)>
=item PUBLIC KEY CRYPTOGRAPHY AND KEY AGREEMENT
L<dsa(3)>, L<dh(3)>, L<ec(3)>, L<rsa(3)>
=item CERTIFICATES
L<x509(3)>, L<x509v3(3)>
=item AUTHENTICATION CODES, HASH FUNCTIONS
L<hmac(3)>, L<md2(3)>, L<md4(3)>,
L<md5(3)>, L<mdc2(3)>, L<ripemd(3)>,
L<sha(3)>
=item AUXILIARY FUNCTIONS
L<err(3)>, L<threads(3)>, L<rand(3)>,
L<OPENSSL_VERSION_NUMBER(3)>
=item INPUT/OUTPUT, DATA ENCODING
L<asn1(3)>, L<bio(3)>, L<evp(3)>, L<pem(3)>,
L<pkcs7(3)>, L<pkcs12(3)>
=item UTILITY FUNCTIONS
L<bn(3)>, L<buffer(3)>, L<lhash(3)>,
L<stack(3)>,
L<txt_db(3)>
=back
See the individual manual pages for details.
=head1 NOTES

View File

@ -22,184 +22,127 @@ PEM_write_X509_AUX, PEM_read_bio_X509_REQ, PEM_read_X509_REQ,
PEM_write_bio_X509_REQ, PEM_write_X509_REQ, PEM_write_bio_X509_REQ_NEW,
PEM_write_X509_REQ_NEW, PEM_read_bio_X509_CRL, PEM_read_X509_CRL,
PEM_write_bio_X509_CRL, PEM_write_X509_CRL, PEM_read_bio_PKCS7, PEM_read_PKCS7,
PEM_write_bio_PKCS7, PEM_write_PKCS7, PEM_read_bio_NETSCAPE_CERT_SEQUENCE,
PEM_read_NETSCAPE_CERT_SEQUENCE, PEM_write_bio_NETSCAPE_CERT_SEQUENCE,
PEM_write_NETSCAPE_CERT_SEQUENCE - PEM routines
PEM_write_bio_PKCS7, PEM_write_PKCS7 - PEM routines
=head1 SYNOPSIS
#include <openssl/pem.h>
EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x,
pem_password_cb *cb, void *u);
pem_password_cb *cb, void *u);
EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x,
pem_password_cb *cb, void *u);
pem_password_cb *cb, void *u);
int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
unsigned char *kstr, int klen,
pem_password_cb *cb, void *u);
unsigned char *kstr, int klen,
pem_password_cb *cb, void *u);
int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
unsigned char *kstr, int klen,
pem_password_cb *cb, void *u);
unsigned char *kstr, int klen,
pem_password_cb *cb, void *u);
int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
char *kstr, int klen,
pem_password_cb *cb, void *u);
char *kstr, int klen,
pem_password_cb *cb, void *u);
int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
char *kstr, int klen,
pem_password_cb *cb, void *u);
char *kstr, int klen,
pem_password_cb *cb, void *u);
int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
char *kstr, int klen,
pem_password_cb *cb, void *u);
char *kstr, int klen,
pem_password_cb *cb, void *u);
int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
char *kstr, int klen,
pem_password_cb *cb, void *u);
char *kstr, int klen,
pem_password_cb *cb, void *u);
EVP_PKEY *PEM_read_bio_PUBKEY(BIO *bp, EVP_PKEY **x,
pem_password_cb *cb, void *u);
pem_password_cb *cb, void *u);
EVP_PKEY *PEM_read_PUBKEY(FILE *fp, EVP_PKEY **x,
pem_password_cb *cb, void *u);
pem_password_cb *cb, void *u);
int PEM_write_bio_PUBKEY(BIO *bp, EVP_PKEY *x);
int PEM_write_PUBKEY(FILE *fp, EVP_PKEY *x);
RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **x,
pem_password_cb *cb, void *u);
pem_password_cb *cb, void *u);
RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **x,
pem_password_cb *cb, void *u);
pem_password_cb *cb, void *u);
int PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc,
unsigned char *kstr, int klen,
pem_password_cb *cb, void *u);
unsigned char *kstr, int klen,
pem_password_cb *cb, void *u);
int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc,
unsigned char *kstr, int klen,
pem_password_cb *cb, void *u);
unsigned char *kstr, int klen,
pem_password_cb *cb, void *u);
RSA *PEM_read_bio_RSAPublicKey(BIO *bp, RSA **x,
pem_password_cb *cb, void *u);
pem_password_cb *cb, void *u);
RSA *PEM_read_RSAPublicKey(FILE *fp, RSA **x,
pem_password_cb *cb, void *u);
pem_password_cb *cb, void *u);
int PEM_write_bio_RSAPublicKey(BIO *bp, RSA *x);
int PEM_write_RSAPublicKey(FILE *fp, RSA *x);
RSA *PEM_read_bio_RSA_PUBKEY(BIO *bp, RSA **x,
pem_password_cb *cb, void *u);
pem_password_cb *cb, void *u);
RSA *PEM_read_RSA_PUBKEY(FILE *fp, RSA **x,
pem_password_cb *cb, void *u);
pem_password_cb *cb, void *u);
int PEM_write_bio_RSA_PUBKEY(BIO *bp, RSA *x);
int PEM_write_RSA_PUBKEY(FILE *fp, RSA *x);
DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **x,
pem_password_cb *cb, void *u);
pem_password_cb *cb, void *u);
DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **x,
pem_password_cb *cb, void *u);
pem_password_cb *cb, void *u);
int PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, const EVP_CIPHER *enc,
unsigned char *kstr, int klen,
pem_password_cb *cb, void *u);
unsigned char *kstr, int klen,
pem_password_cb *cb, void *u);
int PEM_write_DSAPrivateKey(FILE *fp, DSA *x, const EVP_CIPHER *enc,
unsigned char *kstr, int klen,
pem_password_cb *cb, void *u);
unsigned char *kstr, int klen,
pem_password_cb *cb, void *u);
DSA *PEM_read_bio_DSA_PUBKEY(BIO *bp, DSA **x,
pem_password_cb *cb, void *u);
pem_password_cb *cb, void *u);
DSA *PEM_read_DSA_PUBKEY(FILE *fp, DSA **x,
pem_password_cb *cb, void *u);
pem_password_cb *cb, void *u);
int PEM_write_bio_DSA_PUBKEY(BIO *bp, DSA *x);
int PEM_write_DSA_PUBKEY(FILE *fp, DSA *x);
DSA *PEM_read_bio_DSAparams(BIO *bp, DSA **x, pem_password_cb *cb, void *u);
DSA *PEM_read_DSAparams(FILE *fp, DSA **x, pem_password_cb *cb, void *u);
int PEM_write_bio_DSAparams(BIO *bp, DSA *x);
int PEM_write_DSAparams(FILE *fp, DSA *x);
DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u);
DH *PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u);
int PEM_write_bio_DHparams(BIO *bp, DH *x);
int PEM_write_DHparams(FILE *fp, DH *x);
X509 *PEM_read_bio_X509(BIO *bp, X509 **x, pem_password_cb *cb, void *u);
X509 *PEM_read_X509(FILE *fp, X509 **x, pem_password_cb *cb, void *u);
int PEM_write_bio_X509(BIO *bp, X509 *x);
int PEM_write_X509(FILE *fp, X509 *x);
X509 *PEM_read_bio_X509_AUX(BIO *bp, X509 **x, pem_password_cb *cb, void *u);
X509 *PEM_read_X509_AUX(FILE *fp, X509 **x, pem_password_cb *cb, void *u);
int PEM_write_bio_X509_AUX(BIO *bp, X509 *x);
int PEM_write_X509_AUX(FILE *fp, X509 *x);
X509_REQ *PEM_read_bio_X509_REQ(BIO *bp, X509_REQ **x,
pem_password_cb *cb, void *u);
pem_password_cb *cb, void *u);
X509_REQ *PEM_read_X509_REQ(FILE *fp, X509_REQ **x,
pem_password_cb *cb, void *u);
pem_password_cb *cb, void *u);
int PEM_write_bio_X509_REQ(BIO *bp, X509_REQ *x);
int PEM_write_X509_REQ(FILE *fp, X509_REQ *x);
int PEM_write_bio_X509_REQ_NEW(BIO *bp, X509_REQ *x);
int PEM_write_X509_REQ_NEW(FILE *fp, X509_REQ *x);
X509_CRL *PEM_read_bio_X509_CRL(BIO *bp, X509_CRL **x,
pem_password_cb *cb, void *u);
pem_password_cb *cb, void *u);
X509_CRL *PEM_read_X509_CRL(FILE *fp, X509_CRL **x,
pem_password_cb *cb, void *u);
pem_password_cb *cb, void *u);
int PEM_write_bio_X509_CRL(BIO *bp, X509_CRL *x);
int PEM_write_X509_CRL(FILE *fp, X509_CRL *x);
PKCS7 *PEM_read_bio_PKCS7(BIO *bp, PKCS7 **x, pem_password_cb *cb, void *u);
PKCS7 *PEM_read_PKCS7(FILE *fp, PKCS7 **x, pem_password_cb *cb, void *u);
int PEM_write_bio_PKCS7(BIO *bp, PKCS7 *x);
int PEM_write_PKCS7(FILE *fp, PKCS7 *x);
NETSCAPE_CERT_SEQUENCE *PEM_read_bio_NETSCAPE_CERT_SEQUENCE(BIO *bp,
NETSCAPE_CERT_SEQUENCE **x,
pem_password_cb *cb, void *u);
NETSCAPE_CERT_SEQUENCE *PEM_read_NETSCAPE_CERT_SEQUENCE(FILE *fp,
NETSCAPE_CERT_SEQUENCE **x,
pem_password_cb *cb, void *u);
int PEM_write_bio_NETSCAPE_CERT_SEQUENCE(BIO *bp, NETSCAPE_CERT_SEQUENCE *x);
int PEM_write_NETSCAPE_CERT_SEQUENCE(FILE *fp, NETSCAPE_CERT_SEQUENCE *x);
=head1 DESCRIPTION
The PEM functions read or write structures in PEM format. In
@ -288,9 +231,6 @@ structure.
The B<PKCS7> functions process a PKCS#7 ContentInfo using a PKCS7
structure.
The B<NETSCAPE_CERT_SEQUENCE> functions process a Netscape Certificate
Sequence using a NETSCAPE_CERT_SEQUENCE structure.
=head1 PEM FUNCTION ARGUMENTS
The PEM functions have many common arguments.
@ -354,84 +294,65 @@ Read a certificate in PEM format from a BIO:
X509 *x;
x = PEM_read_bio_X509(bp, NULL, 0, NULL);
if (x == NULL)
{
/* Error */
}
if (x == NULL) {
/* Error */
}
Alternative method:
X509 *x = NULL;
if (!PEM_read_bio_X509(bp, &x, 0, NULL))
{
/* Error */
}
if (!PEM_read_bio_X509(bp, &x, 0, NULL)) {
/* Error */
}
Write a certificate to a BIO:
if (!PEM_write_bio_X509(bp, x))
{
/* Error */
}
Write an unencrypted private key to a FILE pointer:
if (!PEM_write_PrivateKey(fp, key, NULL, NULL, 0, 0, NULL))
{
/* Error */
}
if (!PEM_write_bio_X509(bp, x)) {
/* Error */
}
Write a private key (using traditional format) to a BIO using
triple DES encryption, the pass phrase is prompted for:
if (!PEM_write_bio_PrivateKey(bp, key, EVP_des_ede3_cbc(), NULL, 0, 0, NULL))
{
/* Error */
}
if (!PEM_write_bio_PrivateKey(bp, key, EVP_des_ede3_cbc(), NULL, 0, 0, NULL)) {
/* Error */
}
Write a private key (using PKCS#8 format) to a BIO using triple
DES encryption, using the pass phrase "hello":
if (!PEM_write_bio_PKCS8PrivateKey(bp, key, EVP_des_ede3_cbc(), NULL, 0, 0, "hello"))
{
/* Error */
}
Read a private key from a BIO using the pass phrase "hello":
key = PEM_read_bio_PrivateKey(bp, NULL, 0, "hello");
if (key == NULL)
{
/* Error */
}
if (!PEM_write_bio_PKCS8PrivateKey(bp, key, EVP_des_ede3_cbc(), NULL, 0, 0, "hello")) {
/* Error */
}
Read a private key from a BIO using a pass phrase callback:
key = PEM_read_bio_PrivateKey(bp, NULL, pass_cb, "My Private Key");
if (key == NULL)
{
/* Error */
}
if (key == NULL) {
/* Error */
}
Skeleton pass phrase callback:
int pass_cb(char *buf, int size, int rwflag, void *u);
{
int len;
char *tmp;
/* We'd probably do something else if 'rwflag' is 1 */
printf("Enter pass phrase for \"%s\"\n", u);
int pass_cb(char *buf, int size, int rwflag, void *u)
{
int len;
char *tmp;
/* get pass phrase, length 'len' into 'tmp' */
tmp = "hello";
len = strlen(tmp);
/* We'd probably do something else if 'rwflag' is 1 */
printf("Enter pass phrase for \"%s\"\n", (char *)u);
if (len <= 0) return 0;
/* if too long, truncate */
if (len > size) len = size;
memcpy(buf, tmp, len);
return len;
}
/* get pass phrase, length 'len' into 'tmp' */
tmp = "hello";
len = strlen(tmp);
if (len <= 0)
return 0;
if (len > size)
len = size;
memcpy(buf, tmp, len);
return len;
}
=head1 NOTES
@ -456,7 +377,7 @@ which is an uninitialised pointer.
=head1 PEM ENCRYPTION FORMAT
This old B<PrivateKey> routines use a non standard technique for encryption.
These old B<PrivateKey> routines use a non standard technique for encryption.
The private key (or other data) takes the following form:
@ -467,15 +388,43 @@ The private key (or other data) takes the following form:
...base64 encoded data...
-----END RSA PRIVATE KEY-----
The line beginning DEK-Info contains two comma separated pieces of information:
the encryption algorithm name as used by EVP_get_cipherbyname() and an 8
byte B<salt> encoded as a set of hexadecimal digits.
The line beginning with I<Proc-Type> contains the version and the
protection on the encapsulated data. The line beginning I<DEK-Info>
contains two comma separated values: the encryption algorithm name as
used by EVP_get_cipherbyname() and an initialization vector used by the
cipher encoded as a set of hexadecimal digits. After those two lines is
the base64-encoded encrypted data.
After this is the base64 encoded encrypted data.
The encryption key is derived using EVP_BytesToKey(). The cipher's
initialization vector is passed to EVP_BytesToKey() as the B<salt>
parameter. Internally, B<PKCS5_SALT_LEN> bytes of the salt are used
(regardless of the size of the initialization vector). The user's
password is passed to to EVP_BytesToKey() using the B<data> and B<datal>
parameters. Finally, the library uses an iteration count of 1 for
EVP_BytesToKey().
The encryption key is determined using EVP_BytesToKey(), using B<salt> and an
iteration count of 1. The IV used is the value of B<salt> and *not* the IV
returned by EVP_BytesToKey().
he B<key> derived by EVP_BytesToKey() along with the original initialization
vector is then used to decrypt the encrypted data. The B<iv> produced by
EVP_BytesToKey() is not utilized or needed, and NULL should be passed to
the function.
The pseudo code to derive the key would look similar to:
EVP_CIPHER* cipher = EVP_des_ede3_cbc();
EVP_MD* md = EVP_md5();
unsigned int nkey = EVP_CIPHER_key_length(cipher);
unsigned int niv = EVP_CIPHER_iv_length(cipher);
unsigned char key[nkey];
unsigned char iv[niv];
memcpy(iv, HexToBin("3F17F5316E2BAC89"), niv);
rc = EVP_BytesToKey(cipher, md, iv /*salt*/, pword, plen, 1, key, NULL /*iv*/);
if (rc != nkey) {
/* Error */
}
/* On success, use key and iv to initialize the cipher */
=head1 BUGS
@ -498,6 +447,12 @@ if an error occurred.
The write routines return 1 for success or 0 for failure.
=head1 HISTORY
The old Netscape certificate sequences were no longer documented
in OpenSSL 1.1; applications should use the PKCS7 standard instead
as they will be formally deprecated in a future releases.
=head1 SEE ALSO
L<EVP_get_cipherbyname(3)|EVP_EncryptInit(3)>, L<EVP_BytesToKey(3)|EVP_BytesToKey(3)>
L<EVP_EncryptInit(3)>, L<EVP_BytesToKey(3)>

View File

@ -84,9 +84,10 @@ threadid_func(CRYPTO_THREADID *id) is needed to record the currently-executing
thread's identifier into B<id>. The implementation of this callback should not
fill in B<id> directly, but should use CRYPTO_THREADID_set_numeric() if thread
IDs are numeric, or CRYPTO_THREADID_set_pointer() if they are pointer-based.
The B<id> must be unique for the duration of the execution of the program.
If the application does not register such a callback using
CRYPTO_THREADID_set_callback(), then a default implementation is used - on
Windows and BeOS this uses the system's default thread identifying APIs, and on
Windows this uses the system's default thread identifying APIs, and on
all other platforms it uses the address of B<errno>. The latter is satisfactory
for thread-safety if and only if the platform has a thread-local error number
facility.