static VALUE ossl_x509crl_copy(VALUE self, SEL sel, VALUE other) { X509_CRL *a, *b, *crl; rb_check_frozen(self); if (self == other) return self; GetX509CRL(self, a); SafeGetX509CRL(other, b); if (!(crl = X509_CRL_dup(b))) { ossl_raise(eX509CRLError, NULL); } X509_CRL_free(a); DATA_PTR(self) = crl; return self; }
/* * call-seq: * ssl.session_reused? -> true | false * */ static VALUE ossl_ssl_session_reused(VALUE self) { SSL *ssl; Data_Get_Struct(self, SSL, ssl); if (!ssl) { rb_warning("SSL session is not started yet."); return Qnil; } switch(SSL_session_reused(ssl)) { case 1: return Qtrue; case 0: return Qfalse; default: ossl_raise(eSSLError, "SSL_session_reused"); } }
/* Document-method: OpenSSL::Engine#ctrl_cmd * * call-seq: * engine.ctrl_cmd(command, value = nil) -> engine * * Send the given +command+ to this engine. * * Raises an EngineError if the +command+ fails. */ static VALUE ossl_engine_ctrl_cmd(int argc, VALUE *argv, VALUE self) { ENGINE *e; VALUE cmd, val; int ret; GetEngine(self, e); rb_scan_args(argc, argv, "11", &cmd, &val); StringValue(cmd); if (!NIL_P(val)) StringValue(val); ret = ENGINE_ctrl_cmd_string(e, RSTRING_PTR(cmd), NIL_P(val) ? NULL : RSTRING_PTR(val), 0); if (!ret) ossl_raise(eEngineError, NULL); return self; }
/* * call-seq: * PKCS12.create(pass, name, key, cert [, ca, [, key_pbe [, cert_pbe [, key_iter [, mac_iter [, keytype]]]]]]) * * === Parameters * * +pass+ - string * * +name+ - A string describing the key. * * +key+ - Any PKey. * * +cert+ - A X509::Certificate. * * * The public_key portion of the certificate must contain a valid public key. * * * The not_before and not_after fields must be filled in. * * +ca+ - An optional array of X509::Certificate's. * * +key_pbe+ - string * * +cert_pbe+ - string * * +key_iter+ - integer * * +mac_iter+ - integer * * +keytype+ - An integer representing an MSIE specific extension. * * Any optional arguments may be supplied as nil to preserve the OpenSSL defaults. * * See the OpenSSL documentation for PKCS12_create(). */ static VALUE ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self) { VALUE pass, name, pkey, cert, ca, key_nid, cert_nid, key_iter, mac_iter, keytype; VALUE obj; char *passphrase, *friendlyname; EVP_PKEY *key; X509 *x509; STACK_OF(X509) *x509s; int nkey = 0, ncert = 0, kiter = 0, miter = 0, ktype = 0; PKCS12 *p12; rb_scan_args(argc, argv, "46", &pass, &name, &pkey, &cert, &ca, &key_nid, &cert_nid, &key_iter, &mac_iter, &keytype); passphrase = NIL_P(pass) ? NULL : StringValuePtr(pass); friendlyname = NIL_P(name) ? NULL : StringValuePtr(name); key = GetPKeyPtr(pkey); x509 = GetX509CertPtr(cert); x509s = NIL_P(ca) ? NULL : ossl_x509_ary2sk(ca); /* TODO: make a VALUE to nid function */ if (!NIL_P(key_nid)) { if ((nkey = OBJ_txt2nid(StringValuePtr(key_nid))) == NID_undef) rb_raise(rb_eArgError, "Unknown PBE algorithm %s", StringValuePtr(key_nid)); } if (!NIL_P(cert_nid)) { if ((ncert = OBJ_txt2nid(StringValuePtr(cert_nid))) == NID_undef) rb_raise(rb_eArgError, "Unknown PBE algorithm %s", StringValuePtr(cert_nid)); } if (!NIL_P(key_iter)) kiter = NUM2INT(key_iter); if (!NIL_P(mac_iter)) miter = NUM2INT(mac_iter); if (!NIL_P(keytype)) ktype = NUM2INT(keytype); p12 = PKCS12_create(passphrase, friendlyname, key, x509, x509s, nkey, ncert, kiter, miter, ktype); sk_X509_pop_free(x509s, X509_free); if(!p12) ossl_raise(ePKCS12Error, NULL); WrapPKCS12(cPKCS12, obj, p12); ossl_pkcs12_set_key(obj, pkey); ossl_pkcs12_set_cert(obj, cert); ossl_pkcs12_set_ca_certs(obj, ca); return obj; }
/* * call-seq: * dh.public_key -> aDH * * Returns a new DH instance that carries just the public information, i.e. * the prime +p+ and the generator +g+, but no public/private key yet. Such * a pair may be generated using DH#generate_key!. The "public key" needed * for a key exchange with DH#compute_key is considered as per-session * information and may be retrieved with DH#pub_key once a key pair has * been generated. * If the current instance already contains private information (and thus a * valid public/private key pair), this information will no longer be present * in the new instance generated by DH#public_key. This feature is helpful for * publishing the Diffie-Hellman parameters without leaking any of the private * per-session information. * * === Example * dh = OpenSSL::PKey::DH.new(2048) # has public and private key set * public_key = dh.public_key # contains only prime and generator * parameters = public_key.to_der # it's safe to publish this */ static VALUE ossl_dh_to_public_key(VALUE self) { EVP_PKEY *pkey; DH *dh; VALUE obj; GetPKeyDH(self, pkey); dh = DHparams_dup(pkey->pkey.dh); /* err check perfomed by dh_instance */ obj = dh_instance(CLASS_OF(self), dh); if (obj == Qfalse) { DH_free(dh); ossl_raise(eDHError, NULL); } return obj; }
static VALUE ossl_bn_copy(VALUE self, VALUE other) { BIGNUM *bn1, *bn2; rb_check_frozen(self); if (self == other) return self; GetBN(self, bn1); bn2 = GetBNPtr(other); if (!BN_copy(bn1, bn2)) { ossl_raise(eBNError, NULL); } return self; }
/* * call-seq: * bn.to_i => integer */ 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, NULL); } num = rb_cstr_to_inum(txt, 10, Qtrue); OPENSSL_free(txt); return num; }
/* * call-seq: * key.public_key => OpenSSL::PKey::EC::Point * * See the OpenSSL documentation for EC_KEY_get0_public_key() */ static VALUE ossl_ec_key_get_public_key(VALUE self) { EC_KEY *ec; const EC_POINT *point; VALUE group; Require_EC_KEY(self, ec); if ((point = EC_KEY_get0_public_key(ec)) == NULL) return Qnil; group = rb_funcall(self, rb_intern("group"), 0); if (NIL_P(group)) ossl_raise(eECError, "EC_KEY_get0_get0_group (has public_key but no group???"); return ossl_ec_point_dup(point, group); }
static VALUE ossl_ec_point_dup(const EC_POINT *point, VALUE group_v) { VALUE obj; const EC_GROUP *group; ossl_ec_point *new_point; obj = rb_obj_alloc(cEC_POINT); Data_Get_Struct(obj, ossl_ec_point, new_point); SafeRequire_EC_GROUP(group_v, group); new_point->point = EC_POINT_dup(point, group); if (new_point->point == NULL) ossl_raise(eEC_POINT, "EC_POINT_dup"); rb_iv_set(obj, "@group", group_v); return obj; }
static VALUE decode_enum(unsigned char* der, int length) { ASN1_ENUMERATED *ai; const unsigned char *p; VALUE ret; int status = 0; p = der; if(!(ai = d2i_ASN1_ENUMERATED(NULL, &p, length))) ossl_raise(eASN1Error, NULL); ret = rb_protect((VALUE(*)_((VALUE)))asn1integer_to_num, (VALUE)ai, &status); ASN1_ENUMERATED_free(ai); if(status) rb_jump_tag(status); return ret; }
/* * call-seq: * PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, keylen) => string * * === Parameters * * +pass+ - string * * +salt+ - string * * +iter+ - integer - should be greater than 1000. 2000 is better. * * +keylen+ - integer * * This method is available almost any version OpenSSL. * * Conforms to rfc2898. */ static VALUE ossl_pkcs5_pbkdf2_hmac_sha1(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen) { VALUE str; int len = NUM2INT(keylen); StringValue(pass); StringValue(salt); str = rb_str_new(0, len); if (PKCS5_PBKDF2_HMAC_SHA1(RSTRING_PTR(pass), RSTRING_LENINT(pass), (const unsigned char *)RSTRING_PTR(salt), RSTRING_LENINT(salt), NUM2INT(iter), len, (unsigned char *)RSTRING_PTR(str)) != 1) ossl_raise(ePKCS5, "PKCS5_PBKDF2_HMAC_SHA1"); return str; }
static VALUE decode_time(unsigned char* der, int length) { ASN1_TIME *time; const unsigned char *p; VALUE ret; int status = 0; p = der; if(!(time = d2i_ASN1_TIME(NULL, &p, length))) ossl_raise(eASN1Error, NULL); ret = rb_protect((VALUE(*)_((VALUE)))asn1time_to_time, (VALUE)time, &status); ASN1_TIME_free(time); if(status) rb_jump_tag(status); return ret; }
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); }
static VALUE ossl_cipher_copy(VALUE self, VALUE other) { EVP_CIPHER_CTX *ctx1, *ctx2; rb_check_frozen(self); if (self == other) return self; GetCipherInit(self, ctx1); if (!ctx1) { AllocCipher(self, ctx1); } SafeGetCipher(other, ctx2); if (EVP_CIPHER_CTX_copy(ctx1, ctx2) != 1) ossl_raise(eCipherError, NULL); return self; }
static VALUE ossl_pkcs7si_initialize(VALUE self, VALUE cert, VALUE key, VALUE digest) { PKCS7_SIGNER_INFO *p7si; EVP_PKEY *pkey; X509 *x509; const EVP_MD *md; pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */ md = GetDigestPtr(digest); GetPKCS7si(self, p7si); if (!(PKCS7_SIGNER_INFO_set(p7si, x509, pkey, (EVP_MD*)md))) { ossl_raise(ePKCS7Error, NULL); } return self; }
static VALUE ossl_ocspbres_get_status(VALUE self) { OCSP_BASICRESP *bs; OCSP_SINGLERESP *single; OCSP_CERTID *cid; ASN1_TIME *revtime, *thisupd, *nextupd; int status, reason; X509_EXTENSION *x509ext; VALUE ret, ary, ext; int count, ext_count, i, j; GetOCSPBasicRes(self, bs); ret = rb_ary_new(); count = OCSP_resp_count(bs); for(i = 0; i < count; i++) { single = OCSP_resp_get0(bs, i); if(!single) continue; revtime = thisupd = nextupd = NULL; status = OCSP_single_get0_status(single, &reason, &revtime, &thisupd, &nextupd); if(status < 0) continue; if(!(cid = OCSP_CERTID_dup(single->certId))) ossl_raise(eOCSPError, NULL); ary = rb_ary_new(); rb_ary_push(ary, ossl_ocspcertid_new(cid)); rb_ary_push(ary, INT2NUM(status)); rb_ary_push(ary, INT2NUM(reason)); rb_ary_push(ary, revtime ? asn1time_to_time(revtime) : Qnil); rb_ary_push(ary, thisupd ? asn1time_to_time(thisupd) : Qnil); rb_ary_push(ary, nextupd ? asn1time_to_time(nextupd) : Qnil); ext = rb_ary_new(); ext_count = OCSP_SINGLERESP_get_ext_count(single); for(j = 0; j < ext_count; j++) { x509ext = OCSP_SINGLERESP_get_ext(single, j); rb_ary_push(ext, ossl_x509ext_new(x509ext)); } rb_ary_push(ary, ext); rb_ary_push(ret, ary); } return ret; }
/* * call-seq: * Digest.new(string [, data]) -> Digest * * Creates a Digest instance based on +string+, which is either the ln * (long name) or sn (short name) of a supported digest algorithm. * If +data+ (a +String+) is given, it is used as the initial input to the * Digest instance, i.e. * digest = OpenSSL::Digest.new('sha256', 'digestdata') * is equal to * digest = OpenSSL::Digest.new('sha256') * digest.update('digestdata') * * === Example * digest = OpenSSL::Digest.new('sha1') * * */ static VALUE ossl_digest_initialize(int argc, VALUE *argv, VALUE self) { EVP_MD_CTX *ctx; const EVP_MD *md; VALUE type, data; rb_scan_args(argc, argv, "11", &type, &data); md = GetDigestPtr(type); if (!NIL_P(data)) StringValue(data); GetDigest(self, ctx); if (EVP_DigestInit_ex(ctx, md, NULL) != 1) { ossl_raise(eDigestError, "Digest initialization failed."); } if (!NIL_P(data)) return ossl_digest_update(self, data); return self; }
static VALUE ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode) { EVP_CIPHER_CTX *ctx; unsigned char key[EVP_MAX_KEY_LENGTH], *p_key = NULL; unsigned char iv[EVP_MAX_IV_LENGTH], *p_iv = NULL; VALUE pass, init_v; if(rb_scan_args(argc, argv, "02", &pass, &init_v) > 0){ /* * oops. this code mistakes salt for IV. * We deprecated the arguments for this method, but we decided * keeping this behaviour for backward compatibility. */ VALUE cname = rb_class_path(rb_obj_class(self)); rb_warn("arguments for %"PRIsVALUE"#encrypt and %"PRIsVALUE"#decrypt were deprecated; " "use %"PRIsVALUE"#pkcs5_keyivgen to derive key and IV", cname, cname, cname); StringValue(pass); GetCipher(self, ctx); if (NIL_P(init_v)) memcpy(iv, "OpenSSL for Ruby rulez!", sizeof(iv)); else{ StringValue(init_v); if (EVP_MAX_IV_LENGTH > RSTRING_LEN(init_v)) { memset(iv, 0, EVP_MAX_IV_LENGTH); memcpy(iv, RSTRING_PTR(init_v), RSTRING_LEN(init_v)); } else memcpy(iv, RSTRING_PTR(init_v), sizeof(iv)); } EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), EVP_md5(), iv, (unsigned char *)RSTRING_PTR(pass), RSTRING_LENINT(pass), 1, key, NULL); p_key = key; p_iv = iv; } else { GetCipher(self, ctx); } if (EVP_CipherInit_ex(ctx, NULL, NULL, p_key, p_iv, mode) != 1) { ossl_raise(eCipherError, NULL); } return self; }
static VALUE ossl_ocspres_initialize(int argc, VALUE *argv, VALUE self) { VALUE arg; unsigned char *p; rb_scan_args(argc, argv, "01", &arg); if(!NIL_P(arg)) { arg = ossl_to_der_if_possible(arg); StringValue(arg); p = RSTRING_PTR(arg); if(!d2i_OCSP_RESPONSE((OCSP_RESPONSE**)&DATA_PTR(self), &p, RSTRING_LEN(arg))) { ossl_raise(eOCSPError, "cannot load DER encoded response"); } } return self; }
/* * call-seq: * session.to_der -> aString * * Returns an ASN1 encoded String that contains the Session object. */ static VALUE ossl_ssl_session_to_der(VALUE self) { SSL_SESSION *ctx; unsigned char *p; int len; VALUE str; GetSSLSession(self, ctx); len = i2d_SSL_SESSION(ctx, NULL); if (len <= 0) { ossl_raise(eSSLSession, "i2d_SSL_SESSION"); } str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); i2d_SSL_SESSION(ctx, &p); ossl_str_adjust(str, p); return str; }
/* * call-seq: * DH.generate(size [, generator]) -> dh * * Creates a new DH instance from scratch by generating the private and public * components alike. * * === Parameters * * +size+ is an integer representing the desired key size. Keys smaller than 1024 bits should be considered insecure. * * +generator+ is a small number > 1, typically 2 or 5. * */ static VALUE ossl_dh_s_generate(int argc, VALUE *argv, VALUE klass) { DH *dh ; int g = 2; VALUE size, gen, obj; if (rb_scan_args(argc, argv, "11", &size, &gen) == 2) { g = NUM2INT(gen); } dh = dh_generate(NUM2INT(size), g); obj = dh_instance(klass, dh); if (obj == Qfalse) { DH_free(dh); ossl_raise(eDHError, NULL); } return obj; }
/* * call-seq: * PKCS12.new -> pkcs12 * PKCS12.new(str) -> pkcs12 * PKCS12.new(str, pass) -> pkcs12 * * === Parameters * * +str+ - Must be a DER encoded PKCS12 string. * * +pass+ - string */ static VALUE ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self) { BIO *in; VALUE arg, pass, pkey, cert, ca; char *passphrase; EVP_PKEY *key; X509 *x509; STACK_OF(X509) *x509s = NULL; int st = 0; PKCS12 *pkcs = DATA_PTR(self); if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) return self; passphrase = NIL_P(pass) ? NULL : StringValuePtr(pass); in = ossl_obj2bio(arg); d2i_PKCS12_bio(in, &pkcs); DATA_PTR(self) = pkcs; BIO_free(in); pkey = cert = ca = Qnil; if(!PKCS12_parse(pkcs, passphrase, &key, &x509, &x509s)) ossl_raise(ePKCS12Error, "PKCS12_parse"); pkey = rb_protect((VALUE(*)_((VALUE)))ossl_pkey_new, (VALUE)key, &st); /* NO DUP */ if(st) goto err; cert = rb_protect((VALUE(*)_((VALUE)))ossl_x509_new, (VALUE)x509, &st); if(st) goto err; if(x509s){ ca = rb_protect((VALUE(*)_((VALUE)))ossl_x509_sk2ary, (VALUE)x509s, &st); if(st) goto err; } err: X509_free(x509); sk_X509_pop_free(x509s, X509_free); ossl_pkcs12_set_key(self, pkey); ossl_pkcs12_set_cert(self, cert); ossl_pkcs12_set_ca_certs(self, ca); if(st) rb_jump_tag(st); return self; }
/* * call-seq: * cipher.auth_data = string -> string * * Sets the cipher's additional authenticated data. This field must be * set when using AEAD cipher modes such as GCM or CCM. If no associated * data shall be used, this method must *still* be called with a value of "". * The contents of this field should be non-sensitive data which will be * added to the ciphertext to generate the authentication tag which validates * the contents of the ciphertext. * * The AAD must be set prior to encryption or decryption. In encryption mode, * it must be set after calling Cipher#encrypt and setting Cipher#key= and * Cipher#iv=. When decrypting, the authenticated data must be set after key, * iv and especially *after* the authentication tag has been set. I.e. set it * only after calling Cipher#decrypt, Cipher#key=, Cipher#iv= and * Cipher#auth_tag= first. */ static VALUE ossl_cipher_set_auth_data(VALUE self, VALUE data) { EVP_CIPHER_CTX *ctx; unsigned char *in; long in_len, out_len; StringValue(data); in = (unsigned char *) RSTRING_PTR(data); in_len = RSTRING_LEN(data); GetCipher(self, ctx); if (!ossl_cipher_update_long(ctx, NULL, &out_len, in, in_len)) ossl_raise(eCipherError, "couldn't set additional authenticated data"); return data; }
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; }
/* * 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; }
static VALUE ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode) { EVP_CIPHER_CTX *ctx; unsigned char key[EVP_MAX_KEY_LENGTH], *p_key = NULL; unsigned char iv[EVP_MAX_IV_LENGTH], *p_iv = NULL; VALUE pass, init_v; if(rb_scan_args(argc, argv, "02", &pass, &init_v) > 0){ /* * oops. this code mistakes salt for IV. * We deprecated the arguments for this method, but we decided * keeping this behaviour for backward compatibility. */ StringValue(pass); GetCipher(self, ctx); if (NIL_P(init_v)) memcpy(iv, "OpenSSL for Ruby rulez!", sizeof(iv)); else{ char *cname = rb_class2name(rb_obj_class(self)); rb_warning("key derivation by %s#encrypt is deprecated; " "use %s::pkcs5_keyivgen instead", cname, cname); StringValue(init_v); if (EVP_MAX_IV_LENGTH > RSTRING(init_v)->len) { memset(iv, 0, EVP_MAX_IV_LENGTH); memcpy(iv, RSTRING(init_v)->ptr, RSTRING(init_v)->len); } else memcpy(iv, RSTRING(init_v)->ptr, sizeof(iv)); } EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), EVP_md5(), iv, RSTRING(pass)->ptr, RSTRING(pass)->len, 1, key, NULL); p_key = key; p_iv = iv; } else { GetCipher(self, ctx); } if (EVP_CipherInit_ex(ctx, NULL, NULL, p_key, p_iv, mode) != 1) { ossl_raise(eCipherError, NULL); } return self; }
/* * call-seq: * OpenSSL.print_mem_leaks -> true | false * * For debugging the Ruby/OpenSSL library. Calls CRYPTO_mem_leaks_fp(stderr). * Prints detected memory leaks to standard error. This cleans the global state * up thus you cannot use any methods of the library after calling this. * * Returns +true+ if leaks detected, +false+ otherwise. * * This is available only when built with a capable OpenSSL and --enable-debug * configure option. * * === Example * OpenSSL.mem_check_start * NOT_GCED = OpenSSL::PKey::RSA.new(256) * * END { * GC.start * OpenSSL.print_mem_leaks # will print the leakage * } */ static VALUE print_mem_leaks(VALUE self) { #if OPENSSL_VERSION_NUMBER >= 0x10100000 int ret; #endif BN_CTX_free(ossl_bn_ctx); ossl_bn_ctx = NULL; #if OPENSSL_VERSION_NUMBER >= 0x10100000 ret = CRYPTO_mem_leaks_fp(stderr); if (ret < 0) ossl_raise(eOSSLError, "CRYPTO_mem_leaks_fp"); return ret ? Qfalse : Qtrue; #else CRYPTO_mem_leaks_fp(stderr); return Qnil; #endif }
static int ossl_asn1_is_explicit(VALUE obj) { VALUE s; int ret = -1; s = ossl_asn1_get_tagging(obj); if(NIL_P(s)) return 0; else if(SYMBOL_P(s)){ if (SYM2ID(s) == sIMPLICIT) ret = 0; else if (SYM2ID(s) == sEXPLICIT) ret = 1; } if(ret < 0){ ossl_raise(eASN1Error, "invalid tag default"); } return ret; }
static VALUE decode_bstr(unsigned char* der, int length, long *unused_bits) { ASN1_BIT_STRING *bstr; const unsigned char *p; long len; VALUE ret; p = der; if(!(bstr = d2i_ASN1_BIT_STRING(NULL, &p, length))) ossl_raise(eASN1Error, NULL); len = bstr->length; *unused_bits = 0; if(bstr->flags & ASN1_STRING_FLAG_BITS_LEFT) *unused_bits = bstr->flags & 0x07; ret = rb_str_new((const char *)bstr->data, len); ASN1_BIT_STRING_free(bstr); return ret; }
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; }