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); }
/* * Packs signature according to Cryptopro rules * and frees up DSA_SIG structure */ int pack_sign_cp(DSA_SIG *s, int order, unsigned char *sig, size_t *siglen) { const BIGNUM *sig_r = NULL, *sig_s = NULL; DSA_SIG_get0(s, &sig_r, &sig_s); *siglen = 2 * order; memset(sig, 0, *siglen); store_bignum(sig_s, sig, order); store_bignum(sig_r, sig + order, order); DSA_SIG_free(s); return 1; }
/* OpenSSL sadly wants to ASN1 encode the resulting bignums so we use this * function to skip that. Returns > 0 on success */ int HsOpenSSL_dsa_sign(DSA *dsa, const unsigned char *ddata, int dlen, const BIGNUM **r, const BIGNUM **s) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L DSA_SIG *const sig = DSA_do_sign(ddata, dlen, dsa); if (!sig) return 0; DSA_SIG_get0(sig, r, s); *r = BN_dup(*r); *s = BN_dup(*s); DSA_SIG_free(sig); return 1; #else DSA_SIG *const sig = dsa->meth->dsa_do_sign(ddata, dlen, dsa); if (!sig) return 0; *r = sig->r; *s = sig->s; free(sig); return 1; #endif }
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx, const unsigned char *hash, unsigned long hash_len, unsigned char *signature) { DSA_SIG *sig; const BIGNUM * r; const BIGNUM * s; int r_len, s_len; (void) hash_len; sig = DSA_do_sign(hash, SHA_DIGEST_LENGTH, dsactx); if(!sig) { return -1; } #ifdef HAVE_OPAQUE_STRUCTS DSA_SIG_get0(sig, &r, &s); #else r = sig->r; s = sig->s; #endif r_len = BN_num_bytes(r); if(r_len < 1 || r_len > 20) { DSA_SIG_free(sig); return -1; } s_len = BN_num_bytes(s); if(s_len < 1 || s_len > 20) { DSA_SIG_free(sig); return -1; } memset(signature, 0, 40); BN_bn2bin(r, signature + (20 - r_len)); BN_bn2bin(s, signature + 20 + (20 - s_len)); DSA_SIG_free(sig); return 0; }