int DSA_check_signature(int *out_valid, const uint8_t *digest, size_t digest_len, const uint8_t *sig, size_t sig_len, const DSA *dsa) { DSA_SIG *s = NULL; int ret = 0; uint8_t *der = NULL; s = DSA_SIG_new(); if (s == NULL) { goto err; } const uint8_t *sigp = sig; if (d2i_DSA_SIG(&s, &sigp, sig_len) == NULL || sigp != sig + sig_len) { goto err; } /* Ensure that the signature uses DER and doesn't have trailing garbage. */ int der_len = i2d_DSA_SIG(s, &der); if (der_len < 0 || (size_t)der_len != sig_len || memcmp(sig, der, sig_len)) { goto err; } ret = DSA_do_check_signature(out_valid, digest, digest_len, s, dsa); err: OPENSSL_free(der); DSA_SIG_free(s); return ret; }
/** * Setup DSA key digest in DER encoding ... * @param sig: input is signature output alloced ptr (unless failure). * caller must free alloced ptr if this routine returns true. * @param len: input is initial siglen, output is output len. * @return false on failure. */ static int setup_dsa_sig(unsigned char** sig, unsigned int* len) { unsigned char* orig = *sig; unsigned int origlen = *len; int newlen; BIGNUM *R, *S; DSA_SIG *dsasig; /* extract the R and S field from the sig buffer */ if(origlen < 1 + 2*SHA_DIGEST_LENGTH) return 0; R = BN_new(); if(!R) return 0; (void) BN_bin2bn(orig + 1, SHA_DIGEST_LENGTH, R); S = BN_new(); if(!S) return 0; (void) BN_bin2bn(orig + 21, SHA_DIGEST_LENGTH, S); dsasig = DSA_SIG_new(); if(!dsasig) return 0; dsasig->r = R; dsasig->s = S; *sig = NULL; newlen = i2d_DSA_SIG(dsasig, sig); if(newlen < 0) { DSA_SIG_free(dsasig); free(*sig); return 0; } *len = (unsigned int)newlen; DSA_SIG_free(dsasig); return 1; }
/* * data has already been hashed (probably with SHA or SHA-1). * returns * 1: correct signature * 0: incorrect signature * -1: error */ int DSA_verify(int type, const unsigned char *dgst, int dgst_len, const unsigned char *sigbuf, int siglen, DSA *dsa) { DSA_SIG *s; unsigned char *der = NULL; const unsigned char *p = sigbuf; int derlen = -1; int ret = -1; s = DSA_SIG_new(); if (s == NULL) return ret; if (d2i_DSA_SIG(&s, &p, siglen) == NULL) goto err; /* Ensure signature uses DER and doesn't have trailing garbage */ derlen = i2d_DSA_SIG(s, &der); if (derlen != siglen || memcmp(sigbuf, der, derlen)) goto err; ret = DSA_do_verify(dgst, dgst_len, s, dsa); err: freezero(der, derlen); DSA_SIG_free(s); return ret; }
/* returns * 1: correct signature * 0: incorrect signature * -1: error */ int DSA_verify(int type, const unsigned char *dgst, int dgst_len, const unsigned char *sigbuf, int siglen, DSA *dsa) { DSA_SIG *s; /* rdar://problem/20168109 and others a binary compat issue with OpenSSL zd from zc this change seems to be the problem, and is not critical (for now). */ #if 0 const unsigned char *p = sigbuf; unsigned char *der = NULL; int derlen = -1; #endif int ret=-1; #ifdef OPENSSL_FIPS if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) { DSAerr(DSA_F_DSA_VERIFY, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); return 0; } #endif s = DSA_SIG_new(); if (s == NULL) return(ret); /* rdar://problem/20168109 and others a binary compat issue with OpenSSL zd from zc this change seems to be the problem, and is not critical (for now). */ #if 0 if (d2i_DSA_SIG(&s,&p,siglen) == NULL) goto err; /* Ensure signature uses DER and doesn't have trailing garbage */ derlen = i2d_DSA_SIG(s, &der); if (derlen != siglen || memcmp(sigbuf, der, derlen)) goto err; #else if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err; #endif ret=DSA_do_verify(dgst,dgst_len,s,dsa); err: /* more from rdar://problem/20168109 and others */ #if 0 if (derlen > 0) { OPENSSL_cleanse(der, derlen); OPENSSL_free(der); } #endif DSA_SIG_free(s); return(ret); }
int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig, unsigned int *siglen, DSA *dsa) { DSA_SIG *s; s=DSA_do_sign(dgst,dlen,dsa); if (s == NULL) { *siglen=0; return(0); } *siglen=i2d_DSA_SIG(s,&sig); DSA_SIG_free(s); return(1); }
int DSA_sign(int type, const uint8_t *digest, size_t digest_len, uint8_t *out_sig, unsigned int *out_siglen, DSA *dsa) { DSA_SIG *s; s = DSA_do_sign(digest, digest_len, dsa); if (s == NULL) { *out_siglen = 0; return 0; } *out_siglen = i2d_DSA_SIG(s, &out_sig); DSA_SIG_free(s); return 1; }
int unbound_lite_i2d_DSA_SIG(DSA_SIG* dsasig, unsigned char** sig) { unsigned char* n = NULL; int r= i2d_DSA_SIG(dsasig, &n); if(n) { *sig = unbound_stat_malloc_lite((size_t)r, __FILE__, __LINE__, __func__); if(!*sig) return -1; memcpy(*sig, n, (size_t)r); free(n); return r; } *sig = NULL; return r; }
/*! * \brief Verify the DNSSEC signature for supplied data and DSA algorithm. * \see any_sign_verify */ static int dsa_sign_verify(const knot_dnssec_sign_context_t *context, const uint8_t *signature, size_t signature_size) { assert(context); assert(signature); if (signature_size != dsa_sign_size(context->key)) { return KNOT_EINVAL; } // see dsa_sign_write() for conversion details // T (1 byte), R (20 bytes), S (20 bytes) const uint8_t *signature_r = signature + 1; const uint8_t *signature_s = signature + 21; DSA_SIG *decoded = DSA_SIG_new(); if (!decoded) { return KNOT_ENOMEM; } decoded->r = BN_bin2bn(signature_r, 20, decoded->r); decoded->s = BN_bin2bn(signature_s, 20, decoded->s); size_t max_size = EVP_PKEY_size(context->key->data->private_key); uint8_t *raw_signature = malloc(max_size); if (!raw_signature) { DSA_SIG_free(decoded); return KNOT_ENOMEM; } uint8_t *raw_write = raw_signature; int raw_size = i2d_DSA_SIG(decoded, &raw_write); if (raw_size < 0) { free(raw_signature); DSA_SIG_free(decoded); return KNOT_DNSSEC_EDECODE_RAW_SIGNATURE; } assert(raw_write == raw_signature + raw_size); int result = any_sign_verify(context, raw_signature, raw_size); DSA_SIG_free(decoded); free(raw_signature); return result; }
static void check_license_signature(license_raw *lptr) { unsigned char message_digest[SHA_DIGEST_LENGTH]; SHA_CTX sha_ctx; DSA *dsa = DSA_new(); SHA1_Init(&sha_ctx); SHA1_Update(&sha_ctx, lptr, sizeof(*lptr) - sizeof(lptr->dsa_signature)); SHA1_Final(message_digest, &sha_ctx); dsa->p = BN_bin2bn(dsa_p, sizeof(dsa_p), NULL); dsa->q = BN_bin2bn(dsa_q, sizeof(dsa_q), NULL); dsa->g = BN_bin2bn(dsa_g, sizeof(dsa_g), NULL); dsa->pub_key = BN_bin2bn(dsa_pub_key, sizeof(dsa_pub_key), NULL); // calculate the right len of the signiture DSA_SIG *temp_sig=DSA_SIG_new(); int siglen = -1; const unsigned char *data =lptr->dsa_signature; if (temp_sig == NULL || d2i_DSA_SIG(&temp_sig,&data,sizeof(lptr->dsa_signature)) == NULL){ fprintf(stderr, "License signature verification failed: %s\n", ERR_error_string(ERR_get_error(), NULL)); exit(EXIT_FAILURE); } unsigned char *tmp_buff= NULL; siglen = i2d_DSA_SIG(temp_sig, &tmp_buff); OPENSSL_cleanse(tmp_buff, siglen); OPENSSL_free(tmp_buff); DSA_SIG_free(temp_sig); switch(DSA_verify(0, message_digest, sizeof(message_digest), lptr->dsa_signature, siglen, dsa)) { case 0: fputs("License file is corrupted: invalid DSA signature.\n", stderr); exit(EXIT_FAILURE); case 1: break; /* valid signature */ default: fprintf(stderr, "License signature verification failed: %s\n", ERR_error_string(ERR_get_error(), NULL)); exit(EXIT_FAILURE); } DSA_free(dsa); }
int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig, unsigned int *siglen, DSA *dsa) { DSA_SIG *s; #ifdef OPENSSL_FIPS if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) { DSAerr(DSA_F_DSA_SIGN, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); return 0; } #endif RAND_seed(dgst, dlen); s=DSA_do_sign(dgst,dlen,dsa); if (s == NULL) { *siglen=0; return(0); } *siglen=i2d_DSA_SIG(s,&sig); DSA_SIG_free(s); return(1); }
static isc_result_t openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) { dst_key_t *key = dctx->key; DSA *dsa = key->keydata.dsa; int status = 0; unsigned char *cp = sig->base; DSA_SIG *dsasig; #if USE_EVP EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; #if 0 EVP_PKEY *pkey; unsigned char *sigbuf; #endif unsigned int siglen; #else isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; #endif unsigned char digest[ISC_SHA1_DIGESTLENGTH]; #if USE_EVP #if 1 /* Only use EVP for the digest */ if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) { return (ISC_R_FAILURE); } #endif #else isc_sha1_final(sha1ctx, digest); #endif if (sig->length != 2 * ISC_SHA1_DIGESTLENGTH + 1) { return (DST_R_VERIFYFAILURE); } cp++; /*%< Skip T */ dsasig = DSA_SIG_new(); if (dsasig == NULL) return (ISC_R_NOMEMORY); dsasig->r = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL); cp += ISC_SHA1_DIGESTLENGTH; dsasig->s = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL); #if 0 pkey = EVP_PKEY_new(); if (pkey == NULL) return (ISC_R_NOMEMORY); if (!EVP_PKEY_set1_DSA(pkey, dsa)) { EVP_PKEY_free(pkey); return (ISC_R_FAILURE); } /* Convert to Dss-Sig-Value (RFC2459). */ sigbuf = malloc(EVP_PKEY_size(pkey) + 50); if (sigbuf == NULL) { EVP_PKEY_free(pkey); return (ISC_R_NOMEMORY); } siglen = (unsigned) i2d_DSA_SIG(dsasig, &sigbuf); INSIST(EVP_PKEY_size(pkey) >= (int) siglen); status = EVP_VerifyFinal(evp_md_ctx, sigbuf, siglen, pkey); EVP_PKEY_free(pkey); free(sigbuf); #else status = DSA_do_verify(digest, ISC_SHA1_DIGESTLENGTH, dsasig, dsa); #endif DSA_SIG_free(dsasig); if (status != 1) return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); return (ISC_R_SUCCESS); }
bool OpenSSLCryptoKeyDSA::verifyBase64Signature(unsigned char * hashBuf, unsigned int hashLen, char * base64Signature, unsigned int sigLen) { // Use the currently loaded key to validate the Base64 encoded signature if (mp_dsaKey == NULL) { throw XSECCryptoException(XSECCryptoException::DSAError, "OpenSSL:DSA - Attempt to validate signature with empty key"); } unsigned char sigVal[512]; int sigValLen; int err; /* BIO * b64 = BIO_new(BIO_f_base64()); BIO * bmem = BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(bmem, 0); b64 = BIO_push(b64, bmem); // Translate signature from Base64 BIO_write(bmem, base64Signature, sigLen); sigValLen = BIO_read(b64, sigVal, 512); */ EVP_ENCODE_CTX m_dctx; int rc; EVP_DecodeInit(&m_dctx); rc = EVP_DecodeUpdate(&m_dctx, sigVal, &sigValLen, (unsigned char *) base64Signature, sigLen); if (rc < 0) { throw XSECCryptoException(XSECCryptoException::DSAError, "OpenSSL:DSA - Error during Base64 Decode"); } int t = 0; EVP_DecodeFinal(&m_dctx, &sigVal[sigValLen], &t); sigValLen += t; if (sigValLen != 40) { throw XSECCryptoException(XSECCryptoException::DSAError, "OpenSSL:DSA - Signature Length incorrect"); } // Translate to BNs and thence to DSA_SIG BIGNUM * R = BN_bin2bn(sigVal, 20, NULL); BIGNUM * S = BN_bin2bn(&sigVal[20], 20, NULL); DSA_SIG * dsa_sig = DSA_SIG_new(); dsa_sig->r = BN_dup(R); dsa_sig->s = BN_dup(S); unsigned char sigValTranslatedBuf[256]; unsigned char * sigValTranslated = sigValTranslatedBuf; int sigValTranslatedLen; sigValTranslatedLen = i2d_DSA_SIG(dsa_sig, &sigValTranslated); // Now we have a signature and a key - lets check err = DSA_do_verify(hashBuf, hashLen, dsa_sig, mp_dsaKey); DSA_SIG_free(dsa_sig); if (err < 0) { throw XSECCryptoException(XSECCryptoException::DSAError, "OpenSSL:DSA - Error validating signature"); } return (err == 1); }