/* * call-seq: * PKCS7.new => pkcs7 * PKCS7.new(string) => pkcs7 * * Many methods in this class aren't documented. */ static VALUE ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self) { PKCS7 *p7, *pkcs = DATA_PTR(self); BIO *in; VALUE arg; if(rb_scan_args(argc, argv, "01", &arg) == 0) return self; arg = ossl_to_der_if_possible(arg); in = ossl_obj2bio(arg); p7 = PEM_read_bio_PKCS7(in, &pkcs, NULL, NULL); DATA_PTR(self) = pkcs; if (!p7) { OSSL_BIO_reset(in); p7 = d2i_PKCS7_bio(in, &pkcs); if (!p7) ossl_raise(rb_eArgError, "Could not parse the PKCS7"); DATA_PTR(self) = pkcs; } BIO_free(in); ossl_pkcs7_set_data(self, Qnil); ossl_pkcs7_set_err_string(self, Qnil); return self; }
static VALUE ossl_pkcs7_add_data(VALUE self, VALUE data) { PKCS7 *pkcs7; BIO *out, *in; char buf[4096]; int len; in = ossl_obj2bio(data); GetPKCS7(self, pkcs7); if(PKCS7_type_is_signed(pkcs7)){ if(!PKCS7_content_new(pkcs7, NID_pkcs7_data)) ossl_raise(ePKCS7Error, NULL); } if(!(out = PKCS7_dataInit(pkcs7, NULL))) goto err; for(;;){ if((len = BIO_read(in, buf, sizeof(buf))) <= 0) break; if(BIO_write(out, buf, len) != len) goto err; } if(!PKCS7_dataFinal(pkcs7, out)) goto err; ossl_pkcs7_set_data(self, Qnil); err: BIO_free(out); BIO_free(in); if(ERR_peek_error()){ ossl_raise(ePKCS7Error, NULL); } return data; }
/* * call-seq: * PKCS7.encrypt(certs, data, [, cipher [, flags]]) => pkcs7 */ static VALUE ossl_pkcs7_s_encrypt(int argc, VALUE *argv, VALUE klass) { VALUE certs, data, cipher, flags; STACK_OF(X509) *x509s; BIO *in; const EVP_CIPHER *ciph; int flg, status = 0; VALUE ret; PKCS7 *p7; rb_scan_args(argc, argv, "22", &certs, &data, &cipher, &flags); if(NIL_P(cipher)){ #if !defined(OPENSSL_NO_RC2) ciph = EVP_rc2_40_cbc(); #elif !defined(OPENSSL_NO_DES) ciph = EVP_des_ede3_cbc(); #elif !defined(OPENSSL_NO_RC2) ciph = EVP_rc2_40_cbc(); #elif !defined(OPENSSL_NO_AES) ciph = EVP_EVP_aes_128_cbc(); #else ossl_raise(ePKCS7Error, "Must specify cipher"); #endif } else ciph = GetCipherPtr(cipher); /* NO NEED TO DUP */ flg = NIL_P(flags) ? 0 : NUM2INT(flags); ret = NewPKCS7(cPKCS7); in = ossl_obj2bio(data); x509s = ossl_protect_x509_ary2sk(certs, &status); if(status){ BIO_free(in); rb_jump_tag(status); } if(!(p7 = PKCS7_encrypt(x509s, in, (EVP_CIPHER*)ciph, flg))){ BIO_free(in); sk_X509_pop_free(x509s, X509_free); ossl_raise(ePKCS7Error, NULL); } BIO_free(in); SetPKCS7(ret, p7); ossl_pkcs7_set_data(ret, data); sk_X509_pop_free(x509s, X509_free); return ret; }
static VALUE ossl_pkcs7_verify(int argc, VALUE *argv, VALUE self) { VALUE certs, store, indata, flags; STACK_OF(X509) *x509s; X509_STORE *x509st; int flg, ok, status = 0; BIO *in, *out; PKCS7 *p7; VALUE data; const char *msg; rb_scan_args(argc, argv, "22", &certs, &store, &indata, &flags); flg = NIL_P(flags) ? 0 : NUM2INT(flags); if(NIL_P(indata)) indata = ossl_pkcs7_get_data(self); in = NIL_P(indata) ? NULL : ossl_obj2bio(indata); if(NIL_P(certs)) x509s = NULL; else{ x509s = ossl_protect_x509_ary2sk(certs, &status); if(status){ BIO_free(in); /* rb_jump_tag(status); */ rb_notimplement(); } } x509st = GetX509StorePtr(store); GetPKCS7(self, p7); if(!(out = BIO_new(BIO_s_mem()))){ BIO_free(in); sk_X509_pop_free(x509s, X509_free); ossl_raise(ePKCS7Error, NULL); } ok = PKCS7_verify(p7, x509s, x509st, in, out, flg); BIO_free(in); if (ok < 0) ossl_raise(ePKCS7Error, NULL); msg = ERR_reason_error_string(ERR_get_error()); ossl_pkcs7_set_err_string(self, msg ? rb_str_new2(msg) : Qnil); ERR_clear_error(); data = ossl_membio2str(out); ossl_pkcs7_set_data(self, data); sk_X509_pop_free(x509s, X509_free); return (ok == 1) ? Qtrue : Qfalse; }
/* * call-seq: * PKCS7.read_smime(string) => pkcs7 */ static VALUE ossl_pkcs7_s_read_smime(VALUE klass, VALUE arg) { BIO *in, *out; PKCS7 *pkcs7; VALUE ret, data; in = ossl_obj2bio(arg); out = NULL; pkcs7 = SMIME_read_PKCS7(in, &out); BIO_free(in); if(!pkcs7) ossl_raise(ePKCS7Error, NULL); data = out ? ossl_membio2str(out) : Qnil; WrapPKCS7(cPKCS7, ret, pkcs7); ossl_pkcs7_set_data(ret, data); ossl_pkcs7_set_err_string(ret, Qnil); return ret; }
/* * call-seq: * PKCS7.sign(cert, key, data, [, certs [, flags]]) => pkcs7 */ static VALUE ossl_pkcs7_s_sign(int argc, VALUE *argv, VALUE klass) { VALUE cert, key, data, certs, flags; X509 *x509; EVP_PKEY *pkey; BIO *in; STACK_OF(X509) *x509s; int flg, status = 0; PKCS7 *pkcs7; VALUE ret; rb_scan_args(argc, argv, "32", &cert, &key, &data, &certs, &flags); x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */ pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ flg = NIL_P(flags) ? 0 : NUM2INT(flags); ret = NewPKCS7(cPKCS7); in = ossl_obj2bio(data); if(NIL_P(certs)) x509s = NULL; else{ x509s = ossl_protect_x509_ary2sk(certs, &status); if(status){ BIO_free(in); rb_jump_tag(status); } } if(!(pkcs7 = PKCS7_sign(x509, pkey, x509s, in, flg))){ BIO_free(in); sk_X509_pop_free(x509s, X509_free); ossl_raise(ePKCS7Error, NULL); } SetPKCS7(ret, pkcs7); ossl_pkcs7_set_data(ret, data); ossl_pkcs7_set_err_string(ret, Qnil); BIO_free(in); sk_X509_pop_free(x509s, X509_free); return ret; }
/* * call-seq: * PKCS7.new => pkcs7 * PKCS7.new(string) => pkcs7 * * Many methods in this class aren't documented. */ static VALUE ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self) { PKCS7 *p7; BIO *in; VALUE arg; if(rb_scan_args(argc, argv, "01", &arg) == 0) return self; arg = ossl_to_der_if_possible(arg); in = ossl_obj2bio(arg); p7 = PEM_read_bio_PKCS7(in, (PKCS7 **)&DATA_PTR(self), NULL, NULL); if (!p7) { BIO_reset(in); p7 = d2i_PKCS7_bio(in, (PKCS7 **)&DATA_PTR(self)); } BIO_free(in); ossl_pkcs7_set_data(self, Qnil); ossl_pkcs7_set_err_string(self, Qnil); return self; }