/*
* Copyright 1995-2023 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
* https://www.openssl.org/source/license.html
*/
/*
* Low level APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/buffer.h>
#include <openssl/asn1.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/http.h>
#include <openssl/rsa.h>
#include <openssl/dsa.h>
#include <openssl/x509v3.h>
#include "internal/asn1.h"
#include "crypto/pkcs7.h"
#include "crypto/x509.h"
#include "crypto/rsa.h"
int X509_verify(X509 *a, EVP_PKEY *r)
{
if (X509_ALGOR_cmp(&a->sig_alg, &a->cert_info.signature) != 0)
return 0;
return ASN1_item_verify_ex(ASN1_ITEM_rptr(X509_CINF), &a->sig_alg,
&a->signature, &a->cert_info,
a->distinguishing_id, r, a->libctx, a->propq);
}
int X509_REQ_verify_ex(X509_REQ *a, EVP_PKEY *r, OSSL_LIB_CTX *libctx,
const char *propq)
{
return ASN1_item_verify_ex(ASN1_ITEM_rptr(X509_REQ_INFO), &a->sig_alg,
a->signature, &a->req_info, a->distinguishing_id,
r, libctx, propq);
}
int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r)
{
return X509_REQ_verify_ex(a, r, NULL, NULL);
}
int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r)
{
return ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC),
&a->sig_algor, a->signature, a->spkac, r);
}
int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
{
if (x == NULL) {
ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (sk_X509_EXTENSION_num(X509_get0_extensions(x)) > 0
&& !X509_set_version(x, X509_VERSION_3))
return 0;
/*
* Setting the modified flag before signing it. This makes the cached
* encoding to be ignored, so even if the certificate fields have changed,
* they are signed correctly.
* The X509_sign_ctx, X509_REQ_sign{,_ctx}, X509_CRL_sign{,_ctx} functions
* which exist below are the same.
*/
x->cert_info.enc.modified = 1;
return ASN1_item_sign_ex(ASN1_ITEM_rptr(X509_CINF), &x->cert_info.signature,
&x->sig_alg, &x->signature, &x->cert_info, NULL,
pkey, md, x->libctx, x->propq);
}
int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx)
{
if (x == NULL) {
ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (sk_X509_EXTENSION_num(X509_get0_extensions(x)) > 0
&& !X509_set_version(x, X509_VERSION_3))
return 0;
x->cert_info.enc.modified = 1;
return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF),
&x->cert_info.signature,
&x->sig_alg, &x->signature, &x->cert_info, ctx);
}
static ASN1_VALUE *simple_get_asn1(const char *url, BIO *bio, BIO *rbio,
int timeout, const ASN1_ITEM *it)
{
#ifndef OPENSSL_NO_HTTP
BIO *mem = OSSL_HTTP_get(url, NULL /* proxy */, NULL /* no_proxy */,
bio, rbio, NULL /* cb */, NULL /* arg */,
1024 /* buf_size */, NULL /* headers */,
NULL /* expected_ct */, 1 /* expect_asn1 */,
OSSL_HTTP_DEFAULT_MAX_RESP_LEN, timeout);
ASN1_VALUE *res = ASN1_item_d2i_bio(it, mem, NULL);
BIO_free(mem);
return res;
#else
return 0;
#endif
}
X509 *X509_load_http(const char *url, BIO *bio, BIO *rbio, int timeout)
{
return (X509 *)simple_get_asn1(url, bio, rbio, timeout,
ASN1_ITEM_rptr(X509));
}
int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md)
{
if (x == NULL) {
ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
x->req_info.enc.modified = 1;
return ASN1_item_sign_ex(ASN1_ITEM_rptr(X509_REQ_INFO), &x->sig_alg, NULL,
x->signature, &x->req_info, NULL,
pkey, md, x->libctx, x->propq);
}
int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx)
{
if (x == NULL) {
ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
x->req_info.enc.modified = 1;
return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO),
&x->sig_alg, NULL, x->signature, &