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/x509/x_all.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/x509.h>
#include <limits.h>
#include <openssl/asn1.h>
#include <openssl/bytestring.h>
#include <openssl/digest.h>
#include <openssl/dsa.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/rsa.h>
#include <openssl/span.h>
#include <openssl/stack.h>
#include "../asn1/internal.h"
#include "../internal.h"
#include "internal.h"
int X509_verify(X509 *x509, EVP_PKEY *pkey) {
if (X509_ALGOR_cmp(&x509->sig_alg, &x509->tbs_sig_alg)) {
OPENSSL_PUT_ERROR(X509, X509_R_SIGNATURE_ALGORITHM_MISMATCH);
return 0;
}
// This uses the cached TBSCertificate encoding, if any.
bssl::ScopedCBB cbb;
if (!CBB_init(cbb.get(), 128) || !x509_marshal_tbs_cert(cbb.get(), x509)) {
return 0;
}
return x509_verify_signature(
&x509->sig_alg, &x509->signature,
bssl::Span(CBB_data(cbb.get()), CBB_len(cbb.get())), pkey);
}
int X509_REQ_verify(X509_REQ *req, EVP_PKEY *pkey) {
return ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO), req->sig_alg,
req->signature, req->req_info, pkey);
}
int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) {
bssl::ScopedEVP_MD_CTX ctx;
if (!EVP_DigestSignInit(ctx.get(), nullptr, md, nullptr, pkey)) {
return 0;
}
return X509_sign_ctx(x, ctx.get());
}
int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) {
// Historically, this function called |EVP_MD_CTX_cleanup| on return. Some
// callers rely on this to avoid memory leaks.
bssl::Cleanup cleanup = [&] { EVP_MD_CTX_cleanup(ctx); };
// Fill in the two copies of AlgorithmIdentifier. Note one of these modifies
// the TBSCertificate.
if (!x509_digest_sign_algorithm(ctx, &x->tbs_sig_alg) ||
!x509_digest_sign_algorithm(ctx, &x->sig_alg)) {
return 0;
}
// Discard the cached encoding. (We just modified it.)
CRYPTO_BUFFER_free(x->buf);
x->buf = nullptr;
bssl::ScopedCBB cbb;
if (!CBB_init(cbb.get(), 128) || !x509_marshal_tbs_cert(cbb.get(), x)) {
return 0;
}
return x509_sign_to_bit_string(
ctx, &x->signature, bssl::Span(CBB_data(cbb.get()), CBB_len(cbb.get())));
}
int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md) {
asn1_encoding_clear(&x->req_info->enc);
return ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO), x->sig_alg, nullptr,
x->signature, x->req_info, pkey, md);
}
int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx) {
asn1_encoding_clear(&x->req_info->enc);
return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO), x->sig_alg, nullptr,
x->signature, x->req_info, ctx);
}
int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md) {
asn1_encoding_clear(&x->crl->enc);
return ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO), x->crl->sig_alg,
x->sig_alg, x->signature, x->crl, pkey, md);
}
int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx) {
asn1_encoding_clear(&x->crl->enc);
return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO), x->crl->sig_alg,
x->sig_alg, x->signature, x->crl, ctx);
}
int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md) {
return ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor, nullptr,
x->signature, x->spkac, pkey, md);
}
int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *spki, EVP_PKEY *pkey) {
return ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), spki->sig_algor,
spki->signature, spki->spkac, pkey);
}
X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl) {
return reinterpret_cast<X509_CRL *>(
ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl));
}
int i2d_X509_CRL_fp(FILE *fp, const X509_CRL *crl) {
return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
}
X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl) {
return reinterpret_cast<X509_CRL *>(
ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl));
}
int i2d_X509_CRL_bio(BIO *bp, const X509_CRL *crl) {
return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
}
X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req) {
return reinterpret_cast<X509_REQ *>(
ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req));
}
int i2d_X509_REQ_fp(FILE *fp, const X509_REQ *req) {
return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
}
X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req) {
return reinterpret_cast<X509_REQ *>(
ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_REQ), bp, req));
}
int i2d_X509_REQ_bio(BIO *bp, const X509_REQ *req) {
return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_REQ), bp, req);
}
#define IMPLEMENT_D2I_FP(type, name, bio_func) \
type *name(FILE *fp, type **obj) { \
BIO *bio = BIO_new_fp(fp, BIO_NOCLOSE); \
if (bio == nullptr) { \
return nullptr; \
} \
type *ret = bio_func(bio, obj); \
BIO_free(bio); \
return ret; \
}
#define IMPLEMENT_I2D_FP(type, name, bio_func) \
int name(FILE *fp, const type *obj) { \
BIO *bio = BIO_new_fp(fp, BIO_NOCLOSE); \
if (bio == nullptr) { \
return 0; \
} \
int ret = bio_func(bio, obj); \
BIO_free(bio); \
return ret; \
}
IMPLEMENT_D2I_FP(X509, d2i_X509_fp, d2i_X509_bio)
IMPLEMENT_I2D_FP(X509, i2d_X509_fp, i2d_X509_bio)
IMPLEMENT_D2I_FP(RSA, d2i_RSAPrivateKey_fp, d2i_RSAPrivateKey_bio)
IMPLEMENT_I2D_FP(RSA, i2d_RSAPrivateKey_fp, i2d_RSAPrivateKey_bio)
IMPLEMENT_D2I_FP(RSA, d2i_RSAPublicKey_fp, d2i_RSAPublicKey_bio)
IMPLEMENT_I2D_FP(RSA, i2d_RSAPublicKey_fp, i2d_RSAPublicKey_bio)
IMPLEMENT_D2I_FP(RSA, d2i_RSA_PUBKEY_fp, d2i_RSA_PUBKEY_bio)
IMPLEMENT_I2D_FP(RSA, i2d_RSA_PUBKEY_fp, i2d_RSA_PUBKEY_bio)
#define IMPLEMENT_D2I_BIO(type, name, d2i_func) \
type *name(BIO *bio, type **obj) { \
uint8_t *data; \
size_t len; \
if (!BIO_read_asn1(bio, &data, &len, 100 * 1024)) { \
return nullptr; \
} \
const uint8_t *ptr = data; \
type *ret = d2i_func(obj, &ptr, (long)len); \
OPENSSL_free(data); \
return ret; \
}
#define IMPLEMENT_I2D_BIO(type, name, i2d_func) \
int name(BIO *bio, const type *obj) { \
uint8_t *data = nullptr; \
int len = i2d_func(obj, &data); \
if (len < 0) { \
return 0; \
} \
int ret = BIO_write_all(bio, data, len); \
OPENSSL_free(data); \
return ret; \
}
IMPLEMENT_D2I_BIO(X509, d2i_X509_bio, d2i_X509)
IMPLEMENT_I2D_BIO(X509, i2d_X509_bio, i2d_X509)
IMPLEMENT_D2I_BIO(RSA, d2i_RSAPrivateKey_bio, d2i_RSAPrivateKey)
IMPLEMENT_I2D_BIO(RSA, i2d_RSAPrivateKey_bio, i2d_RSAPrivateKey)
IMPLEMENT_D2I_BIO(RSA, d2i_RSAPublicKey_bio, d2i_RSAPublicKey)
IMPLEMENT_I2D_BIO(RSA, i2d_RSAPublicKey_bio, i2d_RSAPublicKey)
IMPLEMENT_D2I_BIO(RSA, d2i_RSA_PUBKEY_bio, d2i_RSA_PUBKEY)
IMPLEMENT_I2D_BIO(RSA, i2d_RSA_PUBKEY_bio, i2d_RSA_PUBKEY)
IMPLEMENT_D2I_FP(DSA, d2i_DSAPrivateKey_fp, d2i_DSAPrivateKey_bio)
IMPLEMENT_I2D_FP(DSA, i2d_DSAPrivateKey_fp, i2d_DSAPrivateKey_bio)
IMPLEMENT_D2I_FP(DSA, d2i_DSA_PUBKEY_fp, d2i_DSA_PUBKEY_bio)
IMPLEMENT_I2D_FP(DSA, i2d_DSA_PUBKEY_fp, i2d_DSA_PUBKEY_bio)
IMPLEMENT_D2I_BIO(DSA, d2i_DSAPrivateKey_bio, d2i_DSAPrivateKey)
IMPLEMENT_I2D_BIO(DSA, i2d_DSAPrivateKey_bio, i2d_DSAPrivateKey)
IMPLEMENT_D2I_BIO(DSA, d2i_DSA_PUBKEY_bio, d2i_DSA_PUBKEY)
IMPLEMENT_I2D_BIO(DSA, i2d_DSA_PUBKEY_bio, i2d_DSA_PUBKEY)
IMPLEMENT_D2I_FP(EC_KEY, d2i_ECPrivateKey_fp, d2i_ECPrivateKey_bio)
IMPLEMENT_I2D_FP(EC_KEY, i2d_ECPrivateKey_fp, i2d_ECPrivateKey_bio)
IMPLEMENT_D2I_FP(EC_KEY, d2i_EC_PUBKEY_fp, d2i_EC_PUBKEY_bio)
IMPLEMENT_I2D_FP(EC_KEY, i2d_EC_PUBKEY_fp, i2d_EC_PUBKEY_bio)
IMPLEMENT_D2I_BIO(EC_KEY, d2i_ECPrivateKey_bio, d2i_ECPrivateKey)
IMPLEMENT_I2D_BIO(EC_KEY, i2d_ECPrivateKey_bio, i2d_ECPrivateKey)
IMPLEMENT_D2I_BIO(EC_KEY, d2i_EC_PUBKEY_bio, d2i_EC_PUBKEY)
IMPLEMENT_I2D_BIO(EC_KEY, i2d_EC_PUBKEY_bio, i2d_EC_PUBKEY)
int X509_pubkey_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
unsigned int *len) {
ASN1_BIT_STRING *key;
key = X509_get0_pubkey_bitstr(data);
if (!key) {
return 0;
}
return EVP_Digest(key->data, key->length, md, len, type, nullptr);
}
int X509_digest(const X509 *x509, const EVP_MD *md, uint8_t *out,
unsigned *out_len) {
uint8_t *der = nullptr;
int der_len = i2d_X509(x509, &der);
if (der_len < 0) {
return 0;
}
int ret = EVP_Digest(der, der_len, out, out_len, md, nullptr);
OPENSSL_free(der);
return ret;
}
int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, unsigned char *md,
unsigned int *len) {
return (
ASN1_item_digest(ASN1_ITEM_rptr(X509_CRL), type, (char *)data, md, len));
}
int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, unsigned char *md,
unsigned int *len) {
return (
ASN1_item_digest(ASN1_ITEM_rptr(X509_REQ), type, (char *)data, md, len));
}
int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type,
unsigned char *md, unsigned int *len) {
return (
ASN1_item_digest(ASN1_ITEM_rptr(X509_NAME), type, (char *)data, md, len));
}
IMPLEMENT_D2I_FP(X509_SIG, d2i_PKCS8_fp, d2i_PKCS8_bio)
IMPLEMENT_I2D_FP(X509_SIG, i2d_PKCS8_fp, i2d_PKCS8_bio)
IMPLEMENT_D2I_BIO(X509_SIG, d2i_PKCS8_bio, d2i_X509_SIG)
IMPLEMENT_I2D_BIO(X509_SIG, i2d_PKCS8_bio, i2d_X509_SIG)
IMPLEMENT_D2I_FP(PKCS8_PRIV_KEY_INFO, d2i_PKCS8_PRIV_KEY_INFO_fp,
d2i_PKCS8_PRIV_KEY_INFO_bio)
IMPLEMENT_I2D_FP(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO_fp,
i2d_PKCS8_PRIV_KEY_INFO_bio)
int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, const EVP_PKEY *key) {
PKCS8_PRIV_KEY_INFO *p8inf;
int ret;
p8inf = EVP_PKEY2PKCS8(key);
if (!p8inf) {
return 0;
}
ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf);
PKCS8_PRIV_KEY_INFO_free(p8inf);
return ret;
}
IMPLEMENT_D2I_FP(EVP_PKEY, d2i_PrivateKey_fp, d2i_PrivateKey_bio)
IMPLEMENT_I2D_FP(EVP_PKEY, i2d_PrivateKey_fp, i2d_PrivateKey_bio)
IMPLEMENT_D2I_FP(EVP_PKEY, d2i_PUBKEY_fp, d2i_PUBKEY_bio)
IMPLEMENT_I2D_FP(EVP_PKEY, i2d_PUBKEY_fp, i2d_PUBKEY_bio)
IMPLEMENT_D2I_BIO(PKCS8_PRIV_KEY_INFO, d2i_PKCS8_PRIV_KEY_INFO_bio,
d2i_PKCS8_PRIV_KEY_INFO)
IMPLEMENT_I2D_BIO(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO_bio,
i2d_PKCS8_PRIV_KEY_INFO)
int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, const EVP_PKEY *key) {
PKCS8_PRIV_KEY_INFO *p8inf;
int ret;
p8inf = EVP_PKEY2PKCS8(key);
if (!p8inf) {
return 0;
}
ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
PKCS8_PRIV_KEY_INFO_free(p8inf);
return ret;
}
IMPLEMENT_D2I_BIO(EVP_PKEY, d2i_PrivateKey_bio, d2i_AutoPrivateKey)
IMPLEMENT_I2D_BIO(EVP_PKEY, i2d_PrivateKey_bio, i2d_PrivateKey)
IMPLEMENT_D2I_BIO(EVP_PKEY, d2i_PUBKEY_bio, d2i_PUBKEY)
IMPLEMENT_I2D_BIO(EVP_PKEY, i2d_PUBKEY_bio, i2d_PUBKEY)
IMPLEMENT_D2I_BIO(DH, d2i_DHparams_bio, d2i_DHparams)
IMPLEMENT_I2D_BIO(DH, i2d_DHparams_bio, i2d_DHparams)