// 
// Decompiled by Procyon v0.6.0
// 

package org.bouncycastle.cms;

import java.io.FilterInputStream;
import org.bouncycastle.operator.DigestCalculator;
import java.io.IOException;
import java.io.InputStream;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.cms.PasswordRecipientInfo;
import org.bouncycastle.asn1.cms.KeyAgreeRecipientInfo;
import org.bouncycastle.asn1.cms.KEKRecipientInfo;
import org.bouncycastle.asn1.cms.KEMRecipientInfo;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
import org.bouncycastle.asn1.cms.OtherRecipientInfo;
import org.bouncycastle.asn1.cms.KeyTransRecipientInfo;
import java.util.Collection;
import java.util.List;
import org.bouncycastle.asn1.cms.RecipientInfo;
import java.util.ArrayList;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.ASN1Set;

class CMSEnvelopedHelper
{
    static RecipientInformationStore buildRecipientInformationStore(final ASN1Set set, final AlgorithmIdentifier algorithmIdentifier, final CMSSecureReadable cmsSecureReadable) {
        final ArrayList list = new ArrayList();
        for (int i = 0; i != set.size(); ++i) {
            readRecipientInfo(list, RecipientInfo.getInstance(set.getObjectAt(i)), algorithmIdentifier, cmsSecureReadable);
        }
        return new RecipientInformationStore(list);
    }
    
    private static void readRecipientInfo(final List list, final RecipientInfo recipientInfo, final AlgorithmIdentifier algorithmIdentifier, final CMSSecureReadable cmsSecureReadable) {
        final ASN1Encodable info = recipientInfo.getInfo();
        if (info instanceof KeyTransRecipientInfo) {
            list.add(new KeyTransRecipientInformation((KeyTransRecipientInfo)info, algorithmIdentifier, cmsSecureReadable));
        }
        else if (info instanceof OtherRecipientInfo) {
            final OtherRecipientInfo instance = OtherRecipientInfo.getInstance(info);
            if (CMSObjectIdentifiers.id_ori_kem.equals(instance.getType())) {
                list.add(new KEMRecipientInformation(KEMRecipientInfo.getInstance(instance.getValue()), algorithmIdentifier, cmsSecureReadable));
            }
        }
        else if (info instanceof KEKRecipientInfo) {
            list.add(new KEKRecipientInformation((KEKRecipientInfo)info, algorithmIdentifier, cmsSecureReadable));
        }
        else if (info instanceof KeyAgreeRecipientInfo) {
            KeyAgreeRecipientInformation.readRecipientInfo(list, (KeyAgreeRecipientInfo)info, algorithmIdentifier, cmsSecureReadable);
        }
        else if (info instanceof PasswordRecipientInfo) {
            list.add(new PasswordRecipientInformation((PasswordRecipientInfo)info, algorithmIdentifier, cmsSecureReadable));
        }
    }
    
    static class CMSAuthEnveSecureReadable extends CMSDefaultSecureReadable
    {
        private AlgorithmIdentifier algorithm;
        
        CMSAuthEnveSecureReadable(final AlgorithmIdentifier algorithm, final ASN1ObjectIdentifier asn1ObjectIdentifier, final CMSReadable cmsReadable) {
            super(asn1ObjectIdentifier, cmsReadable);
            this.algorithm = algorithm;
        }
        
        @Override
        public InputStream getInputStream() throws IOException, CMSException {
            return this.readable.getInputStream();
        }
        
        @Override
        public boolean hasAdditionalData() {
            return false;
        }
    }
    
    abstract static class CMSDefaultSecureReadable implements CMSSecureReadable
    {
        protected final ASN1ObjectIdentifier contentType;
        protected CMSReadable readable;
        protected ASN1Set authAttrSet;
        
        CMSDefaultSecureReadable(final ASN1ObjectIdentifier contentType, final CMSReadable readable) {
            this.contentType = contentType;
            this.readable = readable;
        }
        
        @Override
        public ASN1ObjectIdentifier getContentType() {
            return this.contentType;
        }
        
        @Override
        public ASN1Set getAuthAttrSet() {
            return this.authAttrSet;
        }
        
        @Override
        public void setAuthAttrSet(final ASN1Set authAttrSet) {
            this.authAttrSet = authAttrSet;
        }
    }
    
    static class CMSDigestAuthenticatedSecureReadable extends CMSDefaultSecureReadable
    {
        private DigestCalculator digestCalculator;
        
        public CMSDigestAuthenticatedSecureReadable(final DigestCalculator digestCalculator, final ASN1ObjectIdentifier asn1ObjectIdentifier, final CMSReadable cmsReadable) {
            super(asn1ObjectIdentifier, cmsReadable);
            this.digestCalculator = digestCalculator;
        }
        
        @Override
        public InputStream getInputStream() throws IOException, CMSException {
            return new FilterInputStream(this.readable.getInputStream()) {
                @Override
                public int read() throws IOException {
                    final int read = this.in.read();
                    if (read >= 0) {
                        CMSDigestAuthenticatedSecureReadable.this.digestCalculator.getOutputStream().write(read);
                    }
                    return read;
                }
                
                @Override
                public int read(final byte[] array, final int n, final int len) throws IOException {
                    final int read = this.in.read(array, n, len);
                    if (read >= 0) {
                        CMSDigestAuthenticatedSecureReadable.this.digestCalculator.getOutputStream().write(array, n, read);
                    }
                    return read;
                }
            };
        }
        
        public byte[] getDigest() {
            return this.digestCalculator.getDigest();
        }
        
        @Override
        public boolean hasAdditionalData() {
            return true;
        }
    }
}
