- {
- const unsigned char *p;
- unsigned char hdr_buf[16], *buf = NULL;
- unsigned int bitlen, magic, length;
- int isdss;
- EVP_PKEY *ret = NULL;
- if (BIO_read(in, hdr_buf, 16) != 16)
- {
- PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT);
- return NULL;
- }
- p = hdr_buf;
- if (do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0)
- return NULL;
-
- length = blob_length(bitlen, isdss, ispub);
- buf = OPENSSL_malloc(length);
- if (!buf)
- {
- PEMerr(PEM_F_DO_B2I_BIO, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- p = buf;
- if (BIO_read(in, buf, length) != (int)length)
- {
- PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT);
- goto err;
- }
-
- if (isdss)
- ret = b2i_dss(&p, length, bitlen, ispub);
- else
- ret = b2i_rsa(&p, length, bitlen, ispub);
-
- err:
- if (buf)
- OPENSSL_free(buf);
- return ret;
- }
-
-static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length,
- unsigned int bitlen, int ispub)
- {
- const unsigned char *p = *in;
- EVP_PKEY *ret = NULL;
- DSA *dsa = NULL;
- BN_CTX *ctx = NULL;
- unsigned int nbyte;
- nbyte = (bitlen + 7) >> 3;
-
- dsa = DSA_new();
- ret = EVP_PKEY_new();
- if (!dsa || !ret)
- goto memerr;
- if (!read_lebn(&p, nbyte, &dsa->p))
- goto memerr;
- if (!read_lebn(&p, 20, &dsa->q))
- goto memerr;
- if (!read_lebn(&p, nbyte, &dsa->g))
- goto memerr;
- if (ispub)
- {
- if (!read_lebn(&p, nbyte, &dsa->pub_key))
- goto memerr;
- }
- else
- {
- if (!read_lebn(&p, 20, &dsa->priv_key))
- goto memerr;
- /* Calculate public key */
- if (!(dsa->pub_key = BN_new()))
- goto memerr;
- if (!(ctx = BN_CTX_new()))
- goto memerr;
-
- if (!BN_mod_exp(dsa->pub_key, dsa->g,
- dsa->priv_key, dsa->p, ctx))
-
- goto memerr;
- BN_CTX_free(ctx);
- }
-
- EVP_PKEY_set1_DSA(ret, dsa);
- DSA_free(dsa);
- *in = p;
- return ret;
-
- memerr:
- PEMerr(PEM_F_B2I_DSS, ERR_R_MALLOC_FAILURE);
- if (dsa)
- DSA_free(dsa);
- if (ret)
- EVP_PKEY_free(ret);
- if (ctx)
- BN_CTX_free(ctx);
- return NULL;
- }
-
-static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length,
- unsigned int bitlen, int ispub)
-
- {
- const unsigned char *p = *in;
- EVP_PKEY *ret = NULL;
- RSA *rsa = NULL;
- unsigned int nbyte, hnbyte;
- nbyte = (bitlen + 7) >> 3;
- hnbyte = (bitlen + 15) >> 4;
- rsa = RSA_new();
- ret = EVP_PKEY_new();
- if (!rsa || !ret)
- goto memerr;
- rsa->e = BN_new();
- if (!rsa->e)
- goto memerr;
- if (!BN_set_word(rsa->e, read_ledword(&p)))
- goto memerr;
- if (!read_lebn(&p, nbyte, &rsa->n))
- goto memerr;
- if (!ispub)
- {
- if (!read_lebn(&p, hnbyte, &rsa->p))
- goto memerr;
- if (!read_lebn(&p, hnbyte, &rsa->q))
- goto memerr;
- if (!read_lebn(&p, hnbyte, &rsa->dmp1))
- goto memerr;
- if (!read_lebn(&p, hnbyte, &rsa->dmq1))
- goto memerr;
- if (!read_lebn(&p, hnbyte, &rsa->iqmp))
- goto memerr;
- if (!read_lebn(&p, nbyte, &rsa->d))
- goto memerr;
- }
-
- EVP_PKEY_set1_RSA(ret, rsa);
- RSA_free(rsa);
- *in = p;
- return ret;
- memerr:
- PEMerr(PEM_F_B2I_RSA, ERR_R_MALLOC_FAILURE);
- if (rsa)
- RSA_free(rsa);
- if (ret)
- EVP_PKEY_free(ret);
- return NULL;
- }
+{
+ const unsigned char *p;
+ unsigned char hdr_buf[16], *buf = NULL;
+ unsigned int bitlen, magic, length;
+ int isdss;
+ EVP_PKEY *ret = NULL;
+ if (BIO_read(in, hdr_buf, 16) != 16) {
+ PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT);
+ return NULL;
+ }
+ p = hdr_buf;
+ if (do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0)
+ return NULL;
+
+ length = blob_length(bitlen, isdss, ispub);
+ buf = OPENSSL_malloc(length);
+ if (buf == NULL) {
+ PEMerr(PEM_F_DO_B2I_BIO, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ p = buf;
+ if (BIO_read(in, buf, length) != (int)length) {
+ PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT);
+ goto err;
+ }
+
+ if (isdss)
+ ret = b2i_dss(&p, bitlen, ispub);
+ else
+ ret = b2i_rsa(&p, bitlen, ispub);
+
+ err:
+ OPENSSL_free(buf);
+ return ret;
+}
+
+static EVP_PKEY *b2i_dss(const unsigned char **in,
+ unsigned int bitlen, int ispub)
+{
+ const unsigned char *p = *in;
+ EVP_PKEY *ret = NULL;
+ DSA *dsa = NULL;
+ BN_CTX *ctx = NULL;
+ unsigned int nbyte;
+ BIGNUM *pbn = NULL, *qbn = NULL, *gbn = NULL, *priv_key = NULL;
+ BIGNUM *pub_key = NULL;
+
+ nbyte = (bitlen + 7) >> 3;
+
+ dsa = DSA_new();
+ ret = EVP_PKEY_new();
+ if (dsa == NULL || ret == NULL)
+ goto memerr;
+ if (!read_lebn(&p, nbyte, &pbn))
+ goto memerr;
+
+ if (!read_lebn(&p, 20, &qbn))
+ goto memerr;
+
+ if (!read_lebn(&p, nbyte, &gbn))
+ goto memerr;
+
+ if (ispub) {
+ if (!read_lebn(&p, nbyte, &pub_key))
+ goto memerr;
+ } else {
+ if (!read_lebn(&p, 20, &priv_key))
+ goto memerr;
+
+ /* Calculate public key */
+ pub_key = BN_new();
+ if (pub_key == NULL)
+ goto memerr;
+ if ((ctx = BN_CTX_new()) == NULL)
+ goto memerr;
+
+ if (!BN_mod_exp(pub_key, gbn, priv_key, pbn, ctx))
+ goto memerr;
+
+ BN_CTX_free(ctx);
+ }
+ if (!DSA_set0_pqg(dsa, pbn, qbn, gbn))
+ goto memerr;
+ pbn = qbn = gbn = NULL;
+ if (!DSA_set0_key(dsa, pub_key, priv_key))
+ goto memerr;
+
+ EVP_PKEY_set1_DSA(ret, dsa);
+ DSA_free(dsa);
+ *in = p;
+ return ret;
+
+ memerr:
+ PEMerr(PEM_F_B2I_DSS, ERR_R_MALLOC_FAILURE);
+ DSA_free(dsa);
+ BN_free(pbn);
+ BN_free(qbn);
+ BN_free(gbn);
+ BN_free(pub_key);
+ BN_free(priv_key);
+ EVP_PKEY_free(ret);
+ BN_CTX_free(ctx);
+ return NULL;
+}
+
+static EVP_PKEY *b2i_rsa(const unsigned char **in,
+ unsigned int bitlen, int ispub)
+{
+ const unsigned char *pin = *in;
+ EVP_PKEY *ret = NULL;
+ BIGNUM *e = NULL, *n = NULL, *d = NULL;
+ BIGNUM *p = NULL, *q = NULL, *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL;
+ RSA *rsa = NULL;
+ unsigned int nbyte, hnbyte;
+ nbyte = (bitlen + 7) >> 3;
+ hnbyte = (bitlen + 15) >> 4;
+ rsa = RSA_new();
+ ret = EVP_PKEY_new();
+ if (rsa == NULL || ret == NULL)
+ goto memerr;
+ e = BN_new();
+ if (e == NULL)
+ goto memerr;
+ if (!BN_set_word(e, read_ledword(&pin)))
+ goto memerr;
+ if (!read_lebn(&pin, nbyte, &n))
+ goto memerr;
+ if (!ispub) {
+ if (!read_lebn(&pin, hnbyte, &p))
+ goto memerr;
+ if (!read_lebn(&pin, hnbyte, &q))
+ goto memerr;
+ if (!read_lebn(&pin, hnbyte, &dmp1))
+ goto memerr;
+ if (!read_lebn(&pin, hnbyte, &dmq1))
+ goto memerr;
+ if (!read_lebn(&pin, hnbyte, &iqmp))
+ goto memerr;
+ if (!read_lebn(&pin, nbyte, &d))
+ goto memerr;
+ RSA_set0_factors(rsa, p, q);
+ RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp);
+ }
+ RSA_set0_key(rsa, n, e, d);
+
+ EVP_PKEY_set1_RSA(ret, rsa);
+ RSA_free(rsa);
+ *in = pin;
+ return ret;
+ memerr:
+ PEMerr(PEM_F_B2I_RSA, ERR_R_MALLOC_FAILURE);
+ BN_free(e);
+ BN_free(n);
+ BN_free(p);
+ BN_free(q);
+ BN_free(dmp1);
+ BN_free(dmq1);
+ BN_free(iqmp);
+ BN_free(d);
+ RSA_free(rsa);
+ EVP_PKEY_free(ret);
+ return NULL;
+}