/** * 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; }
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; }
static int constructDSASignature(struct pgpDigSigDSA_s *sig) { int rc; if (sig->dsa_sig) { /* We've already constructed it, so just reuse it */ return 1; } /* Create the DSA signature */ DSA_SIG *dsa_sig = DSA_SIG_new(); if (!dsa_sig) return 0; if (!DSA_SIG_set0(dsa_sig, sig->r, sig->s)) { rc = 0; goto done; } sig->dsa_sig = dsa_sig; rc = 1; done: if (rc == 0) { DSA_SIG_free(sig->dsa_sig); } return rc; }
static isc_result_t openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) { isc_sha1_t *sha1ctx = dctx->opaque; dst_key_t *key = dctx->key; DSA *dsa = key->opaque; DSA_SIG *dsasig; int status = 0; unsigned char digest[ISC_SHA1_DIGESTLENGTH]; unsigned char *cp = sig->base; isc_sha1_final(sha1ctx, digest); if (sig->length < 2 * ISC_SHA1_DIGESTLENGTH + 1) return (DST_R_VERIFYFAILURE); cp++; /*%< Skip T */ dsasig = DSA_SIG_new(); dsasig->r = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL); cp += ISC_SHA1_DIGESTLENGTH; dsasig->s = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL); cp += ISC_SHA1_DIGESTLENGTH; status = DSA_do_verify(digest, ISC_SHA1_DIGESTLENGTH, dsasig, dsa); DSA_SIG_free(dsasig); if (status <= 0) return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); return (ISC_R_SUCCESS); }
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx, const unsigned char *sig, const unsigned char *m, unsigned long m_len) { unsigned char hash[SHA_DIGEST_LENGTH]; DSA_SIG * dsasig; BIGNUM * r; BIGNUM * s; int ret = -1; r = BN_new(); BN_bin2bn(sig, 20, r); s = BN_new(); BN_bin2bn(sig + 20, 20, s); dsasig = DSA_SIG_new(); #ifdef HAVE_OPAQUE_STRUCTS DSA_SIG_set0(dsasig, r, s); #else dsasig->r = r; dsasig->s = s; #endif if(!_libssh2_sha1(m, m_len, hash)) /* _libssh2_sha1() succeeded */ ret = DSA_do_verify(hash, SHA_DIGEST_LENGTH, dsasig, dsactx); DSA_SIG_free(dsasig); return (ret == 1) ? 0 : -1; }
int DSA_verify(int type, 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 = -1, valid; s = DSA_SIG_new(); if (s == NULL) { goto err; } if (d2i_DSA_SIG(&s, &sig, sig_len) == NULL) { goto err; } if (!DSA_do_check_signature(&valid, digest, digest_len, s, dsa)) { goto err; } ret = valid; err: if (s) { DSA_SIG_free(s); } return ret; }
void sigver() { DSA *dsa=NULL; char buf[1024]; int nmod=0; unsigned char hash[20]; DSA_SIG *sig=DSA_SIG_new(); while(fgets(buf,sizeof buf,stdin) != NULL) { if(!strncmp(buf,"[mod = ",7)) { nmod=atoi(buf+7); if(dsa) DSA_free(dsa); dsa=DSA_new(); } else if(!strncmp(buf,"P = ",4)) dsa->p=hex2bn(buf+4); else if(!strncmp(buf,"Q = ",4)) dsa->q=hex2bn(buf+4); else if(!strncmp(buf,"G = ",4)) { dsa->g=hex2bn(buf+4); printf("[mod = %d]\n\n",nmod); pbn("P",dsa->p); pbn("Q",dsa->q); pbn("G",dsa->g); putc('\n',stdout); } else if(!strncmp(buf,"Msg = ",6)) { unsigned char msg[1024]; int n; n=hex2bin(buf+6,msg); pv("Msg",msg,n); SHA1(msg,n,hash); } else if(!strncmp(buf,"Y = ",4)) dsa->pub_key=hex2bn(buf+4); else if(!strncmp(buf,"R = ",4)) sig->r=hex2bn(buf+4); else if(!strncmp(buf,"S = ",4)) { sig->s=hex2bn(buf+4); pbn("Y",dsa->pub_key); pbn("R",sig->r); pbn("S",sig->s); printf("Result = %c\n",DSA_do_verify(hash,sizeof hash,sig,dsa) ? 'P' : 'F'); putc('\n',stdout); } } }
/* 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); }
/*! * \brief Finish the signing and write out the DSA signature. * \see any_sign_write */ static int dsa_sign_write(const knot_dnssec_sign_context_t *context, uint8_t *signature, size_t signature_size) { assert(context); assert(signature); size_t output_size = dsa_sign_size(context->key); if (output_size != signature_size) { return KNOT_DNSSEC_EUNEXPECTED_SIGNATURE_SIZE; } // create raw signature uint8_t *raw_signature = NULL; size_t raw_size = 0; int result = sign_alloc_and_write(context, &raw_signature, &raw_size); if (result != KNOT_EOK) { return result; } // decode signature, X.509 Dss-Sig-Value (RFC2459) DSA_SIG *decoded = DSA_SIG_new(); if (!decoded) { free(raw_signature); return KNOT_ENOMEM; } const uint8_t *decode_scan = raw_signature; if (!d2i_DSA_SIG(&decoded, &decode_scan, (long)raw_size)) { DSA_SIG_free(decoded); free(raw_signature); return KNOT_DNSSEC_EDECODE_RAW_SIGNATURE; } free(raw_signature); // convert to format defined by RFC 2536 (DSA keys and SIGs in DNS) // T (1 byte), R (20 bytes), S (20 bytes) uint8_t *signature_t = signature; uint8_t *signature_r = signature + 21 - BN_num_bytes(decoded->r); uint8_t *signature_s = signature + 41 - BN_num_bytes(decoded->s); memset(signature, '\0', output_size); *signature_t = 0x00; //! \todo Take from public key. Only recommended. BN_bn2bin(decoded->r, signature_r); BN_bn2bin(decoded->s, signature_s); DSA_SIG_free(decoded); return KNOT_EOK; }
/* * Computes signature and returns it as DSA_SIG structure */ DSA_SIG *gost_do_sign (const unsigned char *dgst, int dlen, DSA * dsa) { BIGNUM *k = NULL, *tmp = NULL, *tmp2 = NULL; DSA_SIG *newsig = DSA_SIG_new (); BIGNUM *md = hashsum2bn (dgst); /* check if H(M) mod q is zero */ BN_CTX *ctx = BN_CTX_new (); BN_CTX_start (ctx); if (!newsig) { GOSTerr (GOST_F_GOST_DO_SIGN, GOST_R_NO_MEMORY); goto err; } tmp = BN_CTX_get (ctx); k = BN_CTX_get (ctx); tmp2 = BN_CTX_get (ctx); BN_mod (tmp, md, dsa->q, ctx); if (BN_is_zero (tmp)) { BN_one (md); } do { do { /*Generate random number k less than q */ BN_rand_range (k, dsa->q); /* generate r = (a^x mod p) mod q */ BN_mod_exp (tmp, dsa->g, k, dsa->p, ctx); if (!(newsig->r)) newsig->r = BN_new (); BN_mod (newsig->r, tmp, dsa->q, ctx); } while (BN_is_zero (newsig->r)); /* generate s = (xr + k(Hm)) mod q */ BN_mod_mul (tmp, dsa->priv_key, newsig->r, dsa->q, ctx); BN_mod_mul (tmp2, k, md, dsa->q, ctx); if (!newsig->s) newsig->s = BN_new (); BN_mod_add (newsig->s, tmp, tmp2, dsa->q, ctx); } while (BN_is_zero (newsig->s)); err: BN_free (md); BN_CTX_end (ctx); BN_CTX_free (ctx); return newsig; }
// Verification functions bool OSSLDSA::verify(PublicKey* publicKey, const ByteString& originalData, const ByteString& signature, const AsymMech::Type mechanism, const void* param /* = NULL */, const size_t paramLen /* = 0 */) { if (mechanism == AsymMech::DSA) { // Separate implementation for DSA verification without hash computation // Check if the private key is the right type if (!publicKey->isOfType(OSSLDSAPublicKey::type)) { ERROR_MSG("Invalid key type supplied"); return false; } // Perform the verify operation OSSLDSAPublicKey* pk = (OSSLDSAPublicKey*) publicKey; unsigned int sigLen = pk->getOutputLength(); if (signature.size() != sigLen) return false; DSA_SIG* sig = DSA_SIG_new(); if (sig == NULL) return false; const unsigned char *s = signature.const_byte_str(); sig->r = BN_bin2bn(s, sigLen / 2, NULL); sig->s = BN_bin2bn(s + sigLen / 2, sigLen / 2, NULL); if (sig->r == NULL || sig->s == NULL) { DSA_SIG_free(sig); return false; } int dLen = originalData.size(); int ret = DSA_do_verify(originalData.const_byte_str(), dLen, sig, pk->getOSSLKey()); if (ret != 1) { if (ret < 0) ERROR_MSG("DSA verify failed (0x%08X)", ERR_get_error()); DSA_SIG_free(sig); return false; } DSA_SIG_free(sig); return true; } else { // Call the generic function return AsymmetricAlgorithm::verify(publicKey, originalData, signature, mechanism, param, paramLen); } }
/* Unpack signature according to cryptopro rules */ DSA_SIG *unpack_cp_signature(const unsigned char *sig, size_t siglen) { DSA_SIG *s; s = DSA_SIG_new(); if (s == NULL) { GOSTerr(GOST_F_UNPACK_CP_SIGNATURE, ERR_R_MALLOC_FAILURE); return NULL; } s->s = BN_bin2bn(sig, siglen / 2, NULL); s->r = BN_bin2bn(sig + siglen / 2, siglen / 2, NULL); return s; }
/* Unpack signature according to cryptopro rules */ DSA_SIG *unpack_cp_signature(const unsigned char *sig,size_t siglen) { DSA_SIG *s; s = DSA_SIG_new(); if (s == NULL) { GOSTerr(GOST_F_UNPACK_CP_SIGNATURE,GOST_R_NO_MEMORY); return NULL; } s->s = getbnfrombuf(sig , siglen/2); s->r = getbnfrombuf(sig + siglen/2, siglen/2); return s; }
/* 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; int ret=-1; s = DSA_SIG_new(); if (s == NULL) return(ret); if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err; ret=DSA_do_verify(dgst,dgst_len,s,dsa); err: DSA_SIG_free(s); return(ret); }
/* DSA sign and verify */ static DSA_SIG * surewarehk_dsa_do_sign(const unsigned char *from, int flen, DSA *dsa) { int ret=0; char *hptr=NULL; DSA_SIG *psign=NULL; char msg[64]="ENGINE_dsa_do_sign"; if (!p_surewarehk_Dsa_Sign) { SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ENGINE_R_NOT_INITIALISED); goto err; } /* extract ref to private key */ else if (!(hptr=(char*)DSA_get_ex_data(dsa, dsaHndidx))) { SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,SUREWARE_R_MISSING_KEY_COMPONENTS); goto err; } else { if((psign = DSA_SIG_new()) == NULL) { SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ERR_R_MALLOC_FAILURE); goto err; } psign->r=BN_new(); psign->s=BN_new(); bn_expand2(psign->r, 20/sizeof(BN_ULONG)); bn_expand2(psign->s, 20/sizeof(BN_ULONG)); if (!psign->r || psign->r->dmax!=20/sizeof(BN_ULONG) || !psign->s || psign->s->dmax!=20/sizeof(BN_ULONG)) goto err; ret=p_surewarehk_Dsa_Sign(msg,flen,from, (unsigned long *)psign->r->d, (unsigned long *)psign->s->d, hptr); surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ret); } psign->r->top=20/sizeof(BN_ULONG); bn_fix_top(psign->r); psign->s->top=20/sizeof(BN_ULONG); bn_fix_top(psign->s); err: if (psign) { DSA_SIG_free(psign); psign=NULL; } return psign; }
bool OSSLDSA::verifyFinal(const ByteString& signature) { // Save necessary state before calling super class verifyFinal OSSLDSAPublicKey* pk = (OSSLDSAPublicKey*) currentPublicKey; if (!AsymmetricAlgorithm::verifyFinal(signature)) { return false; } ByteString hash; bool bFirstResult = pCurrentHash->hashFinal(hash); delete pCurrentHash; pCurrentHash = NULL; if (!bFirstResult) { return false; } // Perform the verify operation unsigned int sigLen = pk->getOutputLength(); if (signature.size() != sigLen) return false; DSA_SIG* sig = DSA_SIG_new(); if (sig == NULL) return false; const unsigned char *s = signature.const_byte_str(); sig->r = BN_bin2bn(s, sigLen / 2, NULL); sig->s = BN_bin2bn(s + sigLen / 2, sigLen / 2, NULL); if (sig->r == NULL || sig->s == NULL) { DSA_SIG_free(sig); return false; } int ret = DSA_do_verify(&hash[0], hash.size(), sig, pk->getOSSLKey()); if (ret != 1) { if (ret < 0) ERROR_MSG("DSA verify failed (0x%08X)", ERR_get_error()); DSA_SIG_free(sig); return false; } DSA_SIG_free(sig); return true; }
static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) { struct crypt_kop kop; BIGNUM *r = NULL, *s = NULL; DSA_SIG *dsaret = NULL; if ((r = BN_new()) == NULL) goto err; if ((s = BN_new()) == NULL) { BN_free(r); goto err; } memset(&kop, 0, sizeof kop); kop.crk_op = CRK_DSA_SIGN; /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */ kop.crk_param[0].crp_p = (caddr_t) dgst; kop.crk_param[0].crp_nbits = dlen * 8; if (bn2crparam(dsa->p, &kop.crk_param[1])) goto err; if (bn2crparam(dsa->q, &kop.crk_param[2])) goto err; if (bn2crparam(dsa->g, &kop.crk_param[3])) goto err; if (bn2crparam(dsa->priv_key, &kop.crk_param[4])) goto err; kop.crk_iparams = 5; if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r, BN_num_bytes(dsa->q), s) == 0) { dsaret = DSA_SIG_new(); if (dsaret == NULL) goto err; dsaret->r = r; dsaret->s = s; r = s = NULL; } else { const DSA_METHOD *meth = DSA_OpenSSL(); dsaret = (meth->dsa_do_sign) (dgst, dlen, dsa); } err: BN_free(r); BN_free(s); kop.crk_param[0].crp_p = NULL; zapparams(&kop); return (dsaret); }
ops_boolean_t ops_dsa_verify(const unsigned char *hash,size_t hash_length, const ops_dsa_signature_t *sig, const ops_dsa_public_key_t *dsa) { DSA_SIG *osig; DSA *odsa; int ret; osig=DSA_SIG_new(); osig->r=sig->r; osig->s=sig->s; odsa=DSA_new(); odsa->p=dsa->p; odsa->q=dsa->q; odsa->g=dsa->g; odsa->pub_key=dsa->y; if (debug) { fprintf(stderr,"hash passed in:\n"); unsigned i; for (i=0; i<hash_length; i++) { fprintf(stderr,"%02x ", hash[i]); } fprintf(stderr,"\n"); } //printf("hash_length=%ld\n", hash_length); //printf("Q=%d\n", BN_num_bytes(odsa->q)); unsigned int qlen=BN_num_bytes(odsa->q); if (qlen < hash_length) hash_length=qlen; // ret=DSA_do_verify(hash,hash_length,osig,odsa); ret=DSA_do_verify(hash,hash_length,osig,odsa); if (debug) { fprintf(stderr,"ret=%d\n",ret); } assert(ret >= 0); odsa->p=odsa->q=odsa->g=odsa->pub_key=NULL; DSA_free(odsa); osig->r=osig->s=NULL; DSA_SIG_free(osig); return ret != 0; }
int HsOpenSSL_dsa_verify(DSA *dsa, const unsigned char *ddata, int dlen, const BIGNUM *r, const BIGNUM *s) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L DSA_SIG* sig = DSA_SIG_new(); DSA_SIG_set0(sig, BN_dup(r), BN_dup(s)); int res = DSA_do_verify(ddata, dlen, sig, dsa); DSA_SIG_free(sig); return res; #else DSA_SIG sig; sig.r = (BIGNUM *)r; sig.s = (BIGNUM *)s; return dsa->meth->dsa_do_verify(ddata, dlen, &sig, dsa); #endif }
/* Unpack signature according to cryptopro rules */ DSA_SIG *unpack_cp_signature(const unsigned char *sigbuf, size_t siglen) { DSA_SIG *sig; BIGNUM *r = NULL, *s = NULL; sig = DSA_SIG_new(); if (sig == NULL) { GOSTerr(GOST_F_UNPACK_CP_SIGNATURE, ERR_R_MALLOC_FAILURE); return NULL; } s = BN_bin2bn(sigbuf, siglen / 2, NULL); r = BN_bin2bn(sigbuf + siglen / 2, siglen / 2, NULL); DSA_SIG_set0(sig, r, s); return sig; }
DSA_SIG *DSA_SIG_parse(CBS *cbs) { DSA_SIG *ret = DSA_SIG_new(); if (ret == NULL) { return NULL; } CBS child; if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || !parse_integer(&child, &ret->r) || !parse_integer(&child, &ret->s) || CBS_len(&child) != 0) { OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); DSA_SIG_free(ret); return NULL; } return ret; }
/*! * \brief Finish the signing and write out the DSA signature. * \see rsa_sign_write */ static int dsa_sign_write(const knot_dnssec_sign_context_t *context, uint8_t *signature) { assert(context); assert(signature); int result; uint8_t *raw_signature; size_t raw_signature_size; result = any_sign_finish(context, &raw_signature, &raw_signature_size); if (result != KNOT_EOK) { return result; } // decode signature, X.509 Dss-Sig-Value (RFC2459) DSA_SIG *decoded = DSA_SIG_new(); if (!decoded) { free(raw_signature); return KNOT_ENOMEM; } const uint8_t *decode_scan = raw_signature; if (!d2i_DSA_SIG(&decoded, &decode_scan, (long)raw_signature_size)) { DSA_SIG_free(decoded); free(raw_signature); return KNOT_DNSSEC_EDECODE_RAW_SIGNATURE; } free(raw_signature); // convert to format defined by RFC 2536 (DSA keys and SIGs in DNS) // T (1 byte), R (20 bytes), S (20 bytes) uint8_t *signature_t = signature; uint8_t *signature_r = signature + 21 - BN_num_bytes(decoded->r); uint8_t *signature_s = signature + 41 - BN_num_bytes(decoded->s); *signature_t = 0x00; //! \todo How to compute T? (Only recommended.) BN_bn2bin(decoded->r, signature_r); BN_bn2bin(decoded->s, signature_s); DSA_SIG_free(decoded); return KNOT_EOK; }
/*! * \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); }
unsigned __ops_dsa_verify(const uint8_t *hash, size_t hash_length, const __ops_dsa_sig_t *sig, const __ops_dsa_pubkey_t *dsa) { unsigned qlen; DSA_SIG *osig; DSA *odsa; int ret; osig = DSA_SIG_new(); osig->r = sig->r; osig->s = sig->s; odsa = DSA_new(); odsa->p = dsa->p; odsa->q = dsa->q; odsa->g = dsa->g; odsa->pub_key = dsa->y; if (__ops_get_debug_level(__FILE__)) { hexdump(stderr, "input hash", hash, hash_length); (void) fprintf(stderr, "Q=%d\n", BN_num_bytes(odsa->q)); } if ((qlen = (unsigned)BN_num_bytes(odsa->q)) < hash_length) { hash_length = qlen; } ret = DSA_do_verify(hash, (int)hash_length, osig, odsa); if (__ops_get_debug_level(__FILE__)) { (void) fprintf(stderr, "ret=%d\n", ret); } if (ret < 0) { (void) fprintf(stderr, "__ops_dsa_verify: DSA verification\n"); return 0; } odsa->p = odsa->q = odsa->g = odsa->pub_key = NULL; DSA_free(odsa); osig->r = osig->s = NULL; DSA_SIG_free(osig); return (unsigned)ret; }
/* verify */ void DSASigner::verify( const void *data, size_t dataLen, const void *sig, size_t sigLen) { bool throwSigVerify = false; DSA_SIG *dsaSig = NULL; CSSM_RETURN crtn = CSSM_OK; int irtn; if(mDsaKey == NULL) { CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR); } if(mDsaKey->pub_key == NULL) { CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS); } /* incoming sig is DER encoded....decode into internal format */ dsaSig = DSA_SIG_new(); crtn = DSASigDecode(dsaSig, sig, sigLen); if(crtn) { goto abort; } irtn = DSA_do_verify((unsigned char *)data, dataLen, dsaSig, mDsaKey); if(irtn != 1) { throwSigVerify = true; } abort: if(dsaSig != NULL) { DSA_SIG_free(dsaSig); } if(throwSigVerify) { clearOpensslErrors(); CssmError::throwMe(CSSMERR_CSP_VERIFY_FAILED); } else if(crtn) { CssmError::throwMe(crtn); } }
static int xmlSecOpenSSLDsaSha1EvpVerify(int type ATTRIBUTE_UNUSED, const unsigned char *dgst, unsigned int dgst_len, const unsigned char *sigbuf, unsigned int siglen, void *dsa) { DSA_SIG *s; int ret = -1; s = DSA_SIG_new(); if (s == NULL) { return(ret); } if(siglen != XMLSEC_OPENSSL_DSA_SIGNATURE_SIZE) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, NULL, XMLSEC_ERRORS_R_INVALID_SIZE, "invalid length %d (%d expected)", siglen, XMLSEC_OPENSSL_DSA_SIGNATURE_SIZE); goto err; } s->r = BN_bin2bn(sigbuf, XMLSEC_OPENSSL_DSA_SIGNATURE_SIZE / 2, NULL); s->s = BN_bin2bn(sigbuf + (XMLSEC_OPENSSL_DSA_SIGNATURE_SIZE / 2), XMLSEC_OPENSSL_DSA_SIGNATURE_SIZE / 2, NULL); if((s->r == NULL) || (s->s == NULL)) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "BN_bin2bn", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); goto err; } ret = DSA_do_verify(dgst, dgst_len, s, dsa); err: DSA_SIG_free(s); return(ret); }
static int fips_dsa_verify(int type, const unsigned char *x, int y, const unsigned char *sigbuf, unsigned int siglen, EVP_MD_SVCTX *sv) { DSA *dsa = sv->key; DSA_SIG *s; int ret=-1; unsigned char dig[EVP_MAX_MD_SIZE]; unsigned int dlen; s = DSA_SIG_new(); if (s == NULL) return ret; if (!FIPS_dsa_sig_decode(s,sigbuf,siglen)) goto err; EVP_DigestFinal_ex(sv->mctx, dig, &dlen); ret=dsa->meth->dsa_do_verify(dig,dlen,s,dsa); OPENSSL_cleanse(dig, dlen); err: DSA_SIG_free(s); return ret; }
bool dsa160_key::verify(byte_array const& digest, byte_array const& signature) const { assert(type() != invalid); assert(digest.size() == SHA256_DIGEST_LENGTH); // The version of DSA currently implemented by OpenSSL only supports digests up to 160 bits. int digest_size = 160/8; DSA_SIG *sig = DSA_SIG_new(); if (!sig) return false; byte_array_iwrap<flurry::iarchive> read(signature); read.archive() >> sig->r >> sig->s; // @todo Check if there's more data in the signature, fail. int rc = DSA_do_verify((const unsigned char*)digest.const_data(), digest_size, sig, dsa_); DSA_SIG_free(sig); return rc == 1; }