/* 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_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; }
static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) { DSA_SIG *dsa_sig; const unsigned char *p; if (!sig) { if (BIO_puts(bp, "\n") <= 0) return 0; else return 1; } p = sig->data; dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length); if (dsa_sig) { int rv = 0; const BIGNUM *r, *s; DSA_SIG_get0(dsa_sig, &r, &s); if (BIO_write(bp, "\n", 1) != 1) goto err; if (!ASN1_bn_print(bp, "r: ", r, NULL, indent)) goto err; if (!ASN1_bn_print(bp, "s: ", s, NULL, indent)) goto err; rv = 1; err: DSA_SIG_free(dsa_sig); return rv; } return X509_signature_dump(bp, sig, indent); }
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; }
/* * 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; }
/*! * \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; }
/* 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); }
/*! * \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; }
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); }
static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) { DSA_SIG *dsa_sig; const unsigned char *p; if (!sig) { if (BIO_puts(bp, "\n") <= 0) return 0; else return 1; } p = sig->data; dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length); if (dsa_sig) { int rv = 0; size_t buf_len = 0; unsigned char *m=NULL; update_buflen(dsa_sig->r, &buf_len); update_buflen(dsa_sig->s, &buf_len); m = OPENSSL_malloc(buf_len+10); if (m == NULL) { DSAerr(DSA_F_DSA_SIG_PRINT,ERR_R_MALLOC_FAILURE); goto err; } if (BIO_write(bp, "\n", 1) != 1) goto err; if (!ASN1_bn_print(bp,"r: ",dsa_sig->r,m,indent)) goto err; if (!ASN1_bn_print(bp,"s: ",dsa_sig->s,m,indent)) goto err; rv = 1; err: if (m) OPENSSL_free(m); DSA_SIG_free(dsa_sig); return rv; } return X509_signature_dump(bp, sig, indent); }
static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) { DSA_SIG *dsa_sig; const uint8_t *p; if (!sig) { return BIO_puts(bp, "\n") > 0; } p = sig->data; dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length); if (dsa_sig == NULL) { return X509_signature_dump(bp, sig, indent); } int rv = 0; size_t buf_len = 0; uint8_t *m = NULL; update_buflen(dsa_sig->r, &buf_len); update_buflen(dsa_sig->s, &buf_len); m = OPENSSL_malloc(buf_len + 10); if (m == NULL) { OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); goto err; } if (BIO_write(bp, "\n", 1) != 1 || !ASN1_bn_print(bp, "r: ", dsa_sig->r, m, indent) || !ASN1_bn_print(bp, "s: ", dsa_sig->s, m, indent)) { goto err; } rv = 1; err: OPENSSL_free(m); DSA_SIG_free(dsa_sig); return rv; }
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; s = DSA_SIG_new(); if (s == NULL) { goto err; } if (d2i_DSA_SIG(&s, &sig, sig_len) == NULL) { goto err; } ret = DSA_do_check_signature(out_valid, digest, digest_len, s, dsa); err: if (s) { DSA_SIG_free(s); } return ret; }
static isc_result_t openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { dst_key_t *key = dctx->key; DSA *dsa = key->keydata.dsa; isc_region_t r; DSA_SIG *dsasig; #if USE_EVP EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; EVP_PKEY *pkey; unsigned char *sigbuf; const unsigned char *sb; unsigned int siglen; #else isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; unsigned char digest[ISC_SHA1_DIGESTLENGTH]; #endif isc_buffer_availableregion(sig, &r); if (r.length < ISC_SHA1_DIGESTLENGTH * 2 + 1) return (ISC_R_NOSPACE); #if USE_EVP 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); } sigbuf = malloc(EVP_PKEY_size(pkey)); if (sigbuf == NULL) { EVP_PKEY_free(pkey); return (ISC_R_NOMEMORY); } if (!EVP_SignFinal(evp_md_ctx, sigbuf, &siglen, pkey)) { EVP_PKEY_free(pkey); free(sigbuf); return (ISC_R_FAILURE); } INSIST(EVP_PKEY_size(pkey) >= (int) siglen); EVP_PKEY_free(pkey); /* Convert from Dss-Sig-Value (RFC2459). */ dsasig = DSA_SIG_new(); if (dsasig == NULL) { free(sigbuf); return (ISC_R_NOMEMORY); } sb = sigbuf; if (d2i_DSA_SIG(&dsasig, &sb, (long) siglen) == NULL) { free(sigbuf); return (ISC_R_FAILURE); } free(sigbuf); #elif 0 /* Only use EVP for the Digest */ if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) { return (ISC_R_FAILURE); } dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa); if (dsasig == NULL) return (dst__openssl_toresult(DST_R_SIGNFAILURE)); #else isc_sha1_final(sha1ctx, digest); dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa); if (dsasig == NULL) return (dst__openssl_toresult(DST_R_SIGNFAILURE)); #endif *r.base++ = (key->key_size - 512)/64; BN_bn2bin_fixed(dsasig->r, r.base, ISC_SHA1_DIGESTLENGTH); r.base += ISC_SHA1_DIGESTLENGTH; BN_bn2bin_fixed(dsasig->s, r.base, ISC_SHA1_DIGESTLENGTH); r.base += ISC_SHA1_DIGESTLENGTH; DSA_SIG_free(dsasig); isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH * 2 + 1); return (ISC_R_SUCCESS); }