fr::crypto::pem(3SSL)

NOM
PEM, PEM_read_bio_PrivateKey, PEM_read_PrivateKey, PEM_write_bio_PrivateKey, PEM_write_PrivateKey, PEM_write_bio_PKCS8PrivateKey, PEM_write_PKCS8PrivateKey, PEM_write_bio_PKCS8PrivateKey_nid, PEM_write_PKCS8PrivateKey_nid, PEM_read_bio_PUBKEY, PEM_read_PUBKEY, PEM_write_bio_PUBKEY, PEM_write_PUBKEY, PEM_read_bio_RSAPrivateKey, PEM_read_RSAPrivateKey, PEM_write_bio_RSAPrivateKey, PEM_write_RSAPrivateKey, PEM_read_bio_RSAPublicKey, PEM_read_RSAPublicKey, PEM_write_bio_RSAPublicKey, PEM_write_RSAPublicKey, PEM_read_bio_RSA_PUBKEY, PEM_read_RSA_PUBKEY, PEM_write_bio_RSA_PUBKEY, PEM_write_RSA_PUBKEY, PEM_read_bio_DSAPrivateKey, PEM_read_DSAPrivateKey, PEM_write_bio_DSAPrivateKey, PEM_write_DSAPrivateKey, PEM_read_bio_DSA_PUBKEY, PEM_read_DSA_PUBKEY, PEM_write_bio_DSA_PUBKEY, PEM_write_DSA_PUBKEY, PEM_read_bio_DSAparams, PEM_read_DSAparams, PEM_write_bio_DSAparams, PEM_write_DSAparams, PEM_read_bio_DHparams, PEM_read_DHparams, PEM_write_bio_DHparams, PEM_write_DHparams, PEM_read_bio_X509, PEM_read_X509, PEM_write_bio_X509, PEM_write_X509, PEM_read_bio_X509_AUX, PEM_read_X509_AUX, PEM_write_bio_X509_AUX, 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 - routines PEM

SYNOPSIS
 #include <openssl/pem.h>

 EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x,
                                        pem_password_cb *cb, void *u);

 EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x,
                                        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);

 int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
                                        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);

 int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
                                        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);

 int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
                                        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);

 EVP_PKEY *PEM_read_PUBKEY(FILE *fp, EVP_PKEY **x,
                                        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);

 RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **x,
                                        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);

 int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc,
                                        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);

 RSA *PEM_read_RSAPublicKey(FILE *fp, RSA **x,
                                        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);

 RSA *PEM_read_RSA_PUBKEY(FILE *fp, RSA **x,
                                        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);

 DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **x,
                                        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);

 int PEM_write_DSAPrivateKey(FILE *fp, DSA *x, const EVP_CIPHER *enc,
                                        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);

 DSA *PEM_read_DSA_PUBKEY(FILE *fp, DSA **x,
                                        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);

 X509_REQ *PEM_read_X509_REQ(FILE *fp, X509_REQ **x,
                                        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);
 X509_CRL *PEM_read_X509_CRL(FILE *fp, X509_CRL **x,
                                        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);

DESCRIPTION
Les fonctions PEM lisent ou écrivent des structures au format PEM. En ce sens, le format PEM est simplement des données chiffrées en base64 entourées de lignes d'en-tête.

Pour plus de détails sur la signification des arguments, voir la partie ARGUMENTS DES FONCTIONS PEM.

Chaque opération possède 4 fonctions qui lui sont associées. Pour clarifier le terme « fonctions foobar » sera utilisé pour faire collectivement référence aux fonctions PEM_read_bio_foobar(), PEM_read_foobar(), PEM_write_bio_foobar() et PEM_write_foobar()

La fonction PrivateKey lit et écrit une clé privée dans le format PEM en utilisant une structure EVP_PKEY. Les routines d'écriture utilisent une clé privée au format « traditionnel » et peuvent gérer les clés privées RSA et DSA. Les fonctions de lecture peuvent aussi gérer de façon transparente les clés chiffrées et déchiffrées au format PKCS#8.

