static VALUE ossl_pkcs7_get_recipient(VALUE self) { PKCS7 *pkcs7; STACK_OF(PKCS7_RECIP_INFO) *sk; PKCS7_RECIP_INFO *si; int num, i; VALUE ary; GetPKCS7(self, pkcs7); if (PKCS7_type_is_enveloped(pkcs7)) sk = pkcs7->d.enveloped->recipientinfo; else if (PKCS7_type_is_signedAndEnveloped(pkcs7)) sk = pkcs7->d.signed_and_enveloped->recipientinfo; else sk = NULL; if (!sk) return rb_ary_new(); if ((num = sk_PKCS7_RECIP_INFO_num(sk)) < 0) { ossl_raise(ePKCS7Error, "Negative number of recipient!"); } ary = rb_ary_new2(num); for (i=0; i<num; i++) { si = sk_PKCS7_RECIP_INFO_value(sk, i); rb_ary_push(ary, ossl_pkcs7ri_new(si)); } return ary; }
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; }
static VALUE ossl_pkcs7_decrypt(int argc, VALUE *argv, VALUE self) { VALUE pkey, cert, flags; EVP_PKEY *key; X509 *x509; int flg; PKCS7 *p7; BIO *out; VALUE str; rb_scan_args(argc, argv, "21", &pkey, &cert, &flags); key = GetPrivPKeyPtr(pkey); /* NO NEED TO DUP */ x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */ flg = NIL_P(flags) ? 0 : NUM2INT(flags); GetPKCS7(self, p7); if(!(out = BIO_new(BIO_s_mem()))) ossl_raise(ePKCS7Error, NULL); if(!PKCS7_decrypt(p7, key, x509, out, flg)){ BIO_free(out); ossl_raise(ePKCS7Error, NULL); } str = ossl_membio2str(out); /* out will be free */ return str; }
static VALUE ossl_pkcs7_detached_p(VALUE self) { PKCS7 *p7; GetPKCS7(self, p7); return PKCS7_is_detached(p7) ? Qtrue : Qfalse; }
static VALUE ossl_pkcs7_get_signer(VALUE self) { PKCS7 *pkcs7; STACK_OF(PKCS7_SIGNER_INFO) *sk; PKCS7_SIGNER_INFO *si; int num, i; VALUE ary; GetPKCS7(self, pkcs7); if (!(sk = PKCS7_get_signer_info(pkcs7))) { OSSL_Debug("OpenSSL::PKCS7#get_signer_info == NULL!"); return rb_ary_new(); } if ((num = sk_PKCS7_SIGNER_INFO_num(sk)) < 0) { ossl_raise(ePKCS7Error, "Negative number of signers!"); } ary = rb_ary_new2(num); for (i=0; i<num; i++) { si = sk_PKCS7_SIGNER_INFO_value(sk, i); rb_ary_push(ary, ossl_pkcs7si_new(si)); } return ary; }
/* * call-seq: * pkcs7.type = type => type */ static VALUE ossl_pkcs7_set_type(VALUE self, VALUE type) { PKCS7 *p7; GetPKCS7(self, p7); if(!PKCS7_set_type(p7, ossl_pkcs7_sym2typeid(type))) ossl_raise(ePKCS7Error, NULL); return type; }
static VALUE ossl_pkcs7_set_cipher(VALUE self, VALUE cipher) { PKCS7 *pkcs7; GetPKCS7(self, pkcs7); if (!PKCS7_set_cipher(pkcs7, GetCipherPtr(cipher))) { ossl_raise(ePKCS7Error, NULL); } return cipher; }
static VALUE ossl_pkcs7_set_detached(VALUE self, VALUE flag) { PKCS7 *p7; GetPKCS7(self, p7); if(flag != Qtrue && flag != Qfalse) ossl_raise(ePKCS7Error, "must specify a boolean"); if(!PKCS7_set_detached(p7, flag == Qtrue ? 1 : 0)) ossl_raise(ePKCS7Error, NULL); return flag; }
static VALUE ossl_pkcs7_add_crl(VALUE self, VALUE crl) { PKCS7 *pkcs7; X509_CRL *x509crl; GetPKCS7(self, pkcs7); /* NO DUP needed! */ x509crl = GetX509CRLPtr(crl); if (!PKCS7_add_crl(pkcs7, x509crl)) { ossl_raise(ePKCS7Error, NULL); } return self; }
static VALUE ossl_pkcs7_add_certificate(VALUE self, VALUE cert) { PKCS7 *pkcs7; X509 *x509; GetPKCS7(self, pkcs7); x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */ if (!PKCS7_add_certificate(pkcs7, x509)){ ossl_raise(ePKCS7Error, NULL); } return self; }
static VALUE ossl_pkcs7_add_recipient(VALUE self, VALUE recip) { PKCS7 *pkcs7; PKCS7_RECIP_INFO *ri; ri = DupPKCS7RecipientPtr(recip); /* NEED TO DUP */ GetPKCS7(self, pkcs7); if (!PKCS7_add_recipient_info(pkcs7, ri)) { PKCS7_RECIP_INFO_free(ri); ossl_raise(ePKCS7Error, "Could not add recipient."); } return self; }
/* * call-seq: * pkcs7.type => string or nil */ static VALUE ossl_pkcs7_get_type(VALUE self) { PKCS7 *p7; GetPKCS7(self, p7); if(PKCS7_type_is_signed(p7)) return ID2SYM(rb_intern("signed")); if(PKCS7_type_is_encrypted(p7)) return ID2SYM(rb_intern("encrypted")); if(PKCS7_type_is_enveloped(p7)) return ID2SYM(rb_intern("enveloped")); if(PKCS7_type_is_signedAndEnveloped(p7)) return ID2SYM(rb_intern("signedAndEnveloped")); if(PKCS7_type_is_data(p7)) return ID2SYM(rb_intern("data")); return Qnil; }
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; }
static VALUE ossl_pkcs7_to_pem(VALUE self) { PKCS7 *pkcs7; BIO *out; VALUE str; GetPKCS7(self, pkcs7); if (!(out = BIO_new(BIO_s_mem()))) { ossl_raise(ePKCS7Error, NULL); } if (!PEM_write_bio_PKCS7(out, pkcs7)) { BIO_free(out); ossl_raise(ePKCS7Error, NULL); } str = ossl_membio2str(out); return str; }
static VALUE ossl_pkcs7_to_der(VALUE self) { PKCS7 *pkcs7; VALUE str; long len; unsigned char *p; GetPKCS7(self, pkcs7); if((len = i2d_PKCS7(pkcs7, NULL)) <= 0) ossl_raise(ePKCS7Error, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if(i2d_PKCS7(pkcs7, &p) <= 0) ossl_raise(ePKCS7Error, NULL); ossl_str_adjust(str, p); return str; }
static VALUE ossl_pkcs7_add_signer(VALUE self, VALUE signer) { PKCS7 *pkcs7; PKCS7_SIGNER_INFO *p7si; p7si = DupPKCS7SignerPtr(signer); /* NEED TO DUP */ GetPKCS7(self, pkcs7); if (!PKCS7_add_signer(pkcs7, p7si)) { PKCS7_SIGNER_INFO_free(p7si); ossl_raise(ePKCS7Error, "Could not add signer."); } if (PKCS7_type_is_signed(pkcs7)){ PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType, V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data)); } return self; }
static VALUE ossl_pkcs7_to_der(VALUE self) { PKCS7 *pkcs7; long len; unsigned char *p, *data; GetPKCS7(self, pkcs7); if((len = i2d_PKCS7(pkcs7, NULL)) <= 0) ossl_raise(ePKCS7Error, NULL); data = p = (unsigned char *)xmalloc(sizeof(char) * len); if(i2d_PKCS7(pkcs7, &p) <= 0) ossl_raise(ePKCS7Error, NULL); VALUE str = rb_str_new((char*)data, len); xfree(data); return str; }
static VALUE ossl_pkcs7_copy(VALUE self, VALUE other) { PKCS7 *a, *b, *pkcs7; rb_check_frozen(self); if (self == other) return self; GetPKCS7(self, a); SafeGetPKCS7(other, b); pkcs7 = PKCS7_dup(b); if (!pkcs7) { ossl_raise(ePKCS7Error, NULL); } DATA_PTR(self) = pkcs7; PKCS7_free(a); return self; }
static STACK_OF(X509_CRL) * pkcs7_get_crls(VALUE self) { PKCS7 *pkcs7; STACK_OF(X509_CRL) *crls; int i; GetPKCS7(self, pkcs7); i = OBJ_obj2nid(pkcs7->type); switch(i){ case NID_pkcs7_signed: crls = pkcs7->d.sign->crl; break; case NID_pkcs7_signedAndEnveloped: crls = pkcs7->d.signed_and_enveloped->crl; break; default: crls = NULL; } return crls; }