aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2016-04-11 03:49:30 +0900
committerKazuki Yamaguchi <k@rhe.jp>2016-04-21 00:46:34 +0900
commit1b0e67dbc7272f16df5729fd50d70f89e2539a91 (patch)
treee2db8274e53b43994fed7623c16fbda8c743c642
parent62c1d4dfa01caef4e4042fa651b9a8045b7da8c6 (diff)
downloadruby-1b0e67dbc7272f16df5729fd50d70f89e2539a91.tar.gz
macro!
-rw-r--r--ext/openssl/openssl_missing.h26
-rw-r--r--ext/openssl/ossl_pkey.h59
-rw-r--r--ext/openssl/ossl_pkey_dh.c46
-rw-r--r--ext/openssl/ossl_pkey_dsa.c44
-rw-r--r--ext/openssl/ossl_pkey_rsa.c45
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