00001
00002
00003
00004
00005
00006 #include "ossl.h"
00007
00008 #define WrapPKCS12(klass, obj, p12) do { \
00009 if(!p12) ossl_raise(rb_eRuntimeError, "PKCS12 wasn't initialized."); \
00010 obj = Data_Wrap_Struct(klass, 0, PKCS12_free, p12); \
00011 } while (0)
00012
00013 #define GetPKCS12(obj, p12) do { \
00014 Data_Get_Struct(obj, PKCS12, p12); \
00015 if(!p12) ossl_raise(rb_eRuntimeError, "PKCS12 wasn't initialized."); \
00016 } while (0)
00017
00018 #define SafeGetPKCS12(obj, p12) do { \
00019 OSSL_Check_Kind(obj, cPKCS12); \
00020 GetPKCS12(obj, p12); \
00021 } while (0)
00022
00023 #define ossl_pkcs12_set_key(o,v) rb_iv_set((o), "@key", (v))
00024 #define ossl_pkcs12_set_cert(o,v) rb_iv_set((o), "@certificate", (v))
00025 #define ossl_pkcs12_set_ca_certs(o,v) rb_iv_set((o), "@ca_certs", (v))
00026 #define ossl_pkcs12_get_key(o) rb_iv_get((o), "@key")
00027 #define ossl_pkcs12_get_cert(o) rb_iv_get((o), "@certificate")
00028 #define ossl_pkcs12_get_ca_certs(o) rb_iv_get((o), "@ca_certs")
00029
00030
00031
00032
00033 VALUE cPKCS12;
00034 VALUE ePKCS12Error;
00035
00036
00037
00038
00039 static VALUE
00040 ossl_pkcs12_s_allocate(VALUE klass)
00041 {
00042 PKCS12 *p12;
00043 VALUE obj;
00044
00045 if(!(p12 = PKCS12_new())) ossl_raise(ePKCS12Error, NULL);
00046 WrapPKCS12(klass, obj, p12);
00047
00048 return obj;
00049 }
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 static VALUE
00074 ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self)
00075 {
00076 VALUE pass, name, pkey, cert, ca, key_nid, cert_nid, key_iter, mac_iter, keytype;
00077 VALUE obj;
00078 char *passphrase, *friendlyname;
00079 EVP_PKEY *key;
00080 X509 *x509;
00081 STACK_OF(X509) *x509s;
00082 int nkey = 0, ncert = 0, kiter = 0, miter = 0, ktype = 0;
00083 PKCS12 *p12;
00084
00085 rb_scan_args(argc, argv, "46", &pass, &name, &pkey, &cert, &ca, &key_nid, &cert_nid, &key_iter, &mac_iter, &keytype);
00086 passphrase = NIL_P(pass) ? NULL : StringValuePtr(pass);
00087 friendlyname = NIL_P(name) ? NULL : StringValuePtr(name);
00088 key = GetPKeyPtr(pkey);
00089 x509 = GetX509CertPtr(cert);
00090 x509s = NIL_P(ca) ? NULL : ossl_x509_ary2sk(ca);
00091
00092 if (!NIL_P(key_nid)) {
00093 if ((nkey = OBJ_txt2nid(StringValuePtr(key_nid))) == NID_undef)
00094 rb_raise(rb_eArgError, "Unknown PBE algorithm %s", StringValuePtr(key_nid));
00095 }
00096 if (!NIL_P(cert_nid)) {
00097 if ((ncert = OBJ_txt2nid(StringValuePtr(cert_nid))) == NID_undef)
00098 rb_raise(rb_eArgError, "Unknown PBE algorithm %s", StringValuePtr(cert_nid));
00099 }
00100 if (!NIL_P(key_iter))
00101 kiter = NUM2INT(key_iter);
00102 if (!NIL_P(mac_iter))
00103 miter = NUM2INT(mac_iter);
00104 if (!NIL_P(keytype))
00105 ktype = NUM2INT(keytype);
00106
00107 p12 = PKCS12_create(passphrase, friendlyname, key, x509, x509s,
00108 nkey, ncert, kiter, miter, ktype);
00109 sk_X509_pop_free(x509s, X509_free);
00110 if(!p12) ossl_raise(ePKCS12Error, NULL);
00111 WrapPKCS12(cPKCS12, obj, p12);
00112
00113 ossl_pkcs12_set_key(obj, pkey);
00114 ossl_pkcs12_set_cert(obj, cert);
00115 ossl_pkcs12_set_ca_certs(obj, ca);
00116
00117 return obj;
00118 }
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 static VALUE
00131 ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self)
00132 {
00133 BIO *in;
00134 VALUE arg, pass, pkey, cert, ca;
00135 char *passphrase;
00136 EVP_PKEY *key;
00137 X509 *x509;
00138 STACK_OF(X509) *x509s = NULL;
00139 int st = 0;
00140 PKCS12 *pkcs = DATA_PTR(self);
00141
00142 if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) return self;
00143 passphrase = NIL_P(pass) ? NULL : StringValuePtr(pass);
00144 in = ossl_obj2bio(arg);
00145 d2i_PKCS12_bio(in, &pkcs);
00146 DATA_PTR(self) = pkcs;
00147 BIO_free(in);
00148
00149 pkey = cert = ca = Qnil;
00150 if(!PKCS12_parse(pkcs, passphrase, &key, &x509, &x509s))
00151 ossl_raise(ePKCS12Error, "PKCS12_parse");
00152 pkey = rb_protect((VALUE(*)_((VALUE)))ossl_pkey_new, (VALUE)key,
00153 &st);
00154 if(st) goto err;
00155 cert = rb_protect((VALUE(*)_((VALUE)))ossl_x509_new, (VALUE)x509, &st);
00156 if(st) goto err;
00157 if(x509s){
00158 ca =
00159 rb_protect((VALUE(*)_((VALUE)))ossl_x509_sk2ary, (VALUE)x509s, &st);
00160 if(st) goto err;
00161 }
00162
00163 err:
00164 X509_free(x509);
00165 sk_X509_pop_free(x509s, X509_free);
00166 ossl_pkcs12_set_key(self, pkey);
00167 ossl_pkcs12_set_cert(self, cert);
00168 ossl_pkcs12_set_ca_certs(self, ca);
00169 if(st) rb_jump_tag(st);
00170
00171 return self;
00172 }
00173
00174 static VALUE
00175 ossl_pkcs12_to_der(VALUE self)
00176 {
00177 PKCS12 *p12;
00178 VALUE str;
00179 long len;
00180 unsigned char *p;
00181
00182 GetPKCS12(self, p12);
00183 if((len = i2d_PKCS12(p12, NULL)) <= 0)
00184 ossl_raise(ePKCS12Error, NULL);
00185 str = rb_str_new(0, len);
00186 p = (unsigned char *)RSTRING_PTR(str);
00187 if(i2d_PKCS12(p12, &p) <= 0)
00188 ossl_raise(ePKCS12Error, NULL);
00189 ossl_str_adjust(str, p);
00190
00191 return str;
00192 }
00193
00194 void
00195 Init_ossl_pkcs12()
00196 {
00197
00198
00199
00200
00201
00202 cPKCS12 = rb_define_class_under(mOSSL, "PKCS12", rb_cObject);
00203 ePKCS12Error = rb_define_class_under(cPKCS12, "PKCS12Error", eOSSLError);
00204 rb_define_singleton_method(cPKCS12, "create", ossl_pkcs12_s_create, -1);
00205
00206 rb_define_alloc_func(cPKCS12, ossl_pkcs12_s_allocate);
00207 rb_attr(cPKCS12, rb_intern("key"), 1, 0, Qfalse);
00208 rb_attr(cPKCS12, rb_intern("certificate"), 1, 0, Qfalse);
00209 rb_attr(cPKCS12, rb_intern("ca_certs"), 1, 0, Qfalse);
00210 rb_define_method(cPKCS12, "initialize", ossl_pkcs12_initialize, -1);
00211 rb_define_method(cPKCS12, "to_der", ossl_pkcs12_to_der, 0);
00212 }
00213