All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.virgilsecurity.secureenclave.model.asn1.Envelope Maven / Gradle / Ivy

Go to download

Virgil is a stack of security libraries (ECIES with Crypto Agility wrapped in Virgil Cryptogram) and all the necessary infrastructure to enable seamless, end-to-end encryption for any application, platform or device. Learn about Virgil Crypto Library https://virgilsecurity.com/api-docs/java-android/crypto-library

The newest version!
package com.virgilsecurity.secureenclave.model.asn1;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1ParsingException;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.DERUTF8String;
import org.bouncycastle.asn1.cms.ContentInfo;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;

import com.virgilsecurity.secureenclave.exceptions.ASN1Exception;


/**
 * @author Andrii Iakovenko
 *
 */
public class Envelope implements ASN1Encodable {

    private Collection recipients;
    private Nonce nonce;
    private Map customParams;

    public Envelope(Collection recipients, Nonce nonce, Map customParams) {
        this.recipients = recipients;
        this.nonce = nonce;
        this.customParams = customParams;
    }

    public Envelope(ASN1Sequence asn1Sequence) {
        this.customParams = new HashMap<>();
        ASN1Integer v = ASN1Integer.getInstance(asn1Sequence.getObjectAt(0));
        if (v.getValue().intValue() != 0) {
            throw new ASN1ParsingException("Unsupported version");
        }
        ContentInfo info = ContentInfo.getInstance(asn1Sequence.getObjectAt(1));
        if (! PKCSObjectIdentifiers.envelopedData.getId().equals(info.getContentType().getId())) {
            throw new ASN1ParsingException("Unsupported version");
        }
        DERSequence seq = (DERSequence) info.getContent();

        v = ASN1Integer.getInstance(seq.getObjectAt(0));
        if (v.getValue().intValue() != 2) {
            throw new ASN1ParsingException("Unsupported version");
        }

        DERSet recipientsSet = (DERSet) seq.getObjectAt(1);
        List recipients = new ArrayList<>();
        for (ASN1Encodable recipient : recipientsSet) {
            //TODO check this
            DERTaggedObject tag = (DERTaggedObject) ((DERSequence) recipient).getObjectAt(1);
            if ((tag != null) && (tag.getTagNo() == 3)) {
                recipients.add(PasswordRecipient.getInstance(tag));
            } else if (recipient instanceof DERSequence) {
                recipients.add(PublicKeyRecipient.getInstance(recipient));
            } else {
                throw new ASN1Exception("Unsupported recipient");
            }
        }
        this.recipients = recipients;
        this.nonce = Nonce.getInstance(seq.getObjectAt(2));
        if (asn1Sequence.size() == 3) {
            decodeCustomParams(ASN1TaggedObject.getInstance(asn1Sequence.getObjectAt(2)));
        }

    }

    @Override
    public ASN1Primitive toASN1Primitive() {
        ASN1EncodableVector v = new ASN1EncodableVector();
        v.add(new ASN1Integer(0));
        v.add(new ContentInfo(PKCSObjectIdentifiers.envelopedData,
                        new DERSequence(
                                new ASN1Encodable[] {
                                        new ASN1Integer(2),
                                        new DERSet(this.recipients.toArray(new ASN1Encodable[0])),
                                        this.nonce})
                )
        );
        if(this.customParams!=null && !this.customParams.isEmpty()) {
            v.add(encodeCustomParam());
        }
        return new DERSequence(v);
    }

    private ASN1Encodable encodeCustomParam() {
        ASN1EncodableVector v = new ASN1EncodableVector();
        for (Map.Entry p : this.customParams.entrySet()) {
            if (p.getValue() instanceof byte[]) {
                v.add(new DERSequence(
                        new ASN1Encodable[] {
                                new DERUTF8String(p.getKey()),
                                new DERTaggedObject(true, 2, new DEROctetString((byte[]) p.getValue()))
                        })
                );
            } else if (p.getValue() instanceof Integer) {
                v.add(new DERSequence(
                        new ASN1Encodable[] {
                                new DERUTF8String(p.getKey()),
                                new DERTaggedObject(true, 0, new ASN1Integer((int)p.getValue()))
                        })
                );
            }
        }
        return new DERTaggedObject(true, 0, new DERSet(v));
    }


    private void decodeCustomParams(ASN1TaggedObject asn1) {

        if (asn1.getTagNo() != 0) {
            throw new ASN1ParsingException("Unsupported signature formata");
        }
        ASN1Set set = ASN1Set.getInstance(asn1.getObject());
        for (ASN1Encodable item : set) {
            ASN1Sequence seq = ASN1Sequence.getInstance(item);
            DERUTF8String info = DERUTF8String.getInstance(seq.getObjectAt(0));
            String key = info.getString();

            ASN1TaggedObject tag = ASN1TaggedObject.getInstance(seq.getObjectAt(1));
            switch (tag.getTagNo()) {
                case 2:
                    this.customParams.put(key, getByteValue(tag));
                    break;
                case 0:
                    this.customParams.put(key, getIntValue(tag));
                    break;
                default:
                    throw new ASN1Exception("unsupported tag parameter");
            }

        }
    }

    private Integer getIntValue(ASN1TaggedObject tag) {
        return ASN1Integer.getInstance(tag, true).getValue().intValue();
    }

    private Object getByteValue(ASN1TaggedObject tag) {
        return ASN1OctetString.getInstance(tag.getObject()).getOctets();
    }

    public static Envelope getInstance(Object obj) {
        if (obj == null) {
            return null;
        }
        if (obj instanceof Envelope) {
            return (Envelope) obj;
        }
        return new Envelope(ASN1Sequence.getInstance(obj));
    }

    public Collection getRecipients() {
        return recipients;
    }

    public Map getCustomParams() {
        return customParams;
    }

    public Nonce getNonce() {
        return nonce;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy