org.jruby.ext.openssl.impl.Signed Maven / Gradle / Ivy
/***** BEGIN LICENSE BLOCK *****
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Common 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/cpl-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) 2008 Ola Bini
*
* 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.impl;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509CRL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DLSequence;
import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.Certificate;
import org.bouncycastle.jce.provider.X509CertificateObject;
import org.jruby.ext.openssl.x509store.X509AuxCertificate;
/** PKCS7_SIGNED
*
* @author Ola Bini
*/
public class Signed {
/**
* Describe version here.
*/
private int version;
/**
* Describe crl here.
*/
private Collection crl = new ArrayList();
/**
* Describe cert here.
*/
private Collection cert = new ArrayList();
/**
* Describe mdAlgs here.
*/
private Set mdAlgs = new HashSet();
/**
* Describe signerInfo here.
*/
private Collection signerInfo = new ArrayList();
PKCS7 contents;
/**
* Get the Version
value.
*
* @return an int
value
*/
public final int getVersion() {
return version;
}
/**
* Set the Version
value.
*
* @param newVersion The new Version value.
*/
public final void setVersion(final int newVersion) {
this.version = newVersion;
}
/**
* Get the SignerInfo
value.
*
* @return a Collection
value
*/
public final Collection getSignerInfo() {
return signerInfo;
}
/**
* Set the SignerInfo
value.
*
* @param newSignerInfo The new SignerInfo value.
*/
public final void setSignerInfo(final Collection newSignerInfo) {
this.signerInfo = newSignerInfo;
}
/**
* Get the MdAlgs
value.
*
* @return a Set
value
*/
public final Set getMdAlgs() {
return mdAlgs;
}
/**
* Set the MdAlgs
value.
*
* @param newMdAlgs The new MdAlgs value.
*/
public final void setMdAlgs(final Set newMdAlgs) {
this.mdAlgs = newMdAlgs;
}
/**
* Get the Contents
value.
*
* @return a PKCS7
value
*/
public final PKCS7 getContents() {
return contents;
}
/**
* Set the Contents
value.
*
* @param newContents The new Contents value.
*/
public final void setContents(final PKCS7 newContents) {
this.contents = newContents;
}
/**
* Get the Cert
value.
*
* @return a Collection
value
*/
public final Collection getCert() {
return cert;
}
/**
* Set the Cert
value.
*
* @param newCert The new Cert value.
*/
public final void setCert(final Collection newCert) {
this.cert = newCert;
}
/**
* Get the Crl
value.
*
* @return a Set
value
*/
public final Collection getCrl() {
return crl;
}
/**
* Set the Crl
value.
*
* @param newCrl The new Crl value.
*/
public final void setCrl(final Collection newCrl) {
this.crl = newCrl;
}
@Override
public String toString() {
return "#";
}
public ASN1Encodable asASN1() {
ASN1EncodableVector vector = new ASN1EncodableVector();
vector.add(new ASN1Integer(version));
vector.add(digestAlgorithmsToASN1Set());
if (contents == null) {
contents = PKCS7.newEmpty();
}
vector.add(contents.asASN1());
if (cert != null && cert.size() > 0) {
if (cert.size() > 1) {
vector.add(new DERTaggedObject(false, 0, certificatesToASN1Set()));
} else {
// Encode the signer certificate directly for OpenSSL compatibility.
// OpenSSL does not support multiple signer signature.
// And OpenSSL requires EXPLICIT tagging.
vector.add(new DERTaggedObject(true, 0, firstCertificatesToASN1()));
}
}
if (crl != null && crl.size() > 0) {
vector.add(new DERTaggedObject(false, 1, crlsToASN1Set()));
}
vector.add(signerInfosToASN1Set());
return new DLSequence(vector);
}
private ASN1Set digestAlgorithmsToASN1Set() {
ASN1EncodableVector vector = new ASN1EncodableVector();
for(AlgorithmIdentifier ai : mdAlgs) {
vector.add(ai.toASN1Primitive());
}
return new DERSet(vector);
}
// This imlementation is stupid and wasteful. Ouch.
private ASN1Set certificatesToASN1Set() {
try {
ASN1EncodableVector vector = new ASN1EncodableVector();
for(X509AuxCertificate c : cert) {
vector.add(new ASN1InputStream(new ByteArrayInputStream(c.getEncoded())).readObject());
}
return new DERSet(vector);
} catch(Exception e) {
return null;
}
}
private ASN1Sequence firstCertificatesToASN1() {
try {
X509AuxCertificate c = cert.iterator().next();
return (ASN1Sequence) (new ASN1InputStream(new ByteArrayInputStream(c.getEncoded())).readObject());
} catch (Exception e) {}
return null;
}
private ASN1Set crlsToASN1Set() {
throw new RuntimeException("TODO: implement CRL part");
}
private ASN1Set signerInfosToASN1Set() {
ASN1EncodableVector vector = new ASN1EncodableVector();
for(SignerInfoWithPkey si : signerInfo) {
vector.add(si.toASN1Object());
}
return new DERSet(vector);
}
/**
* SignedData ::= SEQUENCE {
* version Version,
* digestAlgorithms DigestAlgorithmIdentifiers,
* contentInfo ContentInfo,
* certificates [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL,
* crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
* signerInfos SignerInfos }
*
* Version ::= INTEGER
*
* DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
*
* SignerInfos ::= SET OF SignerInfo
*/
public static Signed fromASN1(ASN1Encodable content) throws PKCS7Exception{
ASN1Sequence sequence = (ASN1Sequence)content;
ASN1Integer version = (ASN1Integer)sequence.getObjectAt(0);
ASN1Set digestAlgos = (ASN1Set)sequence.getObjectAt(1);
ASN1Encodable contentInfo = sequence.getObjectAt(2);
ASN1Encodable certificates = null;
ASN1Encodable crls = null;
int index = 3;
ASN1Encodable tmp = sequence.getObjectAt(index);
if((tmp instanceof ASN1TaggedObject) && ((ASN1TaggedObject)tmp).getTagNo() == 0) {
certificates = ((ASN1TaggedObject)tmp).getObject();
index++;
}
tmp = sequence.getObjectAt(index);
if((tmp instanceof ASN1TaggedObject) && ((ASN1TaggedObject)tmp).getTagNo() == 1) {
crls = ((ASN1TaggedObject)tmp).getObject();
index++;
}
ASN1Set signerInfos = (ASN1Set)sequence.getObjectAt(index);
Signed signed = new Signed();
signed.setVersion(version.getValue().intValue());
signed.setMdAlgs(algorithmIdentifiersFromASN1Set(digestAlgos));
signed.setContents(PKCS7.fromASN1(contentInfo));
if(certificates != null) {
signed.setCert(certificatesFromASN1Set(certificates));
}
if(crls != null) {
throw new RuntimeException("TODO: implement CRL part");
}
signed.setSignerInfo(signerInfosFromASN1Set(signerInfos));
return signed;
}
private static Collection certificatesFromASN1Set(ASN1Encodable content) throws PKCS7Exception {
Collection result = new ArrayList();
if (content instanceof ASN1Sequence) {
try {
for (Enumeration> enm = ((ASN1Sequence) content).getObjects(); enm.hasMoreElements();) {
ASN1Encodable current = (ASN1Encodable) enm.nextElement();
result.add(certificateFromASN1(current));
}
} catch (IllegalArgumentException iae) {
result.add(certificateFromASN1(content));
}
} else if (content instanceof ASN1Set) {
// EXPLICIT Set shouldn't apper here but keep this for backward compatibility.
for (Enumeration> enm = ((ASN1Set) content).getObjects(); enm.hasMoreElements();) {
ASN1Encodable current = (ASN1Encodable) enm.nextElement();
result.add(certificateFromASN1(current));
}
} else {
throw new PKCS7Exception(PKCS7.F_B64_READ_PKCS7, PKCS7.R_CERTIFICATE_VERIFY_ERROR, "unknown certificates format");
}
return result;
}
private static X509AuxCertificate certificateFromASN1(ASN1Encodable current) throws PKCS7Exception {
Certificate struct = Certificate.getInstance(current);
try {
return new X509AuxCertificate(struct);
} catch (IOException e) {
throw new PKCS7Exception(PKCS7.F_B64_READ_PKCS7, PKCS7.R_CERTIFICATE_VERIFY_ERROR, e);
} catch (CertificateException e) {
throw new PKCS7Exception(PKCS7.F_B64_READ_PKCS7, PKCS7.R_CERTIFICATE_VERIFY_ERROR, e);
}
}
private static Set algorithmIdentifiersFromASN1Set(ASN1Encodable content) {
ASN1Set set = (ASN1Set)content;
Set result = new HashSet();
for(Enumeration> e = set.getObjects(); e.hasMoreElements();) {
result.add(AlgorithmIdentifier.getInstance(e.nextElement()));
}
return result;
}
private static Collection signerInfosFromASN1Set(ASN1Encodable content) {
ASN1Set set = (ASN1Set)content;
Collection result = new ArrayList();
for(Enumeration> e = set.getObjects(); e.hasMoreElements();) {
result.add(SignerInfoWithPkey.getInstance(e.nextElement()));
}
return result;
}
}// Signed
© 2015 - 2025 Weber Informatics LLC | Privacy Policy