diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2016-04-11 03:49:30 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2016-04-21 00:46:34 +0900 |
commit | 1b0e67dbc7272f16df5729fd50d70f89e2539a91 (patch) | |
tree | e2db8274e53b43994fed7623c16fbda8c743c642 | |
parent | 62c1d4dfa01caef4e4042fa651b9a8045b7da8c6 (diff) | |
download | ruby-1b0e67dbc7272f16df5729fd50d70f89e2539a91.tar.gz |
macro!
-rw-r--r-- | ext/openssl/openssl_missing.h | 26 | ||||
-rw-r--r-- | ext/openssl/ossl_pkey.h | 59 | ||||
-rw-r--r-- | ext/openssl/ossl_pkey_dh.c | 46 | ||||
-rw-r--r-- | ext/openssl/ossl_pkey_dsa.c | 44 | ||||
-rw-r--r-- | ext/openssl/ossl_pkey_rsa.c | 45 |
5 files changed, 145 insertions, 75 deletions
diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h index 1afdbed8dd..9b7eec5f98 100644 --- a/ext/openssl/openssl_missing.h +++ b/ext/openssl/openssl_missing.h @@ -263,6 +263,32 @@ int SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b); # define EVP_PKEY_get0_DSA(p) (p->pkey.dsa) # define EVP_PKEY_get0_EC_KEY(p) (p->pkey.ec) # define EVP_PKEY_get0_DH(p) (p->pkey.dh) + +# define RSA_get0_engine(p) (p->engine) +# define RSA_get0_key(p, pn, pe, pd) do { \ + if (pn) *pn = p->n; \ + if (pe) *pe = p->e; \ + if (pd) *pd = p->d; } +# define RSA_get0_factors(p, pp, pq) do { \ + if (pp) *pp = p->p; \ + if (pq) *pq = p->q; } +# define RSA_get0_crt_params(p, pdmp1, pdmq1, piqmp) do {\ + if (pdmp1) *pdmp1 = p->dmp1; \ + if (pdmq1) *pdmq1 = p->dmq1; \ + if (piqmp) *piqmp = p->iqmp; } + +# define DSA_get0_engine(p) (p->engine) +# define DSA_get0_key(p, ppub, ppriv) do { \ + if (ppub) *ppub = p->pub_key; \ + if (ppriv) *ppriv = p->priv_key; } +# define DSA_get0_pqg(p, pp, pq, pg) do { \ + if (pp) *pp = p->p; \ + if (pq) *pq = p->q; \ + if (pg) *pg = p->g; } + +# define DH_get0_engine(p) (p->engine) +# define DH_get0_key(p, ppub, ppriv) DSA_get0_key(p, ppub, ppriv) +# define DH_get0_pqg(p, pp, pq, pg) DSA_get0_pqg(p, pp, pq, pg) #endif /* HMAC */ diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h index e682de900f..f75cc6c13c 100644 --- a/ext/openssl/ossl_pkey.h +++ b/ext/openssl/ossl_pkey.h @@ -99,8 +99,8 @@ extern VALUE eEC_POINT; VALUE ossl_ec_new(EVP_PKEY *); void Init_ossl_ec(void); - -#define OSSL_PKEY_BN(keytype, type, name) \ +/* yes this is very ugly :( */ +#define OSSL_PKEY_BN_DEF_FUNC(keytype, type, name, b1, b2, b3, get, set)\ /* \ * call-seq: \ * key.##name -> aBN \ @@ -108,13 +108,13 @@ void Init_ossl_ec(void); static VALUE ossl_##keytype##_get_##name(VALUE self) \ { \ EVP_PKEY *pkey; \ - BIGNUM *bn; \ + BIGNUM *b1, *b2, *b3; \ + type *obj; \ \ GetPKey(self, pkey); \ - bn = EVP_PKEY_get0_##type(pkey)->name; \ - if (bn == NULL) \ - return Qnil; \ - return ossl_bn_new(bn); \ + obj = EVP_PKEY_get0_##type(pkey); \ + get; \ + return ossl_bn_new(name); \ } \ /* \ * call-seq: \ @@ -123,27 +123,46 @@ static VALUE ossl_##keytype##_get_##name(VALUE self) \ static VALUE ossl_##keytype##_set_##name(VALUE self, VALUE bignum) \ { \ EVP_PKEY *pkey; \ - BIGNUM *bn; \ + BIGNUM *b1, *b2, *b3; \ + BIGNUM *old; \ type *obj; \ \ GetPKey(self, pkey); \ obj = EVP_PKEY_get0_##type(pkey); \ - if (NIL_P(bignum)) { \ - BN_clear_free(obj->name); \ - obj->name = NULL; \ - return Qnil; \ - } \ - \ - bn = GetBNPtr(bignum); \ - if (obj->name == NULL) \ - obj->name = BN_new(); \ - if (obj->name == NULL) \ - ossl_raise(eBNError, NULL); \ - if (BN_copy(obj->name, bn) == NULL) \ + get; /* get current value */ \ + old = name; \ + if (NIL_P(bignum)) \ + name = NULL; \ + else if (!(name = BN_dup(GetBNPtr(bignum)))) \ ossl_raise(eBNError, NULL); \ + if (!(set)) { \ + if (name) BN_clear_free(name); \ + rb_bug("xx %d %d", !!b1, !!b2);\ + ossl_raise(eBNError, "priv_key set failed"); \ + } \ + BN_clear_free(old); \ return bignum; \ } +#define OSSL_PKEY_BN3(keytype, type, func_name, a1, a2, a3) \ + OSSL_PKEY_BN_DEF_FUNC(keytype, type, a1, a1, a2, a3, \ + type##_get0_##func_name(obj, &a1, &a2, &a3), \ + type##_set0_##func_name(obj, a1, a2, a3)) \ + OSSL_PKEY_BN_DEF_FUNC(keytype, type, a2, a1, a2, a3, \ + type##_get0_##func_name(obj, &a1, &a2, &a3), \ + type##_set0_##func_name(obj, a1, a2, a3)) \ + OSSL_PKEY_BN_DEF_FUNC(keytype, type, a3, a1, a2, a3, \ + type##_get0_##func_name(obj, &a1, &a2, &a3), \ + type##_set0_##func_name(obj, a1, a2, a3)) + +#define OSSL_PKEY_BN2(keytype, type, func_name, a1, a2) \ + OSSL_PKEY_BN_DEF_FUNC(keytype, type, a1, a1, a2, unused, \ + type##_get0_##func_name(obj, &a1, &a2), \ + type##_set0_##func_name(obj, a1, a2)) \ + OSSL_PKEY_BN_DEF_FUNC(keytype, type, a2, a1, a2, unused, \ + type##_get0_##func_name(obj, &a1, &a2), \ + type##_set0_##func_name(obj, a1, a2)) + #define DEF_OSSL_PKEY_BN(class, keytype, name) \ do { \ rb_define_method((class), #name, ossl_##keytype##_get_##name, 0); \ diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c index 96aa80b39e..73ad37d114 100644 --- a/ext/openssl/ossl_pkey_dh.c +++ b/ext/openssl/ossl_pkey_dh.c @@ -18,15 +18,6 @@ } \ } while (0) -#define DH_HAS_PRIVATE(dh) ((dh)->priv_key) - -#ifdef OSSL_ENGINE_ENABLED -# define DH_PRIVATE(dh) (DH_HAS_PRIVATE(dh) || (dh)->engine) -#else -# define DH_PRIVATE(dh) DH_HAS_PRIVATE(dh) -#endif - - /* * Classes */ @@ -259,10 +250,12 @@ static VALUE ossl_dh_is_public(VALUE self) { EVP_PKEY *pkey; + BIGNUM *pub_key; GetPKeyDH(self, pkey); + DH_get0_key(EVP_PKEY_get0_DH(pkey), &pub_key, NULL); - return EVP_PKEY_get0_DH(pkey)->pub_key ? Qtrue : Qfalse; + return pub_key ? Qtrue : Qfalse; } /* @@ -276,12 +269,21 @@ static VALUE ossl_dh_is_private(VALUE self) { EVP_PKEY *pkey; + DH *dh; + BIGNUM *priv_key; GetPKeyDH(self, pkey); + dh = EVP_PKEY_get0_DH(pkey); + DH_get0_key(dh, NULL, &priv_key); - return DH_PRIVATE(EVP_PKEY_get0_DH(pkey)) ? Qtrue : Qfalse; +#ifdef OSSL_ENGINE_ENABLED + return (priv_key || DH_get0_engine(dh)) ? Qtrue : Qfalse; +#else + return priv_key ? Qtrue : Qfalse; +#endif } + /* * call-seq: * dh.export -> aString @@ -355,16 +357,20 @@ ossl_dh_get_params(VALUE self) EVP_PKEY *pkey; VALUE hash; DH *dh; + BIGNUM *pub_key, *priv_key; + BIGNUM *p, *g; GetPKeyDH(self, pkey); - hash = rb_hash_new(); - dh = EVP_PKEY_get0_DH(pkey); - rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(dh->p)); - rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(dh->g)); - rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(dh->pub_key)); - rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(dh->priv_key)); + DH_get0_key(dh, &pub_key, &priv_key); + DH_get0_pqg(dh, &p, NULL, &g); + + hash = rb_hash_new(); + rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(p)); + rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(g)); + rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pub_key)); + rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(priv_key)); return hash; } @@ -524,10 +530,8 @@ ossl_dh_compute_key(VALUE self, VALUE pub) return str; } -OSSL_PKEY_BN(dh, DH, p) -OSSL_PKEY_BN(dh, DH, g) -OSSL_PKEY_BN(dh, DH, pub_key) -OSSL_PKEY_BN(dh, DH, priv_key) +OSSL_PKEY_BN3(dh, DH, pqg, p, q, g) +OSSL_PKEY_BN2(dh, DH, key, pub_key, priv_key) /* * INIT diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c index 160391a2b0..68b8eaa8b2 100644 --- a/ext/openssl/ossl_pkey_dsa.c +++ b/ext/openssl/ossl_pkey_dsa.c @@ -18,8 +18,13 @@ } \ } while (0) -#define DSA_HAS_PRIVATE(dsa) ((dsa)->priv_key) -#define DSA_PRIVATE(obj,dsa) (DSA_HAS_PRIVATE(dsa)||OSSL_PKEY_IS_PRIVATE(obj)) +static inline int +DSA_HAS_PRIVATE(DSA *dsa) +{ + BIGNUM *priv_key; + DSA_get0_key(dsa, NULL, &priv_key); + return !!priv_key; +} /* * Classes @@ -272,10 +277,12 @@ static VALUE ossl_dsa_is_public(VALUE self) { EVP_PKEY *pkey; + BIGNUM *pub_key; GetPKeyDSA(self, pkey); + DSA_get0_key(EVP_PKEY_get0_DSA(pkey), &pub_key, NULL); - return (EVP_PKEY_get0_DSA(pkey)->pub_key) ? Qtrue : Qfalse; + return pub_key ? Qtrue : Qfalse; } /* @@ -292,7 +299,8 @@ ossl_dsa_is_private(VALUE self) GetPKeyDSA(self, pkey); - return (DSA_PRIVATE(self, EVP_PKEY_get0_DSA(pkey))) ? Qtrue : Qfalse; + return (DSA_HAS_PRIVATE(EVP_PKEY_get0_DSA(pkey)) || OSSL_PKEY_IS_PRIVATE(self)) + ? Qtrue : Qfalse; } /* @@ -397,16 +405,22 @@ ossl_dsa_get_params(VALUE self) { EVP_PKEY *pkey; VALUE hash; + DSA *dsa; + BIGNUM *p, *q, *g; + BIGNUM *pub_key, *priv_key; GetPKeyDSA(self, pkey); - hash = rb_hash_new(); + dsa = EVP_PKEY_get0_DSA(pkey); + DSA_get0_key(dsa, &pub_key, &priv_key); + DSA_get0_pqg(dsa, &p, &q, &g); - rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(EVP_PKEY_get0_DSA(pkey)->p)); - rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(EVP_PKEY_get0_DSA(pkey)->q)); - rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(EVP_PKEY_get0_DSA(pkey)->g)); - rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(EVP_PKEY_get0_DSA(pkey)->pub_key)); - rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(EVP_PKEY_get0_DSA(pkey)->priv_key)); + hash = rb_hash_new(); + rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(p)); + rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(q)); + rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(g)); + rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pub_key)); + rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(priv_key)); return hash; } @@ -504,7 +518,8 @@ ossl_dsa_sign(VALUE self, VALUE data) GetPKeyDSA(self, pkey); StringValue(data); - if (!DSA_PRIVATE(self, EVP_PKEY_get0_DSA(pkey))) { + + if (ossl_dsa_is_private(self) != Qtrue) { ossl_raise(eDSAError, "Private DSA key needed!"); } str = rb_str_new(0, ossl_dsa_buf_size(pkey)); @@ -559,11 +574,8 @@ ossl_dsa_verify(VALUE self, VALUE digest, VALUE sig) return Qfalse; } -OSSL_PKEY_BN(dsa, DSA, p) -OSSL_PKEY_BN(dsa, DSA, q) -OSSL_PKEY_BN(dsa, DSA, g) -OSSL_PKEY_BN(dsa, DSA, pub_key) -OSSL_PKEY_BN(dsa, DSA, priv_key) +OSSL_PKEY_BN3(dsa, DSA, pqg, p, q, g) +OSSL_PKEY_BN2(dsa, DSA, key, pub_key, priv_key) /* * INIT diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c index 3e54c9ed4a..41c94e2267 100644 --- a/ext/openssl/ossl_pkey_rsa.c +++ b/ext/openssl/ossl_pkey_rsa.c @@ -18,7 +18,13 @@ } \ } while (0) -#define RSA_HAS_PRIVATE(rsa) ((rsa)->p && (rsa)->q) +static inline int +RSA_HAS_PRIVATE(RSA *rsa) +{ + BIGNUM *p, *q; + RSA_get0_factors(rsa, &p, &q); + return p && q; +} #define RSA_PRIVATE(obj,rsa) (RSA_HAS_PRIVATE(rsa)||OSSL_PKEY_IS_PRIVATE(obj)) /* @@ -514,19 +520,27 @@ ossl_rsa_get_params(VALUE self) { EVP_PKEY *pkey; VALUE hash; + RSA *rsa; + BIGNUM *n, *e, *d; + BIGNUM *p, *q; + BIGNUM *dmp1, *dmq1, *iqmp; GetPKeyRSA(self, pkey); - hash = rb_hash_new(); + rsa = EVP_PKEY_get0_RSA(pkey); + RSA_get0_key(rsa, &n, &e, &d); + RSA_get0_factors(rsa, &p, &q); + RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); - rb_hash_aset(hash, rb_str_new2("n"), ossl_bn_new(EVP_PKEY_get0_RSA(pkey)->n)); - rb_hash_aset(hash, rb_str_new2("e"), ossl_bn_new(EVP_PKEY_get0_RSA(pkey)->e)); - rb_hash_aset(hash, rb_str_new2("d"), ossl_bn_new(EVP_PKEY_get0_RSA(pkey)->d)); - rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(EVP_PKEY_get0_RSA(pkey)->p)); - rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(EVP_PKEY_get0_RSA(pkey)->q)); - rb_hash_aset(hash, rb_str_new2("dmp1"), ossl_bn_new(EVP_PKEY_get0_RSA(pkey)->dmp1)); - rb_hash_aset(hash, rb_str_new2("dmq1"), ossl_bn_new(EVP_PKEY_get0_RSA(pkey)->dmq1)); - rb_hash_aset(hash, rb_str_new2("iqmp"), ossl_bn_new(EVP_PKEY_get0_RSA(pkey)->iqmp)); + hash = rb_hash_new(); + rb_hash_aset(hash, rb_str_new2("n"), ossl_bn_new(n)); + rb_hash_aset(hash, rb_str_new2("e"), ossl_bn_new(e)); + rb_hash_aset(hash, rb_str_new2("d"), ossl_bn_new(d)); + rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(p)); + rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(q)); + rb_hash_aset(hash, rb_str_new2("dmp1"), ossl_bn_new(dmp1)); + rb_hash_aset(hash, rb_str_new2("dmq1"), ossl_bn_new(dmq1)); + rb_hash_aset(hash, rb_str_new2("iqmp"), ossl_bn_new(iqmp)); return hash; } @@ -613,14 +627,9 @@ ossl_rsa_blinding_off(VALUE self) } */ -OSSL_PKEY_BN(rsa, RSA, n) -OSSL_PKEY_BN(rsa, RSA, e) -OSSL_PKEY_BN(rsa, RSA, d) -OSSL_PKEY_BN(rsa, RSA, p) -OSSL_PKEY_BN(rsa, RSA, q) -OSSL_PKEY_BN(rsa, RSA, dmp1) -OSSL_PKEY_BN(rsa, RSA, dmq1) -OSSL_PKEY_BN(rsa, RSA, iqmp) +OSSL_PKEY_BN3(rsa, RSA, key, n, e, d) +OSSL_PKEY_BN2(rsa, RSA, factors, p, q) +OSSL_PKEY_BN3(rsa, RSA, crt_params, dmp1, dmq1, iqmp) /* * INIT |