Extended maintenance of Ruby 1.9.3 ended on February 23, 2015. Read more

In Files

  • openssl/ossl.c

Class/Module Index [+]

Quicksearch

OpenSSL::PKCS7

Constants

Signer

Attributes

data[R]
error_string[RW]

Public Class Methods

encrypt(certs, data, [, cipher [, flags]]) => pkcs7 click to toggle source
 
               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);
    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);
    WrapPKCS7(cPKCS7, ret, p7);
    ossl_pkcs7_set_data(ret, data);
    sk_X509_pop_free(x509s, X509_free);

    return ret;
}
            
new => pkcs7 click to toggle source
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);
    if (!p7) {
        OSSL_BIO_reset(in);
        p7 = d2i_PKCS7_bio(in, &pkcs);
        if (!p7) {
            BIO_free(in);
            PKCS7_free(pkcs);
            DATA_PTR(self) = NULL;
            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;
}
            
read_smime(string) => pkcs7 click to toggle source
 
               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;
}
            
sign(cert, key, data, [, certs [, flags]]) => pkcs7 click to toggle source
 
               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);
    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);
    }
    WrapPKCS7(cPKCS7, 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;
}
            
write_smime(pkcs7 [, data [, flags]]) => string click to toggle source
 
               static VALUE
ossl_pkcs7_s_write_smime(int argc, VALUE *argv, VALUE klass)
{
    VALUE pkcs7, data, flags;
    BIO *out, *in;
    PKCS7 *p7;
    VALUE str;
    int flg;

    rb_scan_args(argc, argv, "12", &pkcs7, &data, &flags);
    flg = NIL_P(flags) ? 0 : NUM2INT(flags);
    if(NIL_P(data)) data = ossl_pkcs7_get_data(pkcs7);
    SafeGetPKCS7(pkcs7, p7);
    if(!NIL_P(data) && PKCS7_is_detached(p7))
        flg |= PKCS7_DETACHED;
    in = NIL_P(data) ? NULL : ossl_obj2bio(data);
    if(!(out = BIO_new(BIO_s_mem()))){
        BIO_free(in);
        ossl_raise(ePKCS7Error, NULL);
    }
    if(!SMIME_write_PKCS7(out, p7, in, flg)){
        BIO_free(out);
        BIO_free(in);
        ossl_raise(ePKCS7Error, NULL);
    }
    BIO_free(in);
    str = ossl_membio2str(out);

    return str;
}
            

Public Instance Methods

add_certificate(p1) click to toggle source
 
               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;
}
            
add_crl(p1) click to toggle source
 
               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;
}
            
add_data(p1) click to toggle source
 
               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;
}
            
Also aliased as: data=
add_recipient(p1) click to toggle source
 
               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;
}
            
add_signer(p1) click to toggle source
 
               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;
}
            
certificates() click to toggle source
 
               static VALUE
ossl_pkcs7_get_certificates(VALUE self)
{
    return ossl_x509_sk2ary(pkcs7_get_certs(self));
}
            
certificates=(p1) click to toggle source
 
               static VALUE
ossl_pkcs7_set_certificates(VALUE self, VALUE ary)
{
    STACK_OF(X509) *certs;
    X509 *cert;

    certs = pkcs7_get_certs(self);
    while((cert = sk_X509_pop(certs))) X509_free(cert);
    rb_block_call(ary, rb_intern("each"), 0, 0, ossl_pkcs7_set_certs_i, self);

    return ary;
}
            
cipher=(p1) click to toggle source
 
               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;
}
            
crls() click to toggle source
 
               static VALUE
ossl_pkcs7_get_crls(VALUE self)
{
    return ossl_x509crl_sk2ary(pkcs7_get_crls(self));
}
            
crls=(p1) click to toggle source
 
               static VALUE
ossl_pkcs7_set_crls(VALUE self, VALUE ary)
{
    STACK_OF(X509_CRL) *crls;
    X509_CRL *crl;

    crls = pkcs7_get_crls(self);
    while((crl = sk_X509_CRL_pop(crls))) X509_CRL_free(crl);
    rb_block_call(ary, rb_intern("each"), 0, 0, ossl_pkcs7_set_crls_i, self);

    return ary;
}
            
data=(p1) click to toggle source
Alias for: add_data
decrypt(p1, p2, p3 = v3) click to toggle source
 
               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;
}
            
detached() click to toggle source
 
               static VALUE
ossl_pkcs7_get_detached(VALUE self)
{
    PKCS7 *p7;
    GetPKCS7(self, p7);
    return PKCS7_get_detached(p7) ? Qtrue : Qfalse;
}
            
detached=(p1) click to toggle source
 
               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;
}
            
detached?() click to toggle source
 
               static VALUE
ossl_pkcs7_detached_p(VALUE self)
{
    PKCS7 *p7;
    GetPKCS7(self, p7);
    return PKCS7_is_detached(p7) ? Qtrue : Qfalse;
}
            
recipients() click to toggle source
 
               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;
}
            
signers() click to toggle source
 
               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;
}
            
to_der() click to toggle source
 
               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;
}
            
to_pem() click to toggle source
 
               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;
}
            
Also aliased as: to_s
to_s() click to toggle source
Alias for: to_pem
type => string or nil click to toggle source
 
               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;
}
            
type = type => type click to toggle source
 
               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;
}
            
verify(p1, p2, p3 = v3, p4 = v4) click to toggle source
 
               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);
        }
    }
    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;
}
            

Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.