PEM_write_bio_PKCS8PrivateKey() et PEM_write_PKCS8PrivateKey() écrivent une clé privée dans une structure EVP_PKEY dans le format PKCS#8 EncryptedPrivateKeyInfo en utilisant un algorithme de mot de passe basé sur PKCS#5 v2.0. L'argument cipher spécifie l'algorithme de chiffrement à utiliser : contrairement à toutes les autres routines PEM, le chiffrement est appliqué au niveau du PKCS#8 et pas dans les en-têtes PEM. Si cipher est NULL alors il n'y aura pas de chiffrement utilisé et une structure PKCS#8 PrivateKeyInfo sera utilisée.

PEM_write_bio_PKCS8PrivateKey_nid() et PEM_write_PKCS8PrivateKey_nid() écrivent aussi une clé privée comme PKCS#8 EncryptedPrivateKeyInfo cependant elles utilisent les algorithmes de chiffrement KCS#5 v1.5 ou PKCS#12 à la place. L'algorithme à utiliser dans le paramètre nid doit être le NID de l'IDENTIFIANT DE L'OBJET (voir la section NOTES).

Les fonctions PUBKEY traitent une clé publique en utilisant une structure EVP_PKEY. La clé publique est chiffrée comme une structure SubjectPublicKeyInfo.

Les fonctions RSAPrivateKey traitent une clé RSA privée en utilisant une structure RSA. Elles gèrent le même format que les fonctions PrivateKey mais une erreur se produit si la clé privée n'est pas une clé RSA.

Les fonctions RSAPublicKey traitent une clé RSA publique en utilisant une structure RSA. La clé publique est chiffrée en utilisant une structure PKCS#1 RSAPublicKey

Les fonctions RSA_PUBKEY traitent aussi une clé publique en utilisant une structure RSA. Mais la clé publique est chiffrée en utilisant une structure SubjectPublicKeyInfo et une erreur se produit si la clé publique n'est pas une clé RSA.

Les fonctions DSAPrivateKey traitent une clé DSA privée en utilisant une structure DSA. Elles gèrent les mêmes formats que les fonctions PrivateKey mais une erreur se produit si la clé privée n'est pas une clé DSA.

Les fonctions DSA_PUBKEY traitent une clé publique DSA en utilisant une structure DSA. La clé publique est chiffrée en utilisant une structure SubjectPublicKeyInfo et une erreur se produit si la clé publique n'est pas une clé DSA.

Les fonctions DSAparams traitent les paramètres DSA en utilisant une structure DSA. Les paramètres sont chiffrés en utilisant une structure Dss-Parms telle que définie dans la RFC2459.

Les fonctions DHparams traitent les paramètres DH en utilisant une structure DH. Les paramètres sont chiffrés en utilisant une structure PKCS#3 DHparameter

Les fonctions X509 traitent un certificat X509 en utilisant une structure X509. Elles traitent aussi les certificats X509 certifiés mais les paramètres de réglages sont ignorés.

Les fonctions X509_AUX traitent un certificat X509 certifié en utilisant une structure X509.

Les fonctions X509_REQ et X509_REQ_NEW traitent une requête de certificat PKCS#10 en utilisant une structure X509_REQ. La fonction d'écriture X509_REQ utilise CERTIFICATE REQUEST dans l'en-tête alors que les fonctions X509_REQ_NEW utilisent NEW CERTIFICATE REQUEST (comme requis par des CA). Les fonctions de lecture X509_REQ peuvent gérer les deux formes, il n'y a donc pas de fonctions de lecture X509_REQ_NEW.

Les fonctions X509_CRL traitent un CRL X509 en utilisant une structure X509_CRL.

Les fonctions PKCS7 traitent un PKCS#7 ContentInfo en utilisant une structure PKCS7.

Les fonctions NETSCAPE_CERT_SEQUENCE traitent une séquence de certificats Netscape en utilisant une structure NETSCAPE_CERT_SEQUENCE.

ARGUMENTS DES FONCTIONS PEM
Les fonctions PEM ont beaucoup d'arguments en commun.

Les paramètres bp (si présents) spécifient le BIO dans lequel il faut lire ou écrire.

