goto err;
}
- if (!EVP_DigestSignUpdate(ctx, buf_in, inl)
- || !EVP_DigestSignFinal(ctx, buf_out, &outl)) {
+ if (!EVP_DigestSign(ctx, buf_out, &outl, buf_in, inl)) {
outl = 0;
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
goto err;
{
EVP_MD_CTX *ctx = NULL;
unsigned char *buf_in = NULL;
- int ret = -1, inl;
+ int ret = -1, inl = 0;
int mdnid, pknid;
goto err;
}
- ret = EVP_DigestVerifyUpdate(ctx, buf_in, inl);
-
- OPENSSL_clear_free(buf_in, (unsigned int)inl);
-
- if (!ret) {
- ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
- goto err;
- }
- ret = -1;
-
- if (EVP_DigestVerifyFinal(ctx, signature->data,
- (size_t)signature->length) <= 0) {
+ ret = EVP_DigestVerify(ctx, signature->data, (size_t)signature->length,
+ buf_in, inl);
+ if (ret <= 0) {
ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
- ret = 0;
goto err;
}
ret = 1;
err:
+ OPENSSL_clear_free(buf_in, (unsigned int)inl);
EVP_MD_CTX_free(ctx);
- return (ret);
+ return ret;
}
return 1;
}
+int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
+ const unsigned char *tbs, size_t tbslen)
+{
+ if (sigret != NULL && EVP_DigestSignUpdate(ctx, tbs, tbslen) <= 0)
+ return 0;
+ return EVP_DigestSignFinal(ctx, sigret, siglen);
+}
+
int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
size_t siglen)
{
return r;
return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen);
}
+
+int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
+ size_t siglen, const unsigned char *tbs, size_t tbslen)
+{
+ if (EVP_DigestVerifyUpdate(ctx, tbs, tbslen) <= 0)
+ return -1;
+ return EVP_DigestVerifyFinal(ctx, sigret, siglen);
+}
=head1 NAME
-EVP_DigestSignInit, EVP_DigestSignUpdate, EVP_DigestSignFinal - EVP signing functions
+EVP_DigestSignInit, EVP_DigestSignUpdate, EVP_DigestSignFinal,
+EVP_DigestSign - EVP signing functions
=head1 SYNOPSIS
int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt);
int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen);
+ int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret,
+ size_t *siglen, const unsigned char *tbs,
+ size_t tbslen);
+
=head1 DESCRIPTION
The EVP signature routines are a high level interface to digital signatures.
call is successful the signature is written to B<sig> and the amount of data
written to B<siglen>.
+EVP_DigestSign() signs B<tbslen> bytes of data at B<tbs> and places the
+signature in B<sig> and its length in B<siglen> in a simiilar way to
+EVP_DigestSignFinal().
+
=head1 RETURN VALUES
-EVP_DigestSignInit() EVP_DigestSignUpdate() and EVP_DigestSignaFinal() return
-1 for success and 0 or a negative value for failure. In particular a return
-value of -2 indicates the operation is not supported by the public key
-algorithm.
+EVP_DigestSignInit(), EVP_DigestSignUpdate(), EVP_DigestSignaFinal() and
+EVP_DigestSign() return 1 for success and 0 or a negative value for failure. In
+particular a return value of -2 indicates the operation is not supported by the
+public key algorithm.
The error codes can be obtained from L<ERR_get_error(3)>.
preference to the low level interfaces. This is because the code then becomes
transparent to the algorithm used and much more flexible.
+EVP_DigestSign() is a single part operation which signs a single block of data
+in one function. It is equivalent to calling EVP_DigestSignUpdate() and
+EVP_DigestSignFinal().
+
In previous versions of OpenSSL there was a link between message digest types
and public key algorithms. This meant that "clone" digests such as EVP_dss1()
needed to be used to sign using SHA1 and DSA. This is no longer necessary and
=head1 NAME
-EVP_DigestVerifyInit, EVP_DigestVerifyUpdate, EVP_DigestVerifyFinal - EVP signature verification functions
+EVP_DigestVerifyInit, EVP_DigestVerifyUpdate, EVP_DigestVerifyFinal,
+EVP_DigestVerify - EVP signature verification functions
=head1 SYNOPSIS
int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt);
- int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, size_t siglen);
+ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
+ size_t siglen);
+ int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
+ size_t siglen, const unsigned char *tbs, size_t tbslen);
=head1 DESCRIPTION
EVP_DigestVerifyFinal() verifies the data in B<ctx> against the signature in
B<sig> of length B<siglen>.
+EVP_DogestVerify() verifies B<tbslen> bytes at B<tbs> against the signature
+in B<sig> of length B<siglen>.
+
=head1 RETURN VALUES
EVP_DigestVerifyInit() and EVP_DigestVerifyUpdate() return 1 for success and 0
for failure.
-EVP_DigestVerifyFinal() returns 1 for success; any other value indicates
-failure. A return value of zero indicates that the signature did not verify
-successfully (that is, tbs did not match the original data or the signature had
-an invalid form), while other values indicate a more serious error (and
-sometimes also indicate an invalid signature form).
+EVP_DigestVerifyFinal() and EVP_DigestVerify() return 1 for success; any other
+value indicates failure. A return value of zero indicates that the signature
+did not verify successfully (that is, B<tbs> did not match the original data or
+the signature had an invalid form), while other values indicate a more serious
+error (and sometimes also indicate an invalid signature form).
The error codes can be obtained from L<ERR_get_error(3)>.
preference to the low level interfaces. This is because the code then becomes
transparent to the algorithm used and much more flexible.
+EVP_DigesVerify() is a single part operation which verifies a single block of
+data in one function. It is equivalent to calling EVP_DigestVerifyUpdate() and
+EVP_DigestVerifyFinal().
+
In previous versions of OpenSSL there was a link between message digest types
and public key algorithms. This meant that "clone" digests such as EVP_dss1()
needed to be used to sign using SHA1 and DSA. This is no longer necessary and
__owur int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s,
EVP_PKEY *pkey);
+__owur int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret,
+ size_t *siglen, const unsigned char *tbs,
+ size_t tbslen);
+
__owur int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
unsigned int siglen, EVP_PKEY *pkey);
+__owur int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
+ size_t siglen, const unsigned char *tbs,
+ size_t tbslen);
+
/*__owur*/ int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
const EVP_MD *type, ENGINE *e,
EVP_PKEY *pkey);
goto err;
}
- if (EVP_DigestSignInit(mctx, &pctx, md, NULL, pkey) <= 0
- || EVP_DigestSignUpdate(mctx, hdata, hdatalen) <= 0) {
+ if (EVP_DigestSignInit(mctx, &pctx, md, NULL, pkey) <= 0) {
SSLerr(SSL_F_TLS_CONSTRUCT_CERT_VERIFY, ERR_R_EVP_LIB);
goto err;
}
}
}
- if (EVP_DigestSignFinal(mctx, sig, &siglen) <= 0) {
+ if (EVP_DigestSign(mctx, sig, &siglen, hdata, hdatalen) <= 0) {
SSLerr(SSL_F_TLS_CONSTRUCT_CERT_VERIFY, ERR_R_EVP_LIB);
goto err;
}
#ifdef SSL_DEBUG
fprintf(stderr, "Using client verify alg %s\n", EVP_MD_name(md));
#endif
- if (EVP_DigestVerifyInit(mctx, &pctx, md, NULL, pkey) <= 0
- || EVP_DigestVerifyUpdate(mctx, hdata, hdatalen) <= 0) {
+ if (EVP_DigestVerifyInit(mctx, &pctx, md, NULL, pkey) <= 0) {
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB);
goto f_err;
}
goto f_err;
}
- if (EVP_DigestVerifyFinal(mctx, data, len) <= 0) {
+ j = EVP_DigestVerify(mctx, data, len, hdata, hdatalen);
+
+ if (j < 0) {
+ SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB);
+ goto f_err;
+ } else if (j == 0) {
al = SSL_AD_DECRYPT_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_SIGNATURE);
goto f_err;