Packages
hackney
2.0.1
4.7.2
4.7.1
4.7.0
4.6.1
4.6.0
4.5.2
4.5.1
4.5.0
4.4.5
4.4.3
4.4.2
4.4.1
4.4.0
4.3.0
4.2.3
4.2.2
4.2.1
4.2.0
4.1.0
4.0.3
4.0.2
4.0.1
4.0.0
3.2.1
3.2.0
3.1.2
3.1.1
3.1.0
3.0.3
3.0.2
3.0.1
3.0.0
retired
2.0.1
2.0.0
2.0.0-beta.1
1.25.0
1.24.1
1.24.0
1.23.0
1.22.0
1.21.0
1.20.1
1.20.0
1.19.1
1.19.0
1.18.2
1.18.1
1.18.0
1.17.4
1.17.3
1.17.2
1.17.1
1.17.0
1.16.0
1.15.2
1.15.1
1.15.0
1.14.3
1.14.2
1.14.0
1.13.0
1.12.1
1.12.0
1.11.0
1.10.1
1.10.0
1.9.0
1.8.6
1.8.5
1.8.4
1.8.3
1.8.2
1.8.0
1.7.1
1.7.0
1.6.6
retired
1.6.5
1.6.4
retired
1.6.3
1.6.2
1.6.1
1.6.0
1.5.7
1.5.6
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.4.10
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.0
1.1.0
1.0.6
1.0.5
1.0.2
1.0.1
0.15.2
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.1
Simple HTTP client with HTTP/1.1, HTTP/2, and HTTP/3 support
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
c_src/boringssl/crypto/pem/pem_pk8.cc
// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/pkcs8.h>
#include <openssl/rand.h>
#include <openssl/x509.h>
static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid,
const EVP_CIPHER *enc, const char *pass, int pass_len,
pem_password_cb *cb, void *u);
static int do_pk8pkey_fp(FILE *bp, const EVP_PKEY *x, int isder, int nid,
const EVP_CIPHER *enc, const char *pass, int pass_len,
pem_password_cb *cb, void *u);
// These functions write a private key in PKCS#8 format: it is a "drop in"
// replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc'
// is NULL then it uses the unencrypted private key form. The 'nid' versions
// uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0.
int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, const EVP_PKEY *x, int nid,
const char *pass, int pass_len,
pem_password_cb *cb, void *u) {
return do_pk8pkey(bp, x, 0, nid, nullptr, pass, pass_len, cb, u);
}
int PEM_write_bio_PKCS8PrivateKey(BIO *bp, const EVP_PKEY *x,
const EVP_CIPHER *enc, const char *pass,
int pass_len, pem_password_cb *cb, void *u) {
return do_pk8pkey(bp, x, 0, -1, enc, pass, pass_len, cb, u);
}
int i2d_PKCS8PrivateKey_bio(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc,
const char *pass, int pass_len, pem_password_cb *cb,
void *u) {
return do_pk8pkey(bp, x, 1, -1, enc, pass, pass_len, cb, u);
}
int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, const EVP_PKEY *x, int nid,
const char *pass, int pass_len,
pem_password_cb *cb, void *u) {
return do_pk8pkey(bp, x, 1, nid, nullptr, pass, pass_len, cb, u);
}
static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid,
const EVP_CIPHER *enc, const char *pass, int pass_len,
pem_password_cb *cb, void *u) {
X509_SIG *p8;
PKCS8_PRIV_KEY_INFO *p8inf;
char buf[PEM_BUFSIZE];
int ret;
if (!(p8inf = EVP_PKEY2PKCS8(x))) {
OPENSSL_PUT_ERROR(PEM, PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
return 0;
}
if (enc || (nid != -1)) {
if (!pass) {
if (!cb) {
cb = PEM_def_callback;
}
pass_len = cb(buf, PEM_BUFSIZE, 1, u);
if (pass_len < 0) {
OPENSSL_PUT_ERROR(PEM, PEM_R_READ_KEY);
PKCS8_PRIV_KEY_INFO_free(p8inf);
return 0;
}
pass = buf;
}
p8 = PKCS8_encrypt(nid, enc, pass, pass_len, nullptr, 0, 0, p8inf);
if (pass == buf) {
OPENSSL_cleanse(buf, pass_len);
}
PKCS8_PRIV_KEY_INFO_free(p8inf);
if (isder) {
ret = i2d_PKCS8_bio(bp, p8);
} else {
ret = PEM_write_bio_PKCS8(bp, p8);
}
X509_SIG_free(p8);
return ret;
} else {
if (isder) {
ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
} else {
ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf);
}
PKCS8_PRIV_KEY_INFO_free(p8inf);
return ret;
}
}
EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
void *u) {
PKCS8_PRIV_KEY_INFO *p8inf = nullptr;
X509_SIG *p8 = nullptr;
int pass_len;
EVP_PKEY *ret;
char psbuf[PEM_BUFSIZE];
p8 = d2i_PKCS8_bio(bp, nullptr);
if (!p8) {
return nullptr;
}
pass_len = 0;
if (!cb) {
cb = PEM_def_callback;
}
pass_len = cb(psbuf, PEM_BUFSIZE, 0, u);
if (pass_len < 0) {
OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ);
X509_SIG_free(p8);
return nullptr;
}
p8inf = PKCS8_decrypt(p8, psbuf, pass_len);
X509_SIG_free(p8);
OPENSSL_cleanse(psbuf, pass_len);
if (!p8inf) {
return nullptr;
}
ret = EVP_PKCS82PKEY(p8inf);
PKCS8_PRIV_KEY_INFO_free(p8inf);
if (!ret) {
return nullptr;
}
if (x) {
if (*x) {
EVP_PKEY_free(*x);
}
*x = ret;
}
return ret;
}
int i2d_PKCS8PrivateKey_fp(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc,
const char *pass, int pass_len, pem_password_cb *cb,
void *u) {
return do_pk8pkey_fp(fp, x, 1, -1, enc, pass, pass_len, cb, u);
}
int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, const EVP_PKEY *x, int nid,
const char *pass, int pass_len,
pem_password_cb *cb, void *u) {
return do_pk8pkey_fp(fp, x, 1, nid, nullptr, pass, pass_len, cb, u);
}
int PEM_write_PKCS8PrivateKey_nid(FILE *fp, const EVP_PKEY *x, int nid,
const char *pass, int pass_len,
pem_password_cb *cb, void *u) {
return do_pk8pkey_fp(fp, x, 0, nid, nullptr, pass, pass_len, cb, u);
}
int PEM_write_PKCS8PrivateKey(FILE *fp, const EVP_PKEY *x,
const EVP_CIPHER *enc, const char *pass,
int pass_len, pem_password_cb *cb, void *u) {
return do_pk8pkey_fp(fp, x, 0, -1, enc, pass, pass_len, cb, u);
}
static int do_pk8pkey_fp(FILE *fp, const EVP_PKEY *x, int isder, int nid,
const EVP_CIPHER *enc, const char *pass, int pass_len,
pem_password_cb *cb, void *u) {
BIO *bp;
int ret;
if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
return 0;
}
ret = do_pk8pkey(bp, x, isder, nid, enc, pass, pass_len, cb, u);
BIO_free(bp);
return ret;
}
EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb,
void *u) {
BIO *bp;
EVP_PKEY *ret;
if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
return nullptr;
}
ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u);
BIO_free(bp);
return ret;
}
IMPLEMENT_PEM_rw(PKCS8, X509_SIG, PEM_STRING_PKCS8, X509_SIG)
IMPLEMENT_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF,
PKCS8_PRIV_KEY_INFO)