return ok;
}
-/*
+/*-
* Return 1 if given cert is considered self-signed, 0 if not, or -1 on error.
- * This does not verify self-signedness but relies on x509v3_cache_extensions()
- * matching issuer and subject names (i.e., the cert being self-issued) and any
- * present authority key identifier matching the subject key identifier, etc.
+ * This actually verifies self-signedness only if requested.
+ * It calls X509v3_cache_extensions()
+ * to match issuer and subject names (i.e., the cert being self-issued) and any
+ * present authority key identifier to match the subject key identifier, etc.
*/
-static int cert_self_signed(X509_STORE_CTX *ctx, X509 *x)
+static int x509_self_signed_ex(X509 *cert, int verify_signature,
+ OPENSSL_CTX *libctx, const char *propq)
{
- if (!X509v3_cache_extensions(x, ctx->libctx, ctx->propq))
- return -1;
+ EVP_PKEY *pkey;
- if (x->ex_flags & EXFLAG_SS)
- return 1;
- else
+ if ((pkey = X509_get0_pubkey(cert)) == NULL) { /* handles cert == NULL */
+ X509err(0, X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY);
+ return -1;
+ }
+ if (!X509v3_cache_extensions(cert, libctx, propq))
+ return -1;
+ if ((cert->ex_flags & EXFLAG_SS) == 0)
return 0;
+ if (!verify_signature)
+ return 1;
+ return X509_verify_ex(cert, pkey, libctx, propq);
}
-/* Given a certificate try and find an exact match in the store */
+/* wrapper for internal use */
+static int cert_self_signed(X509_STORE_CTX *ctx, X509 *x, int verify_signature)
+{
+ return x509_self_signed_ex(x, verify_signature, ctx->libctx, ctx->propq);
+}
+
+int X509_self_signed(X509 *cert, int verify_signature)
+{
+ return x509_self_signed_ex(cert, verify_signature, NULL, NULL);
+}
+/* Given a certificate try and find an exact match in the store */
static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x)
{
STACK_OF(X509) *certs;
}
/* Alternative lookup method: look from a STACK stored in other_ctx */
-
static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
{
*issuer = find_issuer(ctx, ctx->other_ctx, x);
SSL_DANE *dane = ctx->dane;
int num = sk_X509_num(ctx->chain);
X509 *cert = sk_X509_value(ctx->chain, num - 1);
- int self_signed = cert_self_signed(ctx, cert);
+ int self_signed;
STACK_OF(X509) *sktmp = NULL;
unsigned int search;
int may_trusted = 0;
return 0;
}
- self_signed = cert_self_signed(ctx, cert);
+ self_signed = cert_self_signed(ctx, cert, 0);
if (self_signed < 0) {
ctx->error = X509_V_ERR_UNSPECIFIED;
return 0;
search = 0;
continue;
}
- self_signed = cert_self_signed(ctx, x);
+ self_signed = cert_self_signed(ctx, x, 0);
if (self_signed < 0) {
ctx->error = X509_V_ERR_UNSPECIFIED;
return 0;
x = xtmp;
++ctx->num_untrusted;
- self_signed = cert_self_signed(ctx, xtmp);
+ self_signed = cert_self_signed(ctx, xtmp, 0);
if (self_signed < 0) {
sk_X509_free(sktmp);
ctx->error = X509_V_ERR_UNSPECIFIED;