static int old_dsa_priv_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) { DSA *dsa; BN_CTX *ctx = NULL; BIGNUM *j, *p1, *newp1; if (!(dsa = d2i_DSAPrivateKey(NULL, pder, derlen))) { DSAerror(ERR_R_DSA_LIB); return 0; } ctx = BN_CTX_new(); if (ctx == NULL) goto err; /* * Check that p and q are consistent with each other. */ j = BN_CTX_get(ctx); p1 = BN_CTX_get(ctx); newp1 = BN_CTX_get(ctx); if (j == NULL || p1 == NULL || newp1 == NULL) goto err; /* p1 = p - 1 */ if (BN_sub(p1, dsa->p, BN_value_one()) == 0) goto err; /* j = (p - 1) / q */ if (BN_div_ct(j, NULL, p1, dsa->q, ctx) == 0) goto err; /* q * j should == p - 1 */ if (BN_mul(newp1, dsa->q, j, ctx) == 0) goto err; if (BN_cmp(newp1, p1) != 0) { DSAerror(DSA_R_BAD_Q_VALUE); goto err; } /* * Check that q is not a composite number. */ if (BN_is_prime_ex(dsa->q, BN_prime_checks, ctx, NULL) <= 0) { DSAerror(DSA_R_BAD_Q_VALUE); goto err; } BN_CTX_free(ctx); EVP_PKEY_assign_DSA(pkey, dsa); return 1; err: BN_CTX_free(ctx); DSA_free(dsa); return 0; }
static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { const unsigned char *p, *pm; int pklen, pmlen; int ptype; const void *pval; const ASN1_STRING *pstr; X509_ALGOR *palg; ASN1_INTEGER *public_key = NULL; DSA *dsa = NULL; if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) return 0; X509_ALGOR_get0(NULL, &ptype, &pval, palg); if (ptype == V_ASN1_SEQUENCE) { pstr = pval; pm = pstr->data; pmlen = pstr->length; if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) { DSAerror(DSA_R_DECODE_ERROR); goto err; } } else if (ptype == V_ASN1_NULL || ptype == V_ASN1_UNDEF) { if (!(dsa = DSA_new())) { DSAerror(ERR_R_MALLOC_FAILURE); goto err; } } else { DSAerror(DSA_R_PARAMETER_ENCODING_ERROR); goto err; } if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen))) { DSAerror(DSA_R_DECODE_ERROR); goto err; } if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) { DSAerror(DSA_R_BN_DECODE_ERROR); goto err; } ASN1_INTEGER_free(public_key); EVP_PKEY_assign_DSA(pkey, dsa); return 1; err: if (public_key) ASN1_INTEGER_free(public_key); DSA_free(dsa); return 0; }
static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { DSA *dsa; void *pval = NULL; int ptype; unsigned char *penc = NULL; int penclen; dsa = pkey->pkey.dsa; if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) { ASN1_STRING *str; str = ASN1_STRING_new(); if (str == NULL) { DSAerror(ERR_R_MALLOC_FAILURE); goto err; } str->length = i2d_DSAparams(dsa, &str->data); if (str->length <= 0) { DSAerror(ERR_R_MALLOC_FAILURE); ASN1_STRING_free(str); goto err; } pval = str; ptype = V_ASN1_SEQUENCE; } else ptype = V_ASN1_UNDEF; dsa->write_params = 0; penclen = i2d_DSAPublicKey(dsa, &penc); if (penclen <= 0) { DSAerror(ERR_R_MALLOC_FAILURE); goto err; } if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), ptype, pval, penc, penclen)) return 1; err: free(penc); ASN1_STRING_free(pval); return 0; }
static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) { ASN1_STRING *params = NULL; ASN1_INTEGER *prkey = NULL; unsigned char *dp = NULL; int dplen; params = ASN1_STRING_new(); if (!params) { DSAerror(ERR_R_MALLOC_FAILURE); goto err; } params->length = i2d_DSAparams(pkey->pkey.dsa, ¶ms->data); if (params->length <= 0) { DSAerror(ERR_R_MALLOC_FAILURE); goto err; } params->type = V_ASN1_SEQUENCE; /* Get private key into integer */ prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL); if (!prkey) { DSAerror(DSA_R_BN_ERROR); goto err; } dplen = i2d_ASN1_INTEGER(prkey, &dp); ASN1_INTEGER_free(prkey); prkey = NULL; if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0, V_ASN1_SEQUENCE, params, dp, dplen)) goto err; return 1; err: free(dp); ASN1_STRING_free(params); ASN1_INTEGER_free(prkey); return 0; }
static int dsa_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) { DSA *dsa; if (!(dsa = d2i_DSAparams(NULL, pder, derlen))) { DSAerror(ERR_R_DSA_LIB); return 0; } EVP_PKEY_assign_DSA(pkey, dsa); return 1; }
int DSAparams_print_fp(FILE *fp, const DSA *x) { BIO *b; int ret; if ((b = BIO_new(BIO_s_file())) == NULL) { DSAerror(ERR_R_BUF_LIB); return 0; } BIO_set_fp(b, fp, BIO_NOCLOSE); ret = DSAparams_print(b, x); BIO_free(b); return ret; }
/* Override the default new methods */ static int sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) { if (operation == ASN1_OP_NEW_PRE) { DSA_SIG *sig; sig = malloc(sizeof(DSA_SIG)); if (!sig) { DSAerror(ERR_R_MALLOC_FAILURE); return 0; } sig->r = NULL; sig->s = NULL; *pval = (ASN1_VALUE *)sig; return 2; } return 1; }
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 = malloc(buf_len + 10); if (m == NULL) { DSAerror(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: free(m); DSA_SIG_free(dsa_sig); return rv; } return X509_signature_dump(bp, sig, indent); }
static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) { unsigned char *m = NULL; int ret = 0; size_t buf_len = 0; const char *ktype = NULL; const BIGNUM *priv_key, *pub_key; if (ptype == 2) priv_key = x->priv_key; else priv_key = NULL; if (ptype > 0) pub_key = x->pub_key; else pub_key = NULL; if (ptype == 2) ktype = "Private-Key"; else if (ptype == 1) ktype = "Public-Key"; else ktype = "DSA-Parameters"; update_buflen(x->p, &buf_len); update_buflen(x->q, &buf_len); update_buflen(x->g, &buf_len); update_buflen(priv_key, &buf_len); update_buflen(pub_key, &buf_len); m = malloc(buf_len + 10); if (m == NULL) { DSAerror(ERR_R_MALLOC_FAILURE); goto err; } if (priv_key) { if (!BIO_indent(bp, off, 128)) goto err; if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) goto err; } if (!ASN1_bn_print(bp, "priv:", priv_key, m, off)) goto err; if (!ASN1_bn_print(bp, "pub: ", pub_key, m, off)) goto err; if (!ASN1_bn_print(bp, "P: ", x->p, m, off)) goto err; if (!ASN1_bn_print(bp, "Q: ", x->q, m, off)) goto err; if (!ASN1_bn_print(bp, "G: ", x->g, m, off)) goto err; ret = 1; err: free(m); return(ret); }
/* In PKCS#8 DSA: you just get a private key integer and parameters in the * AlgorithmIdentifier the pubkey must be recalculated. */ static int dsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) { const unsigned char *p, *pm; int pklen, pmlen; int ptype; const void *pval; const ASN1_STRING *pstr; const X509_ALGOR *palg; ASN1_INTEGER *privkey = NULL; BN_CTX *ctx = NULL; DSA *dsa = NULL; int ret = 0; if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) return 0; X509_ALGOR_get0(NULL, &ptype, &pval, palg); if (ptype != V_ASN1_SEQUENCE) goto decerr; if ((privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) goto decerr; if (privkey->type == V_ASN1_NEG_INTEGER) goto decerr; pstr = pval; pm = pstr->data; pmlen = pstr->length; if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) goto decerr; /* We have parameters now set private key */ if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) { DSAerror(DSA_R_BN_ERROR); goto dsaerr; } /* Calculate public key */ if (!(dsa->pub_key = BN_new())) { DSAerror(ERR_R_MALLOC_FAILURE); goto dsaerr; } if (!(ctx = BN_CTX_new())) { DSAerror(ERR_R_MALLOC_FAILURE); goto dsaerr; } if (!BN_mod_exp_ct(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { DSAerror(DSA_R_BN_ERROR); goto dsaerr; } if (!EVP_PKEY_assign_DSA(pkey, dsa)) goto decerr; ret = 1; goto done; decerr: DSAerror(DSA_R_DECODE_ERROR); dsaerr: DSA_free(dsa); done: BN_CTX_free(ctx); ASN1_INTEGER_free(privkey); return ret; }