Le paramètre de FILE fp (si présent) spécifie le pointeur de FILE dans lequel il faut lire ou écrire.

Les fonctions de lecture PEM prennent toutes un argument TYPE **x et renvoient toutes un pointeur TYPE *, où TYPE est une structure quelconque que la fonction utilise. Si x est NULL, alors le paramètre est ignoré. Si x n'est pas NULL mais *x est NULL, alors la structure renvoyée sera écrite dans *x. Si ni x et *x ne sont NULL, alors une tentative de réutilisation de la structure sera faite (mais voir la partie BOGUES et EXEMPLES). Quelle que soit la valeur de x, un pointeur vers une structure est toujours renvoyé (ou NULL en cas d'erreur).

Les fonctions PEM qui utilisent des clés privées prennent un paramètre enc qui spécifie l'algorithme de chiffrement à utiliser, le chiffrement est fait au niveau du PEM. Si ce paramètre est mis à NULL, alors la clé privée est écrite de façon non chiffrée.

L'argument cb est le rappel à utiliser pour les requêtes pour le mot de passe utilisé pour chiffrer les structures PEM (que des clés privées normalement).

Pour les routines d'écritures PEM, si le paramètre kstr n'est pas NULL, alors klen octets à kstr sont utilisés comme mot de passe et cb est ignoré.

Si les paramètres cb sont initialisés à NULL et que le paramètre u n'est pas NULL, alors le paramètre u n'est pas correctement interprété comme une chaîne de caractère terminée par un null à utiliser comme mot de passe. Si cb et u sont NULL, alors la routine de retour est utilisée, ce qui affiche généralement une demande d'entrée de texte pour le mot de passe sur le terminal courant et sans affichage de l'entrée.

Le rappel du mot de passe par défaut n'est parfois pas approprié (par exemple dans une application à interface graphique), une alternative peut donc être fournie. La routine de retour de fonction a la forme suivante :

 int cb(char *buf, int size, int rwflag, void *u);

buf est le tampon d'écriture dans lequel sera écrit le mot de passe. size est la taille maximale du mot de passe (c'est-à-dire la taille du tampon). rwflag est un drapeau qui est mis à 0 lors d'une lecture et à 1 lors d'une écriture. Une routine typique demandera à l'utilisateur de vérifier le mot de passe (par exemple pour le demander deux fois) si rwflagest à 1. Le paramètre u a la même valeur que le paramètre u passé à la routine PEM. Il autorise l'application à passer des données arbitraires à la rétroaction (par exemple un gestionnaire de fenêtres dans une application à interface graphique). La rétroaction doit renvoyer le nombre de caractères dans le mot de passe ou 0 en cas d'erreur.

EXEMPLES
Bien que les routines PEM prennent plusieurs arguments, dans presque toutes leurs applications ceux-ci sont mis à 0 ou NULL.

Lire un certificat dans le format PEM à partir d'un BIO :

 X509 *x;
 x = PEM_read_bio_X509(bp, NULL, 0, NULL);
 if (x == NULL)
        {
        /* Erreur */
        }

Méthodes alternatives :

 X509 *x = NULL;
 if (!PEM_read_bio_X509(bp, &x, 0, NULL))
        {
        /* Erreur */
        }

Écrire un certificat dans un BIO :

 if (!PEM_write_bio_X509(bp, x))
        {
        /* Erreur */
        }

Écrire une clé non chiffrée dans un pointeur FILE :

 if (!PEM_write_PrivateKey(fp, key, NULL, NULL, 0, 0, NULL))
        {
        /* Erreur */
        }

Écrire une clé privée (en utilisant le format traditionnel) dans un BIO en utilisant un chiffrement Triple-DES, le mot de passe est requis :

 if (!PEM_write_bio_PrivateKey(bp, key, EVP_des_ede3_cbc(), NULL, 0, 0, NULL))
        {
        /* Erreur */
        }

