/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006, 2007 Ola Bini <ola@ologix.com> * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.io.IOException; import java.io.StringWriter; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.security.GeneralSecurityException; import java.security.PrivateKey; import java.security.cert.CertificateEncodingException; import org.bouncycastle.asn1.ASN1Encodable; import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyBignum; import org.jruby.RubyClass; import org.jruby.RubyFile; import org.jruby.RubyModule; import org.jruby.RubyNumeric; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.anno.JRubyClass; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.runtime.Arity; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.Visibility; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.ByteList; import org.jruby.ext.openssl.impl.ASN1Registry; import org.jruby.ext.openssl.impl.BIO; import org.jruby.ext.openssl.impl.CipherSpec; import org.jruby.ext.openssl.impl.MemBIO; import org.jruby.ext.openssl.impl.Mime; import org.jruby.ext.openssl.impl.NotVerifiedPKCS7Exception; import org.jruby.ext.openssl.impl.PKCS7Exception; import org.jruby.ext.openssl.impl.RecipInfo; import org.jruby.ext.openssl.impl.SMIME; import org.jruby.ext.openssl.impl.SignerInfoWithPkey; import org.jruby.ext.openssl.x509store.PEMInputOutput; import org.jruby.ext.openssl.x509store.Store; import org.jruby.ext.openssl.x509store.X509AuxCertificate; import static org.jruby.ext.openssl.OpenSSL.*; /** * @author <a href="mailto:ola.bini@ki.se">Ola Bini</a> */ @JRubyClass(name = "OpenSSL::PKCS7") public class PKCS7 extends RubyObject { private static final long serialVersionUID = -3925104500966826973L; private static ObjectAllocator PKCS7_ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new PKCS7(runtime, klass); } }; public static void createPKCS7(final Ruby runtime, final RubyModule _OpenSSL) { RubyClass _PKCS7 = _OpenSSL.defineClassUnder("PKCS7", runtime.getObject(), PKCS7_ALLOCATOR); RubyClass _OpenSSLError = runtime.getModule("OpenSSL").getClass("OpenSSLError"); _PKCS7.defineClassUnder("PKCS7Error", _OpenSSLError, _OpenSSLError.getAllocator()); _PKCS7.addReadWriteAttribute(runtime.getCurrentContext(), "data"); _PKCS7.addReadWriteAttribute(runtime.getCurrentContext(), "error_string"); _PKCS7.defineAnnotatedMethods(PKCS7.class); SignerInfo.createSignerInfo(runtime, _PKCS7); RecipientInfo.createRecipientInfo(runtime, _PKCS7); _PKCS7.setConstant("TEXT", runtime.newFixnum(1)); _PKCS7.setConstant("NOCERTS", runtime.newFixnum(2)); _PKCS7.setConstant("NOSIGS", runtime.newFixnum(4)); _PKCS7.setConstant("NOCHAIN", runtime.newFixnum(8)); _PKCS7.setConstant("NOINTERN", runtime.newFixnum(16)); _PKCS7.setConstant("NOVERIFY", runtime.newFixnum(32)); _PKCS7.setConstant("DETACHED", runtime.newFixnum(64)); _PKCS7.setConstant("BINARY", runtime.newFixnum(128)); _PKCS7.setConstant("NOATTR", runtime.newFixnum(256)); _PKCS7.setConstant("NOSMIMECAP", runtime.newFixnum(512)); } public static BIO obj2bio(IRubyObject obj) { if ( obj instanceof RubyFile ) { throw obj.getRuntime().newNotImplementedError("TODO: handle RubyFile correctly"); // if (TYPE(obj) == T_FILE) { // OpenFile *fptr; // GetOpenFile(obj, fptr); // rb_io_check_readable(fptr); // bio = BIO_new_fp(fptr->f, BIO_NOCLOSE); } else { final ByteList str = obj.asString().getByteList(); return BIO.memBuf(str.getUnsafeBytes(), str.getBegin(), str.getRealSize()); } } @Deprecated // no loger used public static PKCS7 wrap(RubyClass klass, org.jruby.ext.openssl.impl.PKCS7 p7) { PKCS7 wrapped = new PKCS7(klass.getRuntime(), klass); wrapped.p7 = p7; return wrapped; } private static PKCS7 wrap(final Ruby runtime, org.jruby.ext.openssl.impl.PKCS7 p7) { PKCS7 wrapped = new PKCS7(runtime, _PKCS7(runtime)); wrapped.p7 = p7; return wrapped; } public static IRubyObject membio2str(Ruby runtime, BIO bio) { return runtime.newString( new ByteList(((MemBIO) bio).getMemCopy(), false) ); } private static List<X509AuxCertificate> getAuxCerts(final IRubyObject arg) { final RubyArray arr = (RubyArray) arg; List<X509AuxCertificate> certs = new ArrayList<X509AuxCertificate>(arr.size()); for ( int i = 0; i<arr.size(); i++ ) { certs.add( ((X509Cert) arr.eltInternal(i)).getAuxCert() ); } return certs; } @JRubyMethod(meta = true) public static IRubyObject read_smime(IRubyObject self, IRubyObject arg) { final Ruby runtime = self.getRuntime(); final BIO in = obj2bio(arg); final BIO[] out = new BIO[]{ null }; org.jruby.ext.openssl.impl.PKCS7 pkcs7Impl = null; try { pkcs7Impl = new SMIME(Mime.DEFAULT).readPKCS7(in, out); } catch (IOException ioe) { throw newPKCS7Error(runtime, ioe.getMessage()); } catch (PKCS7Exception pkcs7e) { throw newPKCS7Error(runtime, pkcs7e); } if ( pkcs7Impl == null ) { throw newPKCS7Error(runtime, (String) null); } IRubyObject data = out[0] != null ? membio2str(runtime, out[0]) : runtime.getNil(); final PKCS7 pkcs7 = wrap(runtime, pkcs7Impl); pkcs7.setData(data); return pkcs7; } @JRubyMethod(meta = true, rest = true) public static IRubyObject write_smime(IRubyObject self, IRubyObject[] args) { final Ruby runtime = self.getRuntime(); final PKCS7 pkcs7; IRubyObject data = runtime.getNil(); IRubyObject flags = runtime.getNil(); switch ( Arity.checkArgumentCount(runtime, args, 1, 3) ) { case 3: flags = args[2]; case 2: data = args[1]; default: pkcs7 = (PKCS7) args[0]; } if (data.isNil()) data = pkcs7.getData(); final int flg = flags.isNil() ? 0 : RubyNumeric.fix2int(flags); String smime = ""; try { smime = new SMIME().writePKCS7(pkcs7.p7, data.asJavaString(), flg); } catch (PKCS7Exception e) { throw newPKCS7Error(runtime, e); } catch (IOException e) { throw newPKCS7Error(runtime, e.getMessage()); } return RubyString.newString(runtime, smime); } @JRubyMethod(meta = true, rest = true) public static IRubyObject sign(IRubyObject self, IRubyObject[] args) { final Ruby runtime = self.getRuntime(); final X509Cert cert; final PKey key; final IRubyObject data; IRubyObject certs = runtime.getNil(); IRubyObject flags = runtime.getNil(); switch ( Arity.checkArgumentCount(runtime, args, 3, 5) ) { case 5: flags = args[4]; case 4: certs = args[3]; default: cert = (X509Cert) args[0]; key = (PKey) args[1]; data = args[2]; } X509AuxCertificate auxCert = cert.getAuxCert(); PrivateKey privKey = key.getPrivateKey(); final int flg = flags.isNil() ? 0 : RubyNumeric.fix2int(flags); final BIO dataBIO = obj2bio(data); List<X509AuxCertificate> auxCerts = certs.isNil() ? null : getAuxCerts(certs); org.jruby.ext.openssl.impl.PKCS7 pkcs7Impl; try { pkcs7Impl = org.jruby.ext.openssl.impl.PKCS7.sign(auxCert, privKey, auxCerts, dataBIO, flg); } catch (PKCS7Exception e) { throw newPKCS7Error(runtime, e); } final PKCS7 pkcs7 = wrap(runtime, pkcs7Impl); pkcs7.setData(data); return pkcs7; } /** ossl_pkcs7_s_encrypt * */ @JRubyMethod(meta = true, rest = true) public static IRubyObject encrypt(IRubyObject self, IRubyObject[] args) { final Ruby runtime = self.getRuntime(); IRubyObject certs, data, cipher = runtime.getNil(), flags = runtime.getNil(); switch ( Arity.checkArgumentCount(self.getRuntime(), args, 2, 4) ) { case 4: flags = args[3]; case 3: cipher = args[2]; } data = args[1]; certs = args[0]; CipherSpec cipherSpec = null; if ( cipher.isNil() ) { try { javax.crypto.Cipher c = SecurityHelper.getCipher("RC2/CBC/PKCS5Padding"); cipherSpec = new CipherSpec(c, Cipher.Algorithm.javaToOssl("RC2/CBC/PKCS5Padding", 40), 40); } catch (GeneralSecurityException e) { throw newPKCS7Error(runtime, e); } } else { final Cipher c = (Cipher) cipher; cipherSpec = new CipherSpec(c.getCipherInstance(), c.getName(), c.getGenerateKeyLength() * 8); } final int flg = flags.isNil() ? 0 : RubyNumeric.fix2int(flags); final List<X509AuxCertificate> auxCerts = getAuxCerts(certs); final byte[] dataBytes = data.asString().getBytes(); org.jruby.ext.openssl.impl.PKCS7 pkcs7Impl; try { pkcs7Impl = org.jruby.ext.openssl.impl.PKCS7.encrypt(auxCerts, dataBytes, cipherSpec, flg); } catch (PKCS7Exception pkcs7e) { throw newPKCS7Error(self.getRuntime(), pkcs7e); } final PKCS7 pkcs7 = wrap(runtime, pkcs7Impl); pkcs7.setData(data); return pkcs7; } public PKCS7(Ruby runtime, RubyClass type) { super(runtime,type); } private org.jruby.ext.openssl.impl.PKCS7 p7; @JRubyMethod(name="initialize", rest = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, IRubyObject[] args) { if ( Arity.checkArgumentCount(getRuntime(), args, 0, 1) == 0 ) { p7 = new org.jruby.ext.openssl.impl.PKCS7(); try { p7.setType(ASN1Registry.NID_undef); } catch (PKCS7Exception e) { throw newPKCS7Error(getRuntime(), e); } return this; } IRubyObject arg = to_der_if_possible(context, args[0]); BIO input = obj2bio(arg); try { p7 = org.jruby.ext.openssl.impl.PKCS7.readPEM(input); if (p7 == null) { input.reset(); p7 = org.jruby.ext.openssl.impl.PKCS7.fromASN1(input); } } catch (IllegalArgumentException e) { throw getRuntime().newArgumentError(e.getMessage()); } catch (IOException ioe) { throw newPKCS7Error(getRuntime(), ioe.getMessage()); } catch (PKCS7Exception pkcs7e) { throw newPKCS7Error(getRuntime(), pkcs7e); } setData( getRuntime().getNil() ); return this; } @Override @JRubyMethod(visibility = Visibility.PRIVATE) public IRubyObject initialize_copy(IRubyObject obj) { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: PKCS7#initialize_copy"); return this; } @JRubyMethod(name="type=") public IRubyObject set_type(IRubyObject type) { final String typeStr = type.toString(); // likely a Symbol int typeId = ASN1Registry.NID_undef; if ("signed".equals(typeStr)) { typeId = ASN1Registry.NID_pkcs7_signed; } else if ("data".equals(typeStr)) { typeId = ASN1Registry.NID_pkcs7_data; } else if ("signedAndEnveloped".equals(typeStr)) { typeId = ASN1Registry.NID_pkcs7_signedAndEnveloped; } else if ("enveloped".equals(typeStr)) { typeId = ASN1Registry.NID_pkcs7_enveloped; } else if ("encrypted".equals(typeStr)) { typeId = ASN1Registry.NID_pkcs7_encrypted; } try { p7.setType(typeId); } catch (PKCS7Exception pkcs7e) { throw newPKCS7Error(getRuntime(), pkcs7e); } return type; } @JRubyMethod(name="type") public IRubyObject get_type() { if(p7.isSigned()) { return getRuntime().newSymbol("signed"); } if(p7.isEncrypted()) { return getRuntime().newSymbol("encrypted"); } if(p7.isEnveloped()) { return getRuntime().newSymbol("enveloped"); } if(p7.isSignedAndEnveloped()) { return getRuntime().newSymbol("signedAndEnveloped"); } if(p7.isData()) { return getRuntime().newSymbol("data"); } return getRuntime().getNil(); } @JRubyMethod(name = "detached") public IRubyObject detached() { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: PKCS7#detached"); return getRuntime().getNil(); } @JRubyMethod(name = "detached=") public IRubyObject set_detached(IRubyObject obj) { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: PKCS7#detached="); return getRuntime().getNil(); } @JRubyMethod(name = "detached?") public IRubyObject detached_p() { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: PKCS7#detached?"); return getRuntime().getNil(); } @JRubyMethod(name="cipher=") public IRubyObject set_cipher(IRubyObject obj) { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: PKCS7#cipher="); return getRuntime().getNil(); } @JRubyMethod public IRubyObject add_signer(IRubyObject obj) { SignerInfoWithPkey signedInfo = ((SignerInfo) obj).getSignerInfo().dup(); try { p7.addSigner(signedInfo); } catch (PKCS7Exception e) { throw newPKCS7Error(getRuntime(), e); } // TODO: Handle exception here if ( p7.isSigned() ) { ASN1Encodable objectId = org.jruby.ext.openssl.impl.PKCS7.OID_pkcs7_data; signedInfo.addSignedAttribute(ASN1Registry.NID_pkcs9_contentType, objectId); } return this; } /** ossl_pkcs7_get_signer * * This seems to return a list of SignerInfo objects. * */ @JRubyMethod public IRubyObject signers() { Collection<SignerInfoWithPkey> signerInfos = p7.getSignerInfo(); RubyArray ary = getRuntime().newArray(signerInfos.size()); for ( SignerInfoWithPkey signerInfo : signerInfos ) { ary.append( SignerInfo.create(getRuntime(), signerInfo) ); } return ary; } @JRubyMethod public IRubyObject add_recipient(IRubyObject obj) { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: PKCS7#add_recipient"); return getRuntime().getNil(); } @JRubyMethod public IRubyObject recipients() { Collection<RecipInfo> sk; if(p7.isEnveloped()) { sk = p7.getEnveloped().getRecipientInfo(); } else if(p7.isSignedAndEnveloped()) { sk = p7.getSignedAndEnveloped().getRecipientInfo(); } else { sk = null; } if(sk == null) { return getRuntime().newArray(); } RubyArray ary = getRuntime().newArray(sk.size()); for(RecipInfo ri : sk) { ary.append(RecipientInfo.create(getRuntime(), ri)); } return ary; } @JRubyMethod public IRubyObject add_certificate(IRubyObject obj) { try { p7.addCertificate(((X509Cert)obj).getAuxCert()); } catch (PKCS7Exception pkcse) { throw newPKCS7Error(getRuntime(), pkcse); } return this; } @JRubyMethod(name="certificates=") public IRubyObject set_certificates(IRubyObject obj) { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: PKCS7#certificates="); return getRuntime().getNil(); } private Collection<X509AuxCertificate> getCertificates() { Collection<X509AuxCertificate> certs; int i = p7.getType(); switch(i) { case ASN1Registry.NID_pkcs7_signed: certs = p7.getSign().getCert(); break; case ASN1Registry.NID_pkcs7_signedAndEnveloped: certs = p7.getSignedAndEnveloped().getCert(); break; default: certs = new HashSet<X509AuxCertificate>(); break; } return certs; } private RubyArray certsToArray(Collection<X509AuxCertificate> certs) throws CertificateEncodingException { RubyArray ary = getRuntime().newArray(certs.size()); for(X509AuxCertificate x509 : certs) { ary.append(X509Cert.wrap(getRuntime(), x509)); } return ary; } @JRubyMethod public IRubyObject certificates() { try { return certsToArray(getCertificates()); } catch (CertificateEncodingException cee) { throw newPKCS7Error(getRuntime(), cee.getMessage()); } } @JRubyMethod public IRubyObject add_crl(IRubyObject obj) { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: PKCS7#add_crl"); return getRuntime().getNil(); } @JRubyMethod(name="crls=") public IRubyObject set_crls(IRubyObject obj) { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: PKCS7#crls="); return getRuntime().getNil(); } @JRubyMethod public IRubyObject crls() { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: PKCS7#crls"); return getRuntime().getNil(); } @JRubyMethod(name={"add_data", "data="}) public IRubyObject add_data(IRubyObject obj) { if (p7.isSigned()) { try { p7.contentNew(ASN1Registry.NID_pkcs7_data); } catch (PKCS7Exception pkcs7e) { throw newPKCS7Error(getRuntime(), pkcs7e); } } BIO in = obj2bio(obj); BIO out = null; try { out = p7.dataInit(null); } catch (PKCS7Exception pkcs7e) { throw newPKCS7Error(getRuntime(), pkcs7e); } byte[] buf = new byte[4096]; for(;;) { try { int i = in.read(buf, 0, buf.length); if(i <= 0) { break; } if(out != null) { out.write(buf, 0, i); } } catch(IOException e) { throw getRuntime().newIOErrorFromException(e); } } try { p7.dataFinal(out); } catch (PKCS7Exception pkcs7e) { throw newPKCS7Error(getRuntime(), pkcs7e); } setData(getRuntime().getNil()); return obj; } @JRubyMethod(rest=true) public IRubyObject verify(IRubyObject[] args) { final Ruby runtime = getRuntime(); IRubyObject certs; X509Store store; IRubyObject indata = runtime.getNil(); IRubyObject vflags = runtime.getNil(); switch ( Arity.checkArgumentCount(runtime, args, 2, 4) ) { case 4: vflags = args[3]; case 3: indata = args[2]; default: store = (X509Store) args[1]; certs = args[0]; } final int flg = vflags.isNil() ? 0 : RubyNumeric.fix2int(vflags); if ( indata.isNil() ) indata = getData(); final BIO in = indata.isNil() ? null : obj2bio(indata); List<X509AuxCertificate> x509s = certs.isNil() ? null : getAuxCerts(certs); final Store storeStr = store.getStore(); final BIO out = BIO.mem(); boolean result = false; try { p7.verify(x509s, storeStr, in, out, flg); result = true; } catch (NotVerifiedPKCS7Exception e) { // result = false; } catch (PKCS7Exception pkcs7e) { if ( isDebug(runtime) ) { // runtime.getOut().println(pkcs7e); pkcs7e.printStackTrace(runtime.getOut()); } // result = false; } IRubyObject data = membio2str(getRuntime(), out); setData(data); return result ? runtime.getTrue() : runtime.getFalse(); } @JRubyMethod(rest=true) public IRubyObject decrypt(IRubyObject[] args) { IRubyObject dflags; if ( Arity.checkArgumentCount(getRuntime(), args, 2, 3) == 3 ) { dflags = args[2]; } else { dflags = getRuntime().getNil(); } PKey pkey = (PKey) args[0]; X509Cert cert = (X509Cert) args[1]; final PrivateKey privKey = pkey.getPrivateKey(); final X509AuxCertificate auxCert = cert.getAuxCert(); final int flg = dflags.isNil() ? 0 : RubyNumeric.fix2int(dflags); final BIO out = BIO.mem(); try { p7.decrypt(privKey, auxCert, out, flg); } catch (PKCS7Exception pkcs7e) { throw newPKCS7Error(getRuntime(), pkcs7e); } return membio2str(getRuntime(), out); } @JRubyMethod(name = {"to_pem", "to_s"}) public IRubyObject to_pem() { StringWriter writer = new StringWriter(); try { PEMInputOutput.writePKCS7(writer, p7.toASN1()); return getRuntime().newString( writer.toString() ); } catch (IOException e) { throw getRuntime().newIOErrorFromException(e); } } @JRubyMethod public IRubyObject to_der() { try { return getRuntime().newString(new ByteList(p7.toASN1(), false)); } catch (IOException e) { throw newPKCS7Error(getRuntime(), e.getMessage()); } } public void setData(IRubyObject object) { setInstanceVariable("@data", object); } public IRubyObject getData() { return getInstanceVariable("@data"); } @JRubyClass(name = "OpenSSL::PKCS7::SignerInfo") public static class SignerInfo extends RubyObject { private static final long serialVersionUID = -3799397032272738848L; private static ObjectAllocator SIGNERINFO_ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new SignerInfo(runtime, klass); } }; public static void createSignerInfo(final Ruby runtime, final RubyModule _PKCS7) { RubyClass _SignerInfo = _PKCS7.defineClassUnder("SignerInfo", runtime.getObject(), SIGNERINFO_ALLOCATOR); _PKCS7.defineConstant("Signer",_SignerInfo); _SignerInfo.defineAnnotatedMethods(SignerInfo.class); } private static RubyClass _SignerInfo(final Ruby runtime) { return _PKCS7(runtime).getClass("SignerInfo"); } public static SignerInfo create(Ruby runtime, SignerInfoWithPkey info) { SignerInfo instance = new SignerInfo(runtime, _SignerInfo(runtime)); instance.info = info; return instance; } public SignerInfo(Ruby runtime, RubyClass type) { super(runtime,type); } private SignerInfoWithPkey info; SignerInfoWithPkey getSignerInfo() { return info; } @JRubyMethod(visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, IRubyObject arg1, IRubyObject arg2, IRubyObject arg3) { warn(context, "WARNING: unimplemented method called: signerInfo#initialize"); return this; } @JRubyMethod(name={"issuer","name"}) public IRubyObject issuer() { return X509Name.newName(getRuntime(), info.getIssuerAndSerialNumber().getName()); } @JRubyMethod public IRubyObject serial() { return RubyBignum.bignorm(getRuntime(), info.getIssuerAndSerialNumber().getCertificateSerialNumber().getValue()); } @JRubyMethod public IRubyObject signed_time(final ThreadContext context) { warn(context, "WARNING: unimplemented method called: signerInfo#signed_time"); return context.runtime.getNil(); } } @JRubyClass(name = "OpenSSL::PKCS7::RecipientInfo") public static class RecipientInfo extends RubyObject { private static final long serialVersionUID = 6977793206950149902L; private static ObjectAllocator RECIPIENTINFO_ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new RecipientInfo(runtime, klass); } }; public static void createRecipientInfo(final Ruby runtime, final RubyModule _PKCS7) { RubyClass _Recipient = _PKCS7.defineClassUnder("RecipientInfo", runtime.getObject(), RECIPIENTINFO_ALLOCATOR); _Recipient.defineAnnotatedMethods(RecipientInfo.class); } private static RubyClass _RecipientInfo(final Ruby runtime) { return _PKCS7(runtime).getClass("RecipientInfo"); } public RecipientInfo(Ruby runtime, RubyClass type) { super(runtime, type); } public static RecipientInfo create(Ruby runtime, RecipInfo info) { RecipientInfo instance = new RecipientInfo(runtime, _RecipientInfo(runtime)); instance.info = info; return instance; } private RecipInfo info; @JRubyMethod(visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, IRubyObject arg) { warn(context, "WARNING: unimplemented method called: recipientInfo#initialize"); return this; } @JRubyMethod public IRubyObject issuer() { return X509Name.newName(getRuntime(), info.getIssuerAndSerial().getName()); } @JRubyMethod public IRubyObject serial() { return RubyBignum.bignorm(getRuntime(), info.getIssuerAndSerial().getCertificateSerialNumber().getValue()); } @JRubyMethod public IRubyObject enc_key(final ThreadContext context) { warn(context, "WARNING: unimplemented method called: recipientInfo#enc_key"); return context.runtime.getNil(); } } private static RaiseException newPKCS7Error(Ruby runtime, Exception e) { return Utils.newError(runtime, _PKCS7(runtime).getClass("PKCS7Error"), e); } private static RaiseException newPKCS7Error(Ruby runtime, String message) { return Utils.newError(runtime, _PKCS7(runtime).getClass("PKCS7Error"), message); } static RubyClass _PKCS7(final Ruby runtime) { return (RubyClass) runtime.getModule("OpenSSL").getConstant("PKCS7"); } }// PKCS7