diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | extconf.rb | 4 | ||||
-rw-r--r-- | lib/openssl/bn.rb | 3 | ||||
-rw-r--r-- | ossl.c | 64 | ||||
-rw-r--r-- | ossl.h | 8 | ||||
-rw-r--r-- | ossl_bn.c | 107 | ||||
-rw-r--r-- | ossl_bn.h | 4 | ||||
-rw-r--r-- | ossl_pkcs7.c | 2 | ||||
-rw-r--r-- | ossl_x509cert.c | 15 | ||||
-rw-r--r-- | ossl_x509revoked.c | 15 |
10 files changed, 180 insertions, 53 deletions
@@ -1,3 +1,14 @@ +Sun, 10 Nov 2002 23:30:56 +0100 -- Michal Rokos <m.rokos@sh.cvut.cz> + * bn.c: enhance BN so you can pass as parameter Ruby's numbers + +Sun, 10 Nov 2002 19:19:32 +0100 -- Michal Rokos <m.rokos@sh.cvut.cz> + * x509cert.c: Fix #serial, #serial= to support big numbers. + * x509req.c: ditto. + * pkcs7.c: ditto. + * bn.c: implemented #to_int, #coerce to act with Ruby's numbers (so you + can: eg. 10 + BN.new("200") + * extconf.rb: fix it (again) to work with latest OpenSSL 0.9.7 + Thu, 7 Nov 2002 14:02:35 +0900 * ossl_ssl.c: memory leak has been in ossl_sslctx_free(). @@ -64,8 +64,8 @@ EOD end if have_header("openssl/crypto.h") and - have_library(CRYPTOLIB, "OpenSSL_add_all_algorithms") and - have_library(SSLLIB, "SSLv23_method") + have_library(CRYPTOLIB, "OPENSSL_load_builtin_modules") and + have_library(SSLLIB, "SSL_library_init") create_makefile("openssl") puts "Done." else diff --git a/lib/openssl/bn.rb b/lib/openssl/bn.rb index 213fb86..27c0423 100644 --- a/lib/openssl/bn.rb +++ b/lib/openssl/bn.rb @@ -22,9 +22,6 @@ module OpenSSL class BN include Comparable - def to_i - to_s.to_i - end end # BN end # OpenSSL @@ -81,6 +81,70 @@ time_to_time_t(VALUE time) } /* + * ASN1_INTEGER conversions + * TODO: Make a decision what's the right way to do this. + */ +VALUE +asn1integer_to_num(ASN1_INTEGER *ai) +{ + BIGNUM *bn; + char *txt; + VALUE num; + + if (!ai) { + ossl_raise(rb_eTypeError, "ASN1_INTEGER is NULL!"); + } + if (!(bn = ASN1_INTEGER_to_BN(ai, NULL))) { + ossl_raise(eOSSLError, ""); + } +#if 0 + if (!(txt = BN_bn2dec(bn))) { + BN_free(bn); + ossl_raise(eOSSLError, ""); + } + num = rb_cstr_to_inum(txt, 10, Qtrue); + OPENSSL_free(txt); +#else + num = ossl_bn_new(bn); +#endif + BN_free(bn); + + return num; +} + +#if 0 +ASN1_INTEGER *num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai) +{ + BIGNUM *bn = NULL; + + if (RTEST(rb_obj_is_kind_of(obj, cBN))) { + bn = GetBNPtr(obj); + } else { + obj = rb_String(obj); + if (!BN_dec2bn(&bn, StringValuePtr(obj))) { + ossl_raise(eOSSLError, ""); + } + } + if (!(ai = BN_to_ASN1_INTEGER(bn, ai))) { + BN_free(bn); + ossl_raise(eOSSLError, ""); + } + BN_free(bn); + return ai; +} +#else +ASN1_INTEGER *num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai) +{ + BIGNUM *bn = GetBNPtr(obj); + + if (!(ai = BN_to_ASN1_INTEGER(bn, ai))) { + ossl_raise(eOSSLError, ""); + } + return ai; +} +#endif + +/* * String to HEXString conversion */ int @@ -88,12 +88,18 @@ extern VALUE eOSSLError; } while (0) /* - * DATE conversion + * ASN1_DATE conversions */ VALUE asn1time_to_time(ASN1_TIME *); time_t time_to_time_t(VALUE); /* + * ASN1_INTEGER conversions + */ +VALUE asn1integer_to_num(ASN1_INTEGER *); +ASN1_INTEGER *num_to_asn1integer(VALUE, ASN1_INTEGER *); + +/* * String to HEXString conversion */ int string2hex(char *, int, char **, int *); @@ -35,10 +35,9 @@ VALUE cBN; VALUE eBNError; /* - * NO Public - * (MADE PRIVATE UNTIL SOMEBODY WANTS THEM) - * -static VALUE + * Public + */ +VALUE ossl_bn_new(BIGNUM *bn) { BIGNUM *new; @@ -56,7 +55,28 @@ ossl_bn_new(BIGNUM *bn) return obj; } - */ + +BIGNUM * +GetBNPtr(VALUE obj) +{ + BIGNUM *bn = NULL; + + if (RTEST(rb_obj_is_kind_of(obj, cBN))) { + GetBN(obj, bn); + } else switch (TYPE(obj)) { + case T_FIXNUM: + case T_BIGNUM: + obj = rb_String(obj); + if (!BN_dec2bn(&bn, StringValuePtr(obj))) { + ossl_raise(eBNError, ""); + } + WrapBN(cBN, obj, bn); /* Handle potencial mem leaks */ + break; + default: + ossl_raise(rb_eTypeError, "Cannot convert into OpenSSL::BN"); + } + return bn; +} /* * Private @@ -93,7 +113,7 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self) if (rb_scan_args(argc, argv, "11", &str, &bs) == 2) { base = NUM2INT(bs); } - if (rb_obj_is_kind_of(str, cBN) == Qtrue) { + if (RTEST(rb_obj_is_kind_of(str, cBN))) { BIGNUM *other; GetBN(str, other); /* Safe - we checked kind_of? above */ @@ -102,6 +122,7 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self) } return self; } + str = rb_String(str); StringValue(str); switch (base) { @@ -186,6 +207,49 @@ ossl_bn_to_s(int argc, VALUE *argv, VALUE self) return str; } +static VALUE +ossl_bn_to_i(VALUE self) +{ + BIGNUM *bn; + char *txt; + VALUE num; + + GetBN(self, bn); + + if (!(txt = BN_bn2dec(bn))) { + ossl_raise(eBNError, ""); + } + num = rb_cstr_to_inum(txt, 10, Qtrue); + OPENSSL_free(txt); + + return num; +} + +static VALUE +ossl_bn_to_bn(VALUE self) +{ + return self; +} + +static VALUE +ossl_bn_coerce(VALUE self, VALUE other) +{ + switch(TYPE(other)) { + case T_STRING: + self = ossl_bn_to_s(0, NULL, self); + break; + case T_FIXNUM: + case T_BIGNUM: + self = ossl_bn_to_i(self); + break; + default: + if (!RTEST(rb_obj_is_kind_of(other, cBN))) { + ossl_raise(rb_eTypeError, "Don't know how to coerce"); + } + } + return rb_assoc_new(other, self); +} + #define BIGNUM_BOOL1(func) \ static VALUE \ ossl_bn_##func(VALUE self) \ @@ -229,11 +293,10 @@ BIGNUM_1c(sqr); static VALUE \ ossl_bn_##func(VALUE self, VALUE other) \ { \ - BIGNUM *bn1, *bn2, *result; \ + BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \ VALUE obj; \ \ GetBN(self, bn1); \ - SafeGetBN(other, bn2); \ \ if (!(result = BN_new())) { \ ossl_raise(eBNError, ""); \ @@ -253,11 +316,10 @@ BIGNUM_2(sub); static VALUE \ ossl_bn_##func(VALUE self, VALUE other) \ { \ - BIGNUM *bn1, *bn2, *result; \ + BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \ VALUE obj; \ \ GetBN(self, bn1); \ - SafeGetBN(other, bn2); \ \ if (!(result = BN_new())) { \ ossl_raise(eBNError, ""); \ @@ -280,11 +342,10 @@ BIGNUM_2c(mod_inverse); static VALUE ossl_bn_div(VALUE self, VALUE other) { - BIGNUM *bn1, *bn2, *r1, *r2; + BIGNUM *bn1, *bn2 = GetBNPtr(other), *r1, *r2; VALUE obj1, obj2; GetBN(self, bn1); - SafeGetBN(other, bn2); if (!(r1 = BN_new())) { ossl_raise(eBNError, ""); @@ -308,12 +369,10 @@ ossl_bn_div(VALUE self, VALUE other) static VALUE \ ossl_bn_##func(VALUE self, VALUE other1, VALUE other2) \ { \ - BIGNUM *bn1, *bn2, *bn3, *result; \ + BIGNUM *bn1, *bn2 = GetBNPtr(other1), *bn3 = GetBNPtr(other2), *result; \ VALUE obj; \ \ GetBN(self, bn1); \ - SafeGetBN(other1, bn2); \ - SafeGetBN(other2, bn3); \ \ if (!(result = BN_new())) { \ ossl_raise(eBNError, ""); \ @@ -422,11 +481,9 @@ BIGNUM_RAND(pseudo_rand); static VALUE \ ossl_bn_s_##func##_range(VALUE klass, VALUE range) \ { \ - BIGNUM *bn, *result; \ + BIGNUM *bn = GetBNPtr(range), *result; \ VALUE obj; \ \ - SafeGetBN(range, bn); \ - \ if (!(result = BN_new())) { \ ossl_raise(eBNError, ""); \ } \ @@ -459,8 +516,8 @@ ossl_bn_s_generate_prime(int argc, VALUE *argv, VALUE klass) if (NIL_P(vrem)) { ossl_raise(rb_eArgError, "if ADD is specified, REM must be also given"); } - SafeGetBN(vadd, add); - SafeGetBN(vrem, rem); + add = GetBNPtr(vadd); + rem = GetBNPtr(vrem); } if (!(result = BN_new())) { ossl_raise(eBNError, ""); @@ -497,7 +554,7 @@ ossl_bn_copy(VALUE self, VALUE other) if (self == other) return self; GetBN(self, bn1); - SafeGetBN(other, bn2); + bn2 = GetBNPtr(other); if (!BN_copy(bn1, bn2)) { ossl_raise(eBNError, ""); @@ -509,10 +566,9 @@ ossl_bn_copy(VALUE self, VALUE other) static VALUE \ ossl_bn_##func(VALUE self, VALUE other) \ { \ - BIGNUM *bn1, *bn2; \ + BIGNUM *bn1, *bn2 = GetBNPtr(other); \ \ GetBN(self, bn1); \ - SafeGetBN(other, bn2); \ \ return INT2FIX(BN_##func(bn1, bn2)); \ } @@ -676,6 +732,11 @@ Init_ossl_bn() * bn2mpi * mpi2bn */ rb_define_method(cBN, "to_s", ossl_bn_to_s, -1); + rb_define_method(cBN, "to_i", ossl_bn_to_i, 0); + rb_define_alias(cBN, "to_int", "to_i"); + rb_define_method(cBN, "to_bn", ossl_bn_to_bn, 0); + rb_define_method(cBN, "coerce", ossl_bn_coerce, 1); + /* * TODO: * But how to: from_bin, from_mpi? PACK? @@ -14,10 +14,8 @@ extern VALUE cBN; extern VALUE eBNError; -/* VALUE ossl_bn_new(BIGNUM *); - */ - +BIGNUM *GetBNPtr(VALUE); void Init_ossl_bn(void); #endif /* _OSS_BN_H_ */ diff --git a/ossl_pkcs7.c b/ossl_pkcs7.c index 94fa097..6b83564 100644 --- a/ossl_pkcs7.c +++ b/ossl_pkcs7.c @@ -503,7 +503,7 @@ ossl_pkcs7si_get_serial(VALUE self) GetPKCS7si(self, p7si); - return INT2NUM(ASN1_INTEGER_get(p7si->issuer_and_serial->serial)); + return asn1integer_to_num(p7si->issuer_and_serial->serial); } static VALUE diff --git a/ossl_x509cert.c b/ossl_x509cert.c index a637c30..eac14dc 100644 --- a/ossl_x509cert.c +++ b/ossl_x509cert.c @@ -295,24 +295,19 @@ ossl_x509_get_serial(VALUE self) GetX509(self, x509); - return LONG2NUM(ASN1_INTEGER_get(X509_get_serialNumber(x509))); + return asn1integer_to_num(X509_get_serialNumber(x509)); } static VALUE -ossl_x509_set_serial(VALUE self, VALUE serial) +ossl_x509_set_serial(VALUE self, VALUE num) { X509 *x509; - long num; GetX509(self, x509); - if ((num = NUM2LONG(serial)) < 0) { - ossl_raise(eX509CertError, "Serial cannot be < 0!"); - } - if (!ASN1_INTEGER_set(x509->cert_info->serialNumber, num)) { - ossl_raise(eX509CertError, ""); - } - return serial; + x509->cert_info->serialNumber = num_to_asn1integer(num, X509_get_serialNumber(x509)); + + return num; } static VALUE diff --git a/ossl_x509revoked.c b/ossl_x509revoked.c index 2499de3..2b05a1b 100644 --- a/ossl_x509revoked.c +++ b/ossl_x509revoked.c @@ -99,24 +99,19 @@ ossl_x509revoked_get_serial(VALUE self) GetX509Rev(self, rev); - return LONG2NUM(ASN1_INTEGER_get(rev->serialNumber)); + return asn1integer_to_num(rev->serialNumber); } static VALUE -ossl_x509revoked_set_serial(VALUE self, VALUE serial) +ossl_x509revoked_set_serial(VALUE self, VALUE num) { X509_REVOKED *rev; - long num; GetX509Rev(self, rev); - if ((num = NUM2LONG(serial)) < 0) { - ossl_raise(eX509RevError, "Serial cannot be < 0!"); - } - if (!ASN1_INTEGER_set(rev->serialNumber, num)) { - ossl_raise(eX509RevError, ""); - } - return serial; + rev->serialNumber = num_to_asn1integer(num, rev->serialNumber); + + return num; } static VALUE |