Écrire une clé privée (en utilisant le format PKCS#8) dans un BIO en utilisant le chiffrement Triple-DES, en utilisant le mot de passe « hello » :

 if (!PEM_write_bio_PKCS8PrivateKey(bp, key, EVP_des_ede3_cbc(), NULL, 0, 0, "hello"))
        {
        /* Erreur */
        }

Lire une clé privée d'un BIO en utilisant le mot de passe « hello » :

 key = PEM_read_bio_PrivateKey(bp, NULL, 0, "hello");
 if (key == NULL)
        {
        /* Erreur */
        }

Lire une clé privée d'un BIO en utilisant le rappel de phrase secrète :

 key = PEM_read_bio_PrivateKey(bp, NULL, pass_cb, "My Private Key");
 if (key == NULL)
        {
        /* Erreur */
        }

Squelette de rappel de phrase secrète :

 int pass_cb(char *buf, int size, int rwflag, void *u);
        {
        int len;
        char *tmp;
        /* On ferait probablement autre chose si 'rwflag' était à 1 */
        printf("Enter pass phrase for \"%s\"\n", u);

        /* obtenir la phrase chiffrée, longueur 'len' dans 'tmp' */
        tmp = "hello";
        len = strlen(tmp);

        if (len <= 0) return 0;
        /* if too long, truncate */
        if (len > size) len = size;
        memcpy(buf, tmp, len);
        return len;
        }

NOTES
Les anciennes routines d'écriture PrivateKey sont gardées pour raisons de comptabilité. Les nouvelles applications doivent écrire de nouvelles clés privées en utilisant les routines PEM_write_bio_PKCS8PrivateKey() ou PEM_write_PKCS8PrivateKey() car elles sont plus sécurisées (elles utilisent un compteur d'itération sur 2048 alors que les routines traditionnelles utilisent un compteur de 1) sauf si la compatibilité avec les anciennes versions d'OpenSSL est importante.

Les routines de lecture PrivateKey peuvent être utilisées dans toutes les applications car elles manipulent tous les formats de façon transparente.

Un cas récurrent de problèmes est la tentative d'utilisation des routines PEM de la façon suivante :

 X509 *x;
 PEM_read_bio_X509(bp, &x, 0, NULL);

cela est un bogue car une tentative de réutilisation des données à x sera faite alors que c'est un pointeur qui n'est pas initialisé.

FORMAT DE CHIFFREMENT PEM
Cette vieille routine PrivateKey utilise une méthode non standard de chiffrement.

La clé privée (ou toute autre donnée) prend la forme suivante :

 -----DÉBUT CLÉ PRIVÉE RSA-----
 Proc-Type: 4,ENCRYPTED
 DEK-Info: DES-EDE3-CBC,3F17F5316E2BAC89

 ...données encodées en base64...
 -----FIN CLÉ PRIVÉE RSA-----

La ligne qui commence DEK-Info contient deux virgules séparées par des morceaux d'information : le nom de l'algorithme de chiffrement comme utilisé par EVP_get_cipherbyname() et un salt de 8 octets chiffré comme un ensemble de valeurs hexadécimales.

Après ce sont les données chiffrées en base64.

La clé de chiffrement est déterminée en utilisant EVP_Bytestokey(), en utilisant salt et un compteur d'itération de 1. Le IV utilisé est la valeur de salt et *pas* le IV renvoyé par EVP_Bytestokey().

BOGUES
Les routines de lecture PEM, dans certaines versions d'OpenSSL, n'utiliseront pas correctement les structures existantes. De ce fait, ce qui suit :

 PEM_read_bio_X509(bp, &x, 0, NULL);

où x contient déjà un certificat valable, risque de ne pas fonctionner, alors que :

 X509_free(x);
 x = PEM_read_bio_X509(bp, NULL, 0, NULL);

est garanti de fonctionner.

CODES DE RETOUR
Les routines de lectures renvoient soit un pointeur vers la structure read ou NULL si une erreur s'est produite.

La routine d'écriture renvoie 1 en cas de succès et 0 en cas d'échec.

VOIR AUSSI
EVP_get_cipherbyname(3), EVP_BytesToKey(3)

TRADUCTION
La traduction de cette page de manuel est maintenue par les membres de la liste <debian-l10n-french AT lists DOT debian DOT org>. Veuillez signaler toute erreur de traduction par un rapport de bogue sur le paquet manpages-fr-